USB: r8a66597-hcd: fix usb device connection timing
authorYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Thu, 10 Apr 2008 12:05:55 +0000 (21:05 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Apr 2008 04:16:49 +0000 (21:16 -0700)
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>
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/r8a66597.h

index dac2f7dd69b9bdf3d6febca9b176057b5bf104c2..bb48f42bd7cee10f157a8dd94bf48132a9ab6b0a 100644 (file)
@@ -900,10 +900,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
 }
 
 /* this function must be called with interrupt disabled */
-static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port)
+static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
+                                       u16 syssts)
 {
-       r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
-                                        | (1 << USB_PORT_FEAT_C_CONNECTION);
+       if (syssts == SE0) {
+               r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+               return;
+       }
+
+       if (syssts == FS_JSTS)
+               r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
+       else if (syssts == LS_JSTS)
+               r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
+
        r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
        r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
 }
@@ -1478,13 +1487,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
        }
 }
 
+static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
+{
+       mod_timer(&r8a66597->rh_timer,
+                       jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
+}
+
 static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
 {
        struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 
        rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
        rh->scount = R8A66597_MAX_SAMPLING;
-       mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50));
+       r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
+                                        | (1 << USB_PORT_FEAT_C_CONNECTION);
+       r8a66597_root_hub_start_polling(r8a66597);
 }
 
 static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
@@ -1571,37 +1588,28 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port)
                if ((tmp & USBRST) == USBRST) {
                        r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
                                      dvstctr_reg);
-                       mod_timer(&r8a66597->rh_timer,
-                                 jiffies + msecs_to_jiffies(50));
+                       r8a66597_root_hub_start_polling(r8a66597);
                } else
                        r8a66597_usb_connect(r8a66597, port);
        }
 
+       if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) {
+               r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
+               r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+       }
+
        if (rh->scount > 0) {
                tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
                if (tmp == rh->old_syssts) {
                        rh->scount--;
-                       if (rh->scount == 0) {
-                               if (tmp == FS_JSTS) {
-                                       r8a66597_bset(r8a66597, HSE,
-                                                     get_syscfg_reg(port));
-                                       r8a66597_usb_preconnect(r8a66597, port);
-                               } else if (tmp == LS_JSTS) {
-                                       r8a66597_bclr(r8a66597, HSE,
-                                                     get_syscfg_reg(port));
-                                       r8a66597_usb_preconnect(r8a66597, port);
-                               } else if (tmp == SE0)
-                                       r8a66597_bset(r8a66597, ATTCHE,
-                                                     get_intenb_reg(port));
-                       } else {
-                               mod_timer(&r8a66597->rh_timer,
-                                         jiffies + msecs_to_jiffies(50));
-                       }
+                       if (rh->scount == 0)
+                               r8a66597_check_syssts(r8a66597, port, tmp);
+                       else
+                               r8a66597_root_hub_start_polling(r8a66597);
                } else {
                        rh->scount = R8A66597_MAX_SAMPLING;
                        rh->old_syssts = tmp;
-                       mod_timer(&r8a66597->rh_timer,
-                                 jiffies + msecs_to_jiffies(50));
+                       r8a66597_root_hub_start_polling(r8a66597);
                }
        }
 }
index a01461017ad692a6e8ba27a5d1b2c9395b8fa922..f46f7dd944a1f5eb7686c1ec73edc4ac1e4b9860 100644 (file)
 #define R8A66597_BUF_BSIZE             8
 #define R8A66597_MAX_DEVICE            10
 #define R8A66597_MAX_ROOT_HUB          2
-#define R8A66597_MAX_SAMPLING          10
+#define R8A66597_MAX_SAMPLING          5
+#define R8A66597_RH_POLL_TIME          10
 #define R8A66597_MAX_DMA_CHANNEL       2
 #define R8A66597_PIPE_NO_DMA           R8A66597_MAX_DMA_CHANNEL
 #define check_bulk_or_isoc(pipenum)    ((pipenum >= 1 && pipenum <= 5))