diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 56 | ||||
-rw-r--r-- | drivers/usb/host/r8a66597.h | 3 |
2 files changed, 34 insertions, 25 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 | } |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index a01461017ad6..f46f7dd944a1 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -396,7 +396,8 @@ | |||
396 | #define R8A66597_BUF_BSIZE 8 | 396 | #define R8A66597_BUF_BSIZE 8 |
397 | #define R8A66597_MAX_DEVICE 10 | 397 | #define R8A66597_MAX_DEVICE 10 |
398 | #define R8A66597_MAX_ROOT_HUB 2 | 398 | #define R8A66597_MAX_ROOT_HUB 2 |
399 | #define R8A66597_MAX_SAMPLING 10 | 399 | #define R8A66597_MAX_SAMPLING 5 |
400 | #define R8A66597_RH_POLL_TIME 10 | ||
400 | #define R8A66597_MAX_DMA_CHANNEL 2 | 401 | #define R8A66597_MAX_DMA_CHANNEL 2 |
401 | #define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL | 402 | #define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL |
402 | #define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5)) | 403 | #define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5)) |