summaryrefslogtreecommitdiff
path: root/drivers/usb/isp1760/isp1760-hcd.c
diff options
context:
space:
mode:
authorRui Miguel Silva <rui.silva@linaro.org>2021-05-13 11:47:15 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-05-21 21:05:32 +0300
commit60d789f3bfbb7428e6ba2949de70a6db8e12e8fa (patch)
treed1ff3b1af72d50cbe755e40f08d93e7740368f84 /drivers/usb/isp1760/isp1760-hcd.c
parent3eb96e04be9918afa54b64fac943de86a9798bda (diff)
downloadlinux-60d789f3bfbb7428e6ba2949de70a6db8e12e8fa.tar.xz
usb: isp1760: add support for isp1763
isp1763 have some differences from the isp1760, 8 bit address for registers and 16 bit for values, no bulk access to memory addresses, 16 PTD's instead of 32. Following the regmap work done before add the registers, memory access and add the functions to support differences in setup sequences. Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> Link: https://lore.kernel.org/r/20210513084717.2487366-8-rui.silva@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/isp1760/isp1760-hcd.c')
-rw-r--r--drivers/usb/isp1760/isp1760-hcd.c627
1 files changed, 481 insertions, 146 deletions
diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c
index a65f5f917ebe..016a54ea76f4 100644
--- a/drivers/usb/isp1760/isp1760-hcd.c
+++ b/drivers/usb/isp1760/isp1760-hcd.c
@@ -11,6 +11,8 @@
*
* (c) 2011 Arvid Brodin <arvid.brodin@enea.com>
*
+ * Copyright 2021 Linaro, Rui Miguel Silva <rui.silva@linaro.org>
+ *
*/
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@@ -44,6 +46,9 @@ static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
return *(struct isp1760_hcd **)hcd->hcd_priv;
}
+#define dw_to_le32(x) (cpu_to_le32((__force u32)x))
+#define le32_to_dw(x) ((__force __dw)(le32_to_cpu(x)))
+
/* urb state*/
#define DELETE_URB (0x0008)
#define NO_TRANSFER_ACTIVE (0xffffffff)
@@ -60,6 +65,18 @@ struct ptd {
__dw dw6;
__dw dw7;
};
+
+struct ptd_le32 {
+ __le32 dw0;
+ __le32 dw1;
+ __le32 dw2;
+ __le32 dw3;
+ __le32 dw4;
+ __le32 dw5;
+ __le32 dw6;
+ __le32 dw7;
+};
+
#define PTD_OFFSET 0x0400
#define ISO_PTD_OFFSET 0x0400
#define INT_PTD_OFFSET 0x0800
@@ -96,7 +113,7 @@ struct ptd {
#define TO_DW2_RL(x) TO_DW(((x) << 25))
#define FROM_DW2_RL(x) ((TO_U32(x) >> 25) & 0xf)
/* DW3 */
-#define FROM_DW3_NRBYTESTRANSFERRED(x) TO_U32((x) & 0x7fff)
+#define FROM_DW3_NRBYTESTRANSFERRED(x) TO_U32((x) & 0x3fff)
#define FROM_DW3_SCS_NRBYTESTRANSFERRED(x) TO_U32((x) & 0x07ff)
#define TO_DW3_NAKCOUNT(x) TO_DW(((x) << 19))
#define FROM_DW3_NAKCOUNT(x) ((TO_U32(x) >> 19) & 0xf)
@@ -123,7 +140,7 @@ struct ptd {
/* Errata 1 */
#define RL_COUNTER (0)
#define NAK_COUNTER (0)
-#define ERR_COUNTER (2)
+#define ERR_COUNTER (3)
struct isp1760_qtd {
u8 packet_type;
@@ -165,6 +182,18 @@ struct urb_listitem {
struct urb *urb;
};
+static const u32 isp1763_hc_portsc1_fields[] = {
+ [PORT_OWNER] = BIT(13),
+ [PORT_POWER] = BIT(12),
+ [PORT_LSTATUS] = BIT(10),
+ [PORT_RESET] = BIT(8),
+ [PORT_SUSPEND] = BIT(7),
+ [PORT_RESUME] = BIT(6),
+ [PORT_PE] = BIT(2),
+ [PORT_CSC] = BIT(1),
+ [PORT_CONNECT] = BIT(0),
+};
+
/*
* Access functions for isp176x registers regmap fields
*/
@@ -175,10 +204,30 @@ static u32 isp1760_hcd_read(struct usb_hcd *hcd, u32 field)
return isp1760_field_read(priv->fields, field);
}
+/*
+ * We need, in isp1763, to write directly the values to the portsc1
+ * register so it will make the other values to trigger.
+ */
+static void isp1760_hcd_portsc1_set_clear(struct isp1760_hcd *priv, u32 field,
+ u32 val)
+{
+ u32 bit = isp1763_hc_portsc1_fields[field];
+ u32 port_status = readl(priv->base + ISP1763_HC_PORTSC1);
+
+ if (val)
+ writel(port_status | bit, priv->base + ISP1763_HC_PORTSC1);
+ else
+ writel(port_status & ~bit, priv->base + ISP1763_HC_PORTSC1);
+}
+
static void isp1760_hcd_write(struct usb_hcd *hcd, u32 field, u32 val)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ if (unlikely(priv->is_isp1763 &&
+ (field >= PORT_OWNER && field <= PORT_CONNECT)))
+ return isp1760_hcd_portsc1_set_clear(priv, field, val);
+
isp1760_field_write(priv->fields, field, val);
}
@@ -192,28 +241,40 @@ static void isp1760_hcd_clear(struct usb_hcd *hcd, u32 field)
isp1760_hcd_write(hcd, field, 0);
}
-static int isp1760_hcd_set_poll_timeout(struct usb_hcd *hcd, u32 field,
- u32 timeout_us)
+static int isp1760_hcd_set_and_wait(struct usb_hcd *hcd, u32 field,
+ u32 timeout_us)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ u32 val;
+
+ isp1760_hcd_set(hcd, field);
+
+ return regmap_field_read_poll_timeout(priv->fields[field], val,
+ val, 10, timeout_us);
+}
+
+static int isp1760_hcd_set_and_wait_swap(struct usb_hcd *hcd, u32 field,
+ u32 timeout_us)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- unsigned int val;
+ u32 val;
isp1760_hcd_set(hcd, field);
- return regmap_field_read_poll_timeout(priv->fields[field], val, 1, 1,
- timeout_us);
+ return regmap_field_read_poll_timeout(priv->fields[field], val,
+ !val, 10, timeout_us);
}
-static int isp1760_hcd_clear_poll_timeout(struct usb_hcd *hcd, u32 field,
- u32 timeout_us)
+static int isp1760_hcd_clear_and_wait(struct usb_hcd *hcd, u32 field,
+ u32 timeout_us)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- unsigned int val;
+ u32 val;
isp1760_hcd_clear(hcd, field);
- return regmap_field_read_poll_timeout(priv->fields[field], val, 0, 1,
- timeout_us);
+ return regmap_field_read_poll_timeout(priv->fields[field], val,
+ !val, 10, timeout_us);
}
static bool isp1760_hcd_is_set(struct usb_hcd *hcd, u32 field)
@@ -221,12 +282,32 @@ static bool isp1760_hcd_is_set(struct usb_hcd *hcd, u32 field)
return !!isp1760_hcd_read(hcd, field);
}
+static bool isp1760_hcd_ppc_is_set(struct usb_hcd *hcd)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (priv->is_isp1763)
+ return true;
+
+ return isp1760_hcd_is_set(hcd, HCS_PPC);
+}
+
+static u32 isp1760_hcd_n_ports(struct usb_hcd *hcd)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (priv->is_isp1763)
+ return 1;
+
+ return isp1760_hcd_read(hcd, HCS_N_PORTS);
+}
+
/*
* Access functions for isp176x memory (offset >= 0x0400).
*
* bank_reads8() reads memory locations prefetched by an earlier write to
* HC_MEMORY_REG (see isp176x datasheet). Unless you want to do fancy multi-
- * bank optimizations, you should use the more generic mem_reads8() below.
+ * bank optimizations, you should use the more generic mem_read() below.
*
* For access to ptd memory, use the specialized ptd_read() and ptd_write()
* below.
@@ -281,19 +362,59 @@ static void bank_reads8(void __iomem *src_base, u32 src_offset, u32 bank_addr,
}
}
-static void mem_reads8(struct usb_hcd *hcd, void __iomem *src_base,
- u32 src_offset, void *dst, u32 bytes)
+static void isp1760_mem_read(struct usb_hcd *hcd, u32 src_offset, void *dst,
+ u32 bytes)
{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
isp1760_hcd_write(hcd, MEM_START_ADDR, src_offset);
+ ndelay(100);
- ndelay(90);
+ bank_reads8(priv->base, src_offset, ISP_BANK_0, dst, bytes);
+}
- bank_reads8(src_base, src_offset, ISP_BANK_0, dst, bytes);
+/*
+ * ISP1763 does not have the banks direct host controller memory access,
+ * needs to use the HC_DATA register. Add data read/write according to this,
+ * and also adjust 16bit access.
+ */
+static void isp1763_mem_read(struct usb_hcd *hcd, u16 srcaddr,
+ u16 *dstptr, u32 bytes)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ /* Write the starting device address to the hcd memory register */
+ isp1760_reg_write(priv->regs, ISP1763_HC_MEMORY, srcaddr);
+ ndelay(100); /* Delay between consecutive access */
+
+ /* As long there are at least 16-bit to read ... */
+ while (bytes >= 2) {
+ *dstptr = __raw_readw(priv->base + ISP1763_HC_DATA);
+ bytes -= 2;
+ dstptr++;
+ }
+
+ /* If there are no more bytes to read, return */
+ if (bytes <= 0)
+ return;
+
+ *((u8 *)dstptr) = (u8)(readw(priv->base + ISP1763_HC_DATA) & 0xFF);
+}
+
+static void mem_read(struct usb_hcd *hcd, u32 src_offset, __u32 *dst,
+ u32 bytes)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (!priv->is_isp1763)
+ return isp1760_mem_read(hcd, src_offset, (u16 *)dst, bytes);
+
+ isp1763_mem_read(hcd, (u16)src_offset, (u16 *)dst, bytes);
}
-static void mem_writes8(void __iomem *dst_base, u32 dst_offset,
- __u32 const *src, u32 bytes)
+static void isp1760_mem_write(void __iomem *dst_base, u32 dst_offset,
+ __u32 const *src, u32 bytes)
{
__u32 __iomem *dst;
@@ -327,33 +448,136 @@ static void mem_writes8(void __iomem *dst_base, u32 dst_offset,
__raw_writel(*src, dst);
}
+static void isp1763_mem_write(struct usb_hcd *hcd, u16 dstaddr, u16 *src,
+ u32 bytes)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ /* Write the starting device address to the hcd memory register */
+ isp1760_reg_write(priv->regs, ISP1763_HC_MEMORY, dstaddr);
+ ndelay(100); /* Delay between consecutive access */
+
+ while (bytes >= 2) {
+ /* Get and write the data; then adjust the data ptr and len */
+ __raw_writew(*src, priv->base + ISP1763_HC_DATA);
+ bytes -= 2;
+ src++;
+ }
+
+ /* If there are no more bytes to process, return */
+ if (bytes <= 0)
+ return;
+
+ /*
+ * The only way to get here is if there is a single byte left,
+ * get it and write it to the data reg;
+ */
+ writew(*((u8 *)src), priv->base + ISP1763_HC_DATA);
+}
+
+static void mem_write(struct usb_hcd *hcd, u32 dst_offset, __u32 *src,
+ u32 bytes)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (!priv->is_isp1763)
+ return isp1760_mem_write(priv->base, dst_offset, src, bytes);
+
+ isp1763_mem_write(hcd, dst_offset, (u16 *)src, bytes);
+}
+
/*
* Read and write ptds. 'ptd_offset' should be one of ISO_PTD_OFFSET,
* INT_PTD_OFFSET, and ATL_PTD_OFFSET. 'slot' should be less than 32.
*/
-static void ptd_read(struct usb_hcd *hcd, void __iomem *base,
- u32 ptd_offset, u32 slot, struct ptd *ptd)
+static void isp1760_ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
+ struct ptd *ptd)
{
+ u16 src_offset = ptd_offset + slot * sizeof(*ptd);
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
- isp1760_hcd_write(hcd, MEM_START_ADDR,
- ptd_offset + slot * sizeof(*ptd));
+ isp1760_hcd_write(hcd, MEM_START_ADDR, src_offset);
ndelay(90);
- bank_reads8(base, ptd_offset + slot * sizeof(*ptd), ISP_BANK_0,
- (void *)ptd, sizeof(*ptd));
+
+ bank_reads8(priv->base, src_offset, ISP_BANK_0, (void *)ptd,
+ sizeof(*ptd));
+}
+
+static void isp1763_ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
+ struct ptd *ptd)
+{
+ u16 src_offset = ptd_offset + slot * sizeof(*ptd);
+ struct ptd_le32 le32_ptd;
+
+ isp1763_mem_read(hcd, src_offset, (u16 *)&le32_ptd, sizeof(le32_ptd));
+ /* Normalize the data obtained */
+ ptd->dw0 = le32_to_dw(le32_ptd.dw0);
+ ptd->dw1 = le32_to_dw(le32_ptd.dw1);
+ ptd->dw2 = le32_to_dw(le32_ptd.dw2);
+ ptd->dw3 = le32_to_dw(le32_ptd.dw3);
+ ptd->dw4 = le32_to_dw(le32_ptd.dw4);
+ ptd->dw5 = le32_to_dw(le32_ptd.dw5);
+ ptd->dw6 = le32_to_dw(le32_ptd.dw6);
+ ptd->dw7 = le32_to_dw(le32_ptd.dw7);
+}
+
+static void ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
+ struct ptd *ptd)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (!priv->is_isp1763)
+ return isp1760_ptd_read(hcd, ptd_offset, slot, ptd);
+
+ isp1763_ptd_read(hcd, ptd_offset, slot, ptd);
+}
+
+static void isp1763_ptd_write(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
+ struct ptd *cpu_ptd)
+{
+ u16 dst_offset = ptd_offset + slot * sizeof(*cpu_ptd);
+ struct ptd_le32 ptd;
+
+ ptd.dw0 = dw_to_le32(cpu_ptd->dw0);
+ ptd.dw1 = dw_to_le32(cpu_ptd->dw1);
+ ptd.dw2 = dw_to_le32(cpu_ptd->dw2);
+ ptd.dw3 = dw_to_le32(cpu_ptd->dw3);
+ ptd.dw4 = dw_to_le32(cpu_ptd->dw4);
+ ptd.dw5 = dw_to_le32(cpu_ptd->dw5);
+ ptd.dw6 = dw_to_le32(cpu_ptd->dw6);
+ ptd.dw7 = dw_to_le32(cpu_ptd->dw7);
+
+ isp1763_mem_write(hcd, dst_offset, (u16 *)&ptd.dw0,
+ 8 * sizeof(ptd.dw0));
}
-static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot,
- struct ptd *ptd)
+static void isp1760_ptd_write(void __iomem *base, u32 ptd_offset, u32 slot,
+ struct ptd *ptd)
{
- mem_writes8(base, ptd_offset + slot*sizeof(*ptd) + sizeof(ptd->dw0),
- (__force u32 *)&ptd->dw1, 7 * sizeof(ptd->dw1));
- /* Make sure dw0 gets written last (after other dw's and after payload)
- since it contains the enable bit */
+ u32 dst_offset = ptd_offset + slot * sizeof(*ptd);
+
+ /*
+ * Make sure dw0 gets written last (after other dw's and after payload)
+ * since it contains the enable bit
+ */
+ isp1760_mem_write(base, dst_offset + sizeof(ptd->dw0),
+ (__force u32 *)&ptd->dw1, 7 * sizeof(ptd->dw1));
wmb();
- mem_writes8(base, ptd_offset + slot * sizeof(*ptd),
- (__force u32 *)&ptd->dw0, sizeof(ptd->dw0));
+ isp1760_mem_write(base, dst_offset, (__force u32 *)&ptd->dw0,
+ sizeof(ptd->dw0));
}
+static void ptd_write(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
+ struct ptd *ptd)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ if (!priv->is_isp1763)
+ return isp1760_ptd_write(priv->base, ptd_offset, slot, ptd);
+
+ isp1763_ptd_write(hcd, ptd_offset, slot, ptd);
+}
/* memory management of the 60kb on the chip from 0x1000 to 0xffff */
static void init_memory(struct isp1760_hcd *priv)
@@ -430,7 +654,7 @@ static int ehci_reset(struct usb_hcd *hcd)
hcd->state = HC_STATE_HALT;
priv->next_statechange = jiffies;
- return isp1760_hcd_set_poll_timeout(hcd, CMD_RESET, 250 * 1000);
+ return isp1760_hcd_set_and_wait_swap(hcd, CMD_RESET, 250 * 1000);
}
static struct isp1760_qh *qh_alloc(gfp_t flags)
@@ -461,7 +685,6 @@ static int priv_init(struct usb_hcd *hcd)
struct isp1760_hcd *priv = hcd_to_priv(hcd);
u32 isoc_cache;
u32 isoc_thres;
-
int i;
spin_lock_init(&priv->lock);
@@ -475,6 +698,11 @@ static int priv_init(struct usb_hcd *hcd)
*/
priv->periodic_size = DEFAULT_I_TDPS;
+ if (priv->is_isp1763) {
+ priv->i_thresh = 2;
+ return 0;
+ }
+
/* controllers may cache some of the periodic schedule ... */
isoc_cache = isp1760_hcd_read(hcd, HCC_ISOC_CACHE);
isoc_thres = isp1760_hcd_read(hcd, HCC_ISOC_THRES);
@@ -491,16 +719,24 @@ static int priv_init(struct usb_hcd *hcd)
static int isp1760_hc_setup(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ u32 atx_reset;
int result;
u32 scratch;
+ u32 pattern;
- isp1760_reg_write(priv->regs, ISP176x_HC_SCRATCH, 0xdeadbabe);
+ if (priv->is_isp1763)
+ pattern = 0xcafe;
+ else
+ pattern = 0xdeadcafe;
+
+ isp1760_hcd_write(hcd, HC_SCRATCH, pattern);
/* Change bus pattern */
- scratch = isp1760_reg_read(priv->regs, ISP176x_HC_CHIP_ID);
- scratch = isp1760_reg_read(priv->regs, ISP176x_HC_SCRATCH);
- if (scratch != 0xdeadbabe) {
- dev_err(hcd->self.controller, "Scratch test failed.\n");
+ scratch = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
+ dev_err(hcd->self.controller, "Scratch test 0x%08x\n", scratch);
+ scratch = isp1760_hcd_read(hcd, HC_SCRATCH);
+ if (scratch != pattern) {
+ dev_err(hcd->self.controller, "Scratch test failed. 0x%08x\n", scratch);
return -ENODEV;
}
@@ -512,13 +748,13 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
* the host controller through the EHCI USB Command register. The device
* has been reset in core code anyway, so this shouldn't matter.
*/
- isp1760_reg_write(priv->regs, ISP176x_HC_BUFFER_STATUS, 0);
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP,
- NO_TRANSFER_ACTIVE);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP,
- NO_TRANSFER_ACTIVE);
- isp1760_reg_write(priv->regs, ISP176x_HC_ISO_PTD_SKIPMAP,
- NO_TRANSFER_ACTIVE);
+ isp1760_hcd_clear(hcd, ISO_BUF_FILL);
+ isp1760_hcd_clear(hcd, INT_BUF_FILL);
+ isp1760_hcd_clear(hcd, ATL_BUF_FILL);
+
+ isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);
result = ehci_reset(hcd);
if (result)
@@ -527,11 +763,26 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
/* Step 11 passed */
/* ATL reset */
- isp1760_hcd_set(hcd, ALL_ATX_RESET);
+ if (priv->is_isp1763)
+ atx_reset = SW_RESET_RESET_ATX;
+ else
+ atx_reset = ALL_ATX_RESET;
+
+ isp1760_hcd_set(hcd, atx_reset);
mdelay(10);
- isp1760_hcd_clear(hcd, ALL_ATX_RESET);
+ isp1760_hcd_clear(hcd, atx_reset);
- isp1760_hcd_set(hcd, HC_INT_ENABLE);
+ if (priv->is_isp1763) {
+ isp1760_hcd_set(hcd, HW_OTG_DISABLE);
+ isp1760_hcd_set(hcd, HW_SW_SEL_HC_DC_CLEAR);
+ isp1760_hcd_set(hcd, HW_HC_2_DIS_CLEAR);
+ mdelay(10);
+
+ isp1760_hcd_set(hcd, HW_INTF_LOCK);
+ }
+
+ isp1760_hcd_set(hcd, HC_INT_IRQ_ENABLE);
+ isp1760_hcd_set(hcd, HC_ATL_IRQ_ENABLE);
return priv_init(hcd);
}
@@ -751,45 +1002,45 @@ static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot,
struct ptd *ptd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ const struct isp1760_memory_layout *mem = priv->memory_layout;
int skip_map;
- WARN_ON((slot < 0) || (slot > 31));
+ WARN_ON((slot < 0) || (slot > mem->slot_num - 1));
WARN_ON(qtd->length && !qtd->payload_addr);
WARN_ON(slots[slot].qtd);
WARN_ON(slots[slot].qh);
WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC);
+ if (priv->is_isp1763)
+ ndelay(100);
+
/* Make sure done map has not triggered from some unlinked transfer */
if (ptd_offset == ATL_PTD_OFFSET) {
- priv->atl_done_map |= isp1760_reg_read(priv->regs,
- ISP176x_HC_ATL_PTD_DONEMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
+ isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP,
+ skip_map | (1 << slot));
+ priv->atl_done_map |= isp1760_hcd_read(hcd, HC_ATL_PTD_DONEMAP);
priv->atl_done_map &= ~(1 << slot);
} else {
- priv->int_done_map |= isp1760_reg_read(priv->regs,
- ISP176x_HC_INT_PTD_DONEMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
+ isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP,
+ skip_map | (1 << slot));
+ priv->int_done_map |= isp1760_hcd_read(hcd, HC_INT_PTD_DONEMAP);
priv->int_done_map &= ~(1 << slot);
}
+ skip_map &= ~(1 << slot);
qh->slot = slot;
qtd->status = QTD_XFER_STARTED;
slots[slot].timestamp = jiffies;
slots[slot].qtd = qtd;
slots[slot].qh = qh;
- ptd_write(priv->base, ptd_offset, slot, ptd);
+ ptd_write(hcd, ptd_offset, slot, ptd);
- if (ptd_offset == ATL_PTD_OFFSET) {
- skip_map = isp1760_reg_read(priv->regs,
- ISP176x_HC_ATL_PTD_SKIPMAP);
- skip_map &= ~(1 << qh->slot);
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP,
- skip_map);
- } else {
- skip_map = isp1760_reg_read(priv->regs,
- ISP176x_HC_INT_PTD_SKIPMAP);
- skip_map &= ~(1 << qh->slot);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP,
- skip_map);
- }
+ if (ptd_offset == ATL_PTD_OFFSET)
+ isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP, skip_map);
+ else
+ isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP, skip_map);
}
static int is_short_bulk(struct isp1760_qtd *qtd)
@@ -801,7 +1052,6 @@ static int is_short_bulk(struct isp1760_qtd *qtd)
static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh,
struct list_head *urb_list)
{
- struct isp1760_hcd *priv = hcd_to_priv(hcd);
struct isp1760_qtd *qtd, *qtd_next;
struct urb_listitem *urb_listitem;
int last_qtd;
@@ -819,10 +1069,9 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh,
if (qtd->actual_length) {
switch (qtd->packet_type) {
case IN_PID:
- mem_reads8(hcd, priv->base,
- qtd->payload_addr,
- qtd->data_buffer,
- qtd->actual_length);
+ mem_read(hcd, qtd->payload_addr,
+ qtd->data_buffer,
+ qtd->actual_length);
fallthrough;
case OUT_PID:
qtd->urb->actual_length +=
@@ -866,6 +1115,8 @@ static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh,
static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ const struct isp1760_memory_layout *mem = priv->memory_layout;
+ int slot_num = mem->slot_num;
int ptd_offset;
struct isp1760_slotinfo *slots;
int curr_slot, free_slot;
@@ -892,7 +1143,7 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
}
free_slot = -1;
- for (curr_slot = 0; curr_slot < 32; curr_slot++) {
+ for (curr_slot = 0; curr_slot < slot_num; curr_slot++) {
if ((free_slot == -1) && (slots[curr_slot].qtd == NULL))
free_slot = curr_slot;
if (slots[curr_slot].qh == qh)
@@ -907,11 +1158,10 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
if ((qtd->length) && (!qtd->payload_addr))
break;
- if ((qtd->length) &&
- ((qtd->packet_type == SETUP_PID) ||
- (qtd->packet_type == OUT_PID))) {
- mem_writes8(priv->base, qtd->payload_addr,
- qtd->data_buffer, qtd->length);
+ if (qtd->length && (qtd->packet_type == SETUP_PID ||
+ qtd->packet_type == OUT_PID)) {
+ mem_write(hcd, qtd->payload_addr,
+ qtd->data_buffer, qtd->length);
}
qtd->status = QTD_PAYLOAD_ALLOC;
@@ -924,7 +1174,7 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
"available for transfer\n", __func__);
*/
/* Start xfer for this endpoint if not already done */
- if ((curr_slot > 31) && (free_slot > -1)) {
+ if ((curr_slot > slot_num - 1) && (free_slot > -1)) {
if (usb_pipeint(qtd->urb->pipe))
create_ptd_int(qh, qtd, &ptd);
else
@@ -1111,9 +1361,9 @@ static void handle_done_ptds(struct usb_hcd *hcd)
int modified;
int skip_map;
- skip_map = isp1760_reg_read(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
priv->int_done_map &= ~skip_map;
- skip_map = isp1760_reg_read(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
priv->atl_done_map &= ~skip_map;
modified = priv->int_done_map || priv->atl_done_map;
@@ -1131,7 +1381,7 @@ static void handle_done_ptds(struct usb_hcd *hcd)
continue;
}
ptd_offset = INT_PTD_OFFSET;
- ptd_read(hcd, priv->base, INT_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, INT_PTD_OFFSET, slot, &ptd);
state = check_int_transfer(hcd, &ptd,
slots[slot].qtd->urb);
} else {
@@ -1146,7 +1396,7 @@ static void handle_done_ptds(struct usb_hcd *hcd)
continue;
}
ptd_offset = ATL_PTD_OFFSET;
- ptd_read(hcd, priv->base, ATL_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, ATL_PTD_OFFSET, slot, &ptd);
state = check_atl_transfer(hcd, &ptd,
slots[slot].qtd->urb);
}
@@ -1239,27 +1489,30 @@ static void handle_done_ptds(struct usb_hcd *hcd)
static irqreturn_t isp1760_irq(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- u32 imask;
irqreturn_t irqret = IRQ_NONE;
+ u32 int_reg;
+ u32 imask;
spin_lock(&priv->lock);
if (!(hcd->state & HC_STATE_RUNNING))
goto leave;
- imask = isp1760_reg_read(priv->regs, ISP176x_HC_INTERRUPT);
+ imask = isp1760_hcd_read(hcd, HC_INTERRUPT);
if (unlikely(!imask))
goto leave;
- isp1760_reg_write(priv->regs, ISP176x_HC_INTERRUPT, imask); /* Clear */
- priv->int_done_map |= isp1760_reg_read(priv->regs,
- ISP176x_HC_INT_PTD_DONEMAP);
- priv->atl_done_map |= isp1760_reg_read(priv->regs,
- ISP176x_HC_ATL_PTD_DONEMAP);
+ int_reg = priv->is_isp1763 ? ISP1763_HC_INTERRUPT :
+ ISP176x_HC_INTERRUPT;
+ isp1760_reg_write(priv->regs, int_reg, imask);
+
+ priv->int_done_map |= isp1760_hcd_read(hcd, HC_INT_PTD_DONEMAP);
+ priv->atl_done_map |= isp1760_hcd_read(hcd, HC_ATL_PTD_DONEMAP);
handle_done_ptds(hcd);
irqret = IRQ_HANDLED;
+
leave:
spin_unlock(&priv->lock);
@@ -1300,17 +1553,18 @@ static void errata2_function(struct timer_list *unused)
{
struct usb_hcd *hcd = errata2_timer_hcd;
struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ const struct isp1760_memory_layout *mem = priv->memory_layout;
int slot;
struct ptd ptd;
unsigned long spinflags;
spin_lock_irqsave(&priv->lock, spinflags);
- for (slot = 0; slot < 32; slot++)
+ for (slot = 0; slot < mem->slot_num; slot++)
if (priv->atl_slots[slot].qh && time_after(jiffies,
priv->atl_slots[slot].timestamp +
msecs_to_jiffies(SLOT_TIMEOUT))) {
- ptd_read(hcd, priv->base, ATL_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, ATL_PTD_OFFSET, slot, &ptd);
if (!FROM_DW0_VALID(ptd.dw0) &&
!FROM_DW3_ACTIVE(ptd.dw3))
priv->atl_done_map |= 1 << slot;
@@ -1325,23 +1579,113 @@ static void errata2_function(struct timer_list *unused)
add_timer(&errata2_timer);
}
+static int isp1763_run(struct usb_hcd *hcd)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ int retval;
+ u32 chipid_h;
+ u32 chipid_l;
+ u32 chip_rev;
+ u32 ptd_atl_int;
+ u32 ptd_iso;
+
+ hcd->uses_new_polling = 1;
+ hcd->state = HC_STATE_RUNNING;
+
+ chipid_h = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
+ chipid_l = isp1760_hcd_read(hcd, HC_CHIP_ID_LOW);
+ chip_rev = isp1760_hcd_read(hcd, HC_CHIP_REV);
+ dev_info(hcd->self.controller, "USB ISP %02x%02x HW rev. %d started\n",
+ chipid_h, chipid_l, chip_rev);
+
+ isp1760_hcd_clear(hcd, ISO_BUF_FILL);
+ isp1760_hcd_clear(hcd, INT_BUF_FILL);
+ isp1760_hcd_clear(hcd, ATL_BUF_FILL);
+
+ isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);
+ ndelay(100);
+ isp1760_hcd_clear(hcd, HC_ATL_PTD_DONEMAP);
+ isp1760_hcd_clear(hcd, HC_INT_PTD_DONEMAP);
+ isp1760_hcd_clear(hcd, HC_ISO_PTD_DONEMAP);
+
+ isp1760_hcd_set(hcd, HW_OTG_DISABLE);
+ isp1760_reg_write(priv->regs, ISP1763_HC_OTG_CTRL_CLEAR, BIT(7));
+ isp1760_reg_write(priv->regs, ISP1763_HC_OTG_CTRL_CLEAR, BIT(15));
+ mdelay(10);
+
+ isp1760_hcd_set(hcd, HC_INT_IRQ_ENABLE);
+ isp1760_hcd_set(hcd, HC_ATL_IRQ_ENABLE);
+
+ isp1760_hcd_set(hcd, HW_GLOBAL_INTR_EN);
+
+ isp1760_hcd_clear(hcd, HC_ATL_IRQ_MASK_AND);
+ isp1760_hcd_clear(hcd, HC_INT_IRQ_MASK_AND);
+ isp1760_hcd_clear(hcd, HC_ISO_IRQ_MASK_AND);
+
+ isp1760_hcd_set(hcd, HC_ATL_IRQ_MASK_OR);
+ isp1760_hcd_set(hcd, HC_INT_IRQ_MASK_OR);
+ isp1760_hcd_set(hcd, HC_ISO_IRQ_MASK_OR);
+
+ ptd_atl_int = 0x8000;
+ ptd_iso = 0x0001;
+
+ isp1760_hcd_write(hcd, HC_ATL_PTD_LASTPTD, ptd_atl_int);
+ isp1760_hcd_write(hcd, HC_INT_PTD_LASTPTD, ptd_atl_int);
+ isp1760_hcd_write(hcd, HC_ISO_PTD_LASTPTD, ptd_iso);
+
+ isp1760_hcd_set(hcd, ATL_BUF_FILL);
+ isp1760_hcd_set(hcd, INT_BUF_FILL);
+
+ isp1760_hcd_clear(hcd, CMD_LRESET);
+ isp1760_hcd_clear(hcd, CMD_RESET);
+
+ retval = isp1760_hcd_set_and_wait(hcd, CMD_RUN, 250 * 1000);
+ if (retval)
+ return retval;
+
+ down_write(&ehci_cf_port_reset_rwsem);
+ retval = isp1760_hcd_set_and_wait(hcd, FLAG_CF, 250 * 1000);
+ up_write(&ehci_cf_port_reset_rwsem);
+ retval = 0;
+ if (retval)
+ return retval;
+
+ return 0;
+}
+
static int isp1760_run(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
int retval;
- u32 chipid;
+ u32 chipid_h;
+ u32 chipid_l;
+ u32 chip_rev;
+ u32 ptd_atl_int;
+ u32 ptd_iso;
+
+ /*
+ * ISP1763 have some differences in the setup and order to enable
+ * the ports, disable otg, setup buffers, and ATL, INT, ISO status.
+ * So, just handle it a separate sequence.
+ */
+ if (priv->is_isp1763)
+ return isp1763_run(hcd);
hcd->uses_new_polling = 1;
hcd->state = HC_STATE_RUNNING;
/* Set PTD interrupt AND & OR maps */
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_IRQ_MASK_AND, 0);
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_IRQ_MASK_OR, 0xffffffff);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_IRQ_MASK_AND, 0);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_IRQ_MASK_OR, 0xffffffff);
- isp1760_reg_write(priv->regs, ISP176x_HC_ISO_IRQ_MASK_AND, 0);
- isp1760_reg_write(priv->regs, ISP176x_HC_ISO_IRQ_MASK_OR, 0xffffffff);
+ isp1760_hcd_clear(hcd, HC_ATL_IRQ_MASK_AND);
+ isp1760_hcd_clear(hcd, HC_INT_IRQ_MASK_AND);
+ isp1760_hcd_clear(hcd, HC_ISO_IRQ_MASK_AND);
+
+ isp1760_hcd_set(hcd, HC_ATL_IRQ_MASK_OR);
+ isp1760_hcd_set(hcd, HC_INT_IRQ_MASK_OR);
+ isp1760_hcd_set(hcd, HC_ISO_IRQ_MASK_OR);
+
/* step 23 passed */
isp1760_hcd_set(hcd, HW_GLOBAL_INTR_EN);
@@ -1349,7 +1693,7 @@ static int isp1760_run(struct usb_hcd *hcd)
isp1760_hcd_clear(hcd, CMD_LRESET);
isp1760_hcd_clear(hcd, CMD_RESET);
- retval = isp1760_hcd_set_poll_timeout(hcd, CMD_RUN, 250 * 1000);
+ retval = isp1760_hcd_set_and_wait(hcd, CMD_RUN, 250 * 1000);
if (retval)
return retval;
@@ -1360,7 +1704,7 @@ static int isp1760_run(struct usb_hcd *hcd)
*/
down_write(&ehci_cf_port_reset_rwsem);
- retval = isp1760_hcd_set_poll_timeout(hcd, FLAG_CF, 250 * 1000);
+ retval = isp1760_hcd_set_and_wait(hcd, FLAG_CF, 250 * 1000);
up_write(&ehci_cf_port_reset_rwsem);
if (retval)
return retval;
@@ -1370,19 +1714,25 @@ static int isp1760_run(struct usb_hcd *hcd)
errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
add_timer(&errata2_timer);
- chipid = isp1760_reg_read(priv->regs, ISP176x_HC_CHIP_ID);
- dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n",
- chipid & 0xffff, chipid >> 16);
+ chipid_h = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
+ chipid_l = isp1760_hcd_read(hcd, HC_CHIP_ID_LOW);
+ chip_rev = isp1760_hcd_read(hcd, HC_CHIP_REV);
+ dev_info(hcd->self.controller, "USB ISP %02x%02x HW rev. %d started\n",
+ chipid_h, chipid_l, chip_rev);
/* PTD Register Init Part 2, Step 28 */
/* Setup registers controlling PTD checking */
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_LASTPTD, 0x80000000);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_LASTPTD, 0x80000000);
- isp1760_reg_write(priv->regs, ISP176x_HC_ISO_PTD_LASTPTD, 0x00000001);
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP, 0xffffffff);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP, 0xffffffff);
- isp1760_reg_write(priv->regs, ISP176x_HC_ISO_PTD_SKIPMAP, 0xffffffff);
+ ptd_atl_int = 0x80000000;
+ ptd_iso = 0x00000001;
+
+ isp1760_hcd_write(hcd, HC_ATL_PTD_LASTPTD, ptd_atl_int);
+ isp1760_hcd_write(hcd, HC_INT_PTD_LASTPTD, ptd_atl_int);
+ isp1760_hcd_write(hcd, HC_ISO_PTD_LASTPTD, ptd_iso);
+
+ isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
+ isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);
isp1760_hcd_set(hcd, ATL_BUF_FILL);
isp1760_hcd_set(hcd, INT_BUF_FILL);
@@ -1623,19 +1973,16 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb,
/* We need to forcefully reclaim the slot since some transfers never
return, e.g. interrupt transfers and NAKed bulk transfers. */
if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) {
- skip_map = isp1760_reg_read(priv->regs,
- ISP176x_HC_ATL_PTD_SKIPMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
skip_map |= (1 << qh->slot);
- isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP,
- skip_map);
+ isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP, skip_map);
+ ndelay(100);
priv->atl_slots[qh->slot].qh = NULL;
priv->atl_slots[qh->slot].qtd = NULL;
} else {
- skip_map = isp1760_reg_read(priv->regs,
- ISP176x_HC_INT_PTD_SKIPMAP);
+ skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
skip_map |= (1 << qh->slot);
- isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP,
- skip_map);
+ isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP, skip_map);
priv->int_slots[qh->slot].qh = NULL;
priv->int_slots[qh->slot].qtd = NULL;
}
@@ -1791,7 +2138,7 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
int ports;
u16 temp;
- ports = isp1760_hcd_read(priv->hcd, HCS_N_PORTS);
+ ports = isp1760_hcd_n_ports(priv->hcd);
desc->bDescriptorType = USB_DT_HUB;
/* priv 1.0, 2.3.9 says 20ms max */
@@ -1808,7 +2155,7 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
/* per-port overcurrent reporting */
temp = HUB_CHAR_INDV_PORT_OCPM;
- if (isp1760_hcd_is_set(priv->hcd, HCS_PPC))
+ if (isp1760_hcd_ppc_is_set(priv->hcd))
/* per-port power control */
temp |= HUB_CHAR_INDV_PORT_LPSM;
else
@@ -1849,7 +2196,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
int retval = 0;
int ports;
- ports = isp1760_hcd_read(hcd, HCS_N_PORTS);
+ ports = isp1760_hcd_n_ports(hcd);
/*
* FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1908,7 +2255,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
/* we auto-clear this feature */
break;
case USB_PORT_FEAT_POWER:
- if (isp1760_hcd_is_set(hcd, HCS_PPC))
+ if (isp1760_hcd_ppc_is_set(hcd))
isp1760_hcd_clear(hcd, PORT_POWER);
break;
case USB_PORT_FEAT_C_CONNECTION:
@@ -1923,7 +2270,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
default:
goto error;
}
- isp1760_reg_read(priv->regs, ISP176x_HC_USBCMD);
+ isp1760_hcd_read(hcd, CMD_RUN);
break;
case GetHubDescriptor:
isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *)
@@ -1943,7 +2290,6 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
if (isp1760_hcd_is_set(hcd, PORT_CSC))
status |= USB_PORT_STAT_C_CONNECTION << 16;
-
/* whoever resumes must GetPortStatus to complete it!! */
if (isp1760_hcd_is_set(hcd, PORT_RESUME)) {
dev_err(hcd->self.controller, "Port resume should be skipped.\n");
@@ -1966,7 +2312,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
/* stop resume signaling */
isp1760_hcd_clear(hcd, PORT_CSC);
- retval = isp1760_hcd_clear_poll_timeout(hcd,
+ retval = isp1760_hcd_clear_and_wait(hcd,
PORT_RESUME, 2000);
if (retval != 0) {
dev_err(hcd->self.controller,
@@ -1987,11 +2333,11 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
/* REVISIT: some hardware needs 550+ usec to clear
* this bit; seems too long to spin routinely...
*/
- retval = isp1760_hcd_clear_poll_timeout(hcd, PORT_RESET,
- 750);
+ retval = isp1760_hcd_clear_and_wait(hcd, PORT_RESET,
+ 750);
if (retval != 0) {
dev_err(hcd->self.controller, "port %d reset error %d\n",
- wIndex + 1, retval);
+ wIndex + 1, retval);
goto error;
}
@@ -2039,6 +2385,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
+
if (isp1760_hcd_is_set(hcd, PORT_OWNER))
break;
@@ -2055,7 +2402,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
isp1760_hcd_set(hcd, PORT_SUSPEND);
break;
case USB_PORT_FEAT_POWER:
- if (isp1760_hcd_is_set(hcd, HCS_PPC))
+ if (isp1760_hcd_ppc_is_set(hcd))
isp1760_hcd_set(hcd, PORT_POWER);
break;
case USB_PORT_FEAT_RESET:
@@ -2084,7 +2431,6 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
default:
goto error;
}
- isp1760_reg_read(priv->regs, ISP176x_HC_USBCMD);
break;
default:
@@ -2219,22 +2565,14 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
priv->hcd = hcd;
- priv->memory_pool = kcalloc(mem_layout->payload_blocks,
- sizeof(struct isp1760_memory_chunk),
- GFP_KERNEL);
- if (!priv->memory_pool) {
- ret = -ENOMEM;
- goto put_hcd;
- }
-
- priv->atl_slots = kcalloc(mem_layout->ptd_num,
+ priv->atl_slots = kcalloc(mem_layout->slot_num,
sizeof(struct isp1760_slotinfo), GFP_KERNEL);
if (!priv->atl_slots) {
ret = -ENOMEM;
- goto free_mem_pool;
+ goto put_hcd;
}
- priv->int_slots = kcalloc(mem_layout->ptd_num,
+ priv->int_slots = kcalloc(mem_layout->slot_num,
sizeof(struct isp1760_slotinfo), GFP_KERNEL);
if (!priv->int_slots) {
ret = -ENOMEM;
@@ -2262,8 +2600,6 @@ free_int_slots:
kfree(priv->int_slots);
free_atl_slots:
kfree(priv->atl_slots);
-free_mem_pool:
- kfree(priv->memory_pool);
put_hcd:
usb_put_hcd(hcd);
return ret;
@@ -2278,5 +2614,4 @@ void isp1760_hcd_unregister(struct isp1760_hcd *priv)
usb_put_hcd(priv->hcd);
kfree(priv->atl_slots);
kfree(priv->int_slots);
- kfree(priv->memory_pool);
}