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:10 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-05-21 21:05:31 +0300
commit1da9e1c06873350c99ba49a052f92de85f2c69f2 (patch)
treec5b957e7fadeab2b9fed6c291ea4e958fa9420c4 /drivers/usb/isp1760/isp1760-hcd.c
parentabfabc8ae3bd625f57fa35d25f2435bb6465a3b1 (diff)
downloadlinux-1da9e1c06873350c99ba49a052f92de85f2c69f2.tar.xz
usb: isp1760: move to regmap for register access
Rework access to registers and memory to use regmap framework. No change in current feature or way of work is intended with this change. This will allow to reuse this driver with other IP of this family, for example isp1763, with little changes and effort. Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> Link: https://lore.kernel.org/r/20210513084717.2487366-3-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.c445
1 files changed, 234 insertions, 211 deletions
diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c
index 0e0a4b01c710..20d142140574 100644
--- a/drivers/usb/isp1760/isp1760-hcd.c
+++ b/drivers/usb/isp1760/isp1760-hcd.c
@@ -66,6 +66,11 @@ struct ptd {
#define ATL_PTD_OFFSET 0x0c00
#define PAYLOAD_OFFSET 0x1000
+#define ISP_BANK_0 0x00
+#define ISP_BANK_1 0x01
+#define ISP_BANK_2 0x02
+#define ISP_BANK_3 0x03
+
#define TO_DW(x) ((__force __dw)x)
#define TO_U32(x) ((__force u32)x)
@@ -161,16 +166,59 @@ struct urb_listitem {
};
/*
- * Access functions for isp176x registers (addresses 0..0x03FF).
+ * Access functions for isp176x registers regmap fields
*/
-static u32 reg_read32(void __iomem *base, u32 reg)
+static u32 isp1760_hcd_read(struct usb_hcd *hcd, u32 field)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ return isp1760_field_read(priv->fields, field);
+}
+
+static void isp1760_hcd_write(struct usb_hcd *hcd, u32 field, u32 val)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+ isp1760_field_write(priv->fields, field, val);
+}
+
+static void isp1760_hcd_set(struct usb_hcd *hcd, u32 field)
+{
+ isp1760_hcd_write(hcd, field, 0xFFFFFFFF);
+}
+
+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)
+{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ unsigned int val;
+
+ isp1760_hcd_set(hcd, field);
+
+ return regmap_field_read_poll_timeout(priv->fields[field], val, 1, 1,
+ timeout_us);
+}
+
+static int isp1760_hcd_clear_poll_timeout(struct usb_hcd *hcd, u32 field,
+ u32 timeout_us)
{
- return isp1760_read32(base, reg);
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ unsigned int val;
+
+ isp1760_hcd_clear(hcd, field);
+
+ return regmap_field_read_poll_timeout(priv->fields[field], val, 0, 1,
+ timeout_us);
}
-static void reg_write32(void __iomem *base, u32 reg, u32 val)
+static bool isp1760_hcd_is_set(struct usb_hcd *hcd, u32 field)
{
- isp1760_write32(base, reg, val);
+ return !!isp1760_hcd_read(hcd, field);
}
/*
@@ -233,12 +281,15 @@ static void bank_reads8(void __iomem *src_base, u32 src_offset, u32 bank_addr,
}
}
-static void mem_reads8(void __iomem *src_base, u32 src_offset, void *dst,
- u32 bytes)
+static void mem_reads8(struct usb_hcd *hcd, void __iomem *src_base,
+ u32 src_offset, void *dst, u32 bytes)
{
- reg_write32(src_base, HC_MEMORY_REG, src_offset + ISP_BANK(0));
+ isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
+ isp1760_hcd_write(hcd, MEM_START_ADDR, src_offset);
+
ndelay(90);
- bank_reads8(src_base, src_offset, ISP_BANK(0), dst, bytes);
+
+ bank_reads8(src_base, src_offset, ISP_BANK_0, dst, bytes);
}
static void mem_writes8(void __iomem *dst_base, u32 dst_offset,
@@ -280,14 +331,15 @@ static void mem_writes8(void __iomem *dst_base, u32 dst_offset,
* 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(void __iomem *base, u32 ptd_offset, u32 slot,
- struct ptd *ptd)
+static void ptd_read(struct usb_hcd *hcd, void __iomem *base,
+ u32 ptd_offset, u32 slot, struct ptd *ptd)
{
- reg_write32(base, HC_MEMORY_REG,
- ISP_BANK(0) + ptd_offset + slot*sizeof(*ptd));
+ isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
+ isp1760_hcd_write(hcd, MEM_START_ADDR,
+ ptd_offset + slot * sizeof(*ptd));
ndelay(90);
- bank_reads8(base, ptd_offset + slot*sizeof(*ptd), ISP_BANK(0),
- (void *) ptd, sizeof(*ptd));
+ bank_reads8(base, ptd_offset + slot * sizeof(*ptd), ISP_BANK_0,
+ (void *)ptd, sizeof(*ptd));
}
static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot,
@@ -379,34 +431,15 @@ static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
qtd->payload_addr = 0;
}
-static int handshake(struct usb_hcd *hcd, u32 reg,
- u32 mask, u32 done, int usec)
-{
- u32 result;
- int ret;
-
- ret = readl_poll_timeout_atomic(hcd->regs + reg, result,
- ((result & mask) == done ||
- result == U32_MAX), 1, usec);
- if (result == U32_MAX)
- return -ENODEV;
-
- return ret;
-}
-
/* reset a non-running (STS_HALT == 1) controller */
static int ehci_reset(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- u32 command = reg_read32(hcd->regs, HC_USBCMD);
-
- command |= CMD_RESET;
- reg_write32(hcd->regs, HC_USBCMD, command);
hcd->state = HC_STATE_HALT;
priv->next_statechange = jiffies;
- return handshake(hcd, HC_USBCMD, CMD_RESET, 0, 250 * 1000);
+ return isp1760_hcd_set_poll_timeout(hcd, CMD_RESET, 250 * 1000);
}
static struct isp1760_qh *qh_alloc(gfp_t flags)
@@ -434,8 +467,10 @@ static void qh_free(struct isp1760_qh *qh)
/* one-time init, only for memory state */
static int priv_init(struct usb_hcd *hcd)
{
- struct isp1760_hcd *priv = hcd_to_priv(hcd);
- u32 hcc_params;
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
+ u32 isoc_cache;
+ u32 isoc_thres;
+
int i;
spin_lock_init(&priv->lock);
@@ -450,12 +485,14 @@ static int priv_init(struct usb_hcd *hcd)
priv->periodic_size = DEFAULT_I_TDPS;
/* controllers may cache some of the periodic schedule ... */
- hcc_params = reg_read32(hcd->regs, HC_HCCPARAMS);
+ isoc_cache = isp1760_hcd_read(hcd, HCC_ISOC_CACHE);
+ isoc_thres = isp1760_hcd_read(hcd, HCC_ISOC_THRES);
+
/* full frame cache */
- if (HCC_ISOC_CACHE(hcc_params))
+ if (isoc_cache)
priv->i_thresh = 8;
else /* N microframes cached */
- priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
+ priv->i_thresh = 2 + isoc_thres;
return 0;
}
@@ -464,12 +501,13 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
int result;
- u32 scratch, hwmode;
+ u32 scratch;
+
+ isp1760_reg_write(priv->regs, ISP176x_HC_SCRATCH, 0xdeadbabe);
- reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe);
/* Change bus pattern */
- scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG);
- scratch = reg_read32(hcd->regs, HC_SCRATCH_REG);
+ 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");
return -ENODEV;
@@ -483,10 +521,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.
*/
- reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0);
- reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
- reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
- reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
+ 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);
result = ehci_reset(hcd);
if (result)
@@ -495,14 +536,11 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
/* Step 11 passed */
/* ATL reset */
- hwmode = reg_read32(hcd->regs, HC_HW_MODE_CTRL) & ~ALL_ATX_RESET;
- reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET);
+ isp1760_hcd_set(hcd, ALL_ATX_RESET);
mdelay(10);
- reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
+ isp1760_hcd_clear(hcd, ALL_ATX_RESET);
- reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK);
-
- priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS);
+ isp1760_hcd_set(hcd, HC_INT_ENABLE);
return priv_init(hcd);
}
@@ -732,12 +770,12 @@ static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot,
/* Make sure done map has not triggered from some unlinked transfer */
if (ptd_offset == ATL_PTD_OFFSET) {
- priv->atl_done_map |= reg_read32(hcd->regs,
- HC_ATL_PTD_DONEMAP_REG);
+ priv->atl_done_map |= isp1760_reg_read(priv->regs,
+ ISP176x_HC_ATL_PTD_DONEMAP);
priv->atl_done_map &= ~(1 << slot);
} else {
- priv->int_done_map |= reg_read32(hcd->regs,
- HC_INT_PTD_DONEMAP_REG);
+ priv->int_done_map |= isp1760_reg_read(priv->regs,
+ ISP176x_HC_INT_PTD_DONEMAP);
priv->int_done_map &= ~(1 << slot);
}
@@ -746,16 +784,20 @@ static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot,
slots[slot].timestamp = jiffies;
slots[slot].qtd = qtd;
slots[slot].qh = qh;
- ptd_write(hcd->regs, ptd_offset, slot, ptd);
+ ptd_write(priv->base, ptd_offset, slot, ptd);
if (ptd_offset == ATL_PTD_OFFSET) {
- skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs,
+ ISP176x_HC_ATL_PTD_SKIPMAP);
skip_map &= ~(1 << qh->slot);
- reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
+ isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP,
+ skip_map);
} else {
- skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs,
+ ISP176x_HC_INT_PTD_SKIPMAP);
skip_map &= ~(1 << qh->slot);
- reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map);
+ isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP,
+ skip_map);
}
}
@@ -768,9 +810,10 @@ 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)
{
- int last_qtd;
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
struct isp1760_qtd *qtd, *qtd_next;
struct urb_listitem *urb_listitem;
+ int last_qtd;
list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list, qtd_list) {
if (qtd->status < QTD_XFER_COMPLETE)
@@ -785,9 +828,10 @@ 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->regs, qtd->payload_addr,
- qtd->data_buffer,
- qtd->actual_length);
+ mem_reads8(hcd, priv->base,
+ qtd->payload_addr,
+ qtd->data_buffer,
+ qtd->actual_length);
fallthrough;
case OUT_PID:
qtd->urb->actual_length +=
@@ -875,8 +919,8 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
if ((qtd->length) &&
((qtd->packet_type == SETUP_PID) ||
(qtd->packet_type == OUT_PID))) {
- mem_writes8(hcd->regs, qtd->payload_addr,
- qtd->data_buffer, qtd->length);
+ mem_writes8(priv->base, qtd->payload_addr,
+ qtd->data_buffer, qtd->length);
}
qtd->status = QTD_PAYLOAD_ALLOC;
@@ -1076,9 +1120,9 @@ static void handle_done_ptds(struct usb_hcd *hcd)
int modified;
int skip_map;
- skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP);
priv->int_done_map &= ~skip_map;
- skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP);
priv->atl_done_map &= ~skip_map;
modified = priv->int_done_map || priv->atl_done_map;
@@ -1096,7 +1140,7 @@ static void handle_done_ptds(struct usb_hcd *hcd)
continue;
}
ptd_offset = INT_PTD_OFFSET;
- ptd_read(hcd->regs, INT_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, priv->base, INT_PTD_OFFSET, slot, &ptd);
state = check_int_transfer(hcd, &ptd,
slots[slot].qtd->urb);
} else {
@@ -1111,7 +1155,7 @@ static void handle_done_ptds(struct usb_hcd *hcd)
continue;
}
ptd_offset = ATL_PTD_OFFSET;
- ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, priv->base, ATL_PTD_OFFSET, slot, &ptd);
state = check_atl_transfer(hcd, &ptd,
slots[slot].qtd->urb);
}
@@ -1136,7 +1180,7 @@ static void handle_done_ptds(struct usb_hcd *hcd)
qtd->status = QTD_XFER_COMPLETE;
if (list_is_last(&qtd->qtd_list, &qh->qtd_list) ||
- is_short_bulk(qtd))
+ is_short_bulk(qtd))
qtd = NULL;
else
qtd = list_entry(qtd->qtd_list.next,
@@ -1212,13 +1256,15 @@ static irqreturn_t isp1760_irq(struct usb_hcd *hcd)
if (!(hcd->state & HC_STATE_RUNNING))
goto leave;
- imask = reg_read32(hcd->regs, HC_INTERRUPT_REG);
+ imask = isp1760_reg_read(priv->regs, ISP176x_HC_INTERRUPT);
if (unlikely(!imask))
goto leave;
- reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */
+ isp1760_reg_write(priv->regs, ISP176x_HC_INTERRUPT, imask); /* Clear */
- priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG);
- priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG);
+ 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);
handle_done_ptds(hcd);
@@ -1273,7 +1319,7 @@ static void errata2_function(struct timer_list *unused)
if (priv->atl_slots[slot].qh && time_after(jiffies,
priv->atl_slots[slot].timestamp +
msecs_to_jiffies(SLOT_TIMEOUT))) {
- ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);
+ ptd_read(hcd, priv->base, ATL_PTD_OFFSET, slot, &ptd);
if (!FROM_DW0_VALID(ptd.dw0) &&
!FROM_DW3_ACTIVE(ptd.dw3))
priv->atl_done_map |= 1 << slot;
@@ -1290,9 +1336,8 @@ static void errata2_function(struct timer_list *unused)
static int isp1760_run(struct usb_hcd *hcd)
{
+ struct isp1760_hcd *priv = hcd_to_priv(hcd);
int retval;
- u32 temp;
- u32 command;
u32 chipid;
hcd->uses_new_polling = 1;
@@ -1300,23 +1345,20 @@ static int isp1760_run(struct usb_hcd *hcd)
hcd->state = HC_STATE_RUNNING;
/* Set PTD interrupt AND & OR maps */
- reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0);
- reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff);
- reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0);
- reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff);
- reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0);
- reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff);
+ 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);
/* step 23 passed */
- temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL);
- reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN);
+ isp1760_hcd_set(hcd, HW_GLOBAL_INTR_EN);
- command = reg_read32(hcd->regs, HC_USBCMD);
- command &= ~(CMD_LRESET|CMD_RESET);
- command |= CMD_RUN;
- reg_write32(hcd->regs, HC_USBCMD, command);
+ isp1760_hcd_clear(hcd, CMD_LRESET);
+ isp1760_hcd_clear(hcd, CMD_RESET);
- retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000);
+ retval = isp1760_hcd_set_poll_timeout(hcd, CMD_RUN, 250 * 1000);
if (retval)
return retval;
@@ -1326,9 +1368,8 @@ static int isp1760_run(struct usb_hcd *hcd)
* the semaphore while doing so.
*/
down_write(&ehci_cf_port_reset_rwsem);
- reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF);
- retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000);
+ retval = isp1760_hcd_set_poll_timeout(hcd, FLAG_CF, 250 * 1000);
up_write(&ehci_cf_port_reset_rwsem);
if (retval)
return retval;
@@ -1338,21 +1379,22 @@ static int isp1760_run(struct usb_hcd *hcd)
errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
add_timer(&errata2_timer);
- chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG);
+ 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);
/* PTD Register Init Part 2, Step 28 */
/* Setup registers controlling PTD checking */
- reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000);
- reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000);
- reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001);
- reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff);
- reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff);
- reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff);
- reg_write32(hcd->regs, HC_BUFFER_STATUS_REG,
- ATL_BUF_FILL | INT_BUF_FILL);
+ 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);
+
+ isp1760_hcd_set(hcd, ATL_BUF_FILL);
+ isp1760_hcd_set(hcd, INT_BUF_FILL);
/* GRR this is run-once init(), being done every time the HC starts.
* So long as they're part of class devices, we can't do it init()
@@ -1586,15 +1628,19 @@ 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 = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs,
+ ISP176x_HC_ATL_PTD_SKIPMAP);
skip_map |= (1 << qh->slot);
- reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
+ isp1760_reg_write(priv->regs, ISP176x_HC_ATL_PTD_SKIPMAP,
+ skip_map);
priv->atl_slots[qh->slot].qh = NULL;
priv->atl_slots[qh->slot].qtd = NULL;
} else {
- skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);
+ skip_map = isp1760_reg_read(priv->regs,
+ ISP176x_HC_INT_PTD_SKIPMAP);
skip_map |= (1 << qh->slot);
- reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map);
+ isp1760_reg_write(priv->regs, ISP176x_HC_INT_PTD_SKIPMAP,
+ skip_map);
priv->int_slots[qh->slot].qh = NULL;
priv->int_slots[qh->slot].qtd = NULL;
}
@@ -1707,8 +1753,7 @@ out:
static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- u32 temp, status = 0;
- u32 mask;
+ u32 status = 0;
int retval = 1;
unsigned long flags;
@@ -1718,17 +1763,13 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
/* init status to no-changes */
buf[0] = 0;
- mask = PORT_CSC;
spin_lock_irqsave(&priv->lock, flags);
- temp = reg_read32(hcd->regs, HC_PORTSC1);
- if (temp & PORT_OWNER) {
- if (temp & PORT_CSC) {
- temp &= ~PORT_CSC;
- reg_write32(hcd->regs, HC_PORTSC1, temp);
- goto done;
- }
+ if (isp1760_hcd_is_set(hcd, PORT_OWNER) &&
+ isp1760_hcd_is_set(hcd, PORT_CSC)) {
+ isp1760_hcd_clear(hcd, PORT_CSC);
+ goto done;
}
/*
@@ -1737,11 +1778,9 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
* high-speed device is switched over to the companion
* controller by the user.
*/
-
- if ((temp & mask) != 0
- || ((temp & PORT_RESUME) != 0
- && time_after_eq(jiffies,
- priv->reset_done))) {
+ if (isp1760_hcd_is_set(hcd, PORT_CSC) ||
+ (isp1760_hcd_is_set(hcd, PORT_RESUME) &&
+ time_after_eq(jiffies, priv->reset_done))) {
buf [0] |= 1 << (0 + 1);
status = STS_PCD;
}
@@ -1754,9 +1793,11 @@ done:
static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
struct usb_hub_descriptor *desc)
{
- int ports = HCS_N_PORTS(priv->hcs_params);
+ int ports;
u16 temp;
+ ports = isp1760_hcd_read(priv->hcd, HCS_N_PORTS);
+
desc->bDescriptorType = USB_DT_HUB;
/* priv 1.0, 2.3.9 says 20ms max */
desc->bPwrOn2PwrGood = 10;
@@ -1772,7 +1813,7 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
/* per-port overcurrent reporting */
temp = HUB_CHAR_INDV_PORT_OCPM;
- if (HCS_PPC(priv->hcs_params))
+ if (isp1760_hcd_is_set(priv->hcd, HCS_PPC))
/* per-port power control */
temp |= HUB_CHAR_INDV_PORT_LPSM;
else
@@ -1783,38 +1824,37 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
-static int check_reset_complete(struct usb_hcd *hcd, int index,
- int port_status)
+static void check_reset_complete(struct usb_hcd *hcd, int index)
{
- if (!(port_status & PORT_CONNECT))
- return port_status;
+ if (!(isp1760_hcd_is_set(hcd, PORT_CONNECT)))
+ return;
/* if reset finished and it's still not enabled -- handoff */
- if (!(port_status & PORT_PE)) {
-
+ if (!isp1760_hcd_is_set(hcd, PORT_PE)) {
dev_info(hcd->self.controller,
- "port %d full speed --> companion\n",
- index + 1);
+ "port %d full speed --> companion\n", index + 1);
- port_status |= PORT_OWNER;
- port_status &= ~PORT_RWC_BITS;
- reg_write32(hcd->regs, HC_PORTSC1, port_status);
+ isp1760_hcd_set(hcd, PORT_OWNER);
- } else
+ isp1760_hcd_clear(hcd, PORT_CSC);
+ } else {
dev_info(hcd->self.controller, "port %d high speed\n",
- index + 1);
+ index + 1);
+ }
- return port_status;
+ return;
}
static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
u16 wValue, u16 wIndex, char *buf, u16 wLength)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- int ports = HCS_N_PORTS(priv->hcs_params);
- u32 temp, status;
+ u32 status;
unsigned long flags;
int retval = 0;
+ int ports;
+
+ ports = isp1760_hcd_read(hcd, HCS_N_PORTS);
/*
* FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1839,7 +1879,6 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
- temp = reg_read32(hcd->regs, HC_PORTSC1);
/*
* Even if OWNER is set, so the port is owned by the
@@ -1850,22 +1889,22 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
- reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_PE);
+ isp1760_hcd_clear(hcd, PORT_PE);
break;
case USB_PORT_FEAT_C_ENABLE:
/* XXX error? */
break;
case USB_PORT_FEAT_SUSPEND:
- if (temp & PORT_RESET)
+ if (isp1760_hcd_is_set(hcd, PORT_RESET))
goto error;
- if (temp & PORT_SUSPEND) {
- if ((temp & PORT_PE) == 0)
+ if (isp1760_hcd_is_set(hcd, PORT_SUSPEND)) {
+ if (!isp1760_hcd_is_set(hcd, PORT_PE))
goto error;
/* resume signaling for 20 msec */
- temp &= ~(PORT_RWC_BITS);
- reg_write32(hcd->regs, HC_PORTSC1,
- temp | PORT_RESUME);
+ isp1760_hcd_clear(hcd, PORT_CSC);
+ isp1760_hcd_set(hcd, PORT_RESUME);
+
priv->reset_done = jiffies +
msecs_to_jiffies(USB_RESUME_TIMEOUT);
}
@@ -1874,12 +1913,11 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
/* we auto-clear this feature */
break;
case USB_PORT_FEAT_POWER:
- if (HCS_PPC(priv->hcs_params))
- reg_write32(hcd->regs, HC_PORTSC1,
- temp & ~PORT_POWER);
+ if (isp1760_hcd_is_set(hcd, HCS_PPC))
+ isp1760_hcd_clear(hcd, PORT_POWER);
break;
case USB_PORT_FEAT_C_CONNECTION:
- reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_CSC);
+ isp1760_hcd_set(hcd, PORT_CSC);
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
/* XXX error ?*/
@@ -1890,7 +1928,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
default:
goto error;
}
- reg_read32(hcd->regs, HC_USBCMD);
+ isp1760_reg_read(priv->regs, ISP176x_HC_USBCMD);
break;
case GetHubDescriptor:
isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *)
@@ -1905,15 +1943,14 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
goto error;
wIndex--;
status = 0;
- temp = reg_read32(hcd->regs, HC_PORTSC1);
/* wPortChange bits */
- if (temp & PORT_CSC)
+ if (isp1760_hcd_is_set(hcd, PORT_CSC))
status |= USB_PORT_STAT_C_CONNECTION << 16;
/* whoever resumes must GetPortStatus to complete it!! */
- if (temp & PORT_RESUME) {
+ if (isp1760_hcd_is_set(hcd, PORT_RESUME)) {
dev_err(hcd->self.controller, "Port resume should be skipped.\n");
/* Remote Wakeup received? */
@@ -1932,35 +1969,31 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
priv->reset_done = 0;
/* stop resume signaling */
- temp = reg_read32(hcd->regs, HC_PORTSC1);
- reg_write32(hcd->regs, HC_PORTSC1,
- temp & ~(PORT_RWC_BITS | PORT_RESUME));
- retval = handshake(hcd, HC_PORTSC1,
- PORT_RESUME, 0, 2000 /* 2msec */);
+ isp1760_hcd_clear(hcd, PORT_CSC);
+
+ retval = isp1760_hcd_clear_poll_timeout(hcd,
+ PORT_RESUME, 2000);
if (retval != 0) {
dev_err(hcd->self.controller,
"port %d resume error %d\n",
wIndex + 1, retval);
goto error;
}
- temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
}
}
/* whoever resets must GetPortStatus to complete it!! */
- if ((temp & PORT_RESET)
- && time_after_eq(jiffies,
- priv->reset_done)) {
+ if (isp1760_hcd_is_set(hcd, PORT_RESET) &&
+ time_after_eq(jiffies, priv->reset_done)) {
status |= USB_PORT_STAT_C_RESET << 16;
priv->reset_done = 0;
/* force reset to complete */
- reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_RESET);
/* REVISIT: some hardware needs 550+ usec to clear
* this bit; seems too long to spin routinely...
*/
- retval = handshake(hcd, HC_PORTSC1,
- PORT_RESET, 0, 750);
+ retval = isp1760_hcd_clear_poll_timeout(hcd, PORT_RESET,
+ 750);
if (retval != 0) {
dev_err(hcd->self.controller, "port %d reset error %d\n",
wIndex + 1, retval);
@@ -1968,8 +2001,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
}
/* see what we found out */
- temp = check_reset_complete(hcd, wIndex,
- reg_read32(hcd->regs, HC_PORTSC1));
+ check_reset_complete(hcd, wIndex);
}
/*
* Even if OWNER is set, there's no harm letting hub_wq
@@ -1977,21 +2009,22 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
* for PORT_POWER anyway).
*/
- if (temp & PORT_OWNER)
+ if (isp1760_hcd_is_set(hcd, PORT_OWNER))
dev_err(hcd->self.controller, "PORT_OWNER is set\n");
- if (temp & PORT_CONNECT) {
+ if (isp1760_hcd_is_set(hcd, PORT_CONNECT)) {
status |= USB_PORT_STAT_CONNECTION;
/* status may be from integrated TT */
status |= USB_PORT_STAT_HIGH_SPEED;
}
- if (temp & PORT_PE)
+ if (isp1760_hcd_is_set(hcd, PORT_PE))
status |= USB_PORT_STAT_ENABLE;
- if (temp & (PORT_SUSPEND|PORT_RESUME))
+ if (isp1760_hcd_is_set(hcd, PORT_SUSPEND) &&
+ isp1760_hcd_is_set(hcd, PORT_RESUME))
status |= USB_PORT_STAT_SUSPEND;
- if (temp & PORT_RESET)
+ if (isp1760_hcd_is_set(hcd, PORT_RESET))
status |= USB_PORT_STAT_RESET;
- if (temp & PORT_POWER)
+ if (isp1760_hcd_is_set(hcd, PORT_POWER))
status |= USB_PORT_STAT_POWER;
put_unaligned(cpu_to_le32(status), (__le32 *) buf);
@@ -2011,41 +2044,39 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
- temp = reg_read32(hcd->regs, HC_PORTSC1);
- if (temp & PORT_OWNER)
+ if (isp1760_hcd_is_set(hcd, PORT_OWNER))
break;
-/* temp &= ~PORT_RWC_BITS; */
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
- reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_PE);
+ isp1760_hcd_set(hcd, PORT_PE);
break;
case USB_PORT_FEAT_SUSPEND:
- if ((temp & PORT_PE) == 0
- || (temp & PORT_RESET) != 0)
+ if (!isp1760_hcd_is_set(hcd, PORT_PE) ||
+ isp1760_hcd_is_set(hcd, PORT_RESET))
goto error;
- reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_SUSPEND);
+ isp1760_hcd_set(hcd, PORT_SUSPEND);
break;
case USB_PORT_FEAT_POWER:
- if (HCS_PPC(priv->hcs_params))
- reg_write32(hcd->regs, HC_PORTSC1,
- temp | PORT_POWER);
+ if (isp1760_hcd_is_set(hcd, HCS_PPC))
+ isp1760_hcd_set(hcd, PORT_POWER);
break;
case USB_PORT_FEAT_RESET:
- if (temp & PORT_RESUME)
+ if (isp1760_hcd_is_set(hcd, PORT_RESUME))
goto error;
/* line status bits may report this as low speed,
* which can be fine if this root hub has a
* transaction translator built in.
*/
- if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
- && PORT_USB11(temp)) {
- temp |= PORT_OWNER;
+ if ((isp1760_hcd_is_set(hcd, PORT_CONNECT) &&
+ !isp1760_hcd_is_set(hcd, PORT_PE)) &&
+ (isp1760_hcd_read(hcd, PORT_LSTATUS) == 1)) {
+ isp1760_hcd_set(hcd, PORT_OWNER);
} else {
- temp |= PORT_RESET;
- temp &= ~PORT_PE;
+ isp1760_hcd_set(hcd, PORT_RESET);
+ isp1760_hcd_clear(hcd, PORT_PE);
/*
* caller must wait, then call GetPortStatus
@@ -2054,12 +2085,11 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
priv->reset_done = jiffies +
msecs_to_jiffies(50);
}
- reg_write32(hcd->regs, HC_PORTSC1, temp);
break;
default:
goto error;
}
- reg_read32(hcd->regs, HC_USBCMD);
+ isp1760_reg_read(priv->regs, ISP176x_HC_USBCMD);
break;
default:
@@ -2076,14 +2106,13 @@ static int isp1760_get_frame(struct usb_hcd *hcd)
struct isp1760_hcd *priv = hcd_to_priv(hcd);
u32 fr;
- fr = reg_read32(hcd->regs, HC_FRINDEX);
+ fr = isp1760_hcd_read(hcd, HC_FRINDEX);
return (fr >> 3) % priv->periodic_size;
}
static void isp1760_stop(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- u32 temp;
del_timer(&errata2_timer);
@@ -2094,24 +2123,19 @@ static void isp1760_stop(struct usb_hcd *hcd)
spin_lock_irq(&priv->lock);
ehci_reset(hcd);
/* Disable IRQ */
- temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL);
- reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN);
+ isp1760_hcd_clear(hcd, HW_GLOBAL_INTR_EN);
spin_unlock_irq(&priv->lock);
- reg_write32(hcd->regs, HC_CONFIGFLAG, 0);
+ isp1760_hcd_clear(hcd, FLAG_CF);
}
static void isp1760_shutdown(struct usb_hcd *hcd)
{
- u32 command, temp;
-
isp1760_stop(hcd);
- temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL);
- reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN);
- command = reg_read32(hcd->regs, HC_USBCMD);
- command &= ~CMD_RUN;
- reg_write32(hcd->regs, HC_USBCMD, command);
+ isp1760_hcd_clear(hcd, HW_GLOBAL_INTR_EN);
+
+ isp1760_hcd_clear(hcd, CMD_RUN);
}
static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd,
@@ -2184,8 +2208,8 @@ void isp1760_deinit_kmem_cache(void)
kmem_cache_destroy(urb_listitem_cachep);
}
-int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
- struct resource *mem, int irq, unsigned long irqflags,
+int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
+ int irq, unsigned long irqflags,
struct device *dev)
{
struct usb_hcd *hcd;
@@ -2202,7 +2226,6 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
init_memory(priv);
hcd->irq = irq;
- hcd->regs = regs;
hcd->rsrc_start = mem->start;
hcd->rsrc_len = resource_size(mem);