aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp116x-hcd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-08 20:21:02 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-08 20:21:02 -0400
commit54205209732a05f51f5fbb3eb3e5c36ac81e79d9 (patch)
tree4992850c7d5d5ed4034cbd4fe5f5ea23aeff317e /drivers/usb/host/isp116x-hcd.c
parent6d8de3a26b5c20b04a9317b4446582167d5883da (diff)
parentb71e318cdb1dc301d734fdd4983dfc6dc167235a (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
Diffstat (limited to 'drivers/usb/host/isp116x-hcd.c')
-rw-r--r--drivers/usb/host/isp116x-hcd.c88
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
89MODULE_DESCRIPTION(DRIVER_DESC); 89MODULE_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*/
1470static int isp116x_reset(struct usb_hcd *hcd) 1472static 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);