Commit 29fab0cd authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Greg Kroah-Hartman

USB: r8a66597-hcd: fix usb device connection timing

Fix the problem that enumeration of a USB device was slow.
Signed-off-by: default avatarYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6d879107
...@@ -900,10 +900,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum) ...@@ -900,10 +900,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
} }
/* this function must be called with interrupt disabled */ /* 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) if (syssts == SE0) {
| (1 << USB_PORT_FEAT_C_CONNECTION); 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_write(r8a66597, ~DTCH, get_intsts_reg(port));
r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
} }
...@@ -1478,13 +1487,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) ...@@ -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) static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
{ {
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
rh->scount = R8A66597_MAX_SAMPLING; 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) 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,37 +1588,28 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port)
if ((tmp & USBRST) == USBRST) { if ((tmp & USBRST) == USBRST) {
r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
dvstctr_reg); dvstctr_reg);
mod_timer(&r8a66597->rh_timer, r8a66597_root_hub_start_polling(r8a66597);
jiffies + msecs_to_jiffies(50));
} else } else
r8a66597_usb_connect(r8a66597, port); 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) { if (rh->scount > 0) {
tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
if (tmp == rh->old_syssts) { if (tmp == rh->old_syssts) {
rh->scount--; rh->scount--;
if (rh->scount == 0) { if (rh->scount == 0)
if (tmp == FS_JSTS) { r8a66597_check_syssts(r8a66597, port, tmp);
r8a66597_bset(r8a66597, HSE, else
get_syscfg_reg(port)); r8a66597_root_hub_start_polling(r8a66597);
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));
}
} else { } else {
rh->scount = R8A66597_MAX_SAMPLING; rh->scount = R8A66597_MAX_SAMPLING;
rh->old_syssts = tmp; rh->old_syssts = tmp;
mod_timer(&r8a66597->rh_timer, r8a66597_root_hub_start_polling(r8a66597);
jiffies + msecs_to_jiffies(50));
} }
} }
} }
......
...@@ -396,7 +396,8 @@ ...@@ -396,7 +396,8 @@
#define R8A66597_BUF_BSIZE 8 #define R8A66597_BUF_BSIZE 8
#define R8A66597_MAX_DEVICE 10 #define R8A66597_MAX_DEVICE 10
#define R8A66597_MAX_ROOT_HUB 2 #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_MAX_DMA_CHANNEL 2
#define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL #define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL
#define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5)) #define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment