Merge 3.4-rc4 into usb-next.
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2012 22:25:26 +0000 (15:25 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Apr 2012 22:25:26 +0000 (15:25 -0700)
This resolves the conflict in:
drivers/usb/host/ehci-fsl.c
And picks up loads of xhci bugfixes to make it easier for others to test
with.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
62 files changed:
Documentation/devicetree/bindings/usb/spear-usb.txt [new file with mode: 0644]
drivers/bcma/scan.c
drivers/staging/asus_oled/asus_oled.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/vmk80xx.c
drivers/staging/frontier/alphatrack.c
drivers/staging/frontier/tranzport.c
drivers/staging/line6/driver.c
drivers/staging/line6/toneport.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/gadget/f_hid.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/fsl_usb2_udc.h
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/bcma-hcd.c [new file with mode: 0644]
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-platform.c
drivers/usb/host/ehci-s5p.c
drivers/usb/host/ehci-sead3.c [new file with mode: 0644]
drivers/usb/host/ehci-sh.c
drivers/usb/host/ehci-spear.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/fhci-tds.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-platform.c
drivers/usb/host/ohci-ppc-of.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/ohci-ssb.c [deleted file]
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/ssb-hcd.c [new file with mode: 0644]
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/misc/idmouse.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/ldusb.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/rio500.c
drivers/usb/misc/usblcd.c
drivers/usb/misc/uss720.c
drivers/usb/misc/yurex.c
drivers/usb/serial/console.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/metro-usb.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb_wwan.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/ene_ub6250.c
include/linux/bcma/bcma.h
include/linux/fsl_devices.h
include/linux/platform_data/ehci-sh.h [new file with mode: 0644]
include/linux/usb.h

diff --git a/Documentation/devicetree/bindings/usb/spear-usb.txt b/Documentation/devicetree/bindings/usb/spear-usb.txt
new file mode 100644 (file)
index 0000000..f8a464a
--- /dev/null
@@ -0,0 +1,39 @@
+ST SPEAr SoC USB controllers:
+-----------------------------
+
+EHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ehci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the EHCI interrupt
+
+Example:
+
+       ehci@e1800000 {
+               compatible = "st,spear600-ehci", "usb-ehci";
+               reg = <0xe1800000 0x1000>;
+               interrupt-parent = <&vic1>;
+               interrupts = <27>;
+       };
+
+
+OHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ohci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the OHCI interrupt
+
+Example:
+
+       ohci@e1900000 {
+               compatible = "st,spear600-ohci", "usb-ohci";
+               reg = <0xe1800000 0x1000>;
+               interrupt-parent = <&vic1>;
+               interrupts = <26>;
+       };
index f94cccc..3bea7fe 100644 (file)
@@ -297,6 +297,23 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
                        return -EILSEQ;
        }
 
+       /* First Slave Address Descriptor should be port 0:
+        * the main register space for the core
+        */
+       tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
+       if (tmp <= 0) {
+               /* Try again to see if it is a bridge */
+               tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                                             SCAN_ADDR_TYPE_BRIDGE, 0);
+               if (tmp <= 0) {
+                       return -EILSEQ;
+               } else {
+                       pr_info("Bridge found\n");
+                       return -ENXIO;
+               }
+       }
+       core->addr = tmp;
+
        /* get & parse slave ports */
        for (i = 0; i < ports[1]; i++) {
                for (j = 0; ; j++) {
@@ -309,7 +326,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
                                break;
                        } else {
                                if (i == 0 && j == 0)
-                                       core->addr = tmp;
+                                       core->addr1 = tmp;
                        }
                }
        }
index 83549d9..510d796 100644 (file)
@@ -782,20 +782,20 @@ static int __init asus_oled_init(void)
        oled_class = class_create(THIS_MODULE, ASUS_OLED_UNDERSCORE_NAME);
 
        if (IS_ERR(oled_class)) {
-               err("Error creating " ASUS_OLED_UNDERSCORE_NAME " class");
+               printk(KERN_ERR "Error creating " ASUS_OLED_UNDERSCORE_NAME " class\n");
                return PTR_ERR(oled_class);
        }
 
        retval = class_create_file(oled_class, &class_attr_version.attr);
        if (retval) {
-               err("Error creating class version file");
+               printk(KERN_ERR "Error creating class version file\n");
                goto error;
        }
 
        retval = usb_register(&oled_driver);
 
        if (retval) {
-               err("usb_register failed. Error number %d", retval);
+               printk(KERN_ERR "usb_register failed. Error number %d\n", retval);
                goto error;
        }
 
index e86ab58..89a49dd 100644 (file)
@@ -547,7 +547,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
                rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
                break;
        default:
-               err("Illegal gain %d\n", gain);
+               dev_err(&dev->interface->dev, "Illegal gain %d\n", gain);
 
        }
 }
@@ -715,7 +715,7 @@ static int dt9812_probe(struct usb_interface *interface,
        iface_desc = interface->cur_altsetting;
 
        if (iface_desc->desc.bNumEndpoints != 5) {
-               err("Wrong number of endpints.");
+               dev_err(&interface->dev, "Wrong number of endpoints.\n");
                retval = -ENODEV;
                goto error;
        }
@@ -781,22 +781,22 @@ static int dt9812_probe(struct usb_interface *interface,
        }
 
        if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) {
-               err("Failed to read vendor.");
+               dev_err(&interface->dev, "Failed to read vendor.\n");
                retval = -ENODEV;
                goto error;
        }
        if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
-               err("Failed to read product.");
+               dev_err(&interface->dev, "Failed to read product.\n");
                retval = -ENODEV;
                goto error;
        }
        if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) {
-               err("Failed to read device.");
+               dev_err(&interface->dev, "Failed to read device.\n");
                retval = -ENODEV;
                goto error;
        }
        if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) {
-               err("Failed to read serial.");
+               dev_err(&interface->dev, "Failed to read serial.\n");
                retval = -ENODEV;
                goto error;
        }
@@ -1146,7 +1146,9 @@ static int __init usb_dt9812_init(void)
        result = comedi_driver_register(&dt9812_comedi_driver);
        if (result) {
                usb_deregister(&dt9812_usb_driver);
-               err("comedi_driver_register failed. Error number %d", result);
+               printk(KERN_ERR KBUILD_MODNAME
+                       ": comedi_driver_register failed. Error number %d\n",
+                       result);
        }
 
        return result;
index 3d13ca6..2dba3ef 100644 (file)
@@ -295,7 +295,9 @@ resubmit:
                if (!usb_submit_urb(urb, GFP_KERNEL))
                        goto exit;
 
-               err("comedi#: vmk80xx: %s - submit urb failed\n", __func__);
+               dev_err(&urb->dev->dev,
+                       "comedi#: vmk80xx: %s - submit urb failed\n",
+                       __func__);
 
                usb_unanchor_urb(urb);
        }
index 3bf0f40..acbb2cc 100644 (file)
@@ -333,8 +333,8 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
        interface = usb_find_interface(&usb_alphatrack_driver, subminor);
 
        if (!interface) {
-               err("%s - error, can't find device for minor %d\n",
-                   __func__, subminor);
+               printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+                      __func__, subminor);
                retval = -ENODEV;
                goto unlock_disconnect_exit;
        }
@@ -494,7 +494,8 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
        /* verify that the device wasn't unplugged */
        if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "%s: No device or device unplugged %d\n",
+                      __func__, retval);
                goto unlock_exit;
        }
 
@@ -564,7 +565,8 @@ static ssize_t usb_alphatrack_write(struct file *file,
        /* verify that the device wasn't unplugged */
        if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "%s: No device or device unplugged %d\n",
+                      __func__, retval);
                goto unlock_exit;
        }
 
@@ -599,7 +601,7 @@ static ssize_t usb_alphatrack_write(struct file *file,
        }
 
        if (dev->interrupt_out_endpoint == NULL) {
-               err("Endpoint should not be be null!\n");
+               dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
                goto unlock_exit;
        }
 
@@ -619,7 +621,8 @@ static ssize_t usb_alphatrack_write(struct file *file,
        retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
        if (retval) {
                dev->interrupt_out_busy = 0;
-               err("Couldn't submit interrupt_out_urb %d\n", retval);
+               dev_err(&dev->intf->dev,
+                       "Couldn't submit interrupt_out_urb %d\n", retval);
                atomic_dec(&dev->writes_pending);
                goto unlock_exit;
        }
index 29e99bb..376706f 100644 (file)
@@ -353,7 +353,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
        interface = usb_find_interface(&usb_tranzport_driver, subminor);
 
        if (!interface) {
-               err("%s - error, can't find device for minor %d\n",
+               printk(KERN_ERR "%s - error, can't find device for minor %d\n",
                        __func__, subminor);
                retval = -ENODEV;
                goto unlock_disconnect_exit;
@@ -517,9 +517,11 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
                goto exit;
        }
 
-       /* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
+       /* verify that the device wasn't unplugged */
+       if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "%s: No device or device unplugged %d\n",
+                       __func__, retval);
                goto unlock_exit;
        }
 
@@ -691,7 +693,8 @@ static ssize_t usb_tranzport_write(struct file *file,
        /* verify that the device wasn't unplugged */
        if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "%s: No device or device unplugged %d\n",
+                       __func__, retval);
                goto unlock_exit;
        }
 
@@ -726,7 +729,7 @@ static ssize_t usb_tranzport_write(struct file *file,
        }
 
        if (dev->interrupt_out_endpoint == NULL) {
-               err("Endpoint should not be be null!\n");
+               dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
                goto unlock_exit;
        }
 
@@ -746,7 +749,8 @@ static ssize_t usb_tranzport_write(struct file *file,
        retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
        if (retval) {
                dev->interrupt_out_busy = 0;
-               err("Couldn't submit interrupt_out_urb %d\n", retval);
+               dev_err(&dev->intf->dev,
+                       "Couldn't submit interrupt_out_urb %d\n", retval);
                goto unlock_exit;
        }
        retval = bytes_to_write;
index e8023af..2e602e1 100644 (file)
@@ -1307,7 +1307,8 @@ static int __init line6_init(void)
        retval = usb_register(&line6_driver);
 
        if (retval) {
-               err("usb_register failed. Error number %d", retval);
+               printk(KERN_ERR KBUILD_MODNAME
+                      ": usb_register failed. Error number %d\n", retval);
                return retval;
        }
 
@@ -1315,7 +1316,7 @@ static int __init line6_init(void)
                                        GFP_KERNEL);
 
        if (line6_request_version == NULL) {
-               err("Out of memory");
+               printk(KERN_ERR KBUILD_MODNAME ":Out of memory\n");
                return -ENOMEM;
        }
 
index b754f69..31b624b 100644 (file)
@@ -168,7 +168,7 @@ static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
                              cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
 
        if (ret < 0) {
-               err("send failed (error %d)\n", ret);
+               dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
                return ret;
        }
 
index 01ea5d7..d7e422d 100644 (file)
@@ -1357,10 +1357,8 @@ static int uea_stat_e1(struct uea_softc *sc)
                /* release the dsp firmware as it is not needed until
                 * the next failure
                 */
-               if (sc->dsp_firm) {
-                       release_firmware(sc->dsp_firm);
-                       sc->dsp_firm = NULL;
-               }
+               release_firmware(sc->dsp_firm);
+               sc->dsp_firm = NULL;
        }
 
        /* always update it as atm layer could not be init when we switch to
@@ -1496,10 +1494,8 @@ static int uea_stat_e4(struct uea_softc *sc)
                /* release the dsp firmware as it is not needed until
                 * the next failure
                 */
-               if (sc->dsp_firm) {
-                       release_firmware(sc->dsp_firm);
-                       sc->dsp_firm = NULL;
-               }
+               release_firmware(sc->dsp_firm);
+               sc->dsp_firm = NULL;
        }
 
        /* always update it as atm layer could not be init when we switch to
@@ -2240,8 +2236,7 @@ static void uea_stop(struct uea_softc *sc)
        /* flush the work item, when no one can schedule it */
        flush_work_sync(&sc->task);
 
-       if (sc->dsp_firm)
-               release_firmware(sc->dsp_firm);
+       release_firmware(sc->dsp_firm);
        uea_leaves(INS_TO_USBDEV(sc));
 }
 
index b211342..3b3932c 100644 (file)
@@ -374,7 +374,7 @@ static int hidg_setup(struct usb_function *f,
                        break;
 
                default:
-                       VDBG(cdev, "Unknown decriptor request 0x%x\n",
+                       VDBG(cdev, "Unknown descriptor request 0x%x\n",
                                 value >> 8);
                        goto stall;
                        break;
index 55abfb6..0d9b2fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc.
  * All rights reserved.
  *
  * Author: Li Yang <leoli@freescale.com>
@@ -58,9 +58,8 @@ static const char driver_name[] = "fsl-usb2-udc";
 static const char driver_desc[] = DRIVER_DESC;
 
 static struct usb_dr_device *dr_regs;
-#ifndef CONFIG_ARCH_MXC
+
 static struct usb_sys_interface *usb_sys_regs;
-#endif
 
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
@@ -244,10 +243,9 @@ static int dr_controller_setup(struct fsl_udc *udc)
 {
        unsigned int tmp, portctrl, ep_num;
        unsigned int max_no_of_ep;
-#ifndef CONFIG_ARCH_MXC
        unsigned int ctrl;
-#endif
        unsigned long timeout;
+
 #define FSL_UDC_RESET_TIMEOUT 1000
 
        /* Config PHY interface */
@@ -255,12 +253,32 @@ static int dr_controller_setup(struct fsl_udc *udc)
        portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
        switch (udc->phy_mode) {
        case FSL_USB2_PHY_ULPI:
+               if (udc->pdata->have_sysif_regs) {
+                       if (udc->pdata->controller_ver) {
+                               /* controller version 1.6 or above */
+                               ctrl = __raw_readl(&usb_sys_regs->control);
+                               ctrl &= ~USB_CTRL_UTMI_PHY_EN;
+                               ctrl |= USB_CTRL_USB_EN;
+                               __raw_writel(ctrl, &usb_sys_regs->control);
+                       }
+               }
                portctrl |= PORTSCX_PTS_ULPI;
                break;
        case FSL_USB2_PHY_UTMI_WIDE:
                portctrl |= PORTSCX_PTW_16BIT;
                /* fall through */
        case FSL_USB2_PHY_UTMI:
+               if (udc->pdata->have_sysif_regs) {
+                       if (udc->pdata->controller_ver) {
+                               /* controller version 1.6 or above */
+                               ctrl = __raw_readl(&usb_sys_regs->control);
+                               ctrl |= (USB_CTRL_UTMI_PHY_EN |
+                                       USB_CTRL_USB_EN);
+                               __raw_writel(ctrl, &usb_sys_regs->control);
+                               mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI
+                                       PHY CLK to become stable - 10ms*/
+                       }
+               }
                portctrl |= PORTSCX_PTS_UTMI;
                break;
        case FSL_USB2_PHY_SERIAL:
index e651469..1212646 100644 (file)
@@ -1,4 +1,12 @@
 /*
+ * Copyright (C) 2004,2012 Freescale Semiconductor, Inc
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
  * Freescale USB device/endpoint management registers
  */
 #ifndef __FSL_USB2_UDC_H
@@ -348,6 +356,9 @@ struct usb_sys_interface {
 /* control Register Bit Masks */
 #define  USB_CTRL_IOENB                       0x00000004
 #define  USB_CTRL_ULPI_INT0EN                 0x00000001
+#define USB_CTRL_UTMI_PHY_EN                 0x00000200
+#define USB_CTRL_USB_EN                              0x00000004
+#define USB_CTRL_ULPI_PHY_CLK_SEL            0x00000400
 
 /* Endpoint Queue Head data struct
  * Rem: all the variables of qh are LittleEndian Mode
index f788eb8..896fc91 100644 (file)
@@ -110,13 +110,14 @@ config USB_EHCI_BIG_ENDIAN_MMIO
        depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
                                    ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
                                    PPC_MPC512x || CPU_CAVIUM_OCTEON || \
-                                   PMC_MSP || SPARC_LEON)
+                                   PMC_MSP || SPARC_LEON || MIPS_SEAD3)
        default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
        bool
        depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
-                                   PPC_MPC512x || PMC_MSP || SPARC_LEON)
+                                   PPC_MPC512x || PMC_MSP || SPARC_LEON || \
+                                   MIPS_SEAD3)
        default y
 
 config XPS_USB_HCD_XILINX
@@ -373,10 +374,15 @@ config USB_OHCI_HCD_PCI
          If unsure, say Y.
 
 config USB_OHCI_HCD_SSB
-       bool "OHCI support for Broadcom SSB OHCI core"
+       bool "OHCI support for Broadcom SSB OHCI core (DEPRECATED)"
        depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
+       select USB_HCD_SSB
+       select USB_OHCI_HCD_PLATFORM
        default n
        ---help---
+         This option is deprecated now and the driver was removed, use
+         USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead.
+
          Support for the Sonics Silicon Backplane (SSB) attached
          Broadcom USB OHCI core.
 
@@ -638,3 +644,27 @@ config USB_OCTEON_OHCI
 config USB_OCTEON2_COMMON
        bool
        default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
+
+config USB_HCD_BCMA
+       tristate "BCMA usb host driver"
+       depends on BCMA && EXPERIMENTAL
+       select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+       select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
+       help
+         Enbale support for the EHCI and OCHI host controller on an bcma bus.
+         It converts the bcma driver into two platform device drivers
+         for ehci and ohci.
+
+         If unsure, say N.
+
+config USB_HCD_SSB
+       tristate "SSB usb host driver"
+       depends on SSB && EXPERIMENTAL
+       select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+       select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
+       help
+         Enbale support for the EHCI and OCHI host controller on an bcma bus.
+         It converts the bcma driver into two platform device drivers
+         for ehci and ohci.
+
+         If unsure, say N.
index 0982bcc..9e0a89c 100644 (file)
@@ -41,3 +41,5 @@ obj-$(CONFIG_USB_IMX21_HCD)   += imx21-hcd.o
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)        += fsl-mph-dr-of.o
 obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
 obj-$(CONFIG_MIPS_ALCHEMY)     += alchemy-common.o
+obj-$(CONFIG_USB_HCD_BCMA)     += bcma-hcd.o
+obj-$(CONFIG_USB_HCD_SSB)      += ssb-hcd.o
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
new file mode 100644 (file)
index 0000000..0b35d42
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Broadcom specific Advanced Microcontroller Bus
+ * Broadcom USB-core driver (BCMA bus glue)
+ *
+ * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Based on ssb-ohci driver
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ *
+ * Derived from the OHCI-PCI driver
+ * Copyright 1999 Roman Weissgaerber
+ * Copyright 2000-2002 David Brownell
+ * Copyright 1999 Linus Torvalds
+ * Copyright 1999 Gregory P. Smith
+ *
+ * Derived from the USBcore related parts of Broadcom-SB
+ * Copyright 2005-2011 Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/bcma/bcma.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
+MODULE_LICENSE("GPL");
+
+struct bcma_hcd_device {
+       struct platform_device *ehci_dev;
+       struct platform_device *ohci_dev;
+};
+
+/* Wait for bitmask in a register to get set or cleared.
+ * timeout is in units of ten-microseconds.
+ */
+static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
+                         int timeout)
+{
+       int i;
+       u32 val;
+
+       for (i = 0; i < timeout; i++) {
+               val = bcma_read32(dev, reg);
+               if ((val & bitmask) == bitmask)
+                       return 0;
+               udelay(10);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
+{
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+       /* Work around for 4716 failures. */
+       if (dev->bus->chipinfo.id == 0x4716) {
+               u32 tmp;
+
+               tmp = bcma_cpu_clock(&dev->bus->drv_mips);
+               if (tmp >= 480000000)
+                       tmp = 0x1846b; /* set CDR to 0x11(fast) */
+               else if (tmp == 453000000)
+                       tmp = 0x1046b; /* set CDR to 0x10(slow) */
+               else
+                       tmp = 0;
+
+               /* Change Shim mdio control reg to fix host not acking at
+                * high frequencies
+                */
+               if (tmp) {
+                       bcma_write32(dev, 0x524, 0x1); /* write sel to enable */
+                       udelay(500);
+
+                       bcma_write32(dev, 0x524, tmp);
+                       udelay(500);
+                       bcma_write32(dev, 0x524, 0x4ab);
+                       udelay(500);
+                       bcma_read32(dev, 0x528);
+                       bcma_write32(dev, 0x528, 0x80000000);
+               }
+       }
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
+}
+
+/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
+static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
+{
+       u32 tmp;
+
+       /*
+        * USB 2.0 special considerations:
+        *
+        * 1. Since the core supports both OHCI and EHCI functions, it must
+        *    only be reset once.
+        *
+        * 2. In addition to the standard SI reset sequence, the Host Control
+        *    Register must be programmed to bring the USB core and various
+        *    phy components out of reset.
+        */
+       if (!bcma_core_is_enabled(dev)) {
+               bcma_core_enable(dev, 0);
+               mdelay(10);
+               if (dev->id.rev >= 5) {
+                       /* Enable Misc PLL */
+                       tmp = bcma_read32(dev, 0x1e0);
+                       tmp |= 0x100;
+                       bcma_write32(dev, 0x1e0, tmp);
+                       if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100))
+                               printk(KERN_EMERG "Failed to enable misc PPL!\n");
+
+                       /* Take out of resets */
+                       bcma_write32(dev, 0x200, 0x4ff);
+                       udelay(25);
+                       bcma_write32(dev, 0x200, 0x6ff);
+                       udelay(25);
+
+                       /* Make sure digital and AFE are locked in USB PHY */
+                       bcma_write32(dev, 0x524, 0x6b);
+                       udelay(50);
+                       tmp = bcma_read32(dev, 0x524);
+                       udelay(50);
+                       bcma_write32(dev, 0x524, 0xab);
+                       udelay(50);
+                       tmp = bcma_read32(dev, 0x524);
+                       udelay(50);
+                       bcma_write32(dev, 0x524, 0x2b);
+                       udelay(50);
+                       tmp = bcma_read32(dev, 0x524);
+                       udelay(50);
+                       bcma_write32(dev, 0x524, 0x10ab);
+                       udelay(50);
+                       tmp = bcma_read32(dev, 0x524);
+
+                       if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) {
+                               tmp = bcma_read32(dev, 0x528);
+                               printk(KERN_EMERG
+                                      "USB20H mdio_rddata 0x%08x\n", tmp);
+                       }
+                       bcma_write32(dev, 0x528, 0x80000000);
+                       tmp = bcma_read32(dev, 0x314);
+                       udelay(265);
+                       bcma_write32(dev, 0x200, 0x7ff);
+                       udelay(10);
+
+                       /* Take USB and HSIC out of non-driving modes */
+                       bcma_write32(dev, 0x510, 0);
+               } else {
+                       bcma_write32(dev, 0x200, 0x7ff);
+
+                       udelay(1);
+               }
+
+               bcma_hcd_4716wa(dev);
+       }
+}
+
+static const struct usb_ehci_pdata ehci_pdata = {
+};
+
+static const struct usb_ohci_pdata ohci_pdata = {
+};
+
+static struct platform_device * __devinit
+bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
+{
+       struct platform_device *hci_dev;
+       struct resource hci_res[2];
+       int ret = -ENOMEM;
+
+       memset(hci_res, 0, sizeof(hci_res));
+
+       hci_res[0].start = addr;
+       hci_res[0].end = hci_res[0].start + 0x1000 - 1;
+       hci_res[0].flags = IORESOURCE_MEM;
+
+       hci_res[1].start = dev->irq;
+       hci_res[1].flags = IORESOURCE_IRQ;
+
+       hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+                                       "ehci-platform" , 0);
+       if (!hci_dev)
+               return NULL;
+
+       hci_dev->dev.parent = &dev->dev;
+       hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
+
+       ret = platform_device_add_resources(hci_dev, hci_res,
+                                           ARRAY_SIZE(hci_res));
+       if (ret)
+               goto err_alloc;
+       if (ohci)
+               ret = platform_device_add_data(hci_dev, &ohci_pdata,
+                                              sizeof(ohci_pdata));
+       else
+               ret = platform_device_add_data(hci_dev, &ehci_pdata,
+                                              sizeof(ehci_pdata));
+       if (ret)
+               goto err_alloc;
+       ret = platform_device_add(hci_dev);
+       if (ret)
+               goto err_alloc;
+
+       return hci_dev;
+
+err_alloc:
+       platform_device_put(hci_dev);
+       return ERR_PTR(ret);
+}
+
+static int __devinit bcma_hcd_probe(struct bcma_device *dev)
+{
+       int err;
+       u16 chipid_top;
+       u32 ohci_addr;
+       struct bcma_hcd_device *usb_dev;
+       struct bcma_chipinfo *chipinfo;
+
+       chipinfo = &dev->bus->chipinfo;
+       /* USBcores are only connected on embedded devices. */
+       chipid_top = (chipinfo->id & 0xFF00);
+       if (chipid_top != 0x4700 && chipid_top != 0x5300)
+               return -ENODEV;
+
+       /* TODO: Probably need checks here; is the core connected? */
+
+       if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
+           dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
+               return -EOPNOTSUPP;
+
+       usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
+       if (!usb_dev)
+               return -ENOMEM;
+
+       bcma_hcd_init_chip(dev);
+
+       /* In AI chips EHCI is addrspace 0, OHCI is 1 */
+       ohci_addr = dev->addr1;
+       if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
+           && chipinfo->rev == 0)
+               ohci_addr = 0x18009000;
+
+       usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
+       if (IS_ERR(usb_dev->ohci_dev)) {
+               err = PTR_ERR(usb_dev->ohci_dev);
+               goto err_free_usb_dev;
+       }
+
+       usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
+       if (IS_ERR(usb_dev->ehci_dev)) {
+               err = PTR_ERR(usb_dev->ehci_dev);
+               goto err_unregister_ohci_dev;
+       }
+
+       bcma_set_drvdata(dev, usb_dev);
+       return 0;
+
+err_unregister_ohci_dev:
+       platform_device_unregister(usb_dev->ohci_dev);
+err_free_usb_dev:
+       kfree(usb_dev);
+       return err;
+}
+
+static void __devexit bcma_hcd_remove(struct bcma_device *dev)
+{
+       struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+       struct platform_device *ohci_dev = usb_dev->ohci_dev;
+       struct platform_device *ehci_dev = usb_dev->ehci_dev;
+
+       if (ohci_dev)
+               platform_device_unregister(ohci_dev);
+       if (ehci_dev)
+               platform_device_unregister(ehci_dev);
+
+       bcma_core_disable(dev, 0);
+}
+
+static void bcma_hcd_shutdown(struct bcma_device *dev)
+{
+       bcma_core_disable(dev, 0);
+}
+
+#ifdef CONFIG_PM
+
+static int bcma_hcd_suspend(struct bcma_device *dev)
+{
+       bcma_core_disable(dev, 0);
+
+       return 0;
+}
+
+static int bcma_hcd_resume(struct bcma_device *dev)
+{
+       bcma_core_enable(dev, 0);
+
+       return 0;
+}
+
+#else /* !CONFIG_PM */
+#define bcma_hcd_suspend       NULL
+#define bcma_hcd_resume        NULL
+#endif /* CONFIG_PM */
+
+static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
+       BCMA_CORETABLE_END
+};
+MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
+
+static struct bcma_driver bcma_hcd_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = bcma_hcd_table,
+       .probe          = bcma_hcd_probe,
+       .remove         = __devexit_p(bcma_hcd_remove),
+       .shutdown       = bcma_hcd_shutdown,
+       .suspend        = bcma_hcd_suspend,
+       .resume         = bcma_hcd_resume,
+};
+
+static int __init bcma_hcd_init(void)
+{
+       return bcma_driver_register(&bcma_hcd_driver);
+}
+module_init(bcma_hcd_init);
+
+static void __exit bcma_hcd_exit(void)
+{
+       bcma_driver_unregister(&bcma_hcd_driver);
+}
+module_exit(bcma_hcd_exit);
index d0a84bd..34acfce 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2005-2009 MontaVista Software, Inc.
- * Copyright 2008      Freescale Semiconductor, Inc.
+ * Copyright 2008,2012      Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -211,22 +211,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
        usb_put_hcd(hcd);
 }
 
-static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
+static void ehci_fsl_setup_phy(struct usb_hcd *hcd,
                               enum fsl_usb2_phy_modes phy_mode,
                               unsigned int port_offset)
 {
-       u32 portsc;
-       struct usb_hcd *hcd = ehci_to_hcd(ehci);
+       u32 portsc, temp;
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        void __iomem *non_ehci = hcd->regs;
-       struct fsl_usb2_platform_data *pdata;
+       struct device *dev = hcd->self.controller;
+       struct fsl_usb2_platform_data *pdata = dev->platform_data;
 
-       pdata = hcd->self.controller->platform_data;
+       if (pdata->controller_ver < 0) {
+               dev_warn(hcd->self.controller, "Could not get controller version\n");
+               return;
+       }
 
        portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
        portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
 
        switch (phy_mode) {
        case FSL_USB2_PHY_ULPI:
+               if (pdata->controller_ver) {
+                       /* controller version 1.6 or above */
+                       temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+                       out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+                               USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL);
+               }
                portsc |= PORT_PTS_ULPI;
                break;
        case FSL_USB2_PHY_SERIAL:
@@ -236,6 +246,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
                portsc |= PORT_PTS_PTW;
                /* fall through */
        case FSL_USB2_PHY_UTMI:
+               if (pdata->controller_ver) {
+                       /* controller version 1.6 or above */
+                       temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+                       out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+                               UTMI_PHY_EN | USB_CTRL_USB_EN);
+                       mdelay(FSL_UTMI_PHY_DLY);  /* Delay for UTMI PHY CLK to
+                                               become stable - 10ms*/
+               }
                /* enable UTMI PHY */
                if (pdata->have_sysif_regs)
                        setbits32(non_ehci + FSL_SOC_USB_CTRL,
@@ -276,7 +294,7 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 
        if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
                        (pdata->operating_mode == FSL_USB2_DR_OTG))
-               ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+               ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
 
        if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
                unsigned int chip, rev, svr;
@@ -290,9 +308,9 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
                        ehci->has_fsl_port_bug = 1;
 
                if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-                       ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+                       ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
                if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
-                       ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
+                       ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1);
        }
 
        if (pdata->have_sysif_regs) {
index 863fb0c..8840368 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
+/* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2005 MontaVista Software
  *
  * This program is free software; you can redistribute  it and/or modify it
 #define CTRL_UTMI_PHY_EN       (1<<9)
 #define CTRL_PHY_CLK_VALID     (1 << 17)
 #define SNOOP_SIZE_2GB         0x1e
+
+/* control Register Bit Masks */
+#define ULPI_INT_EN             (1<<0)
+#define WU_INT_EN               (1<<1)
+#define USB_CTRL_USB_EN         (1<<2)
+#define LINE_STATE_FILTER__EN   (1<<3)
+#define KEEP_OTG_ON             (1<<4)
+#define OTG_PORT                (1<<5)
+#define PLL_RESET               (1<<8)
+#define UTMI_PHY_EN             (1<<9)
+#define ULPI_PHY_CLK_SEL        (1<<10)
 #endif                         /* _EHCI_FSL_H */
index 4a3bc5b..a87c057 100644 (file)
@@ -417,9 +417,6 @@ static void ehci_iaa_watchdog(unsigned long param)
                 * CMD_IAAD when it sets STS_IAA.)
                 */
                cmd = ehci_readl(ehci, &ehci->regs->command);
-               if (cmd & CMD_IAAD)
-                       ehci_writel(ehci, cmd & ~CMD_IAAD,
-                                       &ehci->regs->command);
 
                /* If IAA is set here it either legitimately triggered
                 * before we cleared IAAD above (but _way_ late, so we'll
@@ -894,11 +891,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        /* complete the unlinking of some qh [4.15.2.3] */
        if (status & STS_IAA) {
                /* guard against (alleged) silicon errata */
-               if (cmd & CMD_IAAD) {
-                       ehci_writel(ehci, cmd & ~CMD_IAAD,
-                                       &ehci->regs->command);
+               if (cmd & CMD_IAAD)
                        ehci_dbg(ehci, "IAA with IAAD still set?\n");
-               }
                if (ehci->reclaim) {
                        COUNT(ehci->stats.reclaim);
                        end_unlink_async(ehci);
@@ -1378,6 +1372,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER                ehci_ls1x_driver
 #endif
 
+#ifdef CONFIG_MIPS_SEAD3
+#include "ehci-sead3.c"
+#define        PLATFORM_DRIVER         ehci_hcd_sead3_driver
+#endif
+
 #ifdef CONFIG_USB_EHCI_HCD_PLATFORM
 #include "ehci-platform.c"
 #define PLATFORM_DRIVER                ehci_platform_driver
index 38fe076..402e766 100644 (file)
@@ -531,7 +531,8 @@ static int check_reset_complete (
                if (ehci->has_amcc_usb23)
                        set_ohci_hcfs(ehci, 1);
        } else {
-               ehci_dbg (ehci, "port %d high speed\n", index + 1);
+               ehci_dbg(ehci, "port %d reset complete, port enabled\n",
+                       index + 1);
                /* ensure 440EPx ohci controller state is suspended */
                if (ehci->has_amcc_usb23)
                        set_ohci_hcfs(ehci, 0);
@@ -699,6 +700,7 @@ static int ehci_hub_control (
                        goto error;
                wIndex--;
                temp = ehci_readl(ehci, status_reg);
+               temp &= ~PORT_RWC_BITS;
 
                /*
                 * Even if OWNER is set, so the port is owned by the
@@ -712,8 +714,7 @@ static int ehci_hub_control (
                        ehci_writel(ehci, temp & ~PORT_PE, status_reg);
                        break;
                case USB_PORT_FEAT_C_ENABLE:
-                       ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
-                                       status_reg);
+                       ehci_writel(ehci, temp | PORT_PEC, status_reg);
                        break;
                case USB_PORT_FEAT_SUSPEND:
                        if (temp & PORT_RESET)
@@ -742,7 +743,7 @@ static int ehci_hub_control (
                                spin_lock_irqsave(&ehci->lock, flags);
                        }
                        /* resume signaling for 20 msec */
-                       temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+                       temp &= ~PORT_WAKE_BITS;
                        ehci_writel(ehci, temp | PORT_RESUME, status_reg);
                        ehci->reset_done[wIndex] = jiffies
                                        + msecs_to_jiffies(20);
@@ -752,9 +753,8 @@ static int ehci_hub_control (
                        break;
                case USB_PORT_FEAT_POWER:
                        if (HCS_PPC (ehci->hcs_params))
-                               ehci_writel(ehci,
-                                         temp & ~(PORT_RWC_BITS | PORT_POWER),
-                                         status_reg);
+                               ehci_writel(ehci, temp & ~PORT_POWER,
+                                               status_reg);
                        break;
                case USB_PORT_FEAT_C_CONNECTION:
                        if (ehci->has_lpm) {
@@ -762,12 +762,10 @@ static int ehci_hub_control (
                                temp &= ~PORT_LPM;
                                temp &= ~PORT_DEV_ADDR;
                        }
-                       ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
-                                       status_reg);
+                       ehci_writel(ehci, temp | PORT_CSC, status_reg);
                        break;
                case USB_PORT_FEAT_C_OVER_CURRENT:
-                       ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
-                                       status_reg);
+                       ehci_writel(ehci, temp | PORT_OCC, status_reg);
                        break;
                case USB_PORT_FEAT_C_RESET:
                        /* GetPortStatus clears reset */
index d238b4e..23c530a 100644 (file)
@@ -94,12 +94,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
 
        irq = platform_get_irq(dev, 0);
        if (irq < 0) {
-               pr_err("no irq provieded");
+               pr_err("no irq provided");
                return irq;
        }
        res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res_mem) {
-               pr_err("no memory recourse provieded");
+               pr_err("no memory recourse provided");
                return -ENXIO;
        }
 
index f098e2a..c474cec 100644 (file)
@@ -232,6 +232,8 @@ static int s5p_ehci_suspend(struct device *dev)
        if (pdata && pdata->phy_exit)
                pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
 
+       clk_disable(s5p_ehci->clk);
+
        return rc;
 }
 
@@ -243,6 +245,8 @@ static int s5p_ehci_resume(struct device *dev)
        struct platform_device *pdev = to_platform_device(dev);
        struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 
+       clk_enable(s5p_ehci->clk);
+
        if (pdata && pdata->phy_init)
                pdata->phy_init(pdev, S5P_USB_PHY_HOST);
 
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c
new file mode 100644 (file)
index 0000000..4c16430
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * MIPS CI13320A EHCI Host Controller driver
+ * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+
+static int ehci_sead3_setup(struct usb_hcd *hcd)
+{
+       int ret;
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+       ehci->caps = hcd->regs + 0x100;
+
+       ret = ehci_setup(hcd);
+       if (ret)
+               return ret;
+
+       ehci->need_io_watchdog = 0;
+
+#ifdef __BIG_ENDIAN
+       ehci->big_endian_mmio = 1;
+       ehci->big_endian_desc = 1;
+#endif
+
+       /* Set burst length to 16 words. */
+       ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]);
+
+       return ret;
+}
+
+const struct hc_driver ehci_sead3_hc_driver = {
+       .description            = hcd_name,
+       .product_desc           = "SEAD-3 EHCI",
+       .hcd_priv_size          = sizeof(struct ehci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq                    = ehci_irq,
+       .flags                  = HCD_MEMORY | HCD_USB2,
+
+       /*
+        * basic lifecycle operations
+        *
+        */
+       .reset                  = ehci_sead3_setup,
+       .start                  = ehci_run,
+       .stop                   = ehci_stop,
+       .shutdown               = ehci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue            = ehci_urb_enqueue,
+       .urb_dequeue            = ehci_urb_dequeue,
+       .endpoint_disable       = ehci_endpoint_disable,
+       .endpoint_reset         = ehci_endpoint_reset,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number       = ehci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data        = ehci_hub_status_data,
+       .hub_control            = ehci_hub_control,
+       .bus_suspend            = ehci_bus_suspend,
+       .bus_resume             = ehci_bus_resume,
+       .relinquish_port        = ehci_relinquish_port,
+       .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd;
+       struct resource *res;
+       int ret;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+               pr_debug("resource[1] is not IORESOURCE_IRQ");
+               return -ENOMEM;
+       }
+       hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3");
+       if (!hcd)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       hcd->rsrc_start = res->start;
+       hcd->rsrc_len = resource_size(res);
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+               pr_debug("request_mem_region failed");
+               ret = -EBUSY;
+               goto err1;
+       }
+
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               pr_debug("ioremap failed");
+               ret = -ENOMEM;
+               goto err2;
+       }
+
+       /* Root hub has integrated TT. */
+       hcd->has_tt = 1;
+
+       ret = usb_add_hcd(hcd, pdev->resource[1].start,
+                         IRQF_SHARED);
+       if (ret == 0) {
+               platform_set_drvdata(pdev, hcd);
+               return ret;
+       }
+
+       iounmap(hcd->regs);
+err2:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+       usb_put_hcd(hcd);
+       return ret;
+}
+
+static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+       usb_remove_hcd(hcd);
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int ehci_hcd_sead3_drv_suspend(struct device *dev)
+{
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+       unsigned long flags;
+       int rc = 0;
+
+       if (time_before(jiffies, ehci->next_statechange))
+               msleep(20);
+
+       /* Root hub was already suspended. Disable irq emission and
+        * mark HW unaccessible.  The PM and USB cores make sure that
+        * the root hub is either suspended or stopped.
+        */
+       ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
+       spin_lock_irqsave(&ehci->lock, flags);
+       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+       (void)ehci_readl(ehci, &ehci->regs->intr_enable);
+
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       spin_unlock_irqrestore(&ehci->lock, flags);
+
+       /* could save FLADJ in case of Vaux power loss
+        * ... we'd only use it to handle clock skew
+        */
+
+       return rc;
+}
+
+static int ehci_hcd_sead3_drv_resume(struct device *dev)
+{
+       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+       /* maybe restore FLADJ. */
+
+       if (time_before(jiffies, ehci->next_statechange))
+               msleep(100);
+
+       /* Mark hardware accessible again as we are out of D3 state by now */
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+       /* If CF is still set, we maintained PCI Vaux power.
+        * Just undo the effect of ehci_pci_suspend().
+        */
+       if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
+               int     mask = INTR_MASK;
+
+               ehci_prepare_ports_for_controller_resume(ehci);
+               if (!hcd->self.root_hub->do_remote_wakeup)
+                       mask &= ~STS_PCD;
+               ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+               ehci_readl(ehci, &ehci->regs->intr_enable);
+               return 0;
+       }
+
+       ehci_dbg(ehci, "lost power, restarting\n");
+       usb_root_hub_lost_power(hcd->self.root_hub);
+
+       /* Else reset, to cope with power loss or flush-to-storage
+        * style "resume" having let BIOS kick in during reboot.
+        */
+       (void) ehci_halt(ehci);
+       (void) ehci_reset(ehci);
+
+       /* emptying the schedule aborts any urbs */
+       spin_lock_irq(&ehci->lock);
+       if (ehci->reclaim)
+               end_unlink_async(ehci);
+       ehci_work(ehci);
+       spin_unlock_irq(&ehci->lock);
+
+       ehci_writel(ehci, ehci->command, &ehci->regs->command);
+       ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+       ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+
+       /* here we "know" root ports should always stay powered */
+       ehci_port_power(ehci, 1);
+
+       ehci->rh_state = EHCI_RH_SUSPENDED;
+
+       return 0;
+}
+
+static const struct dev_pm_ops sead3_ehci_pmops = {
+       .suspend        = ehci_hcd_sead3_drv_suspend,
+       .resume         = ehci_hcd_sead3_drv_resume,
+};
+
+#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops)
+
+#else
+#define SEAD3_EHCI_PMOPS NULL
+#endif
+
+static struct platform_driver ehci_hcd_sead3_driver = {
+       .probe          = ehci_hcd_sead3_drv_probe,
+       .remove         = ehci_hcd_sead3_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
+       .driver = {
+               .name   = "sead3-ehci",
+               .owner  = THIS_MODULE,
+               .pm     = SEAD3_EHCI_PMOPS,
+       }
+};
+
+MODULE_ALIAS("platform:sead3-ehci");
index 9d9cf47..ca819cd 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/platform_data/ehci-sh.h>
 
 struct ehci_sh_priv {
        struct clk *iclk, *fclk;
@@ -100,6 +101,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
        const struct hc_driver *driver = &ehci_sh_hc_driver;
        struct resource *res;
        struct ehci_sh_priv *priv;
+       struct ehci_sh_platdata *pdata;
        struct usb_hcd *hcd;
        int irq, ret;
 
@@ -124,6 +126,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
                goto fail_create_hcd;
        }
 
+       if (pdev->dev.platform_data != NULL)
+               pdata = pdev->dev.platform_data;
+
        /* initialize hcd */
        hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
                             dev_name(&pdev->dev));
@@ -168,6 +173,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
        clk_enable(priv->fclk);
        clk_enable(priv->iclk);
 
+       if (pdata && pdata->phy_init)
+               pdata->phy_init();
+
        ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
        if (ret != 0) {
                dev_err(&pdev->dev, "Failed to add hcd");
index 6e92855..37ba8c8 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/jiffies.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 
@@ -25,12 +26,12 @@ struct spear_ehci {
 
 static void spear_start_ehci(struct spear_ehci *ehci)
 {
-       clk_enable(ehci->clk);
+       clk_prepare_enable(ehci->clk);
 }
 
 static void spear_stop_ehci(struct spear_ehci *ehci)
 {
-       clk_disable(ehci->clk);
+       clk_disable_unprepare(ehci->clk);
 }
 
 static int ehci_spear_setup(struct usb_hcd *hcd)
@@ -168,6 +169,8 @@ static int ehci_spear_drv_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
                ehci_spear_drv_resume);
 
+static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd ;
@@ -175,12 +178,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
        struct resource *res;
        struct clk *usbh_clk;
        const struct hc_driver *driver = &ehci_spear_hc_driver;
-       int *pdata = pdev->dev.platform_data;
        int irq, retval;
        char clk_name[20] = "usbh_clk";
-
-       if (pdata == NULL)
-               return -EFAULT;
+       static int instance = -1;
 
        if (usb_disabled())
                return -ENODEV;
@@ -191,8 +191,22 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
                goto fail_irq_get;
        }
 
-       if (*pdata >= 0)
-               sprintf(clk_name, "usbh.%01d_clk", *pdata);
+       /*
+        * Right now device-tree probed devices don't get dma_mask set.
+        * Since shared usb code relies on it, set it here for now.
+        * Once we have dma capability bindings this can go away.
+        */
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &spear_ehci_dma_mask;
+
+       /*
+        * Increment the device instance, when probing via device-tree
+        */
+       if (pdev->id < 0)
+               instance++;
+       else
+               instance = pdev->id;
+       sprintf(clk_name, "usbh.%01d_clk", instance);
 
        usbh_clk = clk_get(NULL, clk_name);
        if (IS_ERR(usbh_clk)) {
@@ -277,6 +291,11 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
        return 0;
 }
 
+static struct of_device_id spear_ehci_id_table[] __devinitdata = {
+       { .compatible = "st,spear600-ehci", },
+       { },
+};
+
 static struct platform_driver spear_ehci_hcd_driver = {
        .probe          = spear_ehci_hcd_drv_probe,
        .remove         = spear_ehci_hcd_drv_remove,
@@ -285,6 +304,7 @@ static struct platform_driver spear_ehci_hcd_driver = {
                .name = "spear-ehci",
                .bus = &platform_bus_type,
                .pm = &ehci_spear_pm_ops,
+               .of_match_table = of_match_ptr(spear_ehci_id_table),
        }
 };
 
index 8618336..43bb0a9 100644 (file)
@@ -148,18 +148,7 @@ static int tegra_ehci_hub_control(
 
        spin_lock_irqsave(&ehci->lock, flags);
 
-       /*
-        * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
-        * that are write on clear, by writing back the register read value, so
-        * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
-        */
-       if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
-               temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
-               ehci_writel(ehci, temp & ~PORT_PE, status_reg);
-               goto done;
-       }
-
-       else if (typeReq == GetPortStatus) {
+       if (typeReq == GetPortStatus) {
                temp = ehci_readl(ehci, status_reg);
                if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
                        /* Resume completed, re-enable disconnect detection */
@@ -464,26 +453,23 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
 }
 #endif
 
-struct temp_buffer {
+struct dma_aligned_buffer {
        void *kmalloc_ptr;
        void *old_xfer_buffer;
        u8 data[0];
 };
 
-static void free_temp_buffer(struct urb *urb)
+static void free_dma_aligned_buffer(struct urb *urb)
 {
-       enum dma_data_direction dir;
-       struct temp_buffer *temp;
+       struct dma_aligned_buffer *temp;
 
        if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
                return;
 
-       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-       temp = container_of(urb->transfer_buffer, struct temp_buffer,
-                           data);
+       temp = container_of(urb->transfer_buffer,
+               struct dma_aligned_buffer, data);
 
-       if (dir == DMA_FROM_DEVICE)
+       if (usb_urb_dir_in(urb))
                memcpy(temp->old_xfer_buffer, temp->data,
                       urb->transfer_buffer_length);
        urb->transfer_buffer = temp->old_xfer_buffer;
@@ -492,10 +478,9 @@ static void free_temp_buffer(struct urb *urb)
        urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
 }
 
-static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
 {
-       enum dma_data_direction dir;
-       struct temp_buffer *temp, *kmalloc_ptr;
+       struct dma_aligned_buffer *temp, *kmalloc_ptr;
        size_t kmalloc_size;
 
        if (urb->num_sgs || urb->sg ||
@@ -503,22 +488,19 @@ static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
            !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
                return 0;
 
-       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
        /* Allocate a buffer with enough padding for alignment */
        kmalloc_size = urb->transfer_buffer_length +
-               sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
+               sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;
 
        kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
        if (!kmalloc_ptr)
                return -ENOMEM;
 
-       /* Position our struct temp_buffer such that data is aligned */
+       /* Position our struct dma_aligned_buffer such that data is aligned */
        temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
-
        temp->kmalloc_ptr = kmalloc_ptr;
        temp->old_xfer_buffer = urb->transfer_buffer;
-       if (dir == DMA_TO_DEVICE)
+       if (usb_urb_dir_out(urb))
                memcpy(temp->data, urb->transfer_buffer,
                       urb->transfer_buffer_length);
        urb->transfer_buffer = temp->data;
@@ -533,13 +515,13 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 {
        int ret;
 
-       ret = alloc_temp_buffer(urb, mem_flags);
+       ret = alloc_dma_aligned_buffer(urb, mem_flags);
        if (ret)
                return ret;
 
        ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
        if (ret)
-               free_temp_buffer(urb);
+               free_dma_aligned_buffer(urb);
 
        return ret;
 }
@@ -547,38 +529,39 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
        usb_hcd_unmap_urb_for_dma(hcd, urb);
-       free_temp_buffer(urb);
+       free_dma_aligned_buffer(urb);
 }
 
 static const struct hc_driver tegra_ehci_hc_driver = {
        .description            = hcd_name,
        .product_desc           = "Tegra EHCI Host Controller",
        .hcd_priv_size          = sizeof(struct ehci_hcd),
-
        .flags                  = HCD_USB2 | HCD_MEMORY,
 
-       .reset                  = tegra_ehci_setup,
+       /* standard ehci functions */
        .irq                    = ehci_irq,
-
        .start                  = ehci_run,
        .stop                   = ehci_stop,
-       .shutdown               = tegra_ehci_shutdown,
        .urb_enqueue            = ehci_urb_enqueue,
        .urb_dequeue            = ehci_urb_dequeue,
-       .map_urb_for_dma        = tegra_ehci_map_urb_for_dma,
-       .unmap_urb_for_dma      = tegra_ehci_unmap_urb_for_dma,
        .endpoint_disable       = ehci_endpoint_disable,
        .endpoint_reset         = ehci_endpoint_reset,
        .get_frame_number       = ehci_get_frame,
        .hub_status_data        = ehci_hub_status_data,
-       .hub_control            = tegra_ehci_hub_control,
        .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+       .relinquish_port        = ehci_relinquish_port,
+       .port_handed_over       = ehci_port_handed_over,
+
+       /* modified ehci functions for tegra */
+       .reset                  = tegra_ehci_setup,
+       .shutdown               = tegra_ehci_shutdown,
+       .map_urb_for_dma        = tegra_ehci_map_urb_for_dma,
+       .unmap_urb_for_dma      = tegra_ehci_unmap_urb_for_dma,
+       .hub_control            = tegra_ehci_hub_control,
 #ifdef CONFIG_PM
        .bus_suspend            = tegra_ehci_bus_suspend,
        .bus_resume             = tegra_ehci_bus_resume,
 #endif
-       .relinquish_port        = ehci_relinquish_port,
-       .port_handed_over       = ehci_port_handed_over,
 };
 
 static int setup_vbus_gpio(struct platform_device *pdev)
index 0ea577b..c5ed881 100644 (file)
@@ -155,7 +155,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
        struct endpoint *ep;
        struct usb_td __iomem *td;
        unsigned long ep_offset;
-       char *err_for = "enpoint PRAM";
+       char *err_for = "endpoint PRAM";
        int ep_mem_size;
        u32 i;
 
index ab333ac..22ff6b3 100644 (file)
@@ -119,6 +119,39 @@ error:
 
 static const struct of_device_id fsl_usb2_mph_dr_of_match[];
 
+static int usb_get_ver_info(struct device_node *np)
+{
+       int ver = -1;
+
+       /*
+        * returns 1 for usb controller version 1.6
+        * returns 2 for usb controller version 2.2
+        * returns 0 otherwise
+        */
+       if (of_device_is_compatible(np, "fsl-usb2-dr")) {
+               if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
+                       ver = FSL_USB_VER_1_6;
+               else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
+                       ver = FSL_USB_VER_2_2;
+               else /* for previous controller versions */
+                       ver = FSL_USB_VER_OLD;
+
+               if (ver > -1)
+                       return ver;
+       }
+
+       if (of_device_is_compatible(np, "fsl-usb2-mph")) {
+               if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
+                       ver = FSL_USB_VER_1_6;
+               else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
+                       ver = FSL_USB_VER_2_2;
+               else /* for previous controller versions */
+                       ver = FSL_USB_VER_OLD;
+       }
+
+       return ver;
+}
+
 static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
 {
        struct device_node *np = ofdev->dev.of_node;
@@ -166,6 +199,14 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
 
        prop = of_get_property(np, "phy_type", NULL);
        pdata->phy_mode = determine_usb_phy(prop);
+       pdata->controller_ver = usb_get_ver_info(np);
+
+       if (pdata->have_sysif_regs) {
+               if (pdata->controller_ver < 0) {
+                       dev_warn(&ofdev->dev, "Could not get controller version\n");
+                       return -ENODEV;
+               }
+       }
 
        for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
                if (!dev_data->drivers[i])
index fc72d44..a35bbdd 100644 (file)
@@ -1562,11 +1562,14 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 
        if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
                retval = -ESHUTDOWN;
+               qtd_list_free(&new_qtds);
                goto out;
        }
        retval = usb_hcd_link_urb_to_ep(hcd, urb);
-       if (retval)
+       if (retval) {
+               qtd_list_free(&new_qtds);
                goto out;
+       }
 
        qh = urb->ep->hcpriv;
        if (qh) {
@@ -1584,6 +1587,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                if (!qh) {
                        retval = -ENOMEM;
                        usb_hcd_unlink_urb_from_ep(hcd, urb);
+                       qtd_list_free(&new_qtds);
                        goto out;
                }
                list_add_tail(&qh->qh_list, ep_queue);
@@ -1683,6 +1687,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
        list_for_each_entry(qtd, &qh->qtd_list, qtd_list)
                if (qtd->urb == urb) {
                        dequeue_urb_from_qtd(hcd, qh, qtd);
+                       list_move(&qtd->qtd_list, &qh->qtd_list);
                        break;
                }
 
@@ -2176,7 +2181,7 @@ static const struct hc_driver isp1760_hc_driver = {
 
 int __init init_kmem_once(void)
 {
-       urb_listitem_cachep = kmem_cache_create("isp1760 urb_listitem",
+       urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem",
                        sizeof(struct urb_listitem), 0, SLAB_TEMPORARY |
                        SLAB_MEM_SPREAD, NULL);
 
index 4592dc1..fff114f 100644 (file)
@@ -398,6 +398,9 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
        hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
                               irqflags, -ENOENT,
                               &pdev->dev, dev_name(&pdev->dev), devflags);
+
+       dev_set_drvdata(&pdev->dev, hcd);
+
        if (IS_ERR(hcd)) {
                pr_warning("isp1760: Failed to register the HCD device\n");
                ret = -ENODEV;
@@ -417,11 +420,16 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
 {
        struct resource *mem_res;
        resource_size_t mem_size;
+       struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
+
+       usb_remove_hcd(hcd);
 
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        mem_size = resource_size(mem_res);
        release_mem_region(mem_res->start, mem_size);
 
+       usb_put_hcd(hcd);
+
        return 0;
 }
 
index 235171f..e0adf5c 100644 (file)
@@ -1080,11 +1080,6 @@ MODULE_LICENSE ("GPL");
 #define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_SSB
-#include "ohci-ssb.c"
-#define SSB_OHCI_DRIVER                ssb_ohci_driver
-#endif
-
 #ifdef CONFIG_MFD_SM501
 #include "ohci-sm501.c"
 #define SM501_OHCI_DRIVER      ohci_hcd_sm501_driver
@@ -1128,8 +1123,7 @@ MODULE_LICENSE ("GPL");
        !defined(SA1111_DRIVER) &&      \
        !defined(PS3_SYSTEM_BUS_DRIVER) && \
        !defined(SM501_OHCI_DRIVER) && \
-       !defined(TMIO_OHCI_DRIVER) && \
-       !defined(SSB_OHCI_DRIVER)
+       !defined(TMIO_OHCI_DRIVER)
 #error "missing bus glue for ohci-hcd"
 #endif
 
@@ -1195,12 +1189,6 @@ static int __init ohci_hcd_mod_init(void)
                goto error_pci;
 #endif
 
-#ifdef SSB_OHCI_DRIVER
-       retval = ssb_driver_register(&SSB_OHCI_DRIVER);
-       if (retval)
-               goto error_ssb;
-#endif
-
 #ifdef SM501_OHCI_DRIVER
        retval = platform_driver_register(&SM501_OHCI_DRIVER);
        if (retval < 0)
@@ -1224,10 +1212,6 @@ static int __init ohci_hcd_mod_init(void)
        platform_driver_unregister(&SM501_OHCI_DRIVER);
  error_sm501:
 #endif
-#ifdef SSB_OHCI_DRIVER
-       ssb_driver_unregister(&SSB_OHCI_DRIVER);
- error_ssb:
-#endif
 #ifdef PCI_DRIVER
        pci_unregister_driver(&PCI_DRIVER);
  error_pci:
@@ -1275,9 +1259,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef SM501_OHCI_DRIVER
        platform_driver_unregister(&SM501_OHCI_DRIVER);
 #endif
-#ifdef SSB_OHCI_DRIVER
-       ssb_driver_unregister(&SSB_OHCI_DRIVER);
-#endif
 #ifdef PCI_DRIVER
        pci_unregister_driver(&PCI_DRIVER);
 #endif
index ec5c679..670c705 100644 (file)
@@ -93,13 +93,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
 
        irq = platform_get_irq(dev, 0);
        if (irq < 0) {
-               pr_err("no irq provieded");
+               pr_err("no irq provided");
                return irq;
        }
 
        res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res_mem) {
-               pr_err("no memory recourse provieded");
+               pr_err("no memory recourse provided");
                return -ENXIO;
        }
 
index d24cc89..b2b5767 100644 (file)
@@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
 
 #if    !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
        !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
-#error "No endianess selected for ppc-of-ohci"
+#error "No endianness selected for ppc-of-ohci"
 #endif
 
 
index 95c1648..fc7305e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/signal.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 
 struct spear_ohci {
        struct ohci_hcd ohci;
@@ -24,12 +25,12 @@ struct spear_ohci {
 
 static void spear_start_ohci(struct spear_ohci *ohci)
 {
-       clk_enable(ohci->clk);
+       clk_prepare_enable(ohci->clk);
 }
 
 static void spear_stop_ohci(struct spear_ohci *ohci)
 {
-       clk_disable(ohci->clk);
+       clk_disable_unprepare(ohci->clk);
 }
 
 static int __devinit ohci_spear_start(struct usb_hcd *hcd)
@@ -90,6 +91,8 @@ static const struct hc_driver ohci_spear_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
+static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
        const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -98,11 +101,8 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
        struct spear_ohci *ohci_p;
        struct resource *res;
        int retval, irq;
-       int *pdata = pdev->dev.platform_data;
        char clk_name[20] = "usbh_clk";
-
-       if (pdata == NULL)
-               return -EFAULT;
+       static int instance = -1;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -110,8 +110,22 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
                goto fail_irq_get;
        }
 
-       if (*pdata >= 0)
-               sprintf(clk_name, "usbh.%01d_clk", *pdata);
+       /*
+        * Right now device-tree probed devices don't get dma_mask set.
+        * Since shared usb code relies on it, set it here for now.
+        * Once we have dma capability bindings this can go away.
+        */
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &spear_ohci_dma_mask;
+
+       /*
+        * Increment the device instance, when probing via device-tree
+        */
+       if (pdev->id < 0)
+               instance++;
+       else
+               instance = pdev->id;
+       sprintf(clk_name, "usbh.%01d_clk", instance);
 
        usbh_clk = clk_get(NULL, clk_name);
        if (IS_ERR(usbh_clk)) {
@@ -222,6 +236,11 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 }
 #endif
 
+static struct of_device_id spear_ohci_id_table[] __devinitdata = {
+       { .compatible = "st,spear600-ohci", },
+       { },
+};
+
 /* Driver definition to register with the platform bus */
 static struct platform_driver spear_ohci_hcd_driver = {
        .probe =        spear_ohci_hcd_drv_probe,
@@ -233,6 +252,7 @@ static struct platform_driver spear_ohci_hcd_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "spear-ohci",
+               .of_match_table = of_match_ptr(spear_ohci_id_table),
        },
 };
 
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
deleted file mode 100644 (file)
index 5ba1859..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Sonics Silicon Backplane
- * Broadcom USB-core OHCI driver
- *
- * Copyright 2007 Michael Buesch <m@bues.ch>
- *
- * Derived from the OHCI-PCI driver
- * Copyright 1999 Roman Weissgaerber
- * Copyright 2000-2002 David Brownell
- * Copyright 1999 Linus Torvalds
- * Copyright 1999 Gregory P. Smith
- *
- * Derived from the USBcore related parts of Broadcom-SB
- * Copyright 2005 Broadcom Corporation
- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-#include <linux/ssb/ssb.h>
-
-
-#define SSB_OHCI_TMSLOW_HOSTMODE       (1 << 29)
-
-struct ssb_ohci_device {
-       struct ohci_hcd ohci; /* _must_ be at the beginning. */
-
-       u32 enable_flags;
-};
-
-static inline
-struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd)
-{
-       return (struct ssb_ohci_device *)(hcd->hcd_priv);
-}
-
-
-static int ssb_ohci_reset(struct usb_hcd *hcd)
-{
-       struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-       struct ohci_hcd *ohci = &ohcidev->ohci;
-       int err;
-
-       ohci_hcd_init(ohci);
-       err = ohci_init(ohci);
-
-       return err;
-}
-
-static int ssb_ohci_start(struct usb_hcd *hcd)
-{
-       struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-       struct ohci_hcd *ohci = &ohcidev->ohci;
-       int err;
-
-       err = ohci_run(ohci);
-       if (err < 0) {
-               ohci_err(ohci, "can't start\n");
-               ohci_stop(hcd);
-       }
-
-       return err;
-}
-
-static const struct hc_driver ssb_ohci_hc_driver = {
-       .description            = "ssb-usb-ohci",
-       .product_desc           = "SSB OHCI Controller",
-       .hcd_priv_size          = sizeof(struct ssb_ohci_device),
-
-       .irq                    = ohci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB11,
-
-       .reset                  = ssb_ohci_reset,
-       .start                  = ssb_ohci_start,
-       .stop                   = ohci_stop,
-       .shutdown               = ohci_shutdown,
-
-       .urb_enqueue            = ohci_urb_enqueue,
-       .urb_dequeue            = ohci_urb_dequeue,
-       .endpoint_disable       = ohci_endpoint_disable,
-
-       .get_frame_number       = ohci_get_frame,
-
-       .hub_status_data        = ohci_hub_status_data,
-       .hub_control            = ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend            = ohci_bus_suspend,
-       .bus_resume             = ohci_bus_resume,
-#endif
-
-       .start_port_reset       = ohci_start_port_reset,
-};
-
-static void ssb_ohci_detach(struct ssb_device *dev)
-{
-       struct usb_hcd *hcd = ssb_get_drvdata(dev);
-
-       if (hcd->driver->shutdown)
-               hcd->driver->shutdown(hcd);
-       usb_remove_hcd(hcd);
-       iounmap(hcd->regs);
-       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-       usb_put_hcd(hcd);
-       ssb_device_disable(dev, 0);
-}
-
-static int ssb_ohci_attach(struct ssb_device *dev)
-{
-       struct ssb_ohci_device *ohcidev;
-       struct usb_hcd *hcd;
-       int err = -ENOMEM;
-       u32 tmp, flags = 0;
-
-       if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
-           dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
-               return -EOPNOTSUPP;
-
-       if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) {
-               /* Put the device into host-mode. */
-               flags |= SSB_OHCI_TMSLOW_HOSTMODE;
-               ssb_device_enable(dev, flags);
-       } else if (dev->id.coreid == SSB_DEV_USB20_HOST) {
-               /*
-                * USB 2.0 special considerations:
-                *
-                * In addition to the standard SSB reset sequence, the Host
-                * Control Register must be programmed to bring the USB core
-                * and various phy components out of reset.
-                */
-               ssb_device_enable(dev, 0);
-               ssb_write32(dev, 0x200, 0x7ff);
-
-               /* Change Flush control reg */
-               tmp = ssb_read32(dev, 0x400);
-               tmp &= ~8;
-               ssb_write32(dev, 0x400, tmp);
-               tmp = ssb_read32(dev, 0x400);
-
-               /* Change Shim control reg */
-               tmp = ssb_read32(dev, 0x304);
-               tmp &= ~0x100;
-               ssb_write32(dev, 0x304, tmp);
-               tmp = ssb_read32(dev, 0x304);
-
-               udelay(1);
-
-               /* Work around for 5354 failures */
-               if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
-                       /* Change syn01 reg */
-                       tmp = 0x00fe00fe;
-                       ssb_write32(dev, 0x894, tmp);
-
-                       /* Change syn03 reg */
-                       tmp = ssb_read32(dev, 0x89c);
-                       tmp |= 0x1;
-                       ssb_write32(dev, 0x89c, tmp);
-               }
-       } else
-               ssb_device_enable(dev, 0);
-
-       hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
-                       dev_name(dev->dev));
-       if (!hcd)
-               goto err_dev_disable;
-       ohcidev = hcd_to_ssb_ohci(hcd);
-       ohcidev->enable_flags = flags;
-
-       tmp = ssb_read32(dev, SSB_ADMATCH0);
-       hcd->rsrc_start = ssb_admatch_base(tmp);
-       hcd->rsrc_len = ssb_admatch_size(tmp);
-       hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
-       if (!hcd->regs)
-               goto err_put_hcd;
-       err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
-       if (err)
-               goto err_iounmap;
-
-       ssb_set_drvdata(dev, hcd);
-
-       return err;
-
-err_iounmap:
-       iounmap(hcd->regs);
-err_put_hcd:
-       usb_put_hcd(hcd);
-err_dev_disable:
-       ssb_device_disable(dev, flags);
-       return err;
-}
-
-static int ssb_ohci_probe(struct ssb_device *dev,
-               const struct ssb_device_id *id)
-{
-       int err;
-       u16 chipid_top;
-
-       /* USBcores are only connected on embedded devices. */
-       chipid_top = (dev->bus->chip_id & 0xFF00);
-       if (chipid_top != 0x4700 && chipid_top != 0x5300)
-               return -ENODEV;
-
-       /* TODO: Probably need checks here; is the core connected? */
-
-       if (usb_disabled())
-               return -ENODEV;
-
-       /* We currently always attach SSB_DEV_USB11_HOSTDEV
-        * as HOST OHCI. If we want to attach it as Client device,
-        * we must branch here and call into the (yet to
-        * be written) Client mode driver. Same for remove(). */
-
-       err = ssb_ohci_attach(dev);
-
-       return err;
-}
-
-static void ssb_ohci_remove(struct ssb_device *dev)
-{
-       ssb_ohci_detach(dev);
-}
-
-#ifdef CONFIG_PM
-
-static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state)
-{
-       ssb_device_disable(dev, 0);
-
-       return 0;
-}
-
-static int ssb_ohci_resume(struct ssb_device *dev)
-{
-       struct usb_hcd *hcd = ssb_get_drvdata(dev);
-       struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-
-       ssb_device_enable(dev, ohcidev->enable_flags);
-
-       ohci_finish_controller_resume(hcd);
-       return 0;
-}
-
-#else /* !CONFIG_PM */
-#define ssb_ohci_suspend       NULL
-#define ssb_ohci_resume        NULL
-#endif /* CONFIG_PM */
-
-static const struct ssb_device_id ssb_ohci_table[] = {
-       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
-       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
-       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
-       SSB_DEVTABLE_END
-};
-MODULE_DEVICE_TABLE(ssb, ssb_ohci_table);
-
-static struct ssb_driver ssb_ohci_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = ssb_ohci_table,
-       .probe          = ssb_ohci_probe,
-       .remove         = ssb_ohci_remove,
-       .suspend        = ssb_ohci_suspend,
-       .resume         = ssb_ohci_resume,
-};
index 3b38030..77a5225 100644 (file)
@@ -2991,8 +2991,9 @@ static int oxu_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                                /* shouldn't happen often, but ...
                                 * FIXME kill those tds' urbs
                                 */
-                               err("can't reschedule qh %p, err %d",
-                                       qh, status);
+                               dev_err(hcd->self.controller,
+                                       "can't reschedule qh %p, err %d\n", qh,
+                                       status);
                        }
                        return status;
                }
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
new file mode 100644 (file)
index 0000000..c2e7343
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Sonics Silicon Backplane
+ * Broadcom USB-core driver  (SSB bus glue)
+ *
+ * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Based on ssb-ohci driver
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ *
+ * Derived from the OHCI-PCI driver
+ * Copyright 1999 Roman Weissgaerber
+ * Copyright 2000-2002 David Brownell
+ * Copyright 1999 Linus Torvalds
+ * Copyright 1999 Gregory P. Smith
+ *
+ * Derived from the USBcore related parts of Broadcom-SB
+ * Copyright 2005-2011 Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/ssb/ssb.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for SSB Bus");
+MODULE_LICENSE("GPL");
+
+#define SSB_HCD_TMSLOW_HOSTMODE        (1 << 29)
+
+struct ssb_hcd_device {
+       struct platform_device *ehci_dev;
+       struct platform_device *ohci_dev;
+
+       u32 enable_flags;
+};
+
+static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
+{
+#ifdef CONFIG_SSB_DRIVER_MIPS
+       /* Work around for 5354 failures */
+       if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
+               /* Change syn01 reg */
+               ssb_write32(dev, 0x894, 0x00fe00fe);
+
+               /* Change syn03 reg */
+               ssb_write32(dev, 0x89c, ssb_read32(dev, 0x89c) | 0x1);
+       }
+#endif
+}
+
+static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
+{
+       if (dev->id.coreid == SSB_DEV_USB20_HOST) {
+               /*
+                * USB 2.0 special considerations:
+                *
+                * In addition to the standard SSB reset sequence, the Host
+                * Control Register must be programmed to bring the USB core
+                * and various phy components out of reset.
+                */
+               ssb_write32(dev, 0x200, 0x7ff);
+
+               /* Change Flush control reg */
+               ssb_write32(dev, 0x400, ssb_read32(dev, 0x400) & ~8);
+               ssb_read32(dev, 0x400);
+
+               /* Change Shim control reg */
+               ssb_write32(dev, 0x304, ssb_read32(dev, 0x304) & ~0x100);
+               ssb_read32(dev, 0x304);
+
+               udelay(1);
+
+               ssb_hcd_5354wa(dev);
+       }
+}
+
+/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
+static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
+{
+       u32 flags = 0;
+
+       if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
+               /* Put the device into host-mode. */
+               flags |= SSB_HCD_TMSLOW_HOSTMODE;
+
+       ssb_device_enable(dev, flags);
+
+       ssb_hcd_usb20wa(dev);
+
+       return flags;
+}
+
+static const struct usb_ehci_pdata ehci_pdata = {
+};
+
+static const struct usb_ohci_pdata ohci_pdata = {
+};
+
+static struct platform_device * __devinit
+ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
+{
+       struct platform_device *hci_dev;
+       struct resource hci_res[2];
+       int ret = -ENOMEM;
+
+       memset(hci_res, 0, sizeof(hci_res));
+
+       hci_res[0].start = addr;
+       hci_res[0].end = hci_res[0].start + len - 1;
+       hci_res[0].flags = IORESOURCE_MEM;
+
+       hci_res[1].start = dev->irq;
+       hci_res[1].flags = IORESOURCE_IRQ;
+
+       hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+                                       "ehci-platform" , 0);
+       if (!hci_dev)
+               return NULL;
+
+       hci_dev->dev.parent = dev->dev;
+       hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
+
+       ret = platform_device_add_resources(hci_dev, hci_res,
+                                           ARRAY_SIZE(hci_res));
+       if (ret)
+               goto err_alloc;
+       if (ohci)
+               ret = platform_device_add_data(hci_dev, &ohci_pdata,
+                                              sizeof(ohci_pdata));
+       else
+               ret = platform_device_add_data(hci_dev, &ehci_pdata,
+                                              sizeof(ehci_pdata));
+       if (ret)
+               goto err_alloc;
+       ret = platform_device_add(hci_dev);
+       if (ret)
+               goto err_alloc;
+
+       return hci_dev;
+
+err_alloc:
+       platform_device_put(hci_dev);
+       return ERR_PTR(ret);
+}
+
+static int __devinit ssb_hcd_probe(struct ssb_device *dev,
+                                  const struct ssb_device_id *id)
+{
+       int err, tmp;
+       int start, len;
+       u16 chipid_top;
+       u16 coreid = dev->id.coreid;
+       struct ssb_hcd_device *usb_dev;
+
+       /* USBcores are only connected on embedded devices. */
+       chipid_top = (dev->bus->chip_id & 0xFF00);
+       if (chipid_top != 0x4700 && chipid_top != 0x5300)
+               return -ENODEV;
+
+       /* TODO: Probably need checks here; is the core connected? */
+
+       if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
+           dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
+               return -EOPNOTSUPP;
+
+       usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL);
+       if (!usb_dev)
+               return -ENOMEM;
+
+       /* We currently always attach SSB_DEV_USB11_HOSTDEV
+        * as HOST OHCI. If we want to attach it as Client device,
+        * we must branch here and call into the (yet to
+        * be written) Client mode driver. Same for remove(). */
+       usb_dev->enable_flags = ssb_hcd_init_chip(dev);
+
+       tmp = ssb_read32(dev, SSB_ADMATCH0);
+
+       start = ssb_admatch_base(tmp);
+       len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
+       usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len);
+       if (IS_ERR(usb_dev->ohci_dev)) {
+               err = PTR_ERR(usb_dev->ohci_dev);
+               goto err_free_usb_dev;
+       }
+
+       if (coreid == SSB_DEV_USB20_HOST) {
+               start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
+               usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, false, start, len);
+               if (IS_ERR(usb_dev->ehci_dev)) {
+                       err = PTR_ERR(usb_dev->ehci_dev);
+                       goto err_unregister_ohci_dev;
+               }
+       }
+
+       ssb_set_drvdata(dev, usb_dev);
+       return 0;
+
+err_unregister_ohci_dev:
+       platform_device_unregister(usb_dev->ohci_dev);
+err_free_usb_dev:
+       kfree(usb_dev);
+       return err;
+}
+
+static void __devexit ssb_hcd_remove(struct ssb_device *dev)
+{
+       struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
+       struct platform_device *ohci_dev = usb_dev->ohci_dev;
+       struct platform_device *ehci_dev = usb_dev->ehci_dev;
+
+       if (ohci_dev)
+               platform_device_unregister(ohci_dev);
+       if (ehci_dev)
+               platform_device_unregister(ehci_dev);
+
+       ssb_device_disable(dev, 0);
+}
+
+static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
+{
+       ssb_device_disable(dev, 0);
+}
+
+#ifdef CONFIG_PM
+
+static int ssb_hcd_suspend(struct ssb_device *dev, pm_message_t state)
+{
+       ssb_device_disable(dev, 0);
+
+       return 0;
+}
+
+static int ssb_hcd_resume(struct ssb_device *dev)
+{
+       struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
+
+       ssb_device_enable(dev, usb_dev->enable_flags);
+
+       return 0;
+}
+
+#else /* !CONFIG_PM */
+#define ssb_hcd_suspend        NULL
+#define ssb_hcd_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
+       SSB_DEVTABLE_END
+};
+MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);
+
+static struct ssb_driver ssb_hcd_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = ssb_hcd_table,
+       .probe          = ssb_hcd_probe,
+       .remove         = __devexit_p(ssb_hcd_remove),
+       .shutdown       = ssb_hcd_shutdown,
+       .suspend        = ssb_hcd_suspend,
+       .resume         = ssb_hcd_resume,
+};
+
+static int __init ssb_hcd_init(void)
+{
+       return ssb_driver_register(&ssb_hcd_driver);
+}
+module_init(ssb_hcd_init);
+
+static void __exit ssb_hcd_exit(void)
+{
+       ssb_driver_unregister(&ssb_hcd_driver);
+}
+module_exit(ssb_hcd_exit);
index da97dce..d65984d 100644 (file)
@@ -78,18 +78,14 @@ static int emi26_load_firmware (struct usb_device *dev)
        const struct firmware *bitstream_fw = NULL;
        const struct firmware *firmware_fw = NULL;
        const struct ihex_binrec *rec;
-       int err;
+       int err = -ENOMEM;
        int i;
        __u32 addr;     /* Address to write */
        __u8 *buf;
 
        buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
-       if (!buf) {
-               dev_err(&dev->dev, "%s - error loading firmware: error = %d\n",
-                       __func__, -ENOMEM);
-               err = -ENOMEM;
+       if (!buf)
                goto wraperr;
-       }
 
        err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev);
        if (err)
@@ -111,11 +107,8 @@ static int emi26_load_firmware (struct usb_device *dev)
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi26_set_reset(dev,1);
-       if (err < 0) {
-               dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
-                       __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        rec = (const struct ihex_binrec *)loader_fw->data;
        /* 1. We need to put the loader for the FPGA into the EZ-USB */
@@ -123,19 +116,15 @@ static int emi26_load_firmware (struct usb_device *dev)
                err = emi26_writememory(dev, be32_to_cpu(rec->addr),
                                        rec->data, be16_to_cpu(rec->len),
                                        ANCHOR_LOAD_INTERNAL);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
                rec = ihex_next_binrec(rec);
        }
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
        msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
@@ -153,18 +142,14 @@ static int emi26_load_firmware (struct usb_device *dev)
                        rec = ihex_next_binrec(rec);
                }
                err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
        } while (rec);
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi26_set_reset(dev,1);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
        for (rec = (const struct ihex_binrec *)loader_fw->data;
@@ -172,19 +157,15 @@ static int emi26_load_firmware (struct usb_device *dev)
                err = emi26_writememory(dev, be32_to_cpu(rec->addr),
                                        rec->data, be16_to_cpu(rec->len),
                                        ANCHOR_LOAD_INTERNAL);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
        }
        msleep(250);    /* let device settle */
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
 
@@ -194,19 +175,15 @@ static int emi26_load_firmware (struct usb_device *dev)
                        err = emi26_writememory(dev, be32_to_cpu(rec->addr),
                                                rec->data, be16_to_cpu(rec->len),
                                                ANCHOR_LOAD_EXTERNAL);
-                       if (err < 0) {
-                               err("%s - error loading firmware: error = %d", __func__, err);
+                       if (err < 0)
                                goto wraperr;
-                       }
                }
        }
-       
+
        /* Assert reset (stop the CPU in the EMI) */
        err = emi26_set_reset(dev,1);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        for (rec = (const struct ihex_binrec *)firmware_fw->data;
             rec; rec = ihex_next_binrec(rec)) {
@@ -214,19 +191,15 @@ static int emi26_load_firmware (struct usb_device *dev)
                        err = emi26_writememory(dev, be32_to_cpu(rec->addr),
                                                rec->data, be16_to_cpu(rec->len),
                                                ANCHOR_LOAD_INTERNAL);
-                       if (err < 0) {
-                               err("%s - error loading firmware: error = %d", __func__, err);
+                       if (err < 0)
                                goto wraperr;
-                       }
                }
        }
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
        msleep(250);    /* let device settle */
 
        /* return 1 to fail the driver inialization
@@ -234,6 +207,10 @@ static int emi26_load_firmware (struct usb_device *dev)
        err = 1;
 
 wraperr:
+       if (err < 0)
+               dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
+                       __func__, err);
+
        release_firmware(loader_fw);
        release_firmware(bitstream_fw);
        release_firmware(firmware_fw);
index 4e0f167..ff08015 100644 (file)
@@ -56,7 +56,7 @@ static int emi62_writememory(struct usb_device *dev, int address,
        unsigned char *buffer =  kmemdup(data, length, GFP_KERNEL);
 
        if (!buffer) {
-               err("emi62: kmalloc(%d) failed.", length);
+               dev_err(&dev->dev, "kmalloc(%d) failed.\n", length);
                return -ENOMEM;
        }
        /* Note: usb_control_msg returns negative value on error or length of the
@@ -73,9 +73,8 @@ static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
        dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit);
        
        response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
-       if (response < 0) {
-               err("emi62: set_reset (%d) failed", reset_bit);
-       }
+       if (response < 0)
+               dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit);
        return response;
 }
 
@@ -87,18 +86,15 @@ static int emi62_load_firmware (struct usb_device *dev)
        const struct firmware *bitstream_fw = NULL;
        const struct firmware *firmware_fw = NULL;
        const struct ihex_binrec *rec;
-       int err;
+       int err = -ENOMEM;
        int i;
        __u32 addr;     /* Address to write */
        __u8 *buf;
 
        dev_dbg(&dev->dev, "load_firmware\n");
        buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
-       if (!buf) {
-               err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
-               err = -ENOMEM;
+       if (!buf)
                goto wraperr;
-       }
 
        err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev);
        if (err)
@@ -112,16 +108,13 @@ static int emi62_load_firmware (struct usb_device *dev)
        err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev);
        if (err) {
        nofw:
-               err( "%s - request_firmware() failed", __func__);
                goto wraperr;
        }
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi62_set_reset(dev,1);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        rec = (const struct ihex_binrec *)loader_fw->data;
 
@@ -130,19 +123,15 @@ static int emi62_load_firmware (struct usb_device *dev)
                err = emi62_writememory(dev, be32_to_cpu(rec->addr),
                                        rec->data, be16_to_cpu(rec->len),
                                        ANCHOR_LOAD_INTERNAL);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
                rec = ihex_next_binrec(rec);
        }
 
        /* De-assert reset (let the CPU run) */
        err = emi62_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
        msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
@@ -160,18 +149,14 @@ static int emi62_load_firmware (struct usb_device *dev)
                        rec = ihex_next_binrec(rec);
                }
                err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
        } while (rec);
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi62_set_reset(dev,1);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
        for (rec = (const struct ihex_binrec *)loader_fw->data;
@@ -179,18 +164,14 @@ static int emi62_load_firmware (struct usb_device *dev)
                err = emi62_writememory(dev, be32_to_cpu(rec->addr),
                                        rec->data, be16_to_cpu(rec->len),
                                        ANCHOR_LOAD_INTERNAL);
-               if (err < 0) {
-                       err("%s - error loading firmware: error = %d", __func__, err);
+               if (err < 0)
                        goto wraperr;
-               }
        }
 
        /* De-assert reset (let the CPU run) */
        err = emi62_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
        msleep(250);    /* let device settle */
 
        /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
@@ -201,19 +182,15 @@ static int emi62_load_firmware (struct usb_device *dev)
                        err = emi62_writememory(dev, be32_to_cpu(rec->addr),
                                                rec->data, be16_to_cpu(rec->len),
                                                ANCHOR_LOAD_EXTERNAL);
-                       if (err < 0) {
-                               err("%s - error loading firmware: error = %d", __func__, err);
+                       if (err < 0)
                                goto wraperr;
-                       }
                }
        }
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi62_set_reset(dev,1);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
 
        for (rec = (const struct ihex_binrec *)firmware_fw->data;
             rec; rec = ihex_next_binrec(rec)) {
@@ -221,19 +198,15 @@ static int emi62_load_firmware (struct usb_device *dev)
                        err = emi62_writememory(dev, be32_to_cpu(rec->addr),
                                                rec->data, be16_to_cpu(rec->len),
                                                ANCHOR_LOAD_EXTERNAL);
-                       if (err < 0) {
-                               err("%s - error loading firmware: error = %d", __func__, err);
+                       if (err < 0)
                                goto wraperr;
-                       }
                }
        }
 
        /* De-assert reset (let the CPU run) */
        err = emi62_set_reset(dev,0);
-       if (err < 0) {
-               err("%s - error loading firmware: error = %d", __func__, err);
+       if (err < 0)
                goto wraperr;
-       }
        msleep(250);    /* let device settle */
 
        release_firmware(loader_fw);
@@ -247,6 +220,9 @@ static int emi62_load_firmware (struct usb_device *dev)
        return 1;
 
 wraperr:
+       if (err < 0)
+               dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
+                       __func__, err);
        release_firmware(loader_fw);
        release_firmware(bitstream_fw);
        release_firmware(firmware_fw);
index 0dee246..c00fcd7 100644 (file)
@@ -366,14 +366,14 @@ static int idmouse_probe(struct usb_interface *interface,
                        kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
 
                if (!dev->bulk_in_buffer) {
-                       err("Unable to allocate input buffer.");
+                       dev_err(&interface->dev, "Unable to allocate input buffer.\n");
                        idmouse_delete(dev);
                        return -ENOMEM;
                }
        }
 
        if (!(dev->bulk_in_endpointAddr)) {
-               err("Unable to find bulk-in endpoint.");
+               dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
                idmouse_delete(dev);
                return -ENODEV;
        }
@@ -385,7 +385,7 @@ static int idmouse_probe(struct usb_interface *interface,
        result = usb_register_dev(interface, &idmouse_class);
        if (result) {
                /* something prevented us from registering this device */
-               err("Unble to allocate minor number.");
+               dev_err(&interface->dev, "Unble to allocate minor number.\n");
                usb_set_intfdata(interface, NULL);
                idmouse_delete(dev);
                return result;
index 4fd0dc8..db46143 100644 (file)
@@ -610,8 +610,8 @@ static int iowarrior_open(struct inode *inode, struct file *file)
        interface = usb_find_interface(&iowarrior_driver, subminor);
        if (!interface) {
                mutex_unlock(&iowarrior_mutex);
-               err("%s - error, can't find device for minor %d", __func__,
-                   subminor);
+               printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+                      __func__, subminor);
                return -ENODEV;
        }
 
index 5db4ab5..ac76229 100644 (file)
@@ -334,8 +334,8 @@ static int ld_usb_open(struct inode *inode, struct file *file)
        interface = usb_find_interface(&ld_usb_driver, subminor);
 
        if (!interface) {
-               err("%s - error, can't find device for minor %d\n",
-                    __func__, subminor);
+               printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+                      __func__, subminor);
                return -ENODEV;
        }
 
@@ -485,7 +485,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
        /* verify that the device wasn't unplugged */
        if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
                goto unlock_exit;
        }
 
@@ -565,7 +565,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
        /* verify that the device wasn't unplugged */
        if (dev->intf == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d\n", retval);
+               printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
                goto unlock_exit;
        }
 
@@ -603,7 +603,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
                                         bytes_to_write,
                                         USB_CTRL_SET_TIMEOUT * HZ);
                if (retval < 0)
-                       err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
+                       dev_err(&dev->intf->dev,
+                               "Couldn't submit HID_REQ_SET_REPORT %d\n",
+                               retval);
                goto unlock_exit;
        }
 
@@ -624,7 +626,8 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
        retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
        if (retval) {
                dev->interrupt_out_busy = 0;
-               err("Couldn't submit interrupt_out_urb %d\n", retval);
+               dev_err(&dev->intf->dev,
+                       "Couldn't submit interrupt_out_urb %d\n", retval);
                goto unlock_exit;
        }
        retval = bytes_to_write;
index 5752220..a2702cb 100644 (file)
@@ -354,8 +354,8 @@ static int tower_open (struct inode *inode, struct file *file)
        interface = usb_find_interface (&tower_driver, subminor);
 
        if (!interface) {
-               err ("%s - error, can't find device for minor %d",
-                    __func__, subminor);
+               printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+                      __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
@@ -397,7 +397,8 @@ static int tower_open (struct inode *inode, struct file *file)
                                  sizeof(reset_reply),
                                  1000);
        if (result < 0) {
-               err("LEGO USB Tower reset control request failed");
+               dev_err(&dev->udev->dev,
+                       "LEGO USB Tower reset control request failed\n");
                retval = result;
                goto unlock_exit;
        }
@@ -420,7 +421,8 @@ static int tower_open (struct inode *inode, struct file *file)
 
        retval = usb_submit_urb (dev->interrupt_in_urb, GFP_KERNEL);
        if (retval) {
-               err("Couldn't submit interrupt_in_urb %d", retval);
+               dev_err(&dev->udev->dev,
+                       "Couldn't submit interrupt_in_urb %d\n", retval);
                dev->interrupt_in_running = 0;
                dev->open_count = 0;
                goto unlock_exit;
@@ -608,7 +610,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count,
        /* verify that the device wasn't unplugged */
        if (dev->udev == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d", retval);
+               printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
                goto unlock_exit;
        }
 
@@ -697,7 +699,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
        /* verify that the device wasn't unplugged */
        if (dev->udev == NULL) {
                retval = -ENODEV;
-               err("No device or device unplugged %d", retval);
+               printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
                goto unlock_exit;
        }
 
@@ -744,7 +746,8 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
        retval = usb_submit_urb (dev->interrupt_out_urb, GFP_KERNEL);
        if (retval) {
                dev->interrupt_out_busy = 0;
-               err("Couldn't submit interrupt_out_urb %d", retval);
+               dev_err(&dev->udev->dev,
+                       "Couldn't submit interrupt_out_urb %d\n", retval);
                goto unlock_exit;
        }
        retval = bytes_to_write;
@@ -803,9 +806,10 @@ resubmit:
        /* resubmit if we're still running */
        if (dev->interrupt_in_running && dev->udev) {
                retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
-               if (retval) {
-                       err("%s: usb_submit_urb failed (%d)", __func__, retval);
-               }
+               if (retval)
+                       dev_err(&dev->udev->dev,
+                               "%s: usb_submit_urb failed (%d)\n",
+                               __func__, retval);
        }
 
 exit:
@@ -852,6 +856,7 @@ static void tower_interrupt_out_callback (struct urb *urb)
  */
 static int tower_probe (struct usb_interface *interface, const struct usb_device_id *id)
 {
+       struct device *idev = &interface->dev;
        struct usb_device *udev = interface_to_usbdev(interface);
        struct lego_usb_tower *dev = NULL;
        struct usb_host_interface *iface_desc;
@@ -871,7 +876,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
        dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
 
        if (dev == NULL) {
-               err ("Out of memory");
+               dev_err(idev, "Out of memory\n");
                goto exit;
        }
 
@@ -915,37 +920,37 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                }
        }
        if(dev->interrupt_in_endpoint == NULL) {
-               err("interrupt in endpoint not found");
+               dev_err(idev, "interrupt in endpoint not found\n");
                goto error;
        }
        if (dev->interrupt_out_endpoint == NULL) {
-               err("interrupt out endpoint not found");
+               dev_err(idev, "interrupt out endpoint not found\n");
                goto error;
        }
 
        dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL);
        if (!dev->read_buffer) {
-               err("Couldn't allocate read_buffer");
+               dev_err(idev, "Couldn't allocate read_buffer\n");
                goto error;
        }
        dev->interrupt_in_buffer = kmalloc (usb_endpoint_maxp(dev->interrupt_in_endpoint), GFP_KERNEL);
        if (!dev->interrupt_in_buffer) {
-               err("Couldn't allocate interrupt_in_buffer");
+               dev_err(idev, "Couldn't allocate interrupt_in_buffer\n");
                goto error;
        }
        dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->interrupt_in_urb) {
-               err("Couldn't allocate interrupt_in_urb");
+               dev_err(idev, "Couldn't allocate interrupt_in_urb\n");
                goto error;
        }
        dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL);
        if (!dev->interrupt_out_buffer) {
-               err("Couldn't allocate interrupt_out_buffer");
+               dev_err(idev, "Couldn't allocate interrupt_out_buffer\n");
                goto error;
        }
        dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->interrupt_out_urb) {
-               err("Couldn't allocate interrupt_out_urb");
+               dev_err(idev, "Couldn't allocate interrupt_out_urb\n");
                goto error;
        }
        dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
@@ -958,7 +963,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
 
        if (retval) {
                /* something prevented us from registering this driver */
-               err ("Not able to get a minor for this device.");
+               dev_err(idev, "Not able to get a minor for this device.\n");
                usb_set_intfdata (interface, NULL);
                goto error;
        }
@@ -980,7 +985,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                                  sizeof(get_version_reply),
                                  1000);
        if (result < 0) {
-               err("LEGO USB Tower get version control request failed");
+               dev_err(idev, "LEGO USB Tower get version control request failed\n");
                retval = result;
                goto error;
        }
index 487a8ce..cb55dc5 100644 (file)
@@ -171,7 +171,9 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
                        if (result == -ETIMEDOUT)
                                retries--;
                        else if (result < 0) {
-                               err("Error executing ioctrl. code = %d", result);
+                               dev_err(&rio->rio_dev->dev,
+                                       "Error executing ioctrl. code = %d\n",
+                                       result);
                                retries = 0;
                        } else {
                                dbg("Executed ioctl. Result = %d (data=%02x)",
@@ -238,7 +240,9 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
                        if (result == -ETIMEDOUT)
                                retries--;
                        else if (result < 0) {
-                               err("Error executing ioctrl. code = %d", result);
+                               dev_err(&rio->rio_dev->dev,
+                                       "Error executing ioctrl. code = %d\n",
+                                       result);
                                retries = 0;
                        } else {
                                dbg("Executed ioctl. Result = %d", result);
@@ -332,7 +336,8 @@ write_rio(struct file *file, const char __user *buffer,
                                break;
                };
                if (result) {
-                       err("Write Whoops - %x", result);
+                       dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
+                               result);
                        errn = -EIO;
                        goto error;
                }
@@ -401,7 +406,8 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                } else if (result == -ETIMEDOUT || result == 15) {      /* FIXME: 15 ??? */
                        if (!maxretry--) {
                                mutex_unlock(&(rio->lock));
-                               err("read_rio: maxretry timeout");
+                               dev_err(&rio->rio_dev->dev,
+                                       "read_rio: maxretry timeout\n");
                                return -ETIME;
                        }
                        prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
@@ -410,8 +416,9 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                        continue;
                } else if (result != -EREMOTEIO) {
                        mutex_unlock(&(rio->lock));
-                       err("Read Whoops - result:%u partial:%u this_read:%u",
-                            result, partial, this_read);
+                       dev_err(&rio->rio_dev->dev,
+                               "Read Whoops - result:%u partial:%u this_read:%u\n",
+                               result, partial, this_read);
                        return -EIO;
                } else {
                        mutex_unlock(&(rio->lock));
@@ -459,21 +466,24 @@ static int probe_rio(struct usb_interface *intf,
 
        retval = usb_register_dev(intf, &usb_rio_class);
        if (retval) {
-               err("Not able to get a minor for this device.");
+               dev_err(&dev->dev,
+                       "Not able to get a minor for this device.\n");
                return -ENOMEM;
        }
 
        rio->rio_dev = dev;
 
        if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
-               err("probe_rio: Not enough memory for the output buffer");
+               dev_err(&dev->dev,
+                       "probe_rio: Not enough memory for the output buffer\n");
                usb_deregister_dev(intf, &usb_rio_class);
                return -ENOMEM;
        }
        dbg("probe_rio: obuf address:%p", rio->obuf);
 
        if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
-               err("probe_rio: Not enough memory for the input buffer");
+               dev_err(&dev->dev,
+                       "probe_rio: Not enough memory for the input buffer\n");
                usb_deregister_dev(intf, &usb_rio_class);
                kfree(rio->obuf);
                return -ENOMEM;
index e2b4bd3..c4ef9a1 100644 (file)
@@ -87,8 +87,8 @@ static int lcd_open(struct inode *inode, struct file *file)
        interface = usb_find_interface(&lcd_driver, subminor);
        if (!interface) {
                mutex_unlock(&lcd_mutex);
-               err("USBLCD: %s - error, can't find device for minor %d",
-                    __func__, subminor);
+               printk(KERN_ERR "USBLCD: %s - error, can't find device for minor %d\n",
+                      __func__, subminor);
                return -ENODEV;
        }
 
@@ -268,8 +268,9 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer,
        /* send the data out the bulk port */
        retval = usb_submit_urb(urb, GFP_KERNEL);
        if (retval) {
-               err("USBLCD: %s - failed submitting write urb, error %d",
-                   __func__, retval);
+               dev_err(&dev->udev->dev,
+                       "%s - failed submitting write urb, error %d\n",
+                       __func__, retval);
                goto error_unanchor;
        }
 
@@ -322,7 +323,7 @@ static int lcd_probe(struct usb_interface *interface,
        /* allocate memory for our device state and initialize it */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
-               err("Out of memory");
+               dev_err(&interface->dev, "Out of memory\n");
                goto error;
        }
        kref_init(&dev->kref);
@@ -352,7 +353,8 @@ static int lcd_probe(struct usb_interface *interface,
                        dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
                        dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
                        if (!dev->bulk_in_buffer) {
-                               err("Could not allocate bulk_in_buffer");
+                               dev_err(&interface->dev,
+                                       "Could not allocate bulk_in_buffer\n");
                                goto error;
                        }
                }
@@ -364,7 +366,8 @@ static int lcd_probe(struct usb_interface *interface,
                }
        }
        if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
-               err("Could not find both bulk-in and bulk-out endpoints");
+               dev_err(&interface->dev,
+                       "Could not find both bulk-in and bulk-out endpoints\n");
                goto error;
        }
 
@@ -375,7 +378,8 @@ static int lcd_probe(struct usb_interface *interface,
        retval = usb_register_dev(interface, &lcd_class);
        if (retval) {
                /* something prevented us from registering this driver */
-               err("Not able to get a minor for this device.");
+               dev_err(&interface->dev,
+                       "Not able to get a minor for this device.\n");
                usb_set_intfdata(interface, NULL);
                goto error;
        }
index 8b1d94a..7f64147 100644 (file)
@@ -118,7 +118,8 @@ static void async_complete(struct urb *urb)
        priv = rq->priv;
        pp = priv->pp;
        if (status) {
-               err("async_complete: urb error %d", status);
+               dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
+                       status);
        } else if (rq->dr.bRequest == 3) {
                memcpy(priv->reg, rq->reg, sizeof(priv->reg));
 #if 0
@@ -151,7 +152,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
                return NULL;
        rq = kmalloc(sizeof(struct uss720_async_request), mem_flags);
        if (!rq) {
-               err("submit_async_request out of memory");
+               dev_err(&usbdev->dev, "submit_async_request out of memory\n");
                return NULL;
        }
        kref_init(&rq->ref_count);
@@ -162,7 +163,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
        rq->urb = usb_alloc_urb(0, mem_flags);
        if (!rq->urb) {
                kref_put(&rq->ref_count, destroy_async);
-               err("submit_async_request out of memory");
+               dev_err(&usbdev->dev, "submit_async_request out of memory\n");
                return NULL;
        }
        rq->dr.bRequestType = requesttype;
@@ -182,7 +183,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
        if (!ret)
                return rq;
        destroy_async(&rq->ref_count);
-       err("submit_async_request submit_urb failed with %d", ret);
+       dev_err(&usbdev->dev, "submit_async_request submit_urb failed with %d\n", ret);
        return NULL;
 }
 
@@ -217,7 +218,8 @@ static int get_1284_register(struct parport *pp, unsigned char reg, unsigned cha
        priv = pp->private_data;
        rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
        if (!rq) {
-               err("get_1284_register(%u) failed", (unsigned int)reg);
+               dev_err(&priv->usbdev->dev, "get_1284_register(%u) failed",
+                       (unsigned int)reg);
                return -EIO;
        }
        if (!val) {
@@ -248,7 +250,8 @@ static int set_1284_register(struct parport *pp, unsigned char reg, unsigned cha
        priv = pp->private_data;
        rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
        if (!rq) {
-               err("set_1284_register(%u,%u) failed", (unsigned int)reg, (unsigned int)val);
+               dev_err(&priv->usbdev->dev, "set_1284_register(%u,%u) failed",
+                       (unsigned int)reg, (unsigned int)val);
                return -EIO;
        }
        kref_put(&rq->ref_count, destroy_async);
index 7020146..1d8ad4c 100644 (file)
@@ -83,7 +83,8 @@ static void yurex_control_callback(struct urb *urb)
        int status = urb->status;
 
        if (status) {
-               err("%s - control failed: %d\n", __func__, status);
+               dev_err(&urb->dev->dev, "%s - control failed: %d\n",
+                       __func__, status);
                wake_up_interruptible(&dev->waitq);
                return;
        }
@@ -137,8 +138,9 @@ static void yurex_interrupt(struct urb *urb)
        case 0: /*success*/
                break;
        case -EOVERFLOW:
-               err("%s - overflow with length %d, actual length is %d",
-                   __func__, YUREX_BUF_SIZE, dev->urb->actual_length);
+               dev_err(&dev->interface->dev,
+                       "%s - overflow with length %d, actual length is %d\n",
+                       __func__, YUREX_BUF_SIZE, dev->urb->actual_length);
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
@@ -146,7 +148,8 @@ static void yurex_interrupt(struct urb *urb)
                /* The device is terminated, clean up */
                return;
        default:
-               err("%s - unknown status received: %d", __func__, status);
+               dev_err(&dev->interface->dev,
+                       "%s - unknown status received: %d\n", __func__, status);
                goto exit;
        }
 
@@ -179,7 +182,7 @@ static void yurex_interrupt(struct urb *urb)
 exit:
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
        if (retval) {
-               err("%s - usb_submit_urb failed: %d",
+               dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n",
                        __func__, retval);
        }
 }
@@ -196,7 +199,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        /* allocate memory for our device state and initialize it */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev) {
-               err("Out of memory");
+               dev_err(&interface->dev, "Out of memory\n");
                goto error;
        }
        kref_init(&dev->kref);
@@ -219,7 +222,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        }
        if (!dev->int_in_endpointAddr) {
                retval = -ENODEV;
-               err("Could not find endpoints");
+               dev_err(&interface->dev, "Could not find endpoints\n");
                goto error;
        }
 
@@ -227,14 +230,14 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        /* allocate control URB */
        dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->cntl_urb) {
-               err("Could not allocate control URB");
+               dev_err(&interface->dev, "Could not allocate control URB\n");
                goto error;
        }
 
        /* allocate buffer for control req */
        dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
        if (!dev->cntl_req) {
-               err("Could not allocate cntl_req");
+               dev_err(&interface->dev, "Could not allocate cntl_req\n");
                goto error;
        }
 
@@ -243,7 +246,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
                                              GFP_KERNEL,
                                              &dev->cntl_urb->transfer_dma);
        if (!dev->cntl_buffer) {
-               err("Could not allocate cntl_buffer");
+               dev_err(&interface->dev, "Could not allocate cntl_buffer\n");
                goto error;
        }
 
@@ -265,7 +268,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        /* allocate interrupt URB */
        dev->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->urb) {
-               err("Could not allocate URB");
+               dev_err(&interface->dev, "Could not allocate URB\n");
                goto error;
        }
 
@@ -273,7 +276,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
                                        GFP_KERNEL, &dev->urb->transfer_dma);
        if (!dev->int_buffer) {
-               err("Could not allocate int_buffer");
+               dev_err(&interface->dev, "Could not allocate int_buffer\n");
                goto error;
        }
 
@@ -285,7 +288,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
                retval = -EIO;
-               err("Could not submitting URB");
+               dev_err(&interface->dev, "Could not submitting URB\n");
                goto error;
        }
 
@@ -295,7 +298,8 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        /* we can register the device now, as it is ready */
        retval = usb_register_dev(interface, &yurex_class);
        if (retval) {
-               err("Not able to get a minor for this device.");
+               dev_err(&interface->dev,
+                       "Not able to get a minor for this device.\n");
                usb_set_intfdata(interface, NULL);
                goto error;
        }
@@ -368,8 +372,8 @@ static int yurex_open(struct inode *inode, struct file *file)
 
        interface = usb_find_interface(&yurex_driver, subminor);
        if (!interface) {
-               err("%s - error, can't find device for minor %d",
-                   __func__, subminor);
+               printk(KERN_ERR "%s - error, can't find device for minor %d",
+                      __func__, subminor);
                retval = -ENODEV;
                goto exit;
        }
@@ -514,7 +518,9 @@ static ssize_t yurex_write(struct file *file, const char *user_buffer, size_t co
        mutex_unlock(&dev->io_mutex);
 
        if (retval < 0) {
-               err("%s - failed to send bulk msg, error %d", __func__, retval);
+               dev_err(&dev->interface->dev,
+                       "%s - failed to send bulk msg, error %d\n",
+                       __func__, retval);
                goto error;
        }
        if (set && timeout)
index 1ee6b2a..b9cca6d 100644 (file)
@@ -113,7 +113,8 @@ static int usb_console_setup(struct console *co, char *options)
        serial = usb_serial_get_by_index(co->index);
        if (serial == NULL) {
                /* no device is connected yet, sorry :( */
-               err("No USB device connected to ttyUSB%i", co->index);
+               printk(KERN_ERR "No USB device connected to ttyUSB%i\n",
+                      co->index);
                return -ENODEV;
        }
 
@@ -137,7 +138,7 @@ static int usb_console_setup(struct console *co, char *options)
                        tty = kzalloc(sizeof(*tty), GFP_KERNEL);
                        if (!tty) {
                                retval = -ENOMEM;
-                               err("no more memory");
+                               dev_err(&port->dev, "no more memory\n");
                                goto reset_open_count;
                        }
                        kref_init(&tty->kref);
@@ -146,7 +147,7 @@ static int usb_console_setup(struct console *co, char *options)
                        tty->index = co->index;
                        if (tty_init_termios(tty)) {
                                retval = -ENOMEM;
-                               err("no more memory");
+                               dev_err(&port->dev, "no more memory\n");
                                goto free_tty;
                        }
                }
@@ -159,7 +160,7 @@ static int usb_console_setup(struct console *co, char *options)
                        retval = usb_serial_generic_open(NULL, port);
 
                if (retval) {
-                       err("could not open USB console port");
+                       dev_err(&port->dev, "could not open USB console port\n");
                        goto fail;
                }
 
index 40a95a7..5e4b471 100644 (file)
@@ -547,6 +547,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
 {
        int baud_rate;
        struct tty_struct *tty = tty_port_tty_get(&port->port->port);
+       struct usb_serial *serial = port->port->serial;
        wait_queue_t wait;
        unsigned long flags;
 
@@ -561,7 +562,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
                set_current_state(TASK_INTERRUPTIBLE);
                if (kfifo_len(&port->write_fifo) == 0
                || timeout == 0 || signal_pending(current)
-               || !usb_get_intfdata(port->port->serial->interface))
+               || serial->disconnected)
                        /* disconnect */
                        break;
                spin_unlock_irqrestore(&port->ep_lock, flags);
@@ -578,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
        /* wait for data to drain from the device */
        timeout += jiffies;
        while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
-       && usb_get_intfdata(port->port->serial->interface)) {
+                                               && !serial->disconnected) {
                /* not disconnected */
                if (!tx_active(port))
                        break;
@@ -586,7 +587,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
        }
 
        /* disconnected */
-       if (!usb_get_intfdata(port->port->serial->interface))
+       if (serial->disconnected)
                return;
 
        /* wait one more character time, based on baud rate */
@@ -2003,8 +2004,8 @@ static void edge_close(struct usb_serial_port *port)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
+       struct usb_serial *serial = port->serial;
        int port_number;
-       int status;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -2028,12 +2029,18 @@ static void edge_close(struct usb_serial_port *port)
         * send a close port command to it */
        dbg("%s - send umpc_close_port", __func__);
        port_number = port->number - port->serial->minor;
-       status = send_cmd(port->serial->dev,
+
+       mutex_lock(&serial->disc_mutex);
+       if (!serial->disconnected) {
+               send_cmd(serial->dev,
                                     UMPC_CLOSE_PORT,
                                     (__u8)(UMPM_UART1_PORT + port_number),
                                     0,
                                     NULL,
                                     0);
+       }
+       mutex_unlock(&serial->disc_mutex);
+
        mutex_lock(&edge_serial->es_lock);
        --edge_port->edge_serial->num_ports_open;
        if (edge_port->edge_serial->num_ports_open <= 0) {
index 10c02b8..61e200f 100644 (file)
@@ -33,7 +33,6 @@
 #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
 #define DRIVER_DESC "USB PocketPC PDA driver"
 
-static __u16 product, vendor;
 static bool debug;
 static int connect_retries = KP_RETRIES;
 static int initial_wait;
@@ -45,8 +44,6 @@ static int  ipaq_calc_num_ports(struct usb_serial *serial);
 static int  ipaq_startup(struct usb_serial *serial);
 
 static struct usb_device_id ipaq_id_table [] = {
-       /* The first entry is a placeholder for the insmod-specified device */
-       { USB_DEVICE(0x049F, 0x0003) },
        { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
        { USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
        { USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
@@ -623,30 +620,7 @@ static int ipaq_startup(struct usb_serial *serial)
        return usb_reset_configuration(serial->dev);
 }
 
-static int __init ipaq_init(void)
-{
-       int retval;
-
-       if (vendor) {
-               ipaq_id_table[0].idVendor = vendor;
-               ipaq_id_table[0].idProduct = product;
-       }
-
-       retval = usb_serial_register_drivers(&ipaq_driver, serial_drivers);
-       if (retval == 0)
-               printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-                              DRIVER_DESC "\n");
-       return retval;
-}
-
-static void __exit ipaq_exit(void)
-{
-       usb_serial_deregister_drivers(&ipaq_driver, serial_drivers);
-}
-
-
-module_init(ipaq_init);
-module_exit(ipaq_exit);
+module_usb_serial_driver(ipaq_driver, serial_drivers);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -655,12 +629,6 @@ MODULE_LICENSE("GPL");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified USB idVendor");
-
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified USB idProduct");
-
 module_param(connect_retries, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(connect_retries,
                "Maximum number of connect retries (one second each)");
index 08d16e8..d17c867 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/tty_flip.h>
 #include <linux/moduleparam.h>
 #include <linux/spinlock.h>
-#include <linux/errno.h>
 #include <linux/uaccess.h>
 #include <linux/usb/serial.h>
 
@@ -56,6 +55,47 @@ MODULE_DEVICE_TABLE(usb, id_table);
 /* Input parameter constants. */
 static bool debug;
 
+/* UNI-Directional mode commands for device configure */
+#define UNI_CMD_OPEN   0x80
+#define UNI_CMD_CLOSE  0xFF
+
+inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
+{
+       __u16 product_id = le16_to_cpu(
+               port->serial->dev->descriptor.idProduct);
+
+       return product_id == FOCUS_PRODUCT_ID_UNI;
+}
+
+static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
+{
+       int ret;
+       int actual_len;
+       u8 *buffer_cmd = NULL;
+
+       if (!metrousb_is_unidirectional_mode(port))
+               return 0;
+
+       buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
+       if (!buffer_cmd)
+               return -ENOMEM;
+
+       *buffer_cmd = cmd;
+
+       ret = usb_interrupt_msg(port->serial->dev,
+               usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
+               buffer_cmd, sizeof(cmd),
+               &actual_len, USB_CTRL_SET_TIMEOUT);
+
+       kfree(buffer_cmd);
+
+       if (ret < 0)
+               return ret;
+       else if (actual_len != sizeof(cmd))
+               return -EIO;
+       return 0;
+}
+
 static void metrousb_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
@@ -78,12 +118,12 @@ static void metrousb_read_int_callback(struct urb *urb)
                /* urb has been terminated. */
                dev_dbg(&port->dev,
                        "%s - urb shutting down, error code=%d\n",
-                       __func__, result);
+                       __func__, urb->status);
                return;
        default:
                dev_dbg(&port->dev,
                        "%s - non-zero urb received, error code=%d\n",
-                       __func__, result);
+                       __func__, urb->status);
                goto exit;
        }
 
@@ -91,7 +131,7 @@ static void metrousb_read_int_callback(struct urb *urb)
        /* Set the data read from the usb port into the serial port buffer. */
        tty = tty_port_tty_get(&port->port);
        if (!tty) {
-               dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n",
+               dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
                        __func__);
                return;
        }
@@ -121,7 +161,7 @@ static void metrousb_read_int_callback(struct urb *urb)
                result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
 
                if (result)
-                       dev_dbg(&port->dev,
+                       dev_err(&port->dev,
                                "%s - failed submitting interrupt in urb, error code=%d\n",
                                __func__, result);
        }
@@ -131,11 +171,19 @@ exit:
        /* Try to resubmit the urb. */
        result = usb_submit_urb(urb, GFP_ATOMIC);
        if (result)
-               dev_dbg(&port->dev,
+               dev_err(&port->dev,
                        "%s - failed submitting interrupt in urb, error code=%d\n",
                        __func__, result);
 }
 
+static void metrousb_write_int_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = urb->context;
+
+       dev_warn(&port->dev, "%s not implemented yet.\n",
+               __func__);
+}
+
 static void metrousb_cleanup(struct usb_serial_port *port)
 {
        dev_dbg(&port->dev, "%s\n", __func__);
@@ -146,6 +194,9 @@ static void metrousb_cleanup(struct usb_serial_port *port)
                        usb_unlink_urb(port->interrupt_in_urb);
                        usb_kill_urb(port->interrupt_in_urb);
                }
+
+               /* Send deactivate cmd to device */
+               metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
        }
 }
 
@@ -160,7 +211,7 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* Make sure the urb is initialized. */
        if (!port->interrupt_in_urb) {
-               dev_dbg(&port->dev, "%s - interrupt urb not initialized\n",
+               dev_err(&port->dev, "%s - interrupt urb not initialized\n",
                        __func__);
                return -ENODEV;
        }
@@ -191,12 +242,21 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 
        if (result) {
-               dev_dbg(&port->dev,
+               dev_err(&port->dev,
                        "%s - failed submitting interrupt in urb, error code=%d\n",
                        __func__, result);
                goto exit;
        }
 
+       /* Send activate cmd to device */
+       result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port);
+       if (result) {
+               dev_err(&port->dev,
+                       "%s - failed to configure device for port number=%d, error code=%d\n",
+                       __func__, port->number, result);
+               goto exit;
+       }
+
        dev_dbg(&port->dev, "%s - port open\n", __func__);
 exit:
        return result;
@@ -221,7 +281,7 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr
                                METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST,
                                control_state, 0, NULL, 0, WDR_TIMEOUT);
        if (retval < 0)
-               dev_dbg(&serial->dev->dev,
+               dev_err(&serial->dev->dev,
                        "%s - set modem ctrl=0x%x failed, error code=%d\n",
                        __func__, mcr, retval);
 
@@ -354,7 +414,7 @@ static void metrousb_unthrottle(struct tty_struct *tty)
        port->interrupt_in_urb->dev = port->serial->dev;
        result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
        if (result)
-               dev_dbg(tty->dev,
+               dev_err(tty->dev,
                        "failed submitting interrupt in urb error code=%d\n",
                        result);
 }
@@ -371,12 +431,13 @@ static struct usb_serial_driver metrousb_device = {
                .owner =        THIS_MODULE,
                .name =         "metro-usb",
        },
-       .description            = "Metrologic USB to serial converter.",
+       .description            = "Metrologic USB to Serial",
        .id_table               = id_table,
        .num_ports              = 1,
        .open                   = metrousb_open,
        .close                  = metrousb_cleanup,
        .read_int_callback      = metrousb_read_int_callback,
+       .write_int_callback     = metrousb_write_int_callback,
        .attach                 = metrousb_startup,
        .release                = metrousb_shutdown,
        .throttle               = metrousb_throttle,
index c526550..aaef523 100644 (file)
 #define USB_VENDOR_ID_MOSCHIP           0x9710
 #define MOSCHIP_DEVICE_ID_7840          0x7840
 #define MOSCHIP_DEVICE_ID_7820          0x7820
+#define MOSCHIP_DEVICE_ID_7810          0x7810
 /* The native component can have its vendor/device id's overridden
  * in vendor-specific implementations.  Such devices can be handled
  * by making a change here, in moschip_port_id_table, and in
 #define NUM_URBS                        16     /* URB Count */
 #define URB_TRANSFER_BUFFER_SIZE        32     /* URB Size  */
 
+/* LED on/off milliseconds*/
+#define LED_ON_MS      500
+#define LED_OFF_MS     500
+
+static int device_type;
 
 static const struct usb_device_id moschip_port_id_table[] = {
        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+       {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -209,6 +216,7 @@ static const struct usb_device_id moschip_port_id_table[] = {
 static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+       {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -261,8 +269,13 @@ struct moschip_port {
        struct urb *write_urb_pool[NUM_URBS];
        char busy[NUM_URBS];
        bool read_urb_busy;
-};
 
+       /* For device(s) with LED indicator */
+       bool has_led;
+       bool led_flag;
+       struct timer_list led_timer1;   /* Timer for LED on */
+       struct timer_list led_timer2;   /* Timer for LED off */
+};
 
 static bool debug;
 
@@ -572,6 +585,69 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
        return ret;
 }
 
+static void mos7840_set_led_callback(struct urb *urb)
+{
+       switch (urb->status) {
+       case 0:
+               /* Success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* This urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d", __func__,
+                       urb->status);
+               break;
+       default:
+               dbg("%s - nonzero urb status received: %d", __func__,
+                       urb->status);
+       }
+}
+
+static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
+                               __u16 reg)
+{
+       struct usb_device *dev = mcs->port->serial->dev;
+       struct usb_ctrlrequest *dr = mcs->dr;
+
+       dr->bRequestType = MCS_WR_RTYPE;
+       dr->bRequest = MCS_WRREQ;
+       dr->wValue = cpu_to_le16(wval);
+       dr->wIndex = cpu_to_le16(reg);
+       dr->wLength = cpu_to_le16(0);
+
+       usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
+               (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
+
+       usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
+}
+
+static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
+                               __u16 val)
+{
+       struct usb_device *dev = port->serial->dev;
+
+       usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
+                       val, reg, NULL, 0, MOS_WDR_TIMEOUT);
+}
+
+static void mos7840_led_off(unsigned long arg)
+{
+       struct moschip_port *mcs = (struct moschip_port *) arg;
+
+       /* Turn off LED */
+       mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
+       mod_timer(&mcs->led_timer2,
+                               jiffies + msecs_to_jiffies(LED_OFF_MS));
+}
+
+static void mos7840_led_flag_off(unsigned long arg)
+{
+       struct moschip_port *mcs = (struct moschip_port *) arg;
+
+       mcs->led_flag = false;
+}
+
 /*****************************************************************************
  * mos7840_interrupt_callback
  *     this is the callback function for when we have received data on the
@@ -792,6 +868,14 @@ static void mos7840_bulk_in_callback(struct urb *urb)
                return;
        }
 
+       /* Turn on LED */
+       if (mos7840_port->has_led && !mos7840_port->led_flag) {
+               mos7840_port->led_flag = true;
+               mos7840_set_led_async(mos7840_port, 0x0301,
+                                       MODEM_CONTROL_REGISTER);
+               mod_timer(&mos7840_port->led_timer1,
+                               jiffies + msecs_to_jiffies(LED_ON_MS));
+       }
 
        mos7840_port->read_urb_busy = true;
        retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
@@ -1554,6 +1638,14 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
        data1 = urb->transfer_buffer;
        dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
 
+       /* Turn on LED */
+       if (mos7840_port->has_led && !mos7840_port->led_flag) {
+               mos7840_port->led_flag = true;
+               mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
+               mod_timer(&mos7840_port->led_timer1,
+                               jiffies + msecs_to_jiffies(LED_ON_MS));
+       }
+
        /* send it down the pipe */
        status = usb_submit_urb(urb, GFP_ATOMIC);
 
@@ -2327,28 +2419,74 @@ static int mos7840_ioctl(struct tty_struct *tty,
        return -ENOIOCTLCMD;
 }
 
+static int mos7810_check(struct usb_serial *serial)
+{
+       int i, pass_count = 0;
+       __u16 data = 0, mcr_data = 0;
+       __u16 test_pattern = 0x55AA;
+
+       /* Store MCR setting */
+       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+               MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
+               &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+       for (i = 0; i < 16; i++) {
+               /* Send the 1-bit test pattern out to MCS7810 test pin */
+               usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       MCS_WRREQ, MCS_WR_RTYPE,
+                       (0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
+                       MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
+
+               /* Read the test pattern back */
+               usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
+                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+               /* If this is a MCS7810 device, both test patterns must match */
+               if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
+                       break;
+
+               pass_count++;
+       }
+
+       /* Restore MCR setting */
+       usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
+               MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
+               0, MOS_WDR_TIMEOUT);
+
+       if (pass_count == 16)
+               return 1;
+
+       return 0;
+}
+
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
-       __u16 Data = 0x00;
-       int ret = 0;
+       __u16 data = 0x00;
        int mos7840_num_ports;
 
-       ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-               MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
+       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+               MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
                VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
 
-       if ((Data & 0x01) == 0) {
-               mos7840_num_ports = 2;
-               serial->num_bulk_in = 2;
-               serial->num_bulk_out = 2;
-               serial->num_ports = 2;
+       if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
+               serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
+               device_type = serial->dev->descriptor.idProduct;
        } else {
-               mos7840_num_ports = 4;
-               serial->num_bulk_in = 4;
-               serial->num_bulk_out = 4;
-               serial->num_ports = 4;
+               /* For a MCS7840 device GPIO0 must be set to 1 */
+               if ((data & 0x01) == 1)
+                       device_type = MOSCHIP_DEVICE_ID_7840;
+               else if (mos7810_check(serial))
+                       device_type = MOSCHIP_DEVICE_ID_7810;
+               else
+                       device_type = MOSCHIP_DEVICE_ID_7820;
        }
 
+       mos7840_num_ports = (device_type >> 4) & 0x000F;
+       serial->num_bulk_in = mos7840_num_ports;
+       serial->num_bulk_out = mos7840_num_ports;
+       serial->num_ports = mos7840_num_ports;
+
        return mos7840_num_ports;
 }
 
@@ -2563,6 +2701,34 @@ static int mos7840_startup(struct usb_serial *serial)
                        status = -ENOMEM;
                        goto error;
                }
+
+               mos7840_port->has_led = false;
+
+               /* Initialize LED timers */
+               if (device_type == MOSCHIP_DEVICE_ID_7810) {
+                       mos7840_port->has_led = true;
+
+                       init_timer(&mos7840_port->led_timer1);
+                       mos7840_port->led_timer1.function = mos7840_led_off;
+                       mos7840_port->led_timer1.expires =
+                                       jiffies + msecs_to_jiffies(LED_ON_MS);
+                       mos7840_port->led_timer1.data =
+                                               (unsigned long)mos7840_port;
+
+                       init_timer(&mos7840_port->led_timer2);
+                       mos7840_port->led_timer2.function =
+                                               mos7840_led_flag_off;
+                       mos7840_port->led_timer2.expires =
+                                       jiffies + msecs_to_jiffies(LED_OFF_MS);
+                       mos7840_port->led_timer2.data =
+                                               (unsigned long)mos7840_port;
+
+                       mos7840_port->led_flag = false;
+
+                       /* Turn off LED */
+                       mos7840_set_led_sync(serial->port[i],
+                                               MODEM_CONTROL_REGISTER, 0x0300);
+               }
        }
        dbg ("mos7840_startup: all ports configured...........");
 
@@ -2654,6 +2820,14 @@ static void mos7840_release(struct usb_serial *serial)
                mos7840_port = mos7840_get_port_private(serial->port[i]);
                dbg("mos7840_port %d = %p", i, mos7840_port);
                if (mos7840_port) {
+                       if (mos7840_port->has_led) {
+                               /* Turn off LED */
+                               mos7840_set_led_sync(mos7840_port->port,
+                                               MODEM_CONTROL_REGISTER, 0x0300);
+
+                               del_timer_sync(&mos7840_port->led_timer1);
+                               del_timer_sync(&mos7840_port->led_timer2);
+                       }
                        kfree(mos7840_port->ctrl_buf);
                        kfree(mos7840_port->dr);
                        kfree(mos7840_port);
index f4465cc..9ea5f4b 100644 (file)
@@ -1413,7 +1413,7 @@ static void option_instat_callback(struct urb *urb)
                                req_pkt->bRequestType, req_pkt->bRequest);
                }
        } else
-               err("%s: error %d", __func__, status);
+               dev_err(&port->dev, "%s: error %d\n", __func__, status);
 
        /* Resubmit urb so we continue receiving IRQ data */
        if (status != -ESHUTDOWN && status != -ENOENT) {
index ab74123..82116f4 100644 (file)
@@ -394,7 +394,9 @@ static int ti_startup(struct usb_serial *serial)
 
        /* if we have only 1 configuration, download firmware */
        if (dev->descriptor.bNumConfigurations == 1) {
-               if ((status = ti_download_firmware(tdev)) != 0)
+               status = ti_download_firmware(tdev);
+
+               if (status != 0)
                        goto free_tdev;
 
                /* 3410 must be reset, 5052 resets itself */
@@ -1683,7 +1685,9 @@ static int ti_download_firmware(struct ti_device *tdev)
        /* try ID specific firmware first, then try generic firmware */
        sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
            dev->descriptor.idProduct);
-       if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
+       status = request_firmware(&fw_p, buf, &dev->dev);
+
+       if (status != 0) {
                buf[0] = '\0';
                if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
                        switch (dev->descriptor.idProduct) {
index c88657d..194c546 100644 (file)
@@ -725,8 +725,8 @@ int usb_wwan_resume(struct usb_serial *serial)
                err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
                dbg("Submitted interrupt URB for port %d (result %d)", i, err);
                if (err < 0) {
-                       err("%s: Error %d for interrupt URB of port%d",
-                           __func__, err, i);
+                       dev_err(&port->dev, "%s: Error %d for interrupt URB\n",
+                               __func__, err);
                        goto err_out;
                }
        }
@@ -747,8 +747,8 @@ int usb_wwan_resume(struct usb_serial *serial)
                        urb = portdata->in_urbs[j];
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err < 0) {
-                               err("%s: Error %d for bulk URB %d",
-                                   __func__, err, i);
+                               dev_err(&port->dev, "%s: Error %d for bulk URB %d\n",
+                                       __func__, err, i);
                                spin_unlock_irq(&intfdata->susp_lock);
                                goto err_out;
                        }
index 71d6964..aa8911d 100644 (file)
@@ -53,8 +53,6 @@ static int palm_os_4_probe(struct usb_serial *serial,
 
 /* Parameters that may be passed into the module. */
 static bool debug;
-static __u16 vendor;
-static __u16 product;
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
@@ -115,14 +113,12 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { },                                    /* optional parameter entry */
        { }                                     /* Terminating entry */
 };
 
 static struct usb_device_id clie_id_5_table [] = {
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { },                                    /* optional parameter entry */
        { }                                     /* Terminating entry */
 };
 
@@ -162,7 +158,6 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
        { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
-       { },                                    /* optional parameter entry */
        { }                                     /* Terminating entry */
 };
 
@@ -648,59 +643,7 @@ static int clie_5_attach(struct usb_serial *serial)
        return 0;
 }
 
-static int __init visor_init(void)
-{
-       int i, retval;
-       /* Only if parameters were passed to us */
-       if (vendor > 0 && product > 0) {
-               struct usb_device_id usb_dev_temp[] = {
-                       {
-                               USB_DEVICE(vendor, product),
-                               .driver_info =
-                                       (kernel_ulong_t) &palm_os_4_probe
-                       }
-               };
-
-               /* Find the last entry in id_table */
-               for (i = 0;; i++) {
-                       if (id_table[i].idVendor == 0) {
-                               id_table[i] = usb_dev_temp[0];
-                               break;
-                       }
-               }
-               /* Find the last entry in id_table_combined */
-               for (i = 0;; i++) {
-                       if (id_table_combined[i].idVendor == 0) {
-                               id_table_combined[i] = usb_dev_temp[0];
-                               break;
-                       }
-               }
-               printk(KERN_INFO KBUILD_MODNAME
-                      ": Untested USB device specified at time of module insertion\n");
-               printk(KERN_INFO KBUILD_MODNAME
-                      ": Warning: This is not guaranteed to work\n");
-               printk(KERN_INFO KBUILD_MODNAME
-                      ": Using a newer kernel is preferred to this method\n");
-               printk(KERN_INFO KBUILD_MODNAME
-                      ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n",
-                       vendor, product);
-       }
-
-       retval = usb_serial_register_drivers(&visor_driver, serial_drivers);
-       if (retval == 0)
-               printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
-       return retval;
-}
-
-
-static void __exit visor_exit (void)
-{
-       usb_serial_deregister_drivers(&visor_driver, serial_drivers);
-}
-
-
-module_init(visor_init);
-module_exit(visor_exit);
+module_usb_serial_driver(visor_driver, serial_drivers);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -708,9 +651,3 @@ MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified vendor ID");
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified product ID");
-
index 407e23c..c141b47 100644 (file)
@@ -45,7 +45,6 @@ static bool debug;
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v2.0"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
@@ -96,10 +95,6 @@ static void whiteheat_release(struct usb_serial *serial);
 static int  whiteheat_open(struct tty_struct *tty,
                        struct usb_serial_port *port);
 static void whiteheat_close(struct usb_serial_port *port);
-static int  whiteheat_write(struct tty_struct *tty,
-                       struct usb_serial_port *port,
-                       const unsigned char *buf, int count);
-static int  whiteheat_write_room(struct tty_struct *tty);
 static int  whiteheat_ioctl(struct tty_struct *tty,
                        unsigned int cmd, unsigned long arg);
 static void whiteheat_set_termios(struct tty_struct *tty,
@@ -108,11 +103,6 @@ static int  whiteheat_tiocmget(struct tty_struct *tty);
 static int  whiteheat_tiocmset(struct tty_struct *tty,
                        unsigned int set, unsigned int clear);
 static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
-static int  whiteheat_chars_in_buffer(struct tty_struct *tty);
-static void whiteheat_throttle(struct tty_struct *tty);
-static void whiteheat_unthrottle(struct tty_struct *tty);
-static void whiteheat_read_callback(struct urb *urb);
-static void whiteheat_write_callback(struct urb *urb);
 
 static struct usb_serial_driver whiteheat_fake_device = {
        .driver = {
@@ -138,18 +128,13 @@ static struct usb_serial_driver whiteheat_device = {
        .release =              whiteheat_release,
        .open =                 whiteheat_open,
        .close =                whiteheat_close,
-       .write =                whiteheat_write,
-       .write_room =           whiteheat_write_room,
        .ioctl =                whiteheat_ioctl,
        .set_termios =          whiteheat_set_termios,
        .break_ctl =            whiteheat_break_ctl,
        .tiocmget =             whiteheat_tiocmget,
        .tiocmset =             whiteheat_tiocmset,
-       .chars_in_buffer =      whiteheat_chars_in_buffer,
-       .throttle =             whiteheat_throttle,
-       .unthrottle =           whiteheat_unthrottle,
-       .read_bulk_callback =   whiteheat_read_callback,
-       .write_bulk_callback =  whiteheat_write_callback,
+       .throttle =             usb_serial_generic_throttle,
+       .unthrottle =           usb_serial_generic_unthrottle,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -166,29 +151,8 @@ struct whiteheat_command_private {
        __u8                    result_buffer[64];
 };
 
-
-#define THROTTLED              0x01
-#define ACTUALLY_THROTTLED     0x02
-
-static int urb_pool_size = 8;
-
-struct whiteheat_urb_wrap {
-       struct list_head        list;
-       struct urb              *urb;
-};
-
 struct whiteheat_private {
-       spinlock_t              lock;
-       __u8                    flags;
        __u8                    mcr;            /* FIXME: no locking on mcr */
-       struct list_head        rx_urbs_free;
-       struct list_head        rx_urbs_submitted;
-       struct list_head        rx_urb_q;
-       struct work_struct      rx_work;
-       struct usb_serial_port  *port;
-       struct list_head        tx_urbs_free;
-       struct list_head        tx_urbs_submitted;
-       struct mutex            deathwarrant;
 };
 
 
@@ -198,12 +162,6 @@ static void stop_command_port(struct usb_serial *serial);
 static void command_port_write_callback(struct urb *urb);
 static void command_port_read_callback(struct urb *urb);
 
-static int start_port_read(struct usb_serial_port *port);
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
-                                               struct list_head *head);
-static struct list_head *list_first(struct list_head *head);
-static void rx_data_softint(struct work_struct *work);
-
 static int firm_send_command(struct usb_serial_port *port, __u8 command,
                                                __u8 *data, __u8 datasize);
 static int firm_open(struct usb_serial_port *port);
@@ -349,11 +307,6 @@ static int whiteheat_attach(struct usb_serial *serial)
        __u8 *command;
        __u8 *result;
        int i;
-       int j;
-       struct urb *urb;
-       int buf_size;
-       struct whiteheat_urb_wrap *wrap;
-       struct list_head *tmp;
 
        command_port = serial->port[COMMAND_PORT];
 
@@ -408,8 +361,8 @@ static int whiteheat_attach(struct usb_serial *serial)
 
        hw_info = (struct whiteheat_hw_info *)&result[1];
 
-       dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n",
-                serial->type->description, DRIVER_VERSION,
+       dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n",
+                serial->type->description,
                 hw_info->sw_major_rev, hw_info->sw_minor_rev);
 
        for (i = 0; i < serial->num_ports; i++) {
@@ -423,72 +376,7 @@ static int whiteheat_attach(struct usb_serial *serial)
                        goto no_private;
                }
 
-               spin_lock_init(&info->lock);
-               mutex_init(&info->deathwarrant);
-               info->flags = 0;
                info->mcr = 0;
-               INIT_WORK(&info->rx_work, rx_data_softint);
-               info->port = port;
-
-               INIT_LIST_HEAD(&info->rx_urbs_free);
-               INIT_LIST_HEAD(&info->rx_urbs_submitted);
-               INIT_LIST_HEAD(&info->rx_urb_q);
-               INIT_LIST_HEAD(&info->tx_urbs_free);
-               INIT_LIST_HEAD(&info->tx_urbs_submitted);
-
-               for (j = 0; j < urb_pool_size; j++) {
-                       urb = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!urb) {
-                               dev_err(&port->dev, "No free urbs available\n");
-                               goto no_rx_urb;
-                       }
-                       buf_size = port->read_urb->transfer_buffer_length;
-                       urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
-                       if (!urb->transfer_buffer) {
-                               dev_err(&port->dev,
-                                       "Couldn't allocate urb buffer\n");
-                               goto no_rx_buf;
-                       }
-                       wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
-                       if (!wrap) {
-                               dev_err(&port->dev,
-                                       "Couldn't allocate urb wrapper\n");
-                               goto no_rx_wrap;
-                       }
-                       usb_fill_bulk_urb(urb, serial->dev,
-                                       usb_rcvbulkpipe(serial->dev,
-                                               port->bulk_in_endpointAddress),
-                                       urb->transfer_buffer, buf_size,
-                                       whiteheat_read_callback, port);
-                       wrap->urb = urb;
-                       list_add(&wrap->list, &info->rx_urbs_free);
-
-                       urb = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!urb) {
-                               dev_err(&port->dev, "No free urbs available\n");
-                               goto no_tx_urb;
-                       }
-                       buf_size = port->write_urb->transfer_buffer_length;
-                       urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
-                       if (!urb->transfer_buffer) {
-                               dev_err(&port->dev,
-                                       "Couldn't allocate urb buffer\n");
-                               goto no_tx_buf;
-                       }
-                       wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
-                       if (!wrap) {
-                               dev_err(&port->dev,
-                                       "Couldn't allocate urb wrapper\n");
-                               goto no_tx_wrap;
-                       }
-                       usb_fill_bulk_urb(urb, serial->dev,
-                                       usb_sndbulkpipe(serial->dev,
-                                               port->bulk_out_endpointAddress),
-                                       urb->transfer_buffer, buf_size,
-                                       whiteheat_write_callback, port);
-                       wrap->urb = urb;
-                       list_add(&wrap->list, &info->tx_urbs_free);
-               }
 
                usb_set_serial_port_data(port, info);
        }
@@ -531,29 +419,6 @@ no_command_private:
        for (i = serial->num_ports - 1; i >= 0; i--) {
                port = serial->port[i];
                info = usb_get_serial_port_data(port);
-               for (j = urb_pool_size - 1; j >= 0; j--) {
-                       tmp = list_first(&info->tx_urbs_free);
-                       list_del(tmp);
-                       wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-                       urb = wrap->urb;
-                       kfree(wrap);
-no_tx_wrap:
-                       kfree(urb->transfer_buffer);
-no_tx_buf:
-                       usb_free_urb(urb);
-no_tx_urb:
-                       tmp = list_first(&info->rx_urbs_free);
-                       list_del(tmp);
-                       wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-                       urb = wrap->urb;
-                       kfree(wrap);
-no_rx_wrap:
-                       kfree(urb->transfer_buffer);
-no_rx_buf:
-                       usb_free_urb(urb);
-no_rx_urb:
-                       ;
-               }
                kfree(info);
 no_private:
                ;
@@ -569,12 +434,7 @@ no_command_buffer:
 static void whiteheat_release(struct usb_serial *serial)
 {
        struct usb_serial_port *command_port;
-       struct usb_serial_port *port;
        struct whiteheat_private *info;
-       struct whiteheat_urb_wrap *wrap;
-       struct urb *urb;
-       struct list_head *tmp;
-       struct list_head *tmp2;
        int i;
 
        dbg("%s", __func__);
@@ -584,31 +444,14 @@ static void whiteheat_release(struct usb_serial *serial)
        kfree(usb_get_serial_port_data(command_port));
 
        for (i = 0; i < serial->num_ports; i++) {
-               port = serial->port[i];
-               info = usb_get_serial_port_data(port);
-               list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
-                       list_del(tmp);
-                       wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-                       urb = wrap->urb;
-                       kfree(wrap);
-                       kfree(urb->transfer_buffer);
-                       usb_free_urb(urb);
-               }
-               list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) {
-                       list_del(tmp);
-                       wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-                       urb = wrap->urb;
-                       kfree(wrap);
-                       kfree(urb->transfer_buffer);
-                       usb_free_urb(urb);
-               }
+               info = usb_get_serial_port_data(serial->port[i]);
                kfree(info);
        }
 }
 
 static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-       int             retval = 0;
+       int retval;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -616,9 +459,6 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
        if (retval)
                goto exit;
 
-       if (tty)
-               tty->low_latency = 1;
-
        /* send an open port command */
        retval = firm_open(port);
        if (retval) {
@@ -640,17 +480,12 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
        usb_clear_halt(port->serial->dev, port->read_urb->pipe);
        usb_clear_halt(port->serial->dev, port->write_urb->pipe);
 
-       /* Start reading from the device */
-       retval = start_port_read(port);
+       retval = usb_serial_generic_open(tty, port);
        if (retval) {
-               dev_err(&port->dev,
-                       "%s - failed submitting read urb, error %d\n",
-                       __func__, retval);
                firm_close(port);
                stop_command_port(port->serial);
                goto exit;
        }
-
 exit:
        dbg("%s - exit, retval = %d", __func__, retval);
        return retval;
@@ -659,125 +494,14 @@ exit:
 
 static void whiteheat_close(struct usb_serial_port *port)
 {
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct whiteheat_urb_wrap *wrap;
-       struct urb *urb;
-       struct list_head *tmp;
-       struct list_head *tmp2;
-
        dbg("%s - port %d", __func__, port->number);
 
        firm_report_tx_done(port);
        firm_close(port);
 
-       /* shutdown our bulk reads and writes */
-       mutex_lock(&info->deathwarrant);
-       spin_lock_irq(&info->lock);
-       list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               urb = wrap->urb;
-               list_del(tmp);
-               spin_unlock_irq(&info->lock);
-               usb_kill_urb(urb);
-               spin_lock_irq(&info->lock);
-               list_add(tmp, &info->rx_urbs_free);
-       }
-       list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
-               list_move(tmp, &info->rx_urbs_free);
-       list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               urb = wrap->urb;
-               list_del(tmp);
-               spin_unlock_irq(&info->lock);
-               usb_kill_urb(urb);
-               spin_lock_irq(&info->lock);
-               list_add(tmp, &info->tx_urbs_free);
-       }
-       spin_unlock_irq(&info->lock);
-       mutex_unlock(&info->deathwarrant);
-       stop_command_port(port->serial);
-}
-
-
-static int whiteheat_write(struct tty_struct *tty,
-       struct usb_serial_port *port, const unsigned char *buf, int count)
-{
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct whiteheat_urb_wrap *wrap;
-       struct urb *urb;
-       int result;
-       int bytes;
-       int sent = 0;
-       unsigned long flags;
-       struct list_head *tmp;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       if (count == 0) {
-               dbg("%s - write request of 0 bytes", __func__);
-               return (0);
-       }
-
-       while (count) {
-               spin_lock_irqsave(&info->lock, flags);
-               if (list_empty(&info->tx_urbs_free)) {
-                       spin_unlock_irqrestore(&info->lock, flags);
-                       break;
-               }
-               tmp = list_first(&info->tx_urbs_free);
-               list_del(tmp);
-               spin_unlock_irqrestore(&info->lock, flags);
-
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               urb = wrap->urb;
-               bytes = (count > port->bulk_out_size) ?
-                                       port->bulk_out_size : count;
-               memcpy(urb->transfer_buffer, buf + sent, bytes);
-
-               usb_serial_debug_data(debug, &port->dev,
-                               __func__, bytes, urb->transfer_buffer);
-
-               urb->transfer_buffer_length = bytes;
-               result = usb_submit_urb(urb, GFP_ATOMIC);
-               if (result) {
-                       dev_err_console(port,
-                               "%s - failed submitting write urb, error %d\n",
-                               __func__, result);
-                       sent = result;
-                       spin_lock_irqsave(&info->lock, flags);
-                       list_add(tmp, &info->tx_urbs_free);
-                       spin_unlock_irqrestore(&info->lock, flags);
-                       break;
-               } else {
-                       sent += bytes;
-                       count -= bytes;
-                       spin_lock_irqsave(&info->lock, flags);
-                       list_add(tmp, &info->tx_urbs_submitted);
-                       spin_unlock_irqrestore(&info->lock, flags);
-               }
-       }
+       usb_serial_generic_close(port);
 
-       return sent;
-}
-
-static int whiteheat_write_room(struct tty_struct *tty)
-{
-       struct usb_serial_port *port = tty->driver_data;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct list_head *tmp;
-       int room = 0;
-       unsigned long flags;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock_irqsave(&info->lock, flags);
-       list_for_each(tmp, &info->tx_urbs_free)
-               room++;
-       spin_unlock_irqrestore(&info->lock, flags);
-       room *= port->bulk_out_size;
-
-       dbg("%s - returns %d", __func__, room);
-       return (room);
+       stop_command_port(port->serial);
 }
 
 static int whiteheat_tiocmget(struct tty_struct *tty)
@@ -837,7 +561,7 @@ static int whiteheat_ioctl(struct tty_struct *tty,
                serstruct.line = port->serial->minor;
                serstruct.port = port->number;
                serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-               serstruct.xmit_fifo_size = port->bulk_out_size;
+               serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
                serstruct.custom_divisor = 0;
                serstruct.baud_base = 460800;
                serstruct.close_delay = CLOSING_DELAY;
@@ -867,60 +591,6 @@ static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
 }
 
 
-static int whiteheat_chars_in_buffer(struct tty_struct *tty)
-{
-       struct usb_serial_port *port = tty->driver_data;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct list_head *tmp;
-       struct whiteheat_urb_wrap *wrap;
-       int chars = 0;
-       unsigned long flags;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock_irqsave(&info->lock, flags);
-       list_for_each(tmp, &info->tx_urbs_submitted) {
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               chars += wrap->urb->transfer_buffer_length;
-       }
-       spin_unlock_irqrestore(&info->lock, flags);
-
-       dbg("%s - returns %d", __func__, chars);
-       return chars;
-}
-
-
-static void whiteheat_throttle(struct tty_struct *tty)
-{
-       struct usb_serial_port *port = tty->driver_data;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock_irq(&info->lock);
-       info->flags |= THROTTLED;
-       spin_unlock_irq(&info->lock);
-}
-
-
-static void whiteheat_unthrottle(struct tty_struct *tty)
-{
-       struct usb_serial_port *port = tty->driver_data;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       int actually_throttled;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock_irq(&info->lock);
-       actually_throttled = info->flags & ACTUALLY_THROTTLED;
-       info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
-       spin_unlock_irq(&info->lock);
-
-       if (actually_throttled)
-               rx_data_softint(&info->rx_work);
-}
-
-
 /*****************************************************************************
  * Connect Tech's White Heat callback routines
  *****************************************************************************/
@@ -989,80 +659,6 @@ static void command_port_read_callback(struct urb *urb)
 }
 
 
-static void whiteheat_read_callback(struct urb *urb)
-{
-       struct usb_serial_port *port = urb->context;
-       struct whiteheat_urb_wrap *wrap;
-       unsigned char *data = urb->transfer_buffer;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       int status = urb->status;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock(&info->lock);
-       wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
-       if (!wrap) {
-               spin_unlock(&info->lock);
-               dev_err(&port->dev, "%s - Not my urb!\n", __func__);
-               return;
-       }
-       list_del(&wrap->list);
-       spin_unlock(&info->lock);
-
-       if (status) {
-               dbg("%s - nonzero read bulk status received: %d",
-                   __func__, status);
-               spin_lock(&info->lock);
-               list_add(&wrap->list, &info->rx_urbs_free);
-               spin_unlock(&info->lock);
-               return;
-       }
-
-       usb_serial_debug_data(debug, &port->dev,
-                               __func__, urb->actual_length, data);
-
-       spin_lock(&info->lock);
-       list_add_tail(&wrap->list, &info->rx_urb_q);
-       if (info->flags & THROTTLED) {
-               info->flags |= ACTUALLY_THROTTLED;
-               spin_unlock(&info->lock);
-               return;
-       }
-       spin_unlock(&info->lock);
-
-       schedule_work(&info->rx_work);
-}
-
-
-static void whiteheat_write_callback(struct urb *urb)
-{
-       struct usb_serial_port *port = urb->context;
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct whiteheat_urb_wrap *wrap;
-       int status = urb->status;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock(&info->lock);
-       wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
-       if (!wrap) {
-               spin_unlock(&info->lock);
-               dev_err(&port->dev, "%s - Not my urb!\n", __func__);
-               return;
-       }
-       list_move(&wrap->list, &info->tx_urbs_free);
-       spin_unlock(&info->lock);
-
-       if (status) {
-               dbg("%s - nonzero write bulk status received: %d",
-                   __func__, status);
-               return;
-       }
-
-       usb_serial_port_softint(port);
-}
-
-
 /*****************************************************************************
  * Connect Tech's White Heat firmware interface
  *****************************************************************************/
@@ -1337,123 +933,6 @@ static void stop_command_port(struct usb_serial *serial)
        mutex_unlock(&command_info->mutex);
 }
 
-
-static int start_port_read(struct usb_serial_port *port)
-{
-       struct whiteheat_private *info = usb_get_serial_port_data(port);
-       struct whiteheat_urb_wrap *wrap;
-       struct urb *urb;
-       int retval = 0;
-       unsigned long flags;
-       struct list_head *tmp;
-       struct list_head *tmp2;
-
-       spin_lock_irqsave(&info->lock, flags);
-
-       list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
-               list_del(tmp);
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               urb = wrap->urb;
-               spin_unlock_irqrestore(&info->lock, flags);
-               retval = usb_submit_urb(urb, GFP_KERNEL);
-               if (retval) {
-                       spin_lock_irqsave(&info->lock, flags);
-                       list_add(tmp, &info->rx_urbs_free);
-                       list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
-                               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-                               urb = wrap->urb;
-                               list_del(tmp);
-                               spin_unlock_irqrestore(&info->lock, flags);
-                               usb_kill_urb(urb);
-                               spin_lock_irqsave(&info->lock, flags);
-                               list_add(tmp, &info->rx_urbs_free);
-                       }
-                       break;
-               }
-               spin_lock_irqsave(&info->lock, flags);
-               list_add(tmp, &info->rx_urbs_submitted);
-       }
-
-       spin_unlock_irqrestore(&info->lock, flags);
-
-       return retval;
-}
-
-
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
-                                               struct list_head *head)
-{
-       struct whiteheat_urb_wrap *wrap;
-       struct list_head *tmp;
-
-       list_for_each(tmp, head) {
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               if (wrap->urb == urb)
-                       return wrap;
-       }
-
-       return NULL;
-}
-
-
-static struct list_head *list_first(struct list_head *head)
-{
-       return head->next;
-}
-
-
-static void rx_data_softint(struct work_struct *work)
-{
-       struct whiteheat_private *info =
-               container_of(work, struct whiteheat_private, rx_work);
-       struct usb_serial_port *port = info->port;
-       struct tty_struct *tty = tty_port_tty_get(&port->port);
-       struct whiteheat_urb_wrap *wrap;
-       struct urb *urb;
-       unsigned long flags;
-       struct list_head *tmp;
-       struct list_head *tmp2;
-       int result;
-       int sent = 0;
-
-       spin_lock_irqsave(&info->lock, flags);
-       if (info->flags & THROTTLED) {
-               spin_unlock_irqrestore(&info->lock, flags);
-               goto out;
-       }
-
-       list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
-               list_del(tmp);
-               spin_unlock_irqrestore(&info->lock, flags);
-
-               wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-               urb = wrap->urb;
-
-               if (tty && urb->actual_length)
-                       sent += tty_insert_flip_string(tty,
-                               urb->transfer_buffer, urb->actual_length);
-
-               result = usb_submit_urb(urb, GFP_ATOMIC);
-               if (result) {
-                       dev_err(&port->dev,
-                               "%s - failed resubmitting read urb, error %d\n",
-                               __func__, result);
-                       spin_lock_irqsave(&info->lock, flags);
-                       list_add(tmp, &info->rx_urbs_free);
-                       continue;
-               }
-
-               spin_lock_irqsave(&info->lock, flags);
-               list_add(tmp, &info->rx_urbs_submitted);
-       }
-       spin_unlock_irqrestore(&info->lock, flags);
-
-       if (sent)
-               tty_flip_buffer_push(tty);
-out:
-       tty_kref_put(tty);
-}
-
 module_usb_serial_driver(whiteheat_driver, serial_drivers);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -1463,8 +942,5 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("whiteheat.fw");
 MODULE_FIRMWARE("whiteheat_loader.fw");
 
-module_param(urb_pool_size, int, 0);
-MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
-
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
index e7e6781..b28f2ad 100644 (file)
@@ -1933,11 +1933,7 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag)
        kfree(buf);
 
 nofw:
-       if (sd_fw != NULL) {
-               release_firmware(sd_fw);
-               sd_fw = NULL;
-       }
-
+       release_firmware(sd_fw);
        return result;
 }
 
index 5af9a07..98bb290 100644 (file)
@@ -139,6 +139,7 @@ struct bcma_device {
        u8 core_unit;
 
        u32 addr;
+       u32 addr1;
        u32 wrap;
 
        void __iomem *io_addr;
index fffdf00..15be561 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2012 Freescale Semiconductor, Inc
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
 #ifndef _FSL_DEVICE_H_
 #define _FSL_DEVICE_H_
 
+#define FSL_UTMI_PHY_DLY       10      /*As per P1010RM, delay for UTMI
+                               PHY CLK to become stable - 10ms*/
+#define FSL_USB_VER_OLD                0
+#define FSL_USB_VER_1_6                1
+#define FSL_USB_VER_2_2                2
+
 #include <linux/types.h>
 
 /*
@@ -63,6 +69,7 @@ struct platform_device;
 
 struct fsl_usb2_platform_data {
        /* board specific information */
+       int                             controller_ver;
        enum fsl_usb2_operating_modes   operating_mode;
        enum fsl_usb2_phy_modes         phy_mode;
        unsigned int                    port_enables;
diff --git a/include/linux/platform_data/ehci-sh.h b/include/linux/platform_data/ehci-sh.h
new file mode 100644 (file)
index 0000000..5c15a73
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * EHCI SuperH driver platform data
+ *
+ * Copyright (C) 2012  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ * Copyright (C) 2012  Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __USB_EHCI_SH_H
+#define __USB_EHCI_SH_H
+
+struct ehci_sh_platdata {
+       void (*phy_init)(void); /* Phy init function */
+};
+
+#endif /* __USB_EHCI_SH_H */
index 73b68d1..22e9b32 100644 (file)
@@ -1627,6 +1627,7 @@ static inline int usb_translate_errors(int error_code)
        case 0:
        case -ENOMEM:
        case -ENODEV:
+       case -EOPNOTSUPP:
                return error_code;
        default:
                return -EIO;