diff options
Diffstat (limited to 'drivers/usb/host/isp116x-hcd.c')
| -rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 88 |
1 files changed, 33 insertions, 55 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 75128c371800..41bbae83fc71 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
| @@ -83,7 +83,7 @@ | |||
| 83 | #include "../core/hcd.h" | 83 | #include "../core/hcd.h" |
| 84 | #include "isp116x.h" | 84 | #include "isp116x.h" |
| 85 | 85 | ||
| 86 | #define DRIVER_VERSION "08 Apr 2005" | 86 | #define DRIVER_VERSION "05 Aug 2005" |
| 87 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" | 87 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" |
| 88 | 88 | ||
| 89 | MODULE_DESCRIPTION(DRIVER_DESC); | 89 | MODULE_DESCRIPTION(DRIVER_DESC); |
| @@ -629,14 +629,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
| 629 | ERR("Unrecoverable error\n"); | 629 | ERR("Unrecoverable error\n"); |
| 630 | /* What should we do here? Reset? */ | 630 | /* What should we do here? Reset? */ |
| 631 | } | 631 | } |
| 632 | if (intstat & HCINT_RHSC) { | 632 | if (intstat & HCINT_RHSC) |
| 633 | isp116x->rhstatus = | 633 | /* When root hub or any of its ports is going |
| 634 | isp116x_read_reg32(isp116x, HCRHSTATUS); | 634 | to come out of suspend, it may take more |
| 635 | isp116x->rhport[0] = | 635 | than 10ms for status bits to stabilize. */ |
| 636 | isp116x_read_reg32(isp116x, HCRHPORT1); | 636 | mod_timer(&hcd->rh_timer, jiffies |
| 637 | isp116x->rhport[1] = | 637 | + msecs_to_jiffies(20) + 1); |
| 638 | isp116x_read_reg32(isp116x, HCRHPORT2); | ||
| 639 | } | ||
| 640 | if (intstat & HCINT_RD) { | 638 | if (intstat & HCINT_RD) { |
| 641 | DBG("---- remote wakeup\n"); | 639 | DBG("---- remote wakeup\n"); |
| 642 | schedule_work(&isp116x->rh_resume); | 640 | schedule_work(&isp116x->rh_resume); |
| @@ -925,20 +923,27 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
| 925 | { | 923 | { |
| 926 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 924 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
| 927 | int ports, i, changed = 0; | 925 | int ports, i, changed = 0; |
| 926 | unsigned long flags; | ||
| 928 | 927 | ||
| 929 | if (!HC_IS_RUNNING(hcd->state)) | 928 | if (!HC_IS_RUNNING(hcd->state)) |
| 930 | return -ESHUTDOWN; | 929 | return -ESHUTDOWN; |
| 931 | 930 | ||
| 932 | ports = isp116x->rhdesca & RH_A_NDP; | 931 | /* Report no status change now, if we are scheduled to be |
| 932 | called later */ | ||
| 933 | if (timer_pending(&hcd->rh_timer)) | ||
| 934 | return 0; | ||
| 933 | 935 | ||
| 934 | /* init status */ | 936 | ports = isp116x->rhdesca & RH_A_NDP; |
| 937 | spin_lock_irqsave(&isp116x->lock, flags); | ||
| 938 | isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS); | ||
| 935 | if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) | 939 | if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) |
| 936 | buf[0] = changed = 1; | 940 | buf[0] = changed = 1; |
| 937 | else | 941 | else |
| 938 | buf[0] = 0; | 942 | buf[0] = 0; |
| 939 | 943 | ||
| 940 | for (i = 0; i < ports; i++) { | 944 | for (i = 0; i < ports; i++) { |
| 941 | u32 status = isp116x->rhport[i]; | 945 | u32 status = isp116x->rhport[i] = |
| 946 | isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); | ||
| 942 | 947 | ||
| 943 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | 948 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC |
| 944 | | RH_PS_OCIC | RH_PS_PRSC)) { | 949 | | RH_PS_OCIC | RH_PS_PRSC)) { |
| @@ -947,6 +952,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
| 947 | continue; | 952 | continue; |
| 948 | } | 953 | } |
| 949 | } | 954 | } |
| 955 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 950 | return changed; | 956 | return changed; |
| 951 | } | 957 | } |
| 952 | 958 | ||
| @@ -1463,10 +1469,6 @@ static int isp116x_sw_reset(struct isp116x *isp116x) | |||
| 1463 | return ret; | 1469 | return ret; |
| 1464 | } | 1470 | } |
| 1465 | 1471 | ||
| 1466 | /* | ||
| 1467 | Reset. Tries to perform platform-specific hardware | ||
| 1468 | reset first; falls back to software reset. | ||
| 1469 | */ | ||
| 1470 | static int isp116x_reset(struct usb_hcd *hcd) | 1472 | static int isp116x_reset(struct usb_hcd *hcd) |
| 1471 | { | 1473 | { |
| 1472 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1474 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
| @@ -1474,17 +1476,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
| 1474 | u16 clkrdy = 0; | 1476 | u16 clkrdy = 0; |
| 1475 | int ret = 0, timeout = 15 /* ms */ ; | 1477 | int ret = 0, timeout = 15 /* ms */ ; |
| 1476 | 1478 | ||
| 1477 | if (isp116x->board && isp116x->board->reset) { | 1479 | ret = isp116x_sw_reset(isp116x); |
| 1478 | /* Hardware reset */ | ||
| 1479 | isp116x->board->reset(hcd->self.controller, 1); | ||
| 1480 | msleep(10); | ||
| 1481 | if (isp116x->board->clock) | ||
| 1482 | isp116x->board->clock(hcd->self.controller, 1); | ||
| 1483 | msleep(1); | ||
| 1484 | isp116x->board->reset(hcd->self.controller, 0); | ||
| 1485 | } else | ||
| 1486 | ret = isp116x_sw_reset(isp116x); | ||
| 1487 | |||
| 1488 | if (ret) | 1480 | if (ret) |
| 1489 | return ret; | 1481 | return ret; |
| 1490 | 1482 | ||
| @@ -1501,10 +1493,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
| 1501 | ERR("Clock not ready after 20ms\n"); | 1493 | ERR("Clock not ready after 20ms\n"); |
| 1502 | /* After sw_reset the clock won't report to be ready, if | 1494 | /* After sw_reset the clock won't report to be ready, if |
| 1503 | H_WAKEUP pin is high. */ | 1495 | H_WAKEUP pin is high. */ |
| 1504 | if (!isp116x->board || !isp116x->board->reset) | 1496 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); |
| 1505 | ERR("The driver does not support hardware wakeup.\n"); | ||
| 1506 | ERR("Please make sure that the H_WAKEUP pin " | ||
| 1507 | "is pulled low!\n"); | ||
| 1508 | ret = -ENODEV; | 1497 | ret = -ENODEV; |
| 1509 | } | 1498 | } |
| 1510 | return ret; | 1499 | return ret; |
| @@ -1527,15 +1516,7 @@ static void isp116x_stop(struct usb_hcd *hcd) | |||
| 1527 | isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS); | 1516 | isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS); |
| 1528 | spin_unlock_irqrestore(&isp116x->lock, flags); | 1517 | spin_unlock_irqrestore(&isp116x->lock, flags); |
| 1529 | 1518 | ||
| 1530 | /* Put the chip into reset state */ | 1519 | isp116x_sw_reset(isp116x); |
| 1531 | if (isp116x->board && isp116x->board->reset) | ||
| 1532 | isp116x->board->reset(hcd->self.controller, 0); | ||
| 1533 | else | ||
| 1534 | isp116x_sw_reset(isp116x); | ||
| 1535 | |||
| 1536 | /* Stop the clock */ | ||
| 1537 | if (isp116x->board && isp116x->board->clock) | ||
| 1538 | isp116x->board->clock(hcd->self.controller, 0); | ||
| 1539 | } | 1520 | } |
| 1540 | 1521 | ||
| 1541 | /* | 1522 | /* |
| @@ -1561,6 +1542,9 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1561 | return -ENODEV; | 1542 | return -ENODEV; |
| 1562 | } | 1543 | } |
| 1563 | 1544 | ||
| 1545 | /* To be removed in future */ | ||
| 1546 | hcd->uses_new_polling = 1; | ||
| 1547 | |||
| 1564 | isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE); | 1548 | isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE); |
| 1565 | isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE); | 1549 | isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE); |
| 1566 | 1550 | ||
| @@ -1569,7 +1553,7 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1569 | if (board->sel15Kres) | 1553 | if (board->sel15Kres) |
| 1570 | val |= HCHWCFG_15KRSEL; | 1554 | val |= HCHWCFG_15KRSEL; |
| 1571 | /* Remote wakeup won't work without working clock */ | 1555 | /* Remote wakeup won't work without working clock */ |
| 1572 | if (board->clknotstop || board->remote_wakeup_enable) | 1556 | if (board->remote_wakeup_enable) |
| 1573 | val |= HCHWCFG_CLKNOTSTOP; | 1557 | val |= HCHWCFG_CLKNOTSTOP; |
| 1574 | if (board->oc_enable) | 1558 | if (board->oc_enable) |
| 1575 | val |= HCHWCFG_ANALOG_OC; | 1559 | val |= HCHWCFG_ANALOG_OC; |
| @@ -1580,16 +1564,13 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1580 | isp116x_write_reg16(isp116x, HCHWCFG, val); | 1564 | isp116x_write_reg16(isp116x, HCHWCFG, val); |
| 1581 | 1565 | ||
| 1582 | /* ----- Root hub conf */ | 1566 | /* ----- Root hub conf */ |
| 1583 | val = 0; | 1567 | val = (25 << 24) & RH_A_POTPGT; |
| 1584 | /* AN10003_1.pdf recommends NPS to be always 1 */ | 1568 | /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to |
| 1585 | if (board->no_power_switching) | 1569 | be always set. Yet, instead, we request individual port |
| 1586 | val |= RH_A_NPS; | 1570 | power switching. */ |
| 1587 | if (board->power_switching_mode) | 1571 | val |= RH_A_PSM; |
| 1588 | val |= RH_A_PSM; | 1572 | /* Report overcurrent per port */ |
| 1589 | if (board->potpg) | 1573 | val |= RH_A_OCPM; |
| 1590 | val |= (board->potpg << 24) & RH_A_POTPGT; | ||
| 1591 | else | ||
| 1592 | val |= (25 << 24) & RH_A_POTPGT; | ||
| 1593 | isp116x_write_reg32(isp116x, HCRHDESCA, val); | 1574 | isp116x_write_reg32(isp116x, HCRHDESCA, val); |
| 1594 | isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA); | 1575 | isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA); |
| 1595 | 1576 | ||
| @@ -1619,9 +1600,6 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1619 | 1600 | ||
| 1620 | /* Go operational */ | 1601 | /* Go operational */ |
| 1621 | val = HCCONTROL_USB_OPER; | 1602 | val = HCCONTROL_USB_OPER; |
| 1622 | /* Remote wakeup connected - NOT SUPPORTED */ | ||
| 1623 | /* if (board->remote_wakeup_connected) | ||
| 1624 | val |= HCCONTROL_RWC; */ | ||
| 1625 | if (board->remote_wakeup_enable) | 1603 | if (board->remote_wakeup_enable) |
| 1626 | val |= HCCONTROL_RWE; | 1604 | val |= HCCONTROL_RWE; |
| 1627 | isp116x_write_reg32(isp116x, HCCONTROL, val); | 1605 | isp116x_write_reg32(isp116x, HCCONTROL, val); |
| @@ -1670,7 +1648,7 @@ static int __init_or_module isp116x_remove(struct device *dev) | |||
| 1670 | struct platform_device *pdev; | 1648 | struct platform_device *pdev; |
| 1671 | struct resource *res; | 1649 | struct resource *res; |
| 1672 | 1650 | ||
| 1673 | if(!hcd) | 1651 | if (!hcd) |
| 1674 | return 0; | 1652 | return 0; |
| 1675 | isp116x = hcd_to_isp116x(hcd); | 1653 | isp116x = hcd_to_isp116x(hcd); |
| 1676 | pdev = container_of(dev, struct platform_device, dev); | 1654 | pdev = container_of(dev, struct platform_device, dev); |
