usb: isp1760: write to status and address register
We were already writing directly the port status register to trigger changes in isp1763. The same is needed in other IP from the family, including also to setup the read address before reading from device. Reported-by: Dietmar Eggemann <dietmar.eggemann@arm.com> Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com> Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> Link: https://lore.kernel.org/r/20210827131154.4151862-4-rui.silva@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
cbfa3effdf
Коммит
36815a4a07
|
@ -182,7 +182,7 @@ struct urb_listitem {
|
|||
struct urb *urb;
|
||||
};
|
||||
|
||||
static const u32 isp1763_hc_portsc1_fields[] = {
|
||||
static const u32 isp176x_hc_portsc1_fields[] = {
|
||||
[PORT_OWNER] = BIT(13),
|
||||
[PORT_POWER] = BIT(12),
|
||||
[PORT_LSTATUS] = BIT(10),
|
||||
|
@ -205,27 +205,28 @@ static u32 isp1760_hcd_read(struct usb_hcd *hcd, u32 field)
|
|||
}
|
||||
|
||||
/*
|
||||
* We need, in isp1763, to write directly the values to the portsc1
|
||||
* We need, in isp176x, 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);
|
||||
u32 bit = isp176x_hc_portsc1_fields[field];
|
||||
u16 portsc1_reg = priv->is_isp1763 ? ISP1763_HC_PORTSC1 :
|
||||
ISP176x_HC_PORTSC1;
|
||||
u32 port_status = readl(priv->base + portsc1_reg);
|
||||
|
||||
if (val)
|
||||
writel(port_status | bit, priv->base + ISP1763_HC_PORTSC1);
|
||||
writel(port_status | bit, priv->base + portsc1_reg);
|
||||
else
|
||||
writel(port_status & ~bit, priv->base + ISP1763_HC_PORTSC1);
|
||||
writel(port_status & ~bit, priv->base + portsc1_reg);
|
||||
}
|
||||
|
||||
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)))
|
||||
if (unlikely((field >= PORT_OWNER && field <= PORT_CONNECT)))
|
||||
return isp1760_hcd_portsc1_set_clear(priv, field, val);
|
||||
|
||||
isp1760_field_write(priv->fields, field, val);
|
||||
|
@ -367,8 +368,7 @@ static void isp1760_mem_read(struct usb_hcd *hcd, u32 src_offset, void *dst,
|
|||
{
|
||||
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);
|
||||
isp1760_reg_write(priv->regs, ISP176x_HC_MEMORY, src_offset);
|
||||
ndelay(100);
|
||||
|
||||
bank_reads8(priv->base, src_offset, ISP_BANK_0, dst, bytes);
|
||||
|
@ -496,8 +496,7 @@ static void isp1760_ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
|
|||
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, src_offset);
|
||||
isp1760_reg_write(priv->regs, ISP176x_HC_MEMORY, src_offset);
|
||||
ndelay(90);
|
||||
|
||||
bank_reads8(priv->base, src_offset, ISP_BANK_0, (void *)ptd,
|
||||
|
|
Загрузка…
Ссылка в новой задаче