diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-08 17:21:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-08 17:21:02 -0700 |
commit | 54205209732a05f51f5fbb3eb3e5c36ac81e79d9 (patch) | |
tree | 4992850c7d5d5ed4034cbd4fe5f5ea23aeff317e /drivers/usb/host | |
parent | 6d8de3a26b5c20b04a9317b4446582167d5883da (diff) | |
parent | b71e318cdb1dc301d734fdd4983dfc6dc167235a (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-q.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 88 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ppc-soc.c | 24 | ||||
-rw-r--r-- | drivers/usb/host/ohci-s3c2410.c | 4 |
6 files changed, 53 insertions, 76 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 20df01a79b2..940d38ca7d9 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -677,6 +677,9 @@ qh_make ( goto done; } } else { + struct usb_tt *tt = urb->dev->tt; + int think_time; + /* gap is f(FS/LS transfer times) */ qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed, is_input, 0, maxp) / (125 * 1000); @@ -690,6 +693,10 @@ qh_make ( qh->c_usecs = HS_USECS (0); } + think_time = tt ? tt->think_time : 0; + qh->tt_usecs = NS_TO_US (think_time + + usb_calc_bus_time (urb->dev->speed, + is_input, 0, max_packet (maxp))); qh->period = urb->interval; } } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 4c972b57c7c..ccc7300baa6 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -700,6 +700,7 @@ iso_stream_init ( } else { u32 addr; + int think_time; addr = dev->ttport << 24; if (!ehci_is_TDI(ehci) @@ -709,6 +710,9 @@ iso_stream_init ( addr |= epnum << 8; addr |= dev->devnum; stream->usecs = HS_USECS_ISO (maxp); + think_time = dev->tt ? dev->tt->think_time : 0; + stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time ( + dev->speed, is_input, 1, maxp)); if (is_input) { u32 tmp; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index a7542157534..20c9b550097 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -421,6 +421,7 @@ struct ehci_qh { u8 usecs; /* intr bandwidth */ u8 gap_uf; /* uframes split/csplit gap */ u8 c_usecs; /* ... split completion bw */ + u16 tt_usecs; /* tt downstream bandwidth */ unsigned short period; /* polling interval */ unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ @@ -479,6 +480,7 @@ struct ehci_iso_stream { */ u8 interval; u8 usecs, c_usecs; + u16 tt_usecs; u16 maxp; u16 raw_mask; unsigned bandwidth; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 75128c37180..41bbae83fc7 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -83,7 +83,7 @@ #include "../core/hcd.h" #include "isp116x.h" -#define DRIVER_VERSION "08 Apr 2005" +#define DRIVER_VERSION "05 Aug 2005" #define DRIVER_DESC "ISP116x USB Host Controller Driver" MODULE_DESCRIPTION(DRIVER_DESC); @@ -629,14 +629,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) ERR("Unrecoverable error\n"); /* What should we do here? Reset? */ } - if (intstat & HCINT_RHSC) { - isp116x->rhstatus = - isp116x_read_reg32(isp116x, HCRHSTATUS); - isp116x->rhport[0] = - isp116x_read_reg32(isp116x, HCRHPORT1); - isp116x->rhport[1] = - isp116x_read_reg32(isp116x, HCRHPORT2); - } + if (intstat & HCINT_RHSC) + /* When root hub or any of its ports is going + to come out of suspend, it may take more + than 10ms for status bits to stabilize. */ + mod_timer(&hcd->rh_timer, jiffies + + msecs_to_jiffies(20) + 1); if (intstat & HCINT_RD) { DBG("---- remote wakeup\n"); schedule_work(&isp116x->rh_resume); @@ -925,20 +923,27 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) { struct isp116x *isp116x = hcd_to_isp116x(hcd); int ports, i, changed = 0; + unsigned long flags; if (!HC_IS_RUNNING(hcd->state)) return -ESHUTDOWN; - ports = isp116x->rhdesca & RH_A_NDP; + /* Report no status change now, if we are scheduled to be + called later */ + if (timer_pending(&hcd->rh_timer)) + return 0; - /* init status */ + ports = isp116x->rhdesca & RH_A_NDP; + spin_lock_irqsave(&isp116x->lock, flags); + isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS); if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) buf[0] = changed = 1; else buf[0] = 0; for (i = 0; i < ports; i++) { - u32 status = isp116x->rhport[i]; + u32 status = isp116x->rhport[i] = + isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { @@ -947,6 +952,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) continue; } } + spin_unlock_irqrestore(&isp116x->lock, flags); return changed; } @@ -1463,10 +1469,6 @@ static int isp116x_sw_reset(struct isp116x *isp116x) return ret; } -/* - Reset. Tries to perform platform-specific hardware - reset first; falls back to software reset. -*/ static int isp116x_reset(struct usb_hcd *hcd) { struct isp116x *isp116x = hcd_to_isp116x(hcd); @@ -1474,17 +1476,7 @@ static int isp116x_reset(struct usb_hcd *hcd) u16 clkrdy = 0; int ret = 0, timeout = 15 /* ms */ ; - if (isp116x->board && isp116x->board->reset) { - /* Hardware reset */ - isp116x->board->reset(hcd->self.controller, 1); - msleep(10); - if (isp116x->board->clock) - isp116x->board->clock(hcd->self.controller, 1); - msleep(1); - isp116x->board->reset(hcd->self.controller, 0); - } else - ret = isp116x_sw_reset(isp116x); - + ret = isp116x_sw_reset(isp116x); if (ret) return ret; @@ -1501,10 +1493,7 @@ static int isp116x_reset(struct usb_hcd *hcd) ERR("Clock not ready after 20ms\n"); /* After sw_reset the clock won't report to be ready, if H_WAKEUP pin is high. */ - if (!isp116x->board || !isp116x->board->reset) - ERR("The driver does not support hardware wakeup.\n"); - ERR("Please make sure that the H_WAKEUP pin " - "is pulled low!\n"); + ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); ret = -ENODEV; } return ret; @@ -1527,15 +1516,7 @@ static void isp116x_stop(struct usb_hcd *hcd) isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS); spin_unlock_irqrestore(&isp116x->lock, flags); - /* Put the chip into reset state */ - if (isp116x->board && isp116x->board->reset) - isp116x->board->reset(hcd->self.controller, 0); - else - isp116x_sw_reset(isp116x); - - /* Stop the clock */ - if (isp116x->board && isp116x->board->clock) - isp116x->board->clock(hcd->self.controller, 0); + isp116x_sw_reset(isp116x); } /* @@ -1561,6 +1542,9 @@ static int isp116x_start(struct usb_hcd *hcd) return -ENODEV; } + /* To be removed in future */ + hcd->uses_new_polling = 1; + isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE); isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE); @@ -1569,7 +1553,7 @@ static int isp116x_start(struct usb_hcd *hcd) if (board->sel15Kres) val |= HCHWCFG_15KRSEL; /* Remote wakeup won't work without working clock */ - if (board->clknotstop || board->remote_wakeup_enable) + if (board->remote_wakeup_enable) val |= HCHWCFG_CLKNOTSTOP; if (board->oc_enable) val |= HCHWCFG_ANALOG_OC; @@ -1580,16 +1564,13 @@ static int isp116x_start(struct usb_hcd *hcd) isp116x_write_reg16(isp116x, HCHWCFG, val); /* ----- Root hub conf */ - val = 0; - /* AN10003_1.pdf recommends NPS to be always 1 */ - if (board->no_power_switching) - val |= RH_A_NPS; - if (board->power_switching_mode) - val |= RH_A_PSM; - if (board->potpg) - val |= (board->potpg << 24) & RH_A_POTPGT; - else - val |= (25 << 24) & RH_A_POTPGT; + val = (25 << 24) & RH_A_POTPGT; + /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to + be always set. Yet, instead, we request individual port + power switching. */ + val |= RH_A_PSM; + /* Report overcurrent per port */ + val |= RH_A_OCPM; isp116x_write_reg32(isp116x, HCRHDESCA, val); isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA); @@ -1619,9 +1600,6 @@ static int isp116x_start(struct usb_hcd *hcd) /* Go operational */ val = HCCONTROL_USB_OPER; - /* Remote wakeup connected - NOT SUPPORTED */ - /* if (board->remote_wakeup_connected) - val |= HCCONTROL_RWC; */ if (board->remote_wakeup_enable) val |= HCCONTROL_RWE; isp116x_write_reg32(isp116x, HCCONTROL, val); @@ -1670,7 +1648,7 @@ static int __init_or_module isp116x_remove(struct device *dev) struct platform_device *pdev; struct resource *res; - if(!hcd) + if (!hcd) return 0; isp116x = hcd_to_isp116x(hcd); pdev = container_of(dev, struct platform_device, dev); diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 17964c39d06..25153336302 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -14,8 +14,6 @@ * This file is licenced under the GPL. */ -#include <asm/usb.h> - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -23,9 +21,7 @@ * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs * Context: !in_interrupt() * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. + * Allocates basic resources for this USB host controller. * * Store this function in the HCD's struct pci_driver as probe(). */ @@ -37,7 +33,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, struct ohci_hcd *ohci; struct resource *res; int irq; - struct usb_hcd_platform_data *pd = pdev->dev.platform_data; pr_debug("initializing PPC-SOC USB Controller\n"); @@ -73,9 +68,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, goto err2; } - if (pd->start && (retval = pd->start(pdev))) - goto err3; - ohci = hcd_to_ohci(hcd); ohci->flags |= OHCI_BIG_ENDIAN; ohci_hcd_init(ohci); @@ -85,9 +77,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, return retval; pr_debug("Removing PPC-SOC USB Controller\n"); - if (pd && pd->stop) - pd->stop(pdev); - err3: + iounmap(hcd->regs); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); @@ -105,25 +95,21 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, * @pdev: USB Host Controller being removed * Context: !in_interrupt() * - * Reverses the effect of usb_hcd_ppc_soc_probe(), first invoking - * the HCD's stop() method. It is always called from a thread + * Reverses the effect of usb_hcd_ppc_soc_probe(). + * It is always called from a thread * context, normally "rmmod", "apmd", or something similar. * */ static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *pdev) { - struct usb_hcd_platform_data *pd = pdev->dev.platform_data; - usb_remove_hcd(hcd); pr_debug("stopping PPC-SOC USB Controller\n"); - if (pd && pd->stop) - pd->stop(pdev); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_hcd_put(hcd); + usb_put_hcd(hcd); } static int __devinit diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index e9401662503..3d9bcf78a9a 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -129,7 +129,7 @@ static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info, if (info->power_control != NULL) { info->port[port-1].power = to; - (info->power_control)(port, to); + (info->power_control)(port-1, to); } } @@ -339,8 +339,8 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver, struct usb_hcd *hcd = NULL; int retval; - s3c2410_usb_set_power(dev->dev.platform_data, 0, 1); s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); + s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) |