Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: ftdi_sio - really enable EM1010PC
  USB: remove incorrect struct class_device from the printer gadget
  USB: pxa2xx_udc: fix misuse of clock enable/disable calls
  USB: ftdi_sio: Workaround for broken Matrix Orbital serial port
  USB: Add support for AXESSTEL MV110H CDMA modem
  usb-storage: update earlier scatter-gather bug fix
  USB: isp116x: fix enumeration on boot
  USB: ehci: handle large bulk URBs correctly (again)
  USB: spruce up the device blacklist
  USB: fix comment of struct usb_interface
  USB: update Kconfig entry for USB_SUSPEND
  usb: Add support for the mos7820/7840-based B&B USB/RS485 converter to mos7840.c
  • Loading branch information
Linus Torvalds committed Mar 5, 2008
2 parents b2a5cd6 + 4ae897d commit 10955d2
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 68 deletions.
9 changes: 5 additions & 4 deletions drivers/usb/core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,13 @@ config USB_DYNAMIC_MINORS
If you are unsure about this, say N here.

config USB_SUSPEND
bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
depends on USB && PM && EXPERIMENTAL
bool "USB selective suspend/resume and wakeup"
depends on USB && PM
help
If you say Y here, you can use driver calls or the sysfs
"power/state" file to suspend or resume individual USB
peripherals.
"power/level" file to suspend or resume individual USB
peripherals and to enable or disable autosuspend (see
Documentation/usb/power-management.txt for more details).

Also, USB "remote wakeup" signaling is supported, whereby some
USB devices (like keyboards and network adapters) can wake up
Expand Down
21 changes: 12 additions & 9 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,38 @@
* devices is broken...
*/
static const struct usb_device_id usb_quirk_list[] = {
/* Action Semiconductor flash disk */
{ USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255},

/* CBM - Flash disk */
{ USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },

/* HP 5300/5370C scanner */
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
{ USB_DEVICE(0x03f0, 0x0701), .driver_info =
USB_QUIRK_STRING_FETCH_255 },

/* Creative SB Audigy 2 NX */
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },

/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },

/* Roland SC-8820 */
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },

/* Edirol SD-20 */
{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },

/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },

/* M-Systems Flash Disk Pioneers */
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },

/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
/* Action Semiconductor flash disk */
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
USB_QUIRK_STRING_FETCH_255 },

/* SKYMEDI USB_DRIVE */
{ USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },

/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },

{ } /* terminating entry must be last */
};

Expand Down
1 change: 0 additions & 1 deletion drivers/usb/gadget/printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ struct printer_dev {
u8 *current_rx_buf;
u8 printer_status;
u8 reset_printer;
struct class_device *printer_class_dev;
struct cdev printer_cdev;
struct device *pdev;
u8 printer_cdev_open;
Expand Down
88 changes: 50 additions & 38 deletions drivers/usb/gadget/pxa2xx_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ static const char ep0name [] = "ep0";
#error "Can't configure both IXP and PXA"
#endif

/* IXP doesn't yet support <linux/clk.h> */
#define clk_get(dev,name) NULL
#define clk_enable(clk) do { } while (0)
#define clk_disable(clk) do { } while (0)
#define clk_put(clk) do { } while (0)

#endif

#include "pxa2xx_udc.h"
Expand Down Expand Up @@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *);
/* We disable the UDC -- and its 48 MHz clock -- whenever it's not
* in active use.
*/
static int pullup(struct pxa2xx_udc *udc, int is_active)
static int pullup(struct pxa2xx_udc *udc)
{
is_active = is_active && udc->vbus && udc->pullup;
int is_active = udc->vbus && udc->pullup && !udc->suspended;
DMSG("%s\n", is_active ? "active" : "inactive");
if (is_active)
udc_enable(udc);
else {
if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
DMSG("disconnect %s\n", udc->driver
? udc->driver->driver.name
: "(no driver)");
stop_activity(udc, udc->driver);
if (is_active) {
if (!udc->active) {
udc->active = 1;
/* Enable clock for USB device */
clk_enable(udc->clk);
udc_enable(udc);
}
udc_disable(udc);
} else {
if (udc->active) {
if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
DMSG("disconnect %s\n", udc->driver
? udc->driver->driver.name
: "(no driver)");
stop_activity(udc, udc->driver);
}
udc_disable(udc);
/* Disable clock for USB device */
clk_disable(udc->clk);
udc->active = 0;
}

}
return 0;
}
Expand All @@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
struct pxa2xx_udc *udc;

udc = container_of(_gadget, struct pxa2xx_udc, gadget);
udc->vbus = is_active = (is_active != 0);
udc->vbus = (is_active != 0);
DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
pullup(udc, is_active);
pullup(udc);
return 0;
}

Expand All @@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
return -EOPNOTSUPP;

is_active = (is_active != 0);
udc->pullup = is_active;
pullup(udc, is_active);
udc->pullup = (is_active != 0);
pullup(udc);
return 0;
}

Expand All @@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
#ifdef CONFIG_USB_GADGET_DEBUG_FS

static int
udc_seq_show(struct seq_file *m, void *d)
udc_seq_show(struct seq_file *m, void *_d)
{
struct pxa2xx_udc *dev = m->private;
unsigned long flags;
Expand Down Expand Up @@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev)

udc_clear_mask_UDCCR(UDCCR_UDE);

#ifdef CONFIG_ARCH_PXA
/* Disable clock for USB device */
clk_disable(dev->clk);
#endif

ep0_idle (dev);
dev->gadget.speed = USB_SPEED_UNKNOWN;
}
Expand Down Expand Up @@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev)
{
udc_clear_mask_UDCCR(UDCCR_UDE);

#ifdef CONFIG_ARCH_PXA
/* Enable clock for USB device */
clk_enable(dev->clk);
#endif

/* try to clear these bits before we enable the udc */
udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);

Expand Down Expand Up @@ -1286,7 +1292,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
* for set_configuration as well as eventual disconnect.
*/
DMSG("registered gadget driver '%s'\n", driver->driver.name);
pullup(dev, 1);
pullup(dev);
dump_state(dev);
return 0;
}
Expand Down Expand Up @@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
return -EINVAL;

local_irq_disable();
pullup(dev, 0);
dev->pullup = 0;
pullup(dev);
stop_activity(dev, driver);
local_irq_enable();

Expand Down Expand Up @@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (irq < 0)
return -ENODEV;

#ifdef CONFIG_ARCH_PXA
dev->clk = clk_get(&pdev->dev, "UDCCLK");
if (IS_ERR(dev->clk)) {
retval = PTR_ERR(dev->clk);
goto err_clk;
}
#endif

pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
dev->has_cfr ? "" : " (!cfr)",
Expand Down Expand Up @@ -2250,10 +2255,8 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
err_gpio_vbus:
#ifdef CONFIG_ARCH_PXA
clk_put(dev->clk);
err_clk:
#endif
return retval;
}

Expand All @@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
if (dev->driver)
return -EBUSY;

udc_disable(dev);
dev->pullup = 0;
pullup(dev);

remove_debug_files(dev);

if (dev->got_irq) {
Expand All @@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);

#ifdef CONFIG_ARCH_PXA
clk_put(dev->clk);
#endif

platform_set_drvdata(pdev, NULL);
the_controller = NULL;
Expand All @@ -2317,19 +2320,28 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
unsigned long flags;

if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
WARN("USB host won't detect disconnect!\n");
pullup(udc, 0);
udc->suspended = 1;

local_irq_save(flags);
pullup(udc);
local_irq_restore(flags);

return 0;
}

static int pxa2xx_udc_resume(struct platform_device *dev)
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
unsigned long flags;

pullup(udc, 1);
udc->suspended = 0;
local_irq_save(flags);
pullup(udc);
local_irq_restore(flags);

return 0;
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/gadget/pxa2xx_udc.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ struct pxa2xx_udc {
has_cfr : 1,
req_pending : 1,
req_std : 1,
req_config : 1;
req_config : 1,
suspended : 1,
active : 1;

#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
struct timer_list timer;
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
if (likely (last->urb != urb)) {
ehci_urb_done(ehci, last->urb, last_status);
count++;
last_status = -EINPROGRESS;
}
ehci_qtd_free (ehci, last);
last = NULL;
last_status = -EINPROGRESS;
}

/* ignore urbs submitted during completions we reported */
Expand Down
15 changes: 6 additions & 9 deletions drivers/usb/host/isp116x-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,8 +911,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
buf[0] = 0;

for (i = 0; i < ports; i++) {
u32 status = isp116x->rhport[i] =
isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);

if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC)) {
Expand Down Expand Up @@ -1031,7 +1030,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
DBG("GetPortStatus\n");
if (!wIndex || wIndex > ports)
goto error;
tmp = isp116x->rhport[--wIndex];
spin_lock_irqsave(&isp116x->lock, flags);
tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
*(__le32 *) buf = cpu_to_le32(tmp);
DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp);
break;
Expand Down Expand Up @@ -1080,8 +1081,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, tmp);
isp116x->rhport[wIndex] =
isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case SetPortFeature:
Expand All @@ -1095,24 +1094,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case USB_PORT_FEAT_POWER:
DBG("USB_PORT_FEAT_POWER\n");
spin_lock_irqsave(&isp116x->lock, flags);
isp116x_write_reg32(isp116x, wIndex
? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case USB_PORT_FEAT_RESET:
DBG("USB_PORT_FEAT_RESET\n");
root_port_reset(isp116x, wIndex);
spin_lock_irqsave(&isp116x->lock, flags);
break;
default:
goto error;
}
isp116x->rhport[wIndex] =
isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;

default:
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/host/isp116x.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ struct isp116x {
u32 rhdesca;
u32 rhdescb;
u32 rhstatus;
u32 rhport[2];

/* async schedule: control, bulk */
struct list_head async;
Expand Down
Loading

0 comments on commit 10955d2

Please sign in to comment.