diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2008-04-10 08:05:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-04-25 00:16:49 -0400 |
commit | 29fab0cd897519be9009ba8c898410ab83b378e9 (patch) | |
tree | df4a57d6574fe505200cd6b69e817fc953bf633c /drivers/usb/host/r8a66597-hcd.c | |
parent | 6d8791076c7742c65dd796ae0ac260ab22e85517 (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.c | 56 |
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 */ |
903 | static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) | 903 | static 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 | ||
1490 | static 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 | |||
1481 | static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) | 1496 | static 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 | ||
1490 | static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | 1507 | static 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 | } |