diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2008-07-11 05:53:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-08-13 20:32:56 -0400 |
commit | 54d0be9e3af1e20c3d0c3cc3eba50d33da24229c (patch) | |
tree | 7d90984e708d834d1f05778fe6ad8dd69ac2e94a | |
parent | cbbcb9b0c7e4d1fd90cf54427382dae525773dc2 (diff) |
USB: sh: r8a66597-hcd: fix disconnect regression
fix the regression in commit 29fab0cd897519be9009ba8c898410ab83b378e9
that this driver executed reconnection processing when disconnected
some devices.
Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index d5f02dddb120..ea7126f99cab 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -964,11 +964,34 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum) | |||
964 | disable_irq_nrdy(r8a66597, pipenum); | 964 | disable_irq_nrdy(r8a66597, pipenum); |
965 | } | 965 | } |
966 | 966 | ||
967 | static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597) | ||
968 | { | ||
969 | mod_timer(&r8a66597->rh_timer, | ||
970 | jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME)); | ||
971 | } | ||
972 | |||
973 | static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port, | ||
974 | int connect) | ||
975 | { | ||
976 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
977 | |||
978 | rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; | ||
979 | rh->scount = R8A66597_MAX_SAMPLING; | ||
980 | if (connect) | ||
981 | rh->port |= 1 << USB_PORT_FEAT_CONNECTION; | ||
982 | else | ||
983 | rh->port &= ~(1 << USB_PORT_FEAT_CONNECTION); | ||
984 | rh->port |= 1 << USB_PORT_FEAT_C_CONNECTION; | ||
985 | |||
986 | r8a66597_root_hub_start_polling(r8a66597); | ||
987 | } | ||
988 | |||
967 | /* this function must be called with interrupt disabled */ | 989 | /* this function must be called with interrupt disabled */ |
968 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | 990 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, |
969 | u16 syssts) | 991 | u16 syssts) |
970 | { | 992 | { |
971 | if (syssts == SE0) { | 993 | if (syssts == SE0) { |
994 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); | ||
972 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); | 995 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); |
973 | return; | 996 | return; |
974 | } | 997 | } |
@@ -1002,13 +1025,10 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) | |||
1002 | { | 1025 | { |
1003 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; | 1026 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; |
1004 | 1027 | ||
1005 | r8a66597->root_hub[port].port &= ~(1 << USB_PORT_FEAT_CONNECTION); | ||
1006 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_C_CONNECTION); | ||
1007 | |||
1008 | disable_r8a66597_pipe_all(r8a66597, dev); | 1028 | disable_r8a66597_pipe_all(r8a66597, dev); |
1009 | free_usb_address(r8a66597, dev); | 1029 | free_usb_address(r8a66597, dev); |
1010 | 1030 | ||
1011 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); | 1031 | start_root_hub_sampling(r8a66597, port, 0); |
1012 | } | 1032 | } |
1013 | 1033 | ||
1014 | /* this function must be called with interrupt disabled */ | 1034 | /* this function must be called with interrupt disabled */ |
@@ -1551,23 +1571,6 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1551 | } | 1571 | } |
1552 | } | 1572 | } |
1553 | 1573 | ||
1554 | static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597) | ||
1555 | { | ||
1556 | mod_timer(&r8a66597->rh_timer, | ||
1557 | jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME)); | ||
1558 | } | ||
1559 | |||
1560 | static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) | ||
1561 | { | ||
1562 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
1563 | |||
1564 | rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; | ||
1565 | rh->scount = R8A66597_MAX_SAMPLING; | ||
1566 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | ||
1567 | | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
1568 | r8a66597_root_hub_start_polling(r8a66597); | ||
1569 | } | ||
1570 | |||
1571 | static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | 1574 | static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) |
1572 | { | 1575 | { |
1573 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1576 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
@@ -1594,7 +1597,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1594 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); | 1597 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); |
1595 | 1598 | ||
1596 | /* start usb bus sampling */ | 1599 | /* start usb bus sampling */ |
1597 | start_root_hub_sampling(r8a66597, 1); | 1600 | start_root_hub_sampling(r8a66597, 1, 1); |
1598 | } | 1601 | } |
1599 | if (mask2 & DTCH) { | 1602 | if (mask2 & DTCH) { |
1600 | r8a66597_write(r8a66597, ~DTCH, INTSTS2); | 1603 | r8a66597_write(r8a66597, ~DTCH, INTSTS2); |
@@ -1609,7 +1612,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1609 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); | 1612 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); |
1610 | 1613 | ||
1611 | /* start usb bus sampling */ | 1614 | /* start usb bus sampling */ |
1612 | start_root_hub_sampling(r8a66597, 0); | 1615 | start_root_hub_sampling(r8a66597, 0, 1); |
1613 | } | 1616 | } |
1614 | if (mask1 & DTCH) { | 1617 | if (mask1 & DTCH) { |
1615 | r8a66597_write(r8a66597, ~DTCH, INTSTS1); | 1618 | r8a66597_write(r8a66597, ~DTCH, INTSTS1); |