aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/r8a66597-hcd.c
diff options
context:
space:
mode:
authorYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>2008-04-10 08:05:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-25 00:16:49 -0400
commit29fab0cd897519be9009ba8c898410ab83b378e9 (patch)
treedf4a57d6574fe505200cd6b69e817fc953bf633c /drivers/usb/host/r8a66597-hcd.c
parent6d8791076c7742c65dd796ae0ac260ab22e85517 (diff)
USB: r8a66597-hcd: fix usb device connection timing
Fix the problem that enumeration of a USB device was slow. Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/r8a66597-hcd.c')
-rw-r--r--drivers/usb/host/r8a66597-hcd.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index dac2f7dd69b9..bb48f42bd7ce 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -900,10 +900,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
900} 900}
901 901
902/* this function must be called with interrupt disabled */ 902/* this function must be called with interrupt disabled */
903static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) 903static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
904 u16 syssts)
904{ 905{
905 r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) 906 if (syssts == SE0) {
906 | (1 << USB_PORT_FEAT_C_CONNECTION); 907 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
908 return;
909 }
910
911 if (syssts == FS_JSTS)
912 r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
913 else if (syssts == LS_JSTS)
914 r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
915
907 r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); 916 r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
908 r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); 917 r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
909} 918}
@@ -1478,13 +1487,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
1478 } 1487 }
1479} 1488}
1480 1489
1490static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
1491{
1492 mod_timer(&r8a66597->rh_timer,
1493 jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
1494}
1495
1481static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) 1496static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
1482{ 1497{
1483 struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; 1498 struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
1484 1499
1485 rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; 1500 rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
1486 rh->scount = R8A66597_MAX_SAMPLING; 1501 rh->scount = R8A66597_MAX_SAMPLING;
1487 mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50)); 1502 r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
1503 | (1 << USB_PORT_FEAT_C_CONNECTION);
1504 r8a66597_root_hub_start_polling(r8a66597);
1488} 1505}
1489 1506
1490static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) 1507static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
@@ -1571,37 +1588,28 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port)
1571 if ((tmp & USBRST) == USBRST) { 1588 if ((tmp & USBRST) == USBRST) {
1572 r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, 1589 r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
1573 dvstctr_reg); 1590 dvstctr_reg);
1574 mod_timer(&r8a66597->rh_timer, 1591 r8a66597_root_hub_start_polling(r8a66597);
1575 jiffies + msecs_to_jiffies(50));
1576 } else 1592 } else
1577 r8a66597_usb_connect(r8a66597, port); 1593 r8a66597_usb_connect(r8a66597, port);
1578 } 1594 }
1579 1595
1596 if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) {
1597 r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
1598 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
1599 }
1600
1580 if (rh->scount > 0) { 1601 if (rh->scount > 0) {
1581 tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; 1602 tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
1582 if (tmp == rh->old_syssts) { 1603 if (tmp == rh->old_syssts) {
1583 rh->scount--; 1604 rh->scount--;
1584 if (rh->scount == 0) { 1605 if (rh->scount == 0)
1585 if (tmp == FS_JSTS) { 1606 r8a66597_check_syssts(r8a66597, port, tmp);
1586 r8a66597_bset(r8a66597, HSE, 1607 else
1587 get_syscfg_reg(port)); 1608 r8a66597_root_hub_start_polling(r8a66597);
1588 r8a66597_usb_preconnect(r8a66597, port);
1589 } else if (tmp == LS_JSTS) {
1590 r8a66597_bclr(r8a66597, HSE,
1591 get_syscfg_reg(port));
1592 r8a66597_usb_preconnect(r8a66597, port);
1593 } else if (tmp == SE0)
1594 r8a66597_bset(r8a66597, ATTCHE,
1595 get_intenb_reg(port));
1596 } else {
1597 mod_timer(&r8a66597->rh_timer,
1598 jiffies + msecs_to_jiffies(50));
1599 }
1600 } else { 1609 } else {
1601 rh->scount = R8A66597_MAX_SAMPLING; 1610 rh->scount = R8A66597_MAX_SAMPLING;
1602 rh->old_syssts = tmp; 1611 rh->old_syssts = tmp;
1603 mod_timer(&r8a66597->rh_timer, 1612 r8a66597_root_hub_start_polling(r8a66597);
1604 jiffies + msecs_to_jiffies(50));
1605 } 1613 }
1606 } 1614 }
1607} 1615}