Merge tag 'usb-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman: "Here's the big set of USB patches for 3.8-rc1. Lots of USB host driver cleanups in here, and a bit of a reorg of the EHCI driver to make it easier for the different EHCI platform drivers to all work together nicer, which was a reduction in overall code. We also deleted some unused firmware files, and got rid of the very old file_storage usb gadget driver that had been broken for a long time. This means we ended up removing way more code than added, always a nice thing to see: 310 files changed, 3028 insertions(+), 10754 deletions(-) Other than that, the usual set of new device ids, driver fixes, gadget driver and controller updates and the like. All of these have been in the linux-next tree for a number of weeks. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'usb-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (228 commits) USB: mark uas driver as BROKEN xhci: Add Lynx Point LP to list of Intel switchable hosts uwb: fix uwb_dev_unlock() missed at an error path in uwb_rc_cmd_async() USB: ftdi_sio: Add support for Newport AGILIS motor drivers MAINTAINERS: remove drivers/block/ub.c USB: chipidea: fix use after free bug ezusb: add dependency to USB usb: ftdi_sio: fixup BeagleBone A5+ quirk USB: cp210x: add Virtenio Preon32 device id usb: storage: remove redundant memset() in usb_probe_stor1() USB: option: blacklist network interface on Huawei E173 USB: OHCI: workaround for hardware bug: retired TDs not added to the Done Queue USB: add new zte 3g-dongle's pid to option.c USB: opticon: switch to generic read implementation USB: opticon: refactor reab-urb processing USB: opticon: use usb-serial bulk-in urb USB: opticon: increase bulk-in size USB: opticon: use port as urb context USB: opticon: pass port to get_serial_info USB: opticon: make private data port specific ...
This commit is contained in:
@@ -671,7 +671,7 @@ than a kernel driver.
|
|||||||
<para>There's a USB Mass Storage class driver, which provides
|
<para>There's a USB Mass Storage class driver, which provides
|
||||||
a different solution for interoperability with systems such
|
a different solution for interoperability with systems such
|
||||||
as MS-Windows and MacOS.
|
as MS-Windows and MacOS.
|
||||||
That <emphasis>File-backed Storage</emphasis> driver uses a
|
That <emphasis>Mass Storage</emphasis> driver uses a
|
||||||
file or block device as backing store for a drive,
|
file or block device as backing store for a drive,
|
||||||
like the <filename>loop</filename> driver.
|
like the <filename>loop</filename> driver.
|
||||||
The USB host uses the BBB, CB, or CBI versions of the mass
|
The USB host uses the BBB, CB, or CBI versions of the mass
|
||||||
|
@@ -2561,9 +2561,6 @@ Your cooperation is appreciated.
|
|||||||
192 = /dev/usb/yurex1 First USB Yurex device
|
192 = /dev/usb/yurex1 First USB Yurex device
|
||||||
...
|
...
|
||||||
209 = /dev/usb/yurex16 16th USB Yurex device
|
209 = /dev/usb/yurex16 16th USB Yurex device
|
||||||
240 = /dev/usb/dabusb0 First daubusb device
|
|
||||||
...
|
|
||||||
243 = /dev/usb/dabusb3 Fourth dabusb device
|
|
||||||
|
|
||||||
180 block USB block devices
|
180 block USB block devices
|
||||||
0 = /dev/uba First USB block device
|
0 = /dev/uba First USB block device
|
||||||
|
@@ -3,12 +3,12 @@ AM33XX MUSB GLUE
|
|||||||
- ti,hwmods : must be "usb_otg_hs"
|
- ti,hwmods : must be "usb_otg_hs"
|
||||||
- multipoint : Should be "1" indicating the musb controller supports
|
- multipoint : Should be "1" indicating the musb controller supports
|
||||||
multipoint. This is a MUSB configuration-specific setting.
|
multipoint. This is a MUSB configuration-specific setting.
|
||||||
- num_eps : Specifies the number of endpoints. This is also a
|
- num-eps : Specifies the number of endpoints. This is also a
|
||||||
MUSB configuration-specific setting. Should be set to "16"
|
MUSB configuration-specific setting. Should be set to "16"
|
||||||
- ram_bits : Specifies the ram address size. Should be set to "12"
|
- ram-bits : Specifies the ram address size. Should be set to "12"
|
||||||
- port0_mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
|
- port0-mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
|
||||||
represents PERIPHERAL.
|
represents PERIPHERAL.
|
||||||
- port1_mode : Should be "1" to represent HOST. "3" signifies OTG and "2"
|
- port1-mode : Should be "1" to represent HOST. "3" signifies OTG and "2"
|
||||||
represents PERIPHERAL.
|
represents PERIPHERAL.
|
||||||
- power : Should be "250". This signifies the controller can supply upto
|
- power : Should be "250". This signifies the controller can supply upto
|
||||||
500mA when operating in host mode.
|
500mA when operating in host mode.
|
||||||
|
@@ -21,6 +21,8 @@ Non-USB-specific:
|
|||||||
|
|
||||||
USB-specific:
|
USB-specific:
|
||||||
|
|
||||||
|
-EBUSY The URB is already active.
|
||||||
|
|
||||||
-ENODEV specified USB-device or bus doesn't exist
|
-ENODEV specified USB-device or bus doesn't exist
|
||||||
|
|
||||||
-ENOENT specified interface or endpoint does not exist or
|
-ENOENT specified interface or endpoint does not exist or
|
||||||
@@ -35,9 +37,8 @@ USB-specific:
|
|||||||
d) ISO: number_of_packets is < 0
|
d) ISO: number_of_packets is < 0
|
||||||
e) various other cases
|
e) various other cases
|
||||||
|
|
||||||
-EAGAIN a) specified ISO start frame too early
|
-EXDEV ISO: URB_ISO_ASAP wasn't specified and all the frames
|
||||||
b) (using ISO-ASAP) too much scheduled for the future
|
the URB would be scheduled in have already expired.
|
||||||
wait some time and try again.
|
|
||||||
|
|
||||||
-EFBIG Host controller driver can't schedule that many ISO frames.
|
-EFBIG Host controller driver can't schedule that many ISO frames.
|
||||||
|
|
||||||
|
@@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
This document describes how to use the gadget from user space, its
|
This document describes how to use the gadget from user space, its
|
||||||
relation to mass storage function (or MSF) and different gadgets
|
relation to mass storage function (or MSF) and different gadgets
|
||||||
using it, and how it differs from File Storage Gadget (or FSG). It
|
using it, and how it differs from File Storage Gadget (or FSG)
|
||||||
will talk only briefly about how to use MSF within composite
|
(which is no longer included in Linux). It will talk only briefly
|
||||||
gadgets.
|
about how to use MSF within composite gadgets.
|
||||||
|
|
||||||
* Module parameters
|
* Module parameters
|
||||||
|
|
||||||
@@ -198,16 +198,15 @@
|
|||||||
The Mass Storage Function and thus the Mass Storage Gadget has been
|
The Mass Storage Function and thus the Mass Storage Gadget has been
|
||||||
based on the File Storage Gadget. The difference between the two is
|
based on the File Storage Gadget. The difference between the two is
|
||||||
that MSG is a composite gadget (ie. uses the composite framework)
|
that MSG is a composite gadget (ie. uses the composite framework)
|
||||||
while file storage gadget is a traditional gadget. From userspace
|
while file storage gadget was a traditional gadget. From userspace
|
||||||
point of view this distinction does not really matter, but from
|
point of view this distinction does not really matter, but from
|
||||||
kernel hacker's point of view, this means that (i) MSG does not
|
kernel hacker's point of view, this means that (i) MSG does not
|
||||||
duplicate code needed for handling basic USB protocol commands and
|
duplicate code needed for handling basic USB protocol commands and
|
||||||
(ii) MSF can be used in any other composite gadget.
|
(ii) MSF can be used in any other composite gadget.
|
||||||
|
|
||||||
Because of that, File Storage Gadget has been deprecated and
|
Because of that, File Storage Gadget has been removed in Linux 3.8.
|
||||||
scheduled to be removed in Linux 3.8. All users need to transition
|
All users need to transition to the Mass Storage Gadget. The two
|
||||||
to the Mass Storage Gadget by that time. The two gadgets behave
|
gadgets behave mostly the same from the outside except:
|
||||||
mostly the same from the outside except:
|
|
||||||
|
|
||||||
1. In FSG the “removable” and “cdrom” module parameters set the flag
|
1. In FSG the “removable” and “cdrom” module parameters set the flag
|
||||||
for all logical units whereas in MSG they accept a list of y/n
|
for all logical units whereas in MSG they accept a list of y/n
|
||||||
|
@@ -7587,12 +7587,6 @@ L: linux-scsi@vger.kernel.org
|
|||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/usb/storage/uas.c
|
F: drivers/usb/storage/uas.c
|
||||||
|
|
||||||
USB BLOCK DRIVER (UB ub)
|
|
||||||
M: Pete Zaitcev <zaitcev@redhat.com>
|
|
||||||
L: linux-usb@vger.kernel.org
|
|
||||||
S: Supported
|
|
||||||
F: drivers/block/ub.c
|
|
||||||
|
|
||||||
USB CDC ETHERNET DRIVER
|
USB CDC ETHERNET DRIVER
|
||||||
M: Oliver Neukum <oliver@neukum.org>
|
M: Oliver Neukum <oliver@neukum.org>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
|
@@ -79,7 +79,7 @@ CONFIG_USB_STORAGE=y
|
|||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_RTC_CLASS=y
|
CONFIG_RTC_CLASS=y
|
||||||
CONFIG_RTC_DEBUG=y
|
CONFIG_RTC_DEBUG=y
|
||||||
|
@@ -75,7 +75,7 @@ CONFIG_USB_STORAGE_DEBUG=y
|
|||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_RTC_CLASS=y
|
CONFIG_RTC_CLASS=y
|
||||||
CONFIG_RTC_DRV_AT91SAM9=y
|
CONFIG_RTC_DRV_AT91SAM9=y
|
||||||
|
@@ -125,7 +125,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_ATMELMCI=m
|
CONFIG_MMC_ATMELMCI=m
|
||||||
|
@@ -133,7 +133,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_SDIO_UART=m
|
CONFIG_SDIO_UART=m
|
||||||
|
@@ -96,7 +96,7 @@ CONFIG_USB_STORAGE=y
|
|||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_ATMELMCI=m
|
CONFIG_MMC_ATMELMCI=m
|
||||||
|
@@ -218,7 +218,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_PXA=y
|
CONFIG_MMC_PXA=y
|
||||||
|
@@ -144,7 +144,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
|
@@ -34,8 +34,7 @@ CONFIG_FB_MODE_HELPERS=y
|
|||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_FILE_STORAGE_TEST=y
|
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_EXT2_FS=y
|
CONFIG_EXT2_FS=y
|
||||||
CONFIG_TMPFS=y
|
CONFIG_TMPFS=y
|
||||||
|
@@ -136,7 +136,7 @@ CONFIG_USB_PXA27X=y
|
|||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
# CONFIG_USB_ETH_RNDIS is not set
|
# CONFIG_USB_ETH_RNDIS is not set
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_USB_GPIO_VBUS=y
|
CONFIG_USB_GPIO_VBUS=y
|
||||||
|
@@ -240,7 +240,7 @@ CONFIG_USB_GADGET_S3C2410=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -214,8 +214,7 @@ CONFIG_USB_TEST=y
|
|||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
# CONFIG_USB_ETH_RNDIS is not set
|
# CONFIG_USB_ETH_RNDIS is not set
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_FILE_STORAGE_TEST=y
|
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_MMC_SDHCI_PLTFM=y
|
CONFIG_MMC_SDHCI_PLTFM=y
|
||||||
|
@@ -37,7 +37,6 @@ CONFIG_SPI_SIRF=y
|
|||||||
CONFIG_SPI_SPIDEV=y
|
CONFIG_SPI_SPIDEV=y
|
||||||
# CONFIG_HWMON is not set
|
# CONFIG_HWMON is not set
|
||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
|
||||||
CONFIG_USB_MASS_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
|
@@ -214,7 +214,7 @@ CONFIG_USB_GADGET_DUMMY_HCD=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_PXA=y
|
CONFIG_MMC_PXA=y
|
||||||
|
@@ -97,7 +97,7 @@ CONFIG_USB_STORAGE=y
|
|||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_ATMELMCI=y
|
CONFIG_MMC_ATMELMCI=y
|
||||||
|
@@ -139,7 +139,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
|
|||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_RTC_CLASS=y
|
CONFIG_RTC_CLASS=y
|
||||||
|
@@ -143,7 +143,7 @@ CONFIG_USB_GADGET=m
|
|||||||
CONFIG_USB_PXA27X=y
|
CONFIG_USB_PXA27X=y
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/usb/ehci_pdriver.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/hardware/gic.h>
|
#include <asm/hardware/gic.h>
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
#include <mach/cns3xxx.h>
|
#include <mach/cns3xxx.h>
|
||||||
#include <mach/irqs.h>
|
#include <mach/irqs.h>
|
||||||
|
#include <mach/pm.h>
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
|
||||||
@@ -125,13 +128,52 @@ static struct resource cns3xxx_usb_ehci_resources[] = {
|
|||||||
|
|
||||||
static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
|
static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static int csn3xxx_usb_power_on(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* EHCI and OHCI share the same clock and power,
|
||||||
|
* resetting twice would cause the 1st controller been reset.
|
||||||
|
* Therefore only do power up at the first up device, and
|
||||||
|
* power down at the last down device.
|
||||||
|
*
|
||||||
|
* Set USB AHB INCR length to 16
|
||||||
|
*/
|
||||||
|
if (atomic_inc_return(&usb_pwr_ref) == 1) {
|
||||||
|
cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
|
||||||
|
cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
|
||||||
|
cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
|
||||||
|
__raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
|
||||||
|
MISC_CHIP_CONFIG_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csn3xxx_usb_power_off(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* EHCI and OHCI share the same clock and power,
|
||||||
|
* resetting twice would cause the 1st controller been reset.
|
||||||
|
* Therefore only do power up at the first up device, and
|
||||||
|
* power down at the last down device.
|
||||||
|
*/
|
||||||
|
if (atomic_dec_return(&usb_pwr_ref) == 0)
|
||||||
|
cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
|
||||||
|
.power_on = csn3xxx_usb_power_on,
|
||||||
|
.power_off = csn3xxx_usb_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device cns3xxx_usb_ehci_device = {
|
static struct platform_device cns3xxx_usb_ehci_device = {
|
||||||
.name = "cns3xxx-ehci",
|
.name = "ehci-platform",
|
||||||
.num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
|
.num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
|
||||||
.resource = cns3xxx_usb_ehci_resources,
|
.resource = cns3xxx_usb_ehci_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &cns3xxx_usb_ehci_dma_mask,
|
.dma_mask = &cns3xxx_usb_ehci_dma_mask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &cns3xxx_usb_ehci_pdata,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,13 +191,20 @@ static struct resource cns3xxx_usb_ohci_resources[] = {
|
|||||||
|
|
||||||
static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
|
static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
|
||||||
|
.num_ports = 1,
|
||||||
|
.power_on = csn3xxx_usb_power_on,
|
||||||
|
.power_off = csn3xxx_usb_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device cns3xxx_usb_ohci_device = {
|
static struct platform_device cns3xxx_usb_ohci_device = {
|
||||||
.name = "cns3xxx-ohci",
|
.name = "ohci-platform",
|
||||||
.num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
|
||||||
.resource = cns3xxx_usb_ohci_resources,
|
.resource = cns3xxx_usb_ohci_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &cns3xxx_usb_ohci_dma_mask,
|
.dma_mask = &cns3xxx_usb_ohci_dma_mask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &cns3xxx_usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -109,7 +109,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -125,7 +125,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -124,7 +124,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -99,7 +99,7 @@ CONFIG_SND_ATMEL_AC97C=m
|
|||||||
# CONFIG_SND_SPI is not set
|
# CONFIG_SND_SPI is not set
|
||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_GADGET_DEBUG_FILES=y
|
CONFIG_USB_GADGET_DEBUG_FILES=y
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_ATMELMCI=y
|
CONFIG_MMC_ATMELMCI=y
|
||||||
|
@@ -111,7 +111,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -128,7 +128,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -127,7 +127,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -126,7 +126,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -105,7 +105,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -104,7 +104,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -129,7 +129,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -117,7 +117,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_CDC_COMPOSITE=m
|
CONFIG_USB_CDC_COMPOSITE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -127,7 +127,7 @@ CONFIG_USB_GADGET=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=m
|
CONFIG_MMC=m
|
||||||
CONFIG_MMC_ATMELMCI=m
|
CONFIG_MMC_ATMELMCI=m
|
||||||
|
@@ -106,7 +106,7 @@ CONFIG_MUSB_PIO_ONLY=y
|
|||||||
CONFIG_USB_STORAGE=m
|
CONFIG_USB_STORAGE=m
|
||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_RTC_CLASS=y
|
CONFIG_RTC_CLASS=y
|
||||||
|
@@ -107,7 +107,7 @@ CONFIG_USB_ZERO=m
|
|||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
# CONFIG_USB_ETH_RNDIS is not set
|
# CONFIG_USB_ETH_RNDIS is not set
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_MMC=m
|
CONFIG_MMC=m
|
||||||
|
@@ -83,7 +83,7 @@ CONFIG_GPIOLIB=y
|
|||||||
CONFIG_GPIO_SYSFS=y
|
CONFIG_GPIO_SYSFS=y
|
||||||
CONFIG_USB_GADGET=m
|
CONFIG_USB_GADGET=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_G_PRINTER=m
|
CONFIG_USB_G_PRINTER=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
|
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
|
||||||
sleeper.o dma.o dbdma.o vss.o irq.o
|
sleeper.o dma.o dbdma.o vss.o irq.o usb.o
|
||||||
|
|
||||||
# optional gpiolib support
|
# optional gpiolib support
|
||||||
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
|
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/usb/ehci_pdriver.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
|
|
||||||
#include <asm/mach-au1x00/au1000.h>
|
#include <asm/mach-au1x00/au1000.h>
|
||||||
#include <asm/mach-au1x00/au1xxx_dbdma.h>
|
#include <asm/mach-au1x00/au1xxx_dbdma.h>
|
||||||
@@ -122,6 +124,53 @@ static void __init alchemy_setup_uarts(int ctype)
|
|||||||
static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
|
static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
|
||||||
static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
|
static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
/* Power on callback for the ehci platform driver */
|
||||||
|
static int alchemy_ehci_power_on(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Power off/suspend callback for the ehci platform driver */
|
||||||
|
static void alchemy_ehci_power_off(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_ehci_pdata alchemy_ehci_pdata = {
|
||||||
|
.no_io_watchdog = 1,
|
||||||
|
.power_on = alchemy_ehci_power_on,
|
||||||
|
.power_off = alchemy_ehci_power_off,
|
||||||
|
.power_suspend = alchemy_ehci_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Power on callback for the ohci platform driver */
|
||||||
|
static int alchemy_ohci_power_on(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
unit = (pdev->id == 1) ?
|
||||||
|
ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
|
||||||
|
|
||||||
|
return alchemy_usb_control(unit, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Power off/suspend callback for the ohci platform driver */
|
||||||
|
static void alchemy_ohci_power_off(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
unit = (pdev->id == 1) ?
|
||||||
|
ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
|
||||||
|
|
||||||
|
alchemy_usb_control(unit, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata alchemy_ohci_pdata = {
|
||||||
|
.power_on = alchemy_ohci_power_on,
|
||||||
|
.power_off = alchemy_ohci_power_off,
|
||||||
|
.power_suspend = alchemy_ohci_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
static unsigned long alchemy_ohci_data[][2] __initdata = {
|
static unsigned long alchemy_ohci_data[][2] __initdata = {
|
||||||
[ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
|
[ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
|
||||||
[ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
|
[ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
|
||||||
@@ -169,9 +218,10 @@ static void __init alchemy_setup_usb(int ctype)
|
|||||||
res[1].start = alchemy_ohci_data[ctype][1];
|
res[1].start = alchemy_ohci_data[ctype][1];
|
||||||
res[1].end = res[1].start;
|
res[1].end = res[1].start;
|
||||||
res[1].flags = IORESOURCE_IRQ;
|
res[1].flags = IORESOURCE_IRQ;
|
||||||
pdev->name = "au1xxx-ohci";
|
pdev->name = "ohci-platform";
|
||||||
pdev->id = 0;
|
pdev->id = 0;
|
||||||
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
|
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
|
||||||
|
pdev->dev.platform_data = &alchemy_ohci_pdata;
|
||||||
|
|
||||||
if (platform_device_register(pdev))
|
if (platform_device_register(pdev))
|
||||||
printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
|
printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
|
||||||
@@ -188,9 +238,10 @@ static void __init alchemy_setup_usb(int ctype)
|
|||||||
res[1].start = alchemy_ehci_data[ctype][1];
|
res[1].start = alchemy_ehci_data[ctype][1];
|
||||||
res[1].end = res[1].start;
|
res[1].end = res[1].start;
|
||||||
res[1].flags = IORESOURCE_IRQ;
|
res[1].flags = IORESOURCE_IRQ;
|
||||||
pdev->name = "au1xxx-ehci";
|
pdev->name = "ehci-platform";
|
||||||
pdev->id = 0;
|
pdev->id = 0;
|
||||||
pdev->dev.dma_mask = &alchemy_ehci_dmamask;
|
pdev->dev.dma_mask = &alchemy_ehci_dmamask;
|
||||||
|
pdev->dev.platform_data = &alchemy_ehci_pdata;
|
||||||
|
|
||||||
if (platform_device_register(pdev))
|
if (platform_device_register(pdev))
|
||||||
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
|
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
|
||||||
@@ -207,9 +258,10 @@ static void __init alchemy_setup_usb(int ctype)
|
|||||||
res[1].start = AU1300_USB_INT;
|
res[1].start = AU1300_USB_INT;
|
||||||
res[1].end = res[1].start;
|
res[1].end = res[1].start;
|
||||||
res[1].flags = IORESOURCE_IRQ;
|
res[1].flags = IORESOURCE_IRQ;
|
||||||
pdev->name = "au1xxx-ohci";
|
pdev->name = "ohci-platform";
|
||||||
pdev->id = 1;
|
pdev->id = 1;
|
||||||
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
|
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
|
||||||
|
pdev->dev.platform_data = &alchemy_ohci_pdata;
|
||||||
|
|
||||||
if (platform_device_register(pdev))
|
if (platform_device_register(pdev))
|
||||||
printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
|
printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
|
||||||
|
@@ -50,13 +50,11 @@ static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
|
|||||||
|
|
||||||
static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
|
static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
|
||||||
.has_synopsys_hc_bug = 1,
|
.has_synopsys_hc_bug = 1,
|
||||||
.port_power_off = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
|
static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
|
||||||
.caps_offset = 0x100,
|
.caps_offset = 0x100,
|
||||||
.has_tt = 1,
|
.has_tt = 1,
|
||||||
.port_power_off = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device ath79_ehci_device = {
|
static struct platform_device ath79_ehci_device = {
|
||||||
|
@@ -473,7 +473,7 @@ CONFIG_USB_GADGET_NET2280=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_MIDI_GADGET=m
|
CONFIG_USB_MIDI_GADGET=m
|
||||||
CONFIG_LEDS_CLASS=y
|
CONFIG_LEDS_CLASS=y
|
||||||
|
@@ -233,6 +233,7 @@ CONFIG_USB_EHCI_HCD=y
|
|||||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
CONFIG_USB_EHCI_TT_NEWSCHED=y
|
CONFIG_USB_EHCI_TT_NEWSCHED=y
|
||||||
CONFIG_USB_OHCI_HCD=y
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||||
CONFIG_USB_UHCI_HCD=y
|
CONFIG_USB_UHCI_HCD=y
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
CONFIG_NEW_LEDS=y
|
CONFIG_NEW_LEDS=y
|
||||||
|
@@ -346,8 +346,10 @@ CONFIG_USB=y
|
|||||||
CONFIG_USB_DYNAMIC_MINORS=y
|
CONFIG_USB_DYNAMIC_MINORS=y
|
||||||
CONFIG_USB_SUSPEND=y
|
CONFIG_USB_SUSPEND=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
CONFIG_USB_OHCI_HCD=y
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_CLKGATE=y
|
CONFIG_MMC_CLKGATE=y
|
||||||
|
@@ -291,6 +291,7 @@ CONFIG_USB_MON=y
|
|||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
CONFIG_USB_OHCI_HCD=y
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||||
CONFIG_USB_STORAGE=m
|
CONFIG_USB_STORAGE=m
|
||||||
CONFIG_USB_LIBUSUAL=y
|
CONFIG_USB_LIBUSUAL=y
|
||||||
CONFIG_USB_SERIAL=y
|
CONFIG_USB_SERIAL=y
|
||||||
|
@@ -76,6 +76,7 @@ CONFIG_HID_GENERIC=m
|
|||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||||
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
|
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
|
||||||
CONFIG_USB_STORAGE=m
|
CONFIG_USB_STORAGE=m
|
||||||
CONFIG_USB_SERIAL=m
|
CONFIG_USB_SERIAL=m
|
||||||
|
@@ -581,6 +581,7 @@ CONFIG_USB_MON=m
|
|||||||
CONFIG_USB_EHCI_HCD=m
|
CONFIG_USB_EHCI_HCD=m
|
||||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
CONFIG_USB_OHCI_HCD=m
|
CONFIG_USB_OHCI_HCD=m
|
||||||
|
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||||
CONFIG_USB_UHCI_HCD=m
|
CONFIG_USB_UHCI_HCD=m
|
||||||
CONFIG_USB_U132_HCD=m
|
CONFIG_USB_U132_HCD=m
|
||||||
CONFIG_USB_SL811_HCD=m
|
CONFIG_USB_SL811_HCD=m
|
||||||
@@ -661,7 +662,7 @@ CONFIG_USB_GADGET_NET2280=y
|
|||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_USB_MIDI_GADGET=m
|
CONFIG_USB_MIDI_GADGET=m
|
||||||
CONFIG_MMC=m
|
CONFIG_MMC=m
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <linux/stmmac.h>
|
#include <linux/stmmac.h>
|
||||||
|
#include <linux/usb/ehci_pdriver.h>
|
||||||
#include <asm-generic/sizes.h>
|
#include <asm-generic/sizes.h>
|
||||||
|
|
||||||
#include <loongson1.h>
|
#include <loongson1.h>
|
||||||
@@ -107,13 +108,17 @@ static struct resource ls1x_ehci_resources[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct usb_ehci_pdata ls1x_ehci_pdata = {
|
||||||
|
};
|
||||||
|
|
||||||
struct platform_device ls1x_ehci_device = {
|
struct platform_device ls1x_ehci_device = {
|
||||||
.name = "ls1x-ehci",
|
.name = "ehci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.num_resources = ARRAY_SIZE(ls1x_ehci_resources),
|
.num_resources = ARRAY_SIZE(ls1x_ehci_resources),
|
||||||
.resource = ls1x_ehci_resources,
|
.resource = ls1x_ehci_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &ls1x_ehci_dmamask,
|
.dma_mask = &ls1x_ehci_dmamask,
|
||||||
|
.platform_data = &ls1x_ehci_pdata,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <linux/serial_reg.h>
|
#include <linux/serial_reg.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/usb/ehci_pdriver.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
|
|
||||||
#include <asm/netlogic/haldefs.h>
|
#include <asm/netlogic/haldefs.h>
|
||||||
#include <asm/netlogic/xlr/iomap.h>
|
#include <asm/netlogic/xlr/iomap.h>
|
||||||
@@ -123,12 +125,18 @@ static u64 xls_usb_dmamask = ~(u32)0;
|
|||||||
}, \
|
}, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct usb_ehci_pdata xls_usb_ehci_pdata = {
|
||||||
|
.caps_offset = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata xls_usb_ohci_pdata;
|
||||||
|
|
||||||
static struct platform_device xls_usb_ehci_device =
|
static struct platform_device xls_usb_ehci_device =
|
||||||
USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ);
|
USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
|
||||||
static struct platform_device xls_usb_ohci_device_0 =
|
static struct platform_device xls_usb_ohci_device_0 =
|
||||||
USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ);
|
USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
|
||||||
static struct platform_device xls_usb_ohci_device_1 =
|
static struct platform_device xls_usb_ohci_device_1 =
|
||||||
USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ);
|
USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);
|
||||||
|
|
||||||
static struct platform_device *xls_platform_devices[] = {
|
static struct platform_device *xls_platform_devices[] = {
|
||||||
&xls_usb_ehci_device,
|
&xls_usb_ehci_device,
|
||||||
@@ -172,14 +180,17 @@ int xls_platform_usb_init(void)
|
|||||||
memres = CPHYSADDR((unsigned long)usb_mmio);
|
memres = CPHYSADDR((unsigned long)usb_mmio);
|
||||||
xls_usb_ehci_device.resource[0].start = memres;
|
xls_usb_ehci_device.resource[0].start = memres;
|
||||||
xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
|
xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
|
||||||
|
xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;
|
||||||
|
|
||||||
memres += 0x400;
|
memres += 0x400;
|
||||||
xls_usb_ohci_device_0.resource[0].start = memres;
|
xls_usb_ohci_device_0.resource[0].start = memres;
|
||||||
xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
|
xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
|
||||||
|
xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;
|
||||||
|
|
||||||
memres += 0x400;
|
memres += 0x400;
|
||||||
xls_usb_ohci_device_1.resource[0].start = memres;
|
xls_usb_ohci_device_1.resource[0].start = memres;
|
||||||
xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
|
xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
|
||||||
|
xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;
|
||||||
|
|
||||||
return platform_add_devices(xls_platform_devices,
|
return platform_add_devices(xls_platform_devices,
|
||||||
ARRAY_SIZE(xls_platform_devices));
|
ARRAY_SIZE(xls_platform_devices));
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
#include <linux/serial_pnx8xxx.h>
|
#include <linux/serial_pnx8xxx.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
|
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
@@ -96,12 +97,40 @@ static u64 ohci_dmamask = DMA_BIT_MASK(32);
|
|||||||
|
|
||||||
static u64 uart_dmamask = DMA_BIT_MASK(32);
|
static u64 uart_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static int pnx8550_usb_ohci_power_on(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set register CLK48CTL to enable and 48MHz
|
||||||
|
*/
|
||||||
|
outl(0x00000003, PCI_BASE | 0x0004770c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set register CLK12CTL to enable and 48MHz
|
||||||
|
*/
|
||||||
|
outl(0x00000003, PCI_BASE | 0x00047710);
|
||||||
|
|
||||||
|
udelay(100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pnx8550_usb_ohci_power_off(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = {
|
||||||
|
.power_on = pnx8550_usb_ohci_power_on,
|
||||||
|
.power_off = pnx8550_usb_ohci_power_off,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device pnx8550_usb_ohci_device = {
|
static struct platform_device pnx8550_usb_ohci_device = {
|
||||||
.name = "pnx8550-ohci",
|
.name = "ohci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &ohci_dmamask,
|
.dma_mask = &ohci_dmamask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &pnx8550_usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
|
||||||
.resource = pnx8550_usb_ohci_resources,
|
.resource = pnx8550_usb_ohci_resources,
|
||||||
|
@@ -112,7 +112,7 @@ CONFIG_USB_MON=y
|
|||||||
CONFIG_USB_R8A66597_HCD=y
|
CONFIG_USB_R8A66597_HCD=y
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_SPI=y
|
CONFIG_MMC_SPI=y
|
||||||
CONFIG_MMC_SDHI=y
|
CONFIG_MMC_SDHI=y
|
||||||
|
@@ -109,7 +109,7 @@ CONFIG_USB_STORAGE=y
|
|||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_GADGETFS=m
|
CONFIG_USB_GADGETFS=m
|
||||||
CONFIG_USB_FILE_STORAGE=m
|
CONFIG_USB_MASS_STORAGE=m
|
||||||
CONFIG_USB_G_SERIAL=m
|
CONFIG_USB_G_SERIAL=m
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
CONFIG_MMC_SPI=y
|
CONFIG_MMC_SPI=y
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <linux/serial_sci.h>
|
#include <linux/serial_sci.h>
|
||||||
#include <linux/sh_timer.h>
|
#include <linux/sh_timer.h>
|
||||||
#include <linux/sh_intc.h>
|
#include <linux/sh_intc.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
#include <asm/rtc.h>
|
#include <asm/rtc.h>
|
||||||
#include <cpu/serial.h>
|
#include <cpu/serial.h>
|
||||||
|
|
||||||
@@ -103,12 +104,15 @@ static struct resource usb_ohci_resources[] = {
|
|||||||
|
|
||||||
static u64 usb_ohci_dma_mask = 0xffffffffUL;
|
static u64 usb_ohci_dma_mask = 0xffffffffUL;
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata usb_ohci_pdata;
|
||||||
|
|
||||||
static struct platform_device usb_ohci_device = {
|
static struct platform_device usb_ohci_device = {
|
||||||
.name = "sh_ohci",
|
.name = "ohci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &usb_ohci_dma_mask,
|
.dma_mask = &usb_ohci_dma_mask,
|
||||||
.coherent_dma_mask = 0xffffffff,
|
.coherent_dma_mask = 0xffffffff,
|
||||||
|
.platform_data = &usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
||||||
.resource = usb_ohci_resources,
|
.resource = usb_ohci_resources,
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <linux/sh_timer.h>
|
#include <linux/sh_timer.h>
|
||||||
#include <linux/sh_dma.h>
|
#include <linux/sh_dma.h>
|
||||||
#include <linux/sh_intc.h>
|
#include <linux/sh_intc.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
#include <cpu/dma-register.h>
|
#include <cpu/dma-register.h>
|
||||||
#include <cpu/sh7757.h>
|
#include <cpu/sh7757.h>
|
||||||
|
|
||||||
@@ -750,12 +751,15 @@ static struct resource usb_ohci_resources[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata usb_ohci_pdata;
|
||||||
|
|
||||||
static struct platform_device usb_ohci_device = {
|
static struct platform_device usb_ohci_device = {
|
||||||
.name = "sh_ohci",
|
.name = "ohci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
|
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
||||||
.resource = usb_ohci_resources,
|
.resource = usb_ohci_resources,
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include <linux/sh_intc.h>
|
#include <linux/sh_intc.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/serial_sci.h>
|
#include <linux/serial_sci.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
|
|
||||||
static struct plat_sci_port scif0_platform_data = {
|
static struct plat_sci_port scif0_platform_data = {
|
||||||
.mapbase = 0xffe00000,
|
.mapbase = 0xffe00000,
|
||||||
@@ -106,12 +107,15 @@ static struct resource usb_ohci_resources[] = {
|
|||||||
|
|
||||||
static u64 usb_ohci_dma_mask = 0xffffffffUL;
|
static u64 usb_ohci_dma_mask = 0xffffffffUL;
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata usb_ohci_pdata;
|
||||||
|
|
||||||
static struct platform_device usb_ohci_device = {
|
static struct platform_device usb_ohci_device = {
|
||||||
.name = "sh_ohci",
|
.name = "ohci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &usb_ohci_dma_mask,
|
.dma_mask = &usb_ohci_dma_mask,
|
||||||
.coherent_dma_mask = 0xffffffff,
|
.coherent_dma_mask = 0xffffffff,
|
||||||
|
.platform_data = &usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
||||||
.resource = usb_ohci_resources,
|
.resource = usb_ohci_resources,
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include <linux/sh_timer.h>
|
#include <linux/sh_timer.h>
|
||||||
#include <linux/sh_dma.h>
|
#include <linux/sh_dma.h>
|
||||||
#include <linux/sh_intc.h>
|
#include <linux/sh_intc.h>
|
||||||
|
#include <linux/usb/ohci_pdriver.h>
|
||||||
#include <cpu/dma-register.h>
|
#include <cpu/dma-register.h>
|
||||||
#include <asm/mmzone.h>
|
#include <asm/mmzone.h>
|
||||||
|
|
||||||
@@ -583,12 +584,15 @@ static struct resource usb_ohci_resources[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct usb_ohci_pdata usb_ohci_pdata;
|
||||||
|
|
||||||
static struct platform_device usb_ohci_device = {
|
static struct platform_device usb_ohci_device = {
|
||||||
.name = "sh_ohci",
|
.name = "ohci-platform",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
|
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &usb_ohci_pdata,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
.num_resources = ARRAY_SIZE(usb_ohci_resources),
|
||||||
.resource = usb_ohci_resources,
|
.resource = usb_ohci_resources,
|
||||||
|
@@ -116,7 +116,7 @@ static irqreturn_t c67x00_irq(int irq, void *__dev)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int __devinit c67x00_drv_probe(struct platform_device *pdev)
|
static int c67x00_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct c67x00_device *c67x00;
|
struct c67x00_device *c67x00;
|
||||||
struct c67x00_platform_data *pdata;
|
struct c67x00_platform_data *pdata;
|
||||||
@@ -191,7 +191,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit c67x00_drv_remove(struct platform_device *pdev)
|
static int c67x00_drv_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
|
struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
@@ -219,7 +219,7 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver c67x00_driver = {
|
static struct platform_driver c67x00_driver = {
|
||||||
.probe = c67x00_drv_probe,
|
.probe = c67x00_drv_probe,
|
||||||
.remove = __devexit_p(c67x00_drv_remove),
|
.remove = c67x00_drv_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "c67x00",
|
.name = "c67x00",
|
||||||
|
@@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC
|
|||||||
config USB_CHIPIDEA_HOST
|
config USB_CHIPIDEA_HOST
|
||||||
bool "ChipIdea host controller"
|
bool "ChipIdea host controller"
|
||||||
depends on USB=y || USB=USB_CHIPIDEA
|
depends on USB=y || USB=USB_CHIPIDEA
|
||||||
|
depends on USB_EHCI_HCD
|
||||||
select USB_EHCI_ROOT_HUB_TT
|
select USB_EHCI_ROOT_HUB_TT
|
||||||
help
|
help
|
||||||
Say Y here to enable host controller functionality of the
|
Say Y here to enable host controller functionality of the
|
||||||
|
@@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
|
|||||||
|
|
||||||
/* End of common functions shared by usbmisc drivers*/
|
/* End of common functions shared by usbmisc drivers*/
|
||||||
|
|
||||||
static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = {
|
static struct ci13xxx_platform_data ci13xxx_imx_platdata = {
|
||||||
.name = "ci13xxx_imx",
|
.name = "ci13xxx_imx",
|
||||||
.flags = CI13XXX_REQUIRE_TRANSCEIVER |
|
.flags = CI13XXX_REQUIRE_TRANSCEIVER |
|
||||||
CI13XXX_PULLUP_ON_VBUS |
|
CI13XXX_PULLUP_ON_VBUS |
|
||||||
@@ -93,7 +93,7 @@ static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = {
|
|||||||
.capoffset = DEF_CAPOFFSET,
|
.capoffset = DEF_CAPOFFSET,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit ci13xxx_imx_probe(struct platform_device *pdev)
|
static int ci13xxx_imx_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ci13xxx_imx_data *data;
|
struct ci13xxx_imx_data *data;
|
||||||
struct platform_device *plat_ci, *phy_pdev;
|
struct platform_device *plat_ci, *phy_pdev;
|
||||||
@@ -220,7 +220,7 @@ put_np:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit ci13xxx_imx_remove(struct platform_device *pdev)
|
static int ci13xxx_imx_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ci13xxx_imx_data *data = platform_get_drvdata(pdev);
|
struct ci13xxx_imx_data *data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ MODULE_DEVICE_TABLE(of, ci13xxx_imx_dt_ids);
|
|||||||
|
|
||||||
static struct platform_driver ci13xxx_imx_driver = {
|
static struct platform_driver ci13xxx_imx_driver = {
|
||||||
.probe = ci13xxx_imx_probe,
|
.probe = ci13xxx_imx_probe,
|
||||||
.remove = __devexit_p(ci13xxx_imx_remove),
|
.remove = ci13xxx_imx_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "imx_usb",
|
.name = "imx_usb",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@@ -55,7 +55,7 @@ static struct ci13xxx_platform_data ci13xxx_msm_platdata = {
|
|||||||
.notify_event = ci13xxx_msm_notify_event,
|
.notify_event = ci13xxx_msm_notify_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit ci13xxx_msm_probe(struct platform_device *pdev)
|
static int ci13xxx_msm_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct platform_device *plat_ci;
|
struct platform_device *plat_ci;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ static int __devinit ci13xxx_msm_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit ci13xxx_msm_remove(struct platform_device *pdev)
|
static int ci13xxx_msm_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct platform_device *plat_ci = platform_get_drvdata(pdev);
|
struct platform_device *plat_ci = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ static int __devexit ci13xxx_msm_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver ci13xxx_msm_driver = {
|
static struct platform_driver ci13xxx_msm_driver = {
|
||||||
.probe = ci13xxx_msm_probe,
|
.probe = ci13xxx_msm_probe,
|
||||||
.remove = __devexit_p(ci13xxx_msm_remove),
|
.remove = ci13xxx_msm_remove,
|
||||||
.driver = { .name = "msm_hsusb", },
|
.driver = { .name = "msm_hsusb", },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ struct ci13xxx_platform_data penwell_pci_platdata = {
|
|||||||
* Allocates basic PCI resources for this USB device controller, and then
|
* Allocates basic PCI resources for this USB device controller, and then
|
||||||
* invokes the udc_probe() method to start the UDC associated with it
|
* invokes the udc_probe() method to start the UDC associated with it
|
||||||
*/
|
*/
|
||||||
static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
|
static int ci13xxx_pci_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *id)
|
const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
struct ci13xxx_platform_data *platdata = (void *)id->driver_data;
|
struct ci13xxx_platform_data *platdata = (void *)id->driver_data;
|
||||||
@@ -107,7 +107,7 @@ static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
|
|||||||
* first invoking the udc_remove() and then releases
|
* first invoking the udc_remove() and then releases
|
||||||
* all PCI resources allocated for this USB device controller
|
* all PCI resources allocated for this USB device controller
|
||||||
*/
|
*/
|
||||||
static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
|
static void ci13xxx_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct platform_device *plat_ci = pci_get_drvdata(pdev);
|
struct platform_device *plat_ci = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ static struct pci_driver ci13xxx_pci_driver = {
|
|||||||
.name = UDC_DRIVER_NAME,
|
.name = UDC_DRIVER_NAME,
|
||||||
.id_table = ci13xxx_pci_id_table,
|
.id_table = ci13xxx_pci_id_table,
|
||||||
.probe = ci13xxx_pci_probe,
|
.probe = ci13xxx_pci_probe,
|
||||||
.remove = __devexit_p(ci13xxx_pci_remove),
|
.remove = ci13xxx_pci_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_pci_driver(ci13xxx_pci_driver);
|
module_pci_driver(ci13xxx_pci_driver);
|
||||||
|
@@ -385,12 +385,13 @@ EXPORT_SYMBOL_GPL(ci13xxx_add_device);
|
|||||||
|
|
||||||
void ci13xxx_remove_device(struct platform_device *pdev)
|
void ci13xxx_remove_device(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
int id = pdev->id;
|
||||||
platform_device_unregister(pdev);
|
platform_device_unregister(pdev);
|
||||||
ida_simple_remove(&ci_ida, pdev->id);
|
ida_simple_remove(&ci_ida, id);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ci13xxx_remove_device);
|
EXPORT_SYMBOL_GPL(ci13xxx_remove_device);
|
||||||
|
|
||||||
static int __devinit ci_hdrc_probe(struct platform_device *pdev)
|
static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct ci13xxx *ci;
|
struct ci13xxx *ci;
|
||||||
@@ -508,7 +509,7 @@ rm_wq:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit ci_hdrc_remove(struct platform_device *pdev)
|
static int ci_hdrc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ci13xxx *ci = platform_get_drvdata(pdev);
|
struct ci13xxx *ci = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -523,7 +524,7 @@ static int __devexit ci_hdrc_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver ci_hdrc_driver = {
|
static struct platform_driver ci_hdrc_driver = {
|
||||||
.probe = ci_hdrc_probe,
|
.probe = ci_hdrc_probe,
|
||||||
.remove = __devexit_p(ci_hdrc_remove),
|
.remove = ci_hdrc_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ci_hdrc",
|
.name = "ci_hdrc",
|
||||||
},
|
},
|
||||||
|
@@ -160,9 +160,6 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr,
|
|||||||
gadget->speed);
|
gadget->speed);
|
||||||
n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
|
n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
|
||||||
gadget->max_speed);
|
gadget->max_speed);
|
||||||
/* TODO: Scheduled for removal in 3.8. */
|
|
||||||
n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
|
|
||||||
gadget_is_dualspeed(gadget));
|
|
||||||
n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
|
n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
|
||||||
gadget->is_otg);
|
gadget->is_otg);
|
||||||
n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
|
n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
|
||||||
|
@@ -20,77 +20,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/io.h>
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#include <linux/usb/hcd.h>
|
#include <linux/usb/hcd.h>
|
||||||
#include <linux/usb/chipidea.h>
|
#include <linux/usb/chipidea.h>
|
||||||
|
|
||||||
#define CHIPIDEA_EHCI
|
#include "../host/ehci.h"
|
||||||
#include "../host/ehci-hcd.c"
|
|
||||||
|
|
||||||
#include "ci.h"
|
#include "ci.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
|
|
||||||
static int ci_ehci_setup(struct usb_hcd *hcd)
|
static struct hc_driver __read_mostly ci_ehci_hc_driver;
|
||||||
{
|
|
||||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hcd->has_tt = 1;
|
|
||||||
|
|
||||||
ret = ehci_setup(hcd);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ehci_port_power(ehci, 0);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct hc_driver ci_ehci_hc_driver = {
|
|
||||||
.description = "ehci_hcd",
|
|
||||||
.product_desc = "ChipIdea HDRC EHCI",
|
|
||||||
.hcd_priv_size = sizeof(struct ehci_hcd),
|
|
||||||
|
|
||||||
/*
|
|
||||||
* generic hardware linkage
|
|
||||||
*/
|
|
||||||
.irq = ehci_irq,
|
|
||||||
.flags = HCD_MEMORY | HCD_USB2,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* basic lifecycle operations
|
|
||||||
*/
|
|
||||||
.reset = ci_ehci_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 irqreturn_t host_irq(struct ci13xxx *ci)
|
static irqreturn_t host_irq(struct ci13xxx *ci)
|
||||||
{
|
{
|
||||||
@@ -157,5 +98,7 @@ int ci_hdrc_host_init(struct ci13xxx *ci)
|
|||||||
rdrv->name = "host";
|
rdrv->name = "host";
|
||||||
ci->roles[CI_ROLE_HOST] = rdrv;
|
ci->roles[CI_ROLE_HOST] = rdrv;
|
||||||
|
|
||||||
|
ehci_init_driver(&ci_ehci_hc_driver, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -82,7 +82,7 @@ static const struct of_device_id usbmisc_imx6q_dt_ids[] = {
|
|||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev)
|
static int usbmisc_imx6q_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct imx6q_usbmisc *data;
|
struct imx6q_usbmisc *data;
|
||||||
@@ -127,7 +127,7 @@ static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev)
|
static int usbmisc_imx6q_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
usbmisc_unset_ops(&imx6q_usbmisc_ops);
|
usbmisc_unset_ops(&imx6q_usbmisc_ops);
|
||||||
clk_disable_unprepare(usbmisc->clk);
|
clk_disable_unprepare(usbmisc->clk);
|
||||||
@@ -136,7 +136,7 @@ static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver usbmisc_imx6q_driver = {
|
static struct platform_driver usbmisc_imx6q_driver = {
|
||||||
.probe = usbmisc_imx6q_probe,
|
.probe = usbmisc_imx6q_probe,
|
||||||
.remove = __devexit_p(usbmisc_imx6q_remove),
|
.remove = usbmisc_imx6q_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "usbmisc_imx6q",
|
.name = "usbmisc_imx6q",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@@ -787,6 +787,10 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
|
|||||||
tmp.flags = ASYNC_LOW_LATENCY;
|
tmp.flags = ASYNC_LOW_LATENCY;
|
||||||
tmp.xmit_fifo_size = acm->writesize;
|
tmp.xmit_fifo_size = acm->writesize;
|
||||||
tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
|
tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
|
||||||
|
tmp.close_delay = acm->port.close_delay / 10;
|
||||||
|
tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
|
||||||
|
ASYNC_CLOSING_WAIT_NONE :
|
||||||
|
acm->port.closing_wait / 10;
|
||||||
|
|
||||||
if (copy_to_user(info, &tmp, sizeof(tmp)))
|
if (copy_to_user(info, &tmp, sizeof(tmp)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -794,6 +798,37 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_serial_info(struct acm *acm,
|
||||||
|
struct serial_struct __user *newinfo)
|
||||||
|
{
|
||||||
|
struct serial_struct new_serial;
|
||||||
|
unsigned int closing_wait, close_delay;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
close_delay = new_serial.close_delay * 10;
|
||||||
|
closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
|
||||||
|
ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
|
||||||
|
|
||||||
|
mutex_lock(&acm->port.mutex);
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN)) {
|
||||||
|
if ((close_delay != acm->port.close_delay) ||
|
||||||
|
(closing_wait != acm->port.closing_wait))
|
||||||
|
retval = -EPERM;
|
||||||
|
else
|
||||||
|
retval = -EOPNOTSUPP;
|
||||||
|
} else {
|
||||||
|
acm->port.close_delay = close_delay;
|
||||||
|
acm->port.closing_wait = closing_wait;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&acm->port.mutex);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static int acm_tty_ioctl(struct tty_struct *tty,
|
static int acm_tty_ioctl(struct tty_struct *tty,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
@@ -804,6 +839,9 @@ static int acm_tty_ioctl(struct tty_struct *tty,
|
|||||||
case TIOCGSERIAL: /* gets serial port data */
|
case TIOCGSERIAL: /* gets serial port data */
|
||||||
rv = get_serial_info(acm, (struct serial_struct __user *) arg);
|
rv = get_serial_info(acm, (struct serial_struct __user *) arg);
|
||||||
break;
|
break;
|
||||||
|
case TIOCSSERIAL:
|
||||||
|
rv = set_serial_info(acm, (struct serial_struct __user *) arg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@@ -591,7 +591,6 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
|||||||
|
|
||||||
/* Now look at all of this device's children. */
|
/* Now look at all of this device's children. */
|
||||||
usb_hub_for_each_child(usbdev, chix, childdev) {
|
usb_hub_for_each_child(usbdev, chix, childdev) {
|
||||||
if (childdev) {
|
|
||||||
usb_lock_device(childdev);
|
usb_lock_device(childdev);
|
||||||
ret = usb_device_dump(buffer, nbytes, skip_bytes,
|
ret = usb_device_dump(buffer, nbytes, skip_bytes,
|
||||||
file_offset, childdev, bus,
|
file_offset, childdev, bus,
|
||||||
@@ -601,7 +600,6 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
|||||||
return total_written;
|
return total_written;
|
||||||
total_written += ret;
|
total_written += ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return total_written;
|
return total_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,8 +32,6 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a new dynamic USBdevice ID to this driver,
|
* Adds a new dynamic USBdevice ID to this driver,
|
||||||
* and cause the driver to probe for all devices again.
|
* and cause the driver to probe for all devices again.
|
||||||
@@ -194,20 +192,6 @@ static void usb_free_dynids(struct usb_driver *usb_drv)
|
|||||||
}
|
}
|
||||||
spin_unlock(&usb_drv->dynids.lock);
|
spin_unlock(&usb_drv->dynids.lock);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline int usb_create_newid_files(struct usb_driver *usb_drv)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb_remove_newid_files(struct usb_driver *usb_drv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void usb_free_dynids(struct usb_driver *usb_drv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
|
static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
|
||||||
struct usb_driver *drv)
|
struct usb_driver *drv)
|
||||||
@@ -790,7 +774,6 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG
|
|
||||||
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct usb_device *usb_dev;
|
struct usb_device *usb_dev;
|
||||||
@@ -832,14 +815,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HOTPLUG */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* usb_register_device_driver - register a USB device (not interface) driver
|
* usb_register_device_driver - register a USB device (not interface) driver
|
||||||
* @new_udriver: USB operations for the device driver
|
* @new_udriver: USB operations for the device driver
|
||||||
|
@@ -47,6 +47,9 @@ int usb_choose_configuration(struct usb_device *udev)
|
|||||||
int insufficient_power = 0;
|
int insufficient_power = 0;
|
||||||
struct usb_host_config *c, *best;
|
struct usb_host_config *c, *best;
|
||||||
|
|
||||||
|
if (usb_device_is_owned(udev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
best = NULL;
|
best = NULL;
|
||||||
c = udev->config;
|
c = udev->config;
|
||||||
num_configs = udev->descriptor.bNumConfigurations;
|
num_configs = udev->descriptor.bNumConfigurations;
|
||||||
@@ -160,9 +163,7 @@ static int generic_probe(struct usb_device *udev)
|
|||||||
/* Choose and set the configuration. This registers the interfaces
|
/* Choose and set the configuration. This registers the interfaces
|
||||||
* with the driver core and lets interface drivers bind to them.
|
* with the driver core and lets interface drivers bind to them.
|
||||||
*/
|
*/
|
||||||
if (usb_device_is_owned(udev))
|
if (udev->authorized == 0)
|
||||||
; /* Don't configure if the device is owned */
|
|
||||||
else if (udev->authorized == 0)
|
|
||||||
dev_err(&udev->dev, "Device is not authorized for usage\n");
|
dev_err(&udev->dev, "Device is not authorized for usage\n");
|
||||||
else {
|
else {
|
||||||
c = usb_choose_configuration(udev);
|
c = usb_choose_configuration(udev);
|
||||||
|
@@ -2039,8 +2039,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
|
|||||||
status = hcd->driver->bus_resume(hcd);
|
status = hcd->driver->bus_resume(hcd);
|
||||||
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
|
clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
/* TRSMRCY = 10 msec */
|
struct usb_device *udev;
|
||||||
msleep(10);
|
int port1;
|
||||||
|
|
||||||
spin_lock_irq(&hcd_root_hub_lock);
|
spin_lock_irq(&hcd_root_hub_lock);
|
||||||
if (!HCD_DEAD(hcd)) {
|
if (!HCD_DEAD(hcd)) {
|
||||||
usb_set_device_state(rhdev, rhdev->actconfig
|
usb_set_device_state(rhdev, rhdev->actconfig
|
||||||
@@ -2050,6 +2051,20 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
|
|||||||
hcd->state = HC_STATE_RUNNING;
|
hcd->state = HC_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&hcd_root_hub_lock);
|
spin_unlock_irq(&hcd_root_hub_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether any of the enabled ports on the root hub are
|
||||||
|
* unsuspended. If they are then a TRSMRCY delay is needed
|
||||||
|
* (this is what the USB-2 spec calls a "global resume").
|
||||||
|
* Otherwise we can skip the delay.
|
||||||
|
*/
|
||||||
|
usb_hub_for_each_child(rhdev, port1, udev) {
|
||||||
|
if (udev->state != USB_STATE_NOTATTACHED &&
|
||||||
|
!udev->port_is_suspended) {
|
||||||
|
usleep_range(10000, 11000); /* TRSMRCY */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
hcd->state = old_state;
|
hcd->state = old_state;
|
||||||
dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
|
dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
|
||||||
|
@@ -39,6 +39,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define USB_VENDOR_GENESYS_LOGIC 0x05e3
|
||||||
|
#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01
|
||||||
|
|
||||||
struct usb_port {
|
struct usb_port {
|
||||||
struct usb_device *child;
|
struct usb_device *child;
|
||||||
struct device dev;
|
struct device dev;
|
||||||
@@ -86,6 +89,8 @@ struct usb_hub {
|
|||||||
unsigned quiescing:1;
|
unsigned quiescing:1;
|
||||||
unsigned disconnected:1;
|
unsigned disconnected:1;
|
||||||
|
|
||||||
|
unsigned quirk_check_port_auto_suspend:1;
|
||||||
|
|
||||||
unsigned has_indicators:1;
|
unsigned has_indicators:1;
|
||||||
u8 indicator[USB_MAXCHILDREN];
|
u8 indicator[USB_MAXCHILDREN];
|
||||||
struct delayed_work leds;
|
struct delayed_work leds;
|
||||||
@@ -736,7 +741,6 @@ static void hub_tt_work(struct work_struct *work)
|
|||||||
struct usb_hub *hub =
|
struct usb_hub *hub =
|
||||||
container_of(work, struct usb_hub, tt.clear_work);
|
container_of(work, struct usb_hub, tt.clear_work);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int limit = 100;
|
|
||||||
|
|
||||||
spin_lock_irqsave (&hub->tt.lock, flags);
|
spin_lock_irqsave (&hub->tt.lock, flags);
|
||||||
while (!list_empty(&hub->tt.clear_list)) {
|
while (!list_empty(&hub->tt.clear_list)) {
|
||||||
@@ -746,9 +750,6 @@ static void hub_tt_work(struct work_struct *work)
|
|||||||
const struct hc_driver *drv;
|
const struct hc_driver *drv;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!hub->quiescing && --limit < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
next = hub->tt.clear_list.next;
|
next = hub->tt.clear_list.next;
|
||||||
clear = list_entry (next, struct usb_tt_clear, clear_list);
|
clear = list_entry (next, struct usb_tt_clear, clear_list);
|
||||||
list_del (&clear->clear_list);
|
list_del (&clear->clear_list);
|
||||||
@@ -1612,6 +1613,41 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||||||
desc = intf->cur_altsetting;
|
desc = intf->cur_altsetting;
|
||||||
hdev = interface_to_usbdev(intf);
|
hdev = interface_to_usbdev(intf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set default autosuspend delay as 0 to speedup bus suspend,
|
||||||
|
* based on the below considerations:
|
||||||
|
*
|
||||||
|
* - Unlike other drivers, the hub driver does not rely on the
|
||||||
|
* autosuspend delay to provide enough time to handle a wakeup
|
||||||
|
* event, and the submitted status URB is just to check future
|
||||||
|
* change on hub downstream ports, so it is safe to do it.
|
||||||
|
*
|
||||||
|
* - The patch might cause one or more auto supend/resume for
|
||||||
|
* below very rare devices when they are plugged into hub
|
||||||
|
* first time:
|
||||||
|
*
|
||||||
|
* devices having trouble initializing, and disconnect
|
||||||
|
* themselves from the bus and then reconnect a second
|
||||||
|
* or so later
|
||||||
|
*
|
||||||
|
* devices just for downloading firmware, and disconnects
|
||||||
|
* themselves after completing it
|
||||||
|
*
|
||||||
|
* For these quite rare devices, their drivers may change the
|
||||||
|
* autosuspend delay of their parent hub in the probe() to one
|
||||||
|
* appropriate value to avoid the subtle problem if someone
|
||||||
|
* does care it.
|
||||||
|
*
|
||||||
|
* - The patch may cause one or more auto suspend/resume on
|
||||||
|
* hub during running 'lsusb', but it is probably too
|
||||||
|
* infrequent to worry about.
|
||||||
|
*
|
||||||
|
* - Change autosuspend delay of hub can avoid unnecessary auto
|
||||||
|
* suspend timer for hub, also may decrease power consumption
|
||||||
|
* of USB bus.
|
||||||
|
*/
|
||||||
|
pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
|
||||||
|
|
||||||
/* Hubs have proper suspend/resume support. */
|
/* Hubs have proper suspend/resume support. */
|
||||||
usb_enable_autosuspend(hdev);
|
usb_enable_autosuspend(hdev);
|
||||||
|
|
||||||
@@ -1670,6 +1706,9 @@ descriptor_error:
|
|||||||
if (hdev->speed == USB_SPEED_HIGH)
|
if (hdev->speed == USB_SPEED_HIGH)
|
||||||
highspeed_hubs++;
|
highspeed_hubs++;
|
||||||
|
|
||||||
|
if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
|
||||||
|
hub->quirk_check_port_auto_suspend = 1;
|
||||||
|
|
||||||
if (hub_configure(hub, endpoint) >= 0)
|
if (hub_configure(hub, endpoint) >= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -2012,7 +2051,7 @@ static void show_string(struct usb_device *udev, char *id, char *string)
|
|||||||
{
|
{
|
||||||
if (!string)
|
if (!string)
|
||||||
return;
|
return;
|
||||||
dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string);
|
dev_info(&udev->dev, "%s: %s\n", id, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void announce_device(struct usb_device *udev)
|
static void announce_device(struct usb_device *udev)
|
||||||
@@ -2879,6 +2918,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||||||
(PMSG_IS_AUTO(msg) ? "auto-" : ""),
|
(PMSG_IS_AUTO(msg) ? "auto-" : ""),
|
||||||
udev->do_remote_wakeup);
|
udev->do_remote_wakeup);
|
||||||
usb_set_device_state(udev, USB_STATE_SUSPENDED);
|
usb_set_device_state(udev, USB_STATE_SUSPENDED);
|
||||||
|
udev->port_is_suspended = 1;
|
||||||
msleep(10);
|
msleep(10);
|
||||||
}
|
}
|
||||||
usb_mark_last_busy(hub->hdev);
|
usb_mark_last_busy(hub->hdev);
|
||||||
@@ -3043,6 +3083,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
|
|||||||
|
|
||||||
SuspendCleared:
|
SuspendCleared:
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
udev->port_is_suspended = 0;
|
||||||
if (hub_is_superspeed(hub->hdev)) {
|
if (hub_is_superspeed(hub->hdev)) {
|
||||||
if (portchange & USB_PORT_STAT_C_LINK_STATE)
|
if (portchange & USB_PORT_STAT_C_LINK_STATE)
|
||||||
clear_port_feature(hub->hdev, port1,
|
clear_port_feature(hub->hdev, port1,
|
||||||
@@ -3126,6 +3167,21 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int check_ports_changed(struct usb_hub *hub)
|
||||||
|
{
|
||||||
|
int port1;
|
||||||
|
|
||||||
|
for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) {
|
||||||
|
u16 portstatus, portchange;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = hub_port_status(hub, port1, &portstatus, &portchange);
|
||||||
|
if (!status && portchange)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||||
{
|
{
|
||||||
struct usb_hub *hub = usb_get_intfdata (intf);
|
struct usb_hub *hub = usb_get_intfdata (intf);
|
||||||
@@ -3144,6 +3200,16 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) {
|
||||||
|
/* check if there are changes pending on hub ports */
|
||||||
|
if (check_ports_changed(hub)) {
|
||||||
|
if (PMSG_IS_AUTO(msg))
|
||||||
|
return -EBUSY;
|
||||||
|
pm_wakeup_event(&hdev->dev, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
|
if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
|
||||||
/* Enable hub to send remote wakeup for all ports. */
|
/* Enable hub to send remote wakeup for all ports. */
|
||||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||||
@@ -3972,6 +4038,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||||||
if (retval)
|
if (retval)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (hcd->phy && !hdev->parent)
|
||||||
|
usb_phy_notify_connect(hcd->phy, udev->speed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some superspeed devices have finished the link training process
|
* Some superspeed devices have finished the link training process
|
||||||
* and attached to a superspeed hub port, but the device descriptor
|
* and attached to a superspeed hub port, but the device descriptor
|
||||||
@@ -4166,8 +4235,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Disconnect any existing devices under this port */
|
/* Disconnect any existing devices under this port */
|
||||||
if (udev)
|
if (udev) {
|
||||||
|
if (hcd->phy && !hdev->parent &&
|
||||||
|
!(portstatus & USB_PORT_STAT_CONNECTION))
|
||||||
|
usb_phy_notify_disconnect(hcd->phy, udev->speed);
|
||||||
usb_disconnect(&hub->ports[port1 - 1]->child);
|
usb_disconnect(&hub->ports[port1 - 1]->child);
|
||||||
|
}
|
||||||
clear_bit(port1, hub->change_bits);
|
clear_bit(port1, hub->change_bits);
|
||||||
|
|
||||||
/* We can forget about a "removed" device when there's a physical
|
/* We can forget about a "removed" device when there's a physical
|
||||||
@@ -4190,13 +4263,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcd->phy && !hdev->parent) {
|
|
||||||
if (portstatus & USB_PORT_STAT_CONNECTION)
|
|
||||||
usb_phy_notify_connect(hcd->phy, port1);
|
|
||||||
else
|
|
||||||
usb_phy_notify_disconnect(hcd->phy, port1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return now if debouncing failed or nothing is connected or
|
/* Return now if debouncing failed or nothing is connected or
|
||||||
* the device was "removed".
|
* the device was "removed".
|
||||||
*/
|
*/
|
||||||
@@ -4648,6 +4714,11 @@ static int hub_thread(void *__unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct usb_device_id hub_id_table[] = {
|
static const struct usb_device_id hub_id_table[] = {
|
||||||
|
{ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
|
||||||
|
| USB_DEVICE_ID_MATCH_INT_CLASS,
|
||||||
|
.idVendor = USB_VENDOR_GENESYS_LOGIC,
|
||||||
|
.bInterfaceClass = USB_CLASS_HUB,
|
||||||
|
.driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
|
||||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
|
{ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
|
||||||
.bDeviceClass = USB_CLASS_HUB},
|
.bDeviceClass = USB_CLASS_HUB},
|
||||||
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
|
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
|
||||||
|
@@ -1540,7 +1540,6 @@ static void usb_release_interface(struct device *dev)
|
|||||||
kfree(intf);
|
kfree(intf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG
|
|
||||||
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct usb_device *usb_dev;
|
struct usb_device *usb_dev;
|
||||||
@@ -1575,14 +1574,6 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HOTPLUG */
|
|
||||||
|
|
||||||
struct device_type usb_if_device_type = {
|
struct device_type usb_if_device_type = {
|
||||||
.name = "usb_interface",
|
.name = "usb_interface",
|
||||||
.release = usb_release_interface,
|
.release = usb_release_interface,
|
||||||
@@ -1795,7 +1786,8 @@ free_interfaces:
|
|||||||
if (dev->actconfig && usb_disable_lpm(dev)) {
|
if (dev->actconfig && usb_disable_lpm(dev)) {
|
||||||
dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
|
dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
|
||||||
mutex_unlock(hcd->bandwidth_mutex);
|
mutex_unlock(hcd->bandwidth_mutex);
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto free_interfaces;
|
||||||
}
|
}
|
||||||
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
|
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1806,29 +1798,8 @@ free_interfaces:
|
|||||||
goto free_interfaces;
|
goto free_interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
/*
|
||||||
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
|
* Initialize the new interface structures and the
|
||||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
|
||||||
if (ret < 0) {
|
|
||||||
/* All the old state is gone, so what else can we do?
|
|
||||||
* The device is probably useless now anyway.
|
|
||||||
*/
|
|
||||||
cp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->actconfig = cp;
|
|
||||||
if (!cp) {
|
|
||||||
usb_set_device_state(dev, USB_STATE_ADDRESS);
|
|
||||||
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
|
|
||||||
/* Leave LPM disabled while the device is unconfigured. */
|
|
||||||
mutex_unlock(hcd->bandwidth_mutex);
|
|
||||||
usb_autosuspend_device(dev);
|
|
||||||
goto free_interfaces;
|
|
||||||
}
|
|
||||||
mutex_unlock(hcd->bandwidth_mutex);
|
|
||||||
usb_set_device_state(dev, USB_STATE_CONFIGURED);
|
|
||||||
|
|
||||||
/* Initialize the new interface structures and the
|
|
||||||
* hc/hcd/usbcore interface/endpoint state.
|
* hc/hcd/usbcore interface/endpoint state.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < nintf; ++i) {
|
for (i = 0; i < nintf; ++i) {
|
||||||
@@ -1872,6 +1843,35 @@ free_interfaces:
|
|||||||
}
|
}
|
||||||
kfree(new_interfaces);
|
kfree(new_interfaces);
|
||||||
|
|
||||||
|
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
|
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
|
||||||
|
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
|
if (ret < 0 && cp) {
|
||||||
|
/*
|
||||||
|
* All the old state is gone, so what else can we do?
|
||||||
|
* The device is probably useless now anyway.
|
||||||
|
*/
|
||||||
|
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
|
||||||
|
for (i = 0; i < nintf; ++i) {
|
||||||
|
usb_disable_interface(dev, cp->interface[i], true);
|
||||||
|
put_device(&cp->interface[i]->dev);
|
||||||
|
cp->interface[i] = NULL;
|
||||||
|
}
|
||||||
|
cp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->actconfig = cp;
|
||||||
|
mutex_unlock(hcd->bandwidth_mutex);
|
||||||
|
|
||||||
|
if (!cp) {
|
||||||
|
usb_set_device_state(dev, USB_STATE_ADDRESS);
|
||||||
|
|
||||||
|
/* Leave LPM disabled while the device is unconfigured. */
|
||||||
|
usb_autosuspend_device(dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
usb_set_device_state(dev, USB_STATE_CONFIGURED);
|
||||||
|
|
||||||
if (cp->string == NULL &&
|
if (cp->string == NULL &&
|
||||||
!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
|
!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
|
||||||
cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
|
cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
|
||||||
|
@@ -214,9 +214,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
|
|||||||
* urb->interval is modified to reflect the actual transfer period used
|
* urb->interval is modified to reflect the actual transfer period used
|
||||||
* (normally some power of two units). And for isochronous urbs,
|
* (normally some power of two units). And for isochronous urbs,
|
||||||
* urb->start_frame is modified to reflect when the URB's transfers were
|
* urb->start_frame is modified to reflect when the URB's transfers were
|
||||||
* scheduled to start. Not all isochronous transfer scheduling policies
|
* scheduled to start.
|
||||||
* will work, but most host controller drivers should easily handle ISO
|
*
|
||||||
* queues going from now until 10-200 msec into the future.
|
* Not all isochronous transfer scheduling policies will work, but most
|
||||||
|
* host controller drivers should easily handle ISO queues going from now
|
||||||
|
* until 10-200 msec into the future. Drivers should try to keep at
|
||||||
|
* least one or two msec of data in the queue; many controllers require
|
||||||
|
* that new transfers start at least 1 msec in the future when they are
|
||||||
|
* added. If the driver is unable to keep up and the queue empties out,
|
||||||
|
* the behavior for new submissions is governed by the URB_ISO_ASAP flag.
|
||||||
|
* If the flag is set, or if the queue is idle, then the URB is always
|
||||||
|
* assigned to the first available (and not yet expired) slot in the
|
||||||
|
* endpoint's schedule. If the flag is not set and the queue is active
|
||||||
|
* then the URB is always assigned to the next slot in the schedule
|
||||||
|
* following the end of the endpoint's previous URB, even if that slot is
|
||||||
|
* in the past. When a packet is assigned in this way to a slot that has
|
||||||
|
* already expired, the packet is not transmitted and the corresponding
|
||||||
|
* usb_iso_packet_descriptor's status field will return -EXDEV. If this
|
||||||
|
* would happen to all the packets in the URB, submission fails with a
|
||||||
|
* -EXDEV error code.
|
||||||
*
|
*
|
||||||
* For control endpoints, the synchronous usb_control_msg() call is
|
* For control endpoints, the synchronous usb_control_msg() call is
|
||||||
* often used (in non-interrupt context) instead of this call.
|
* often used (in non-interrupt context) instead of this call.
|
||||||
@@ -305,8 +321,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
|||||||
struct usb_host_endpoint *ep;
|
struct usb_host_endpoint *ep;
|
||||||
int is_out;
|
int is_out;
|
||||||
|
|
||||||
if (!urb || urb->hcpriv || !urb->complete)
|
if (!urb || !urb->complete)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (urb->hcpriv) {
|
||||||
|
WARN_ONCE(1, "URB %p submitted while active\n", urb);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
dev = urb->dev;
|
dev = urb->dev;
|
||||||
if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
|
if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@@ -233,7 +233,6 @@ static void usb_release_dev(struct device *dev)
|
|||||||
kfree(udev);
|
kfree(udev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG
|
|
||||||
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct usb_device *usb_dev;
|
struct usb_device *usb_dev;
|
||||||
@@ -249,14 +248,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HOTPLUG */
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/* USB device Power-Management thunks.
|
/* USB device Power-Management thunks.
|
||||||
@@ -370,14 +361,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
|
|||||||
struct usb_bus *bus, unsigned port1)
|
struct usb_bus *bus, unsigned port1)
|
||||||
{
|
{
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
|
struct usb_hcd *usb_hcd = bus_to_hcd(bus);
|
||||||
unsigned root_hub = 0;
|
unsigned root_hub = 0;
|
||||||
|
|
||||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!usb_get_hcd(bus_to_hcd(bus))) {
|
if (!usb_get_hcd(usb_hcd)) {
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -27,19 +27,7 @@ endif
|
|||||||
##
|
##
|
||||||
|
|
||||||
obj-$(CONFIG_USB_DWC3) += dwc3-omap.o
|
obj-$(CONFIG_USB_DWC3) += dwc3-omap.o
|
||||||
|
obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
|
||||||
##
|
|
||||||
# REVISIT Samsung Exynos platform needs the clk API which isn't
|
|
||||||
# defined on all architectures. If we allow dwc3-exynos.c compile
|
|
||||||
# always we will fail the linking phase on those architectures
|
|
||||||
# which don't provide clk api implementation and that's unnaceptable.
|
|
||||||
#
|
|
||||||
# When Samsung's platform start supporting pm_runtime, this check
|
|
||||||
# for HAVE_CLK should be removed.
|
|
||||||
##
|
|
||||||
ifneq ($(CONFIG_HAVE_CLK),)
|
|
||||||
obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(CONFIG_PCI),)
|
ifneq ($(CONFIG_PCI),)
|
||||||
obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
|
obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
|
||||||
|
@@ -66,45 +66,6 @@ MODULE_PARM_DESC(maximum_speed, "Maximum supported speed.");
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define DWC3_DEVS_POSSIBLE 32
|
|
||||||
|
|
||||||
static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE);
|
|
||||||
|
|
||||||
int dwc3_get_device_id(void)
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
|
|
||||||
again:
|
|
||||||
id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE);
|
|
||||||
if (id < DWC3_DEVS_POSSIBLE) {
|
|
||||||
int old;
|
|
||||||
|
|
||||||
old = test_and_set_bit(id, dwc3_devs);
|
|
||||||
if (old)
|
|
||||||
goto again;
|
|
||||||
} else {
|
|
||||||
pr_err("dwc3: no space for new device\n");
|
|
||||||
id = -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(dwc3_get_device_id);
|
|
||||||
|
|
||||||
void dwc3_put_device_id(int id)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (id < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ret = test_bit(id, dwc3_devs);
|
|
||||||
WARN(!ret, "dwc3: ID %d not in use\n", id);
|
|
||||||
smp_mb__before_clear_bit();
|
|
||||||
clear_bit(id, dwc3_devs);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(dwc3_put_device_id);
|
|
||||||
|
|
||||||
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
|
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
@@ -169,7 +130,6 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
|
|||||||
struct dwc3_event_buffer *evt)
|
struct dwc3_event_buffer *evt)
|
||||||
{
|
{
|
||||||
dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
|
dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
|
||||||
kfree(evt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,12 +140,11 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
|
|||||||
* Returns a pointer to the allocated event buffer structure on success
|
* Returns a pointer to the allocated event buffer structure on success
|
||||||
* otherwise ERR_PTR(errno).
|
* otherwise ERR_PTR(errno).
|
||||||
*/
|
*/
|
||||||
static struct dwc3_event_buffer *__devinit
|
static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
|
||||||
dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
|
|
||||||
{
|
{
|
||||||
struct dwc3_event_buffer *evt;
|
struct dwc3_event_buffer *evt;
|
||||||
|
|
||||||
evt = kzalloc(sizeof(*evt), GFP_KERNEL);
|
evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
|
||||||
if (!evt)
|
if (!evt)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
@@ -193,10 +152,8 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
|
|||||||
evt->length = length;
|
evt->length = length;
|
||||||
evt->buf = dma_alloc_coherent(dwc->dev, length,
|
evt->buf = dma_alloc_coherent(dwc->dev, length,
|
||||||
&evt->dma, GFP_KERNEL);
|
&evt->dma, GFP_KERNEL);
|
||||||
if (!evt->buf) {
|
if (!evt->buf)
|
||||||
kfree(evt);
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
|
||||||
|
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
@@ -215,8 +172,6 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
|
|||||||
if (evt)
|
if (evt)
|
||||||
dwc3_free_one_event_buffer(dwc, evt);
|
dwc3_free_one_event_buffer(dwc, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(dwc->ev_buffs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,7 +182,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
|
|||||||
* Returns 0 on success otherwise negative errno. In the error case, dwc
|
* Returns 0 on success otherwise negative errno. In the error case, dwc
|
||||||
* may contain some buffers allocated but not all which were requested.
|
* may contain some buffers allocated but not all which were requested.
|
||||||
*/
|
*/
|
||||||
static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
|
static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
int i;
|
int i;
|
||||||
@@ -235,7 +190,8 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
|
|||||||
num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
|
num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
|
||||||
dwc->num_event_buffers = num;
|
dwc->num_event_buffers = num;
|
||||||
|
|
||||||
dwc->ev_buffs = kzalloc(sizeof(*dwc->ev_buffs) * num, GFP_KERNEL);
|
dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
|
||||||
|
GFP_KERNEL);
|
||||||
if (!dwc->ev_buffs) {
|
if (!dwc->ev_buffs) {
|
||||||
dev_err(dwc->dev, "can't allocate event buffers array\n");
|
dev_err(dwc->dev, "can't allocate event buffers array\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -303,7 +259,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
|
static void dwc3_cache_hwparams(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
struct dwc3_hwparams *parms = &dwc->hwparams;
|
struct dwc3_hwparams *parms = &dwc->hwparams;
|
||||||
|
|
||||||
@@ -324,7 +280,7 @@ static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
|
|||||||
*
|
*
|
||||||
* Returns 0 on success otherwise negative errno.
|
* Returns 0 on success otherwise negative errno.
|
||||||
*/
|
*/
|
||||||
static int __devinit dwc3_core_init(struct dwc3 *dwc)
|
static int dwc3_core_init(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
@@ -358,8 +314,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
|
|||||||
|
|
||||||
dwc3_core_soft_reset(dwc);
|
dwc3_core_soft_reset(dwc);
|
||||||
|
|
||||||
dwc3_cache_hwparams(dwc);
|
|
||||||
|
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
||||||
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
|
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
|
||||||
reg &= ~DWC3_GCTL_DISSCRAMBLE;
|
reg &= ~DWC3_GCTL_DISSCRAMBLE;
|
||||||
@@ -383,24 +337,14 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
|
|||||||
|
|
||||||
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
||||||
|
|
||||||
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dwc->dev, "failed to allocate event buffers\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = dwc3_event_buffers_setup(dwc);
|
ret = dwc3_event_buffers_setup(dwc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dwc->dev, "failed to setup event buffers\n");
|
dev_err(dwc->dev, "failed to setup event buffers\n");
|
||||||
goto err1;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err1:
|
|
||||||
dwc3_free_event_buffers(dwc);
|
|
||||||
|
|
||||||
err0:
|
err0:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -408,16 +352,14 @@ err0:
|
|||||||
static void dwc3_core_exit(struct dwc3 *dwc)
|
static void dwc3_core_exit(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
dwc3_event_buffers_cleanup(dwc);
|
dwc3_event_buffers_cleanup(dwc);
|
||||||
dwc3_free_event_buffers(dwc);
|
|
||||||
|
|
||||||
usb_phy_shutdown(dwc->usb2_phy);
|
usb_phy_shutdown(dwc->usb2_phy);
|
||||||
usb_phy_shutdown(dwc->usb3_phy);
|
usb_phy_shutdown(dwc->usb3_phy);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DWC3_ALIGN_MASK (16 - 1)
|
#define DWC3_ALIGN_MASK (16 - 1)
|
||||||
|
|
||||||
static int __devinit dwc3_probe(struct platform_device *pdev)
|
static int dwc3_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
@@ -515,10 +457,19 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
|
|||||||
pm_runtime_get_sync(dev);
|
pm_runtime_get_sync(dev);
|
||||||
pm_runtime_forbid(dev);
|
pm_runtime_forbid(dev);
|
||||||
|
|
||||||
|
dwc3_cache_hwparams(dwc);
|
||||||
|
|
||||||
|
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dwc->dev, "failed to allocate event buffers\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dwc3_core_init(dwc);
|
ret = dwc3_core_init(dwc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to initialize core\n");
|
dev_err(dev, "failed to initialize core\n");
|
||||||
return ret;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = DWC3_MODE(dwc->hwparams.hwparams0);
|
mode = DWC3_MODE(dwc->hwparams.hwparams0);
|
||||||
@@ -590,10 +541,13 @@ err2:
|
|||||||
err1:
|
err1:
|
||||||
dwc3_core_exit(dwc);
|
dwc3_core_exit(dwc);
|
||||||
|
|
||||||
|
err0:
|
||||||
|
dwc3_free_event_buffers(dwc);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit dwc3_remove(struct platform_device *pdev)
|
static int dwc3_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3 *dwc = platform_get_drvdata(pdev);
|
struct dwc3 *dwc = platform_get_drvdata(pdev);
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
@@ -628,7 +582,7 @@ static int __devexit dwc3_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver dwc3_driver = {
|
static struct platform_driver dwc3_driver = {
|
||||||
.probe = dwc3_probe,
|
.probe = dwc3_probe,
|
||||||
.remove = __devexit_p(dwc3_remove),
|
.remove = dwc3_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "dwc3",
|
.name = "dwc3",
|
||||||
},
|
},
|
||||||
|
@@ -868,7 +868,4 @@ void dwc3_host_exit(struct dwc3 *dwc);
|
|||||||
int dwc3_gadget_init(struct dwc3 *dwc);
|
int dwc3_gadget_init(struct dwc3 *dwc);
|
||||||
void dwc3_gadget_exit(struct dwc3 *dwc);
|
void dwc3_gadget_exit(struct dwc3 *dwc);
|
||||||
|
|
||||||
extern int dwc3_get_device_id(void);
|
|
||||||
extern void dwc3_put_device_id(int id);
|
|
||||||
|
|
||||||
#endif /* __DRIVERS_USB_DWC3_CORE_H */
|
#endif /* __DRIVERS_USB_DWC3_CORE_H */
|
||||||
|
@@ -652,7 +652,7 @@ static const struct file_operations dwc3_link_state_fops = {
|
|||||||
.release = single_release,
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
|
int dwc3_debugfs_init(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
struct dentry *file;
|
struct dentry *file;
|
||||||
@@ -703,7 +703,7 @@ err0:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
|
void dwc3_debugfs_exit(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
debugfs_remove_recursive(dwc->root);
|
debugfs_remove_recursive(dwc->root);
|
||||||
dwc->root = NULL;
|
dwc->root = NULL;
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/usb/otg.h>
|
#include <linux/usb/otg.h>
|
||||||
#include <linux/usb/nop-usb-xceiv.h>
|
#include <linux/usb/nop-usb-xceiv.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ struct dwc3_exynos {
|
|||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
|
static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
|
||||||
{
|
{
|
||||||
struct nop_usb_xceiv_platform_data pdata;
|
struct nop_usb_xceiv_platform_data pdata;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
@@ -87,14 +88,14 @@ err1:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
|
static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static int dwc3_exynos_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
|
|
||||||
struct platform_device *dwc3;
|
struct platform_device *dwc3;
|
||||||
struct dwc3_exynos *exynos;
|
struct dwc3_exynos *exynos;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
||||||
int devid;
|
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
exynos = kzalloc(sizeof(*exynos), GFP_KERNEL);
|
exynos = kzalloc(sizeof(*exynos), GFP_KERNEL);
|
||||||
@@ -103,11 +104,15 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
|
|||||||
goto err0;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, exynos);
|
/*
|
||||||
|
* 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 move to full device tree support this will vanish off.
|
||||||
|
*/
|
||||||
|
if (!pdev->dev.dma_mask)
|
||||||
|
pdev->dev.dma_mask = &dwc3_exynos_dma_mask;
|
||||||
|
|
||||||
devid = dwc3_get_device_id();
|
platform_set_drvdata(pdev, exynos);
|
||||||
if (devid < 0)
|
|
||||||
goto err1;
|
|
||||||
|
|
||||||
ret = dwc3_exynos_register_phys(exynos);
|
ret = dwc3_exynos_register_phys(exynos);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -115,10 +120,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
|
|||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwc3 = platform_device_alloc("dwc3", devid);
|
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
|
||||||
if (!dwc3) {
|
if (!dwc3) {
|
||||||
dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
|
dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
|
||||||
goto err2;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk = clk_get(&pdev->dev, "usbdrd30");
|
clk = clk_get(&pdev->dev, "usbdrd30");
|
||||||
@@ -139,14 +144,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
clk_enable(exynos->clk);
|
clk_enable(exynos->clk);
|
||||||
|
|
||||||
/* PHY initialization */
|
|
||||||
if (!pdata) {
|
|
||||||
dev_dbg(&pdev->dev, "missing platform data\n");
|
|
||||||
} else {
|
|
||||||
if (pdata->phy_init)
|
|
||||||
pdata->phy_init(pdev, pdata->phy_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = platform_device_add_resources(dwc3, pdev->resource,
|
ret = platform_device_add_resources(dwc3, pdev->resource,
|
||||||
pdev->num_resources);
|
pdev->num_resources);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -163,35 +160,24 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err4:
|
err4:
|
||||||
if (pdata && pdata->phy_exit)
|
|
||||||
pdata->phy_exit(pdev, pdata->phy_type);
|
|
||||||
|
|
||||||
clk_disable(clk);
|
clk_disable(clk);
|
||||||
clk_put(clk);
|
clk_put(clk);
|
||||||
err3:
|
err3:
|
||||||
platform_device_put(dwc3);
|
platform_device_put(dwc3);
|
||||||
err2:
|
|
||||||
dwc3_put_device_id(devid);
|
|
||||||
err1:
|
err1:
|
||||||
kfree(exynos);
|
kfree(exynos);
|
||||||
err0:
|
err0:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
|
static int dwc3_exynos_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
|
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
|
||||||
struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
|
|
||||||
|
|
||||||
platform_device_unregister(exynos->dwc3);
|
platform_device_unregister(exynos->dwc3);
|
||||||
platform_device_unregister(exynos->usb2_phy);
|
platform_device_unregister(exynos->usb2_phy);
|
||||||
platform_device_unregister(exynos->usb3_phy);
|
platform_device_unregister(exynos->usb3_phy);
|
||||||
|
|
||||||
dwc3_put_device_id(exynos->dwc3->id);
|
|
||||||
|
|
||||||
if (pdata && pdata->phy_exit)
|
|
||||||
pdata->phy_exit(pdev, pdata->phy_type);
|
|
||||||
|
|
||||||
clk_disable(exynos->clk);
|
clk_disable(exynos->clk);
|
||||||
clk_put(exynos->clk);
|
clk_put(exynos->clk);
|
||||||
|
|
||||||
@@ -200,11 +186,20 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id exynos_dwc3_match[] = {
|
||||||
|
{ .compatible = "samsung,exynos-dwc3" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, exynos_dwc3_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver dwc3_exynos_driver = {
|
static struct platform_driver dwc3_exynos_driver = {
|
||||||
.probe = dwc3_exynos_probe,
|
.probe = dwc3_exynos_probe,
|
||||||
.remove = __devexit_p(dwc3_exynos_remove),
|
.remove = dwc3_exynos_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "exynos-dwc3",
|
.name = "exynos-dwc3",
|
||||||
|
.of_match_table = of_match_ptr(exynos_dwc3_match),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -157,7 +157,7 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
|
|||||||
writel(value, base + offset);
|
writel(value, base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap)
|
static int dwc3_omap_register_phys(struct dwc3_omap *omap)
|
||||||
{
|
{
|
||||||
struct nop_usb_xceiv_platform_data pdata;
|
struct nop_usb_xceiv_platform_data pdata;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
@@ -262,7 +262,7 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit dwc3_omap_probe(struct platform_device *pdev)
|
static int dwc3_omap_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_omap_data *pdata = pdev->dev.platform_data;
|
struct dwc3_omap_data *pdata = pdev->dev.platform_data;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
@@ -272,7 +272,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
|
|||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
|
||||||
int devid;
|
|
||||||
int size;
|
int size;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
int irq;
|
int irq;
|
||||||
@@ -315,14 +314,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
devid = dwc3_get_device_id();
|
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
|
||||||
if (devid < 0)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
dwc3 = platform_device_alloc("dwc3", devid);
|
|
||||||
if (!dwc3) {
|
if (!dwc3) {
|
||||||
dev_err(dev, "couldn't allocate dwc3 device\n");
|
dev_err(dev, "couldn't allocate dwc3 device\n");
|
||||||
goto err1;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL);
|
context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL);
|
||||||
@@ -423,23 +418,16 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
err2:
|
err2:
|
||||||
platform_device_put(dwc3);
|
platform_device_put(dwc3);
|
||||||
|
|
||||||
err1:
|
|
||||||
dwc3_put_device_id(devid);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit dwc3_omap_remove(struct platform_device *pdev)
|
static int dwc3_omap_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_omap *omap = platform_get_drvdata(pdev);
|
struct dwc3_omap *omap = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
platform_device_unregister(omap->dwc3);
|
platform_device_unregister(omap->dwc3);
|
||||||
platform_device_unregister(omap->usb2_phy);
|
platform_device_unregister(omap->usb2_phy);
|
||||||
platform_device_unregister(omap->usb3_phy);
|
platform_device_unregister(omap->usb3_phy);
|
||||||
|
|
||||||
dwc3_put_device_id(omap->dwc3->id);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +441,7 @@ MODULE_DEVICE_TABLE(of, of_dwc3_matach);
|
|||||||
|
|
||||||
static struct platform_driver dwc3_omap_driver = {
|
static struct platform_driver dwc3_omap_driver = {
|
||||||
.probe = dwc3_omap_probe,
|
.probe = dwc3_omap_probe,
|
||||||
.remove = __devexit_p(dwc3_omap_remove),
|
.remove = dwc3_omap_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "omap-dwc3",
|
.name = "omap-dwc3",
|
||||||
.of_match_table = of_dwc3_matach,
|
.of_match_table = of_dwc3_matach,
|
||||||
|
@@ -58,7 +58,7 @@ struct dwc3_pci {
|
|||||||
struct platform_device *usb3_phy;
|
struct platform_device *usb3_phy;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue)
|
static int dwc3_pci_register_phys(struct dwc3_pci *glue)
|
||||||
{
|
{
|
||||||
struct nop_usb_xceiv_platform_data pdata;
|
struct nop_usb_xceiv_platform_data pdata;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
@@ -112,14 +112,13 @@ err1:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit dwc3_pci_probe(struct pci_dev *pci,
|
static int dwc3_pci_probe(struct pci_dev *pci,
|
||||||
const struct pci_device_id *id)
|
const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
struct resource res[2];
|
struct resource res[2];
|
||||||
struct platform_device *dwc3;
|
struct platform_device *dwc3;
|
||||||
struct dwc3_pci *glue;
|
struct dwc3_pci *glue;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
int devid;
|
|
||||||
struct device *dev = &pci->dev;
|
struct device *dev = &pci->dev;
|
||||||
|
|
||||||
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
|
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
|
||||||
@@ -145,13 +144,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
devid = dwc3_get_device_id();
|
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
|
||||||
if (devid < 0) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwc3 = platform_device_alloc("dwc3", devid);
|
|
||||||
if (!dwc3) {
|
if (!dwc3) {
|
||||||
dev_err(dev, "couldn't allocate dwc3 device\n");
|
dev_err(dev, "couldn't allocate dwc3 device\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@@ -172,7 +165,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
|
|||||||
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
|
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "couldn't add resources to dwc3 device\n");
|
dev_err(dev, "couldn't add resources to dwc3 device\n");
|
||||||
goto err2;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_set_drvdata(pci, glue);
|
pci_set_drvdata(pci, glue);
|
||||||
@@ -195,23 +188,18 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
|
|||||||
err3:
|
err3:
|
||||||
pci_set_drvdata(pci, NULL);
|
pci_set_drvdata(pci, NULL);
|
||||||
platform_device_put(dwc3);
|
platform_device_put(dwc3);
|
||||||
|
|
||||||
err2:
|
|
||||||
dwc3_put_device_id(devid);
|
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
pci_disable_device(pci);
|
pci_disable_device(pci);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit dwc3_pci_remove(struct pci_dev *pci)
|
static void dwc3_pci_remove(struct pci_dev *pci)
|
||||||
{
|
{
|
||||||
struct dwc3_pci *glue = pci_get_drvdata(pci);
|
struct dwc3_pci *glue = pci_get_drvdata(pci);
|
||||||
|
|
||||||
platform_device_unregister(glue->usb2_phy);
|
platform_device_unregister(glue->usb2_phy);
|
||||||
platform_device_unregister(glue->usb3_phy);
|
platform_device_unregister(glue->usb3_phy);
|
||||||
dwc3_put_device_id(glue->dwc3->id);
|
|
||||||
platform_device_unregister(glue->dwc3);
|
platform_device_unregister(glue->dwc3);
|
||||||
pci_set_drvdata(pci, NULL);
|
pci_set_drvdata(pci, NULL);
|
||||||
pci_disable_device(pci);
|
pci_disable_device(pci);
|
||||||
@@ -230,7 +218,7 @@ static struct pci_driver dwc3_pci_driver = {
|
|||||||
.name = "dwc3-pci",
|
.name = "dwc3-pci",
|
||||||
.id_table = dwc3_pci_id_table,
|
.id_table = dwc3_pci_id_table,
|
||||||
.probe = dwc3_pci_probe,
|
.probe = dwc3_pci_probe,
|
||||||
.remove = __devexit_p(dwc3_pci_remove),
|
.remove = dwc3_pci_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
||||||
|
@@ -1579,7 +1579,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
|
static int dwc3_gadget_init_endpoints(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
struct dwc3_ep *dep;
|
struct dwc3_ep *dep;
|
||||||
u8 epnum;
|
u8 epnum;
|
||||||
@@ -2374,7 +2374,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
|
|||||||
*
|
*
|
||||||
* Returns 0 on success otherwise negative errno.
|
* Returns 0 on success otherwise negative errno.
|
||||||
*/
|
*/
|
||||||
int __devinit dwc3_gadget_init(struct dwc3 *dwc)
|
int dwc3_gadget_init(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
int ret;
|
int ret;
|
||||||
|
@@ -974,7 +974,7 @@ struct console early_dbgp_console = {
|
|||||||
.index = -1,
|
.index = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_EHCI_HCD)
|
#if IS_ENABLED(CONFIG_USB)
|
||||||
int dbgp_reset_prep(struct usb_hcd *hcd)
|
int dbgp_reset_prep(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
int ret = xen_dbgp_reset_prep(hcd);
|
int ret = xen_dbgp_reset_prep(hcd);
|
||||||
@@ -1008,7 +1008,7 @@ int dbgp_external_startup(struct usb_hcd *hcd)
|
|||||||
return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
|
return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dbgp_external_startup);
|
EXPORT_SYMBOL_GPL(dbgp_external_startup);
|
||||||
#endif /* USB_EHCI_HCD */
|
#endif /* USB */
|
||||||
|
|
||||||
#ifdef CONFIG_KGDB
|
#ifdef CONFIG_KGDB
|
||||||
|
|
||||||
|
@@ -721,31 +721,6 @@ config USB_FUNCTIONFS_GENERIC
|
|||||||
Include a configuration with the Function Filesystem alone with
|
Include a configuration with the Function Filesystem alone with
|
||||||
no Ethernet interface.
|
no Ethernet interface.
|
||||||
|
|
||||||
config USB_FILE_STORAGE
|
|
||||||
tristate "File-backed Storage Gadget (DEPRECATED)"
|
|
||||||
depends on BLOCK
|
|
||||||
help
|
|
||||||
The File-backed Storage Gadget acts as a USB Mass Storage
|
|
||||||
disk drive. As its storage repository it can use a regular
|
|
||||||
file or a block device (in much the same way as the "loop"
|
|
||||||
device driver), specified as a module parameter.
|
|
||||||
|
|
||||||
Say "y" to link the driver statically, or "m" to build a
|
|
||||||
dynamically linked module called "g_file_storage".
|
|
||||||
|
|
||||||
NOTE: This driver is deprecated. Its replacement is the
|
|
||||||
Mass Storage Gadget.
|
|
||||||
|
|
||||||
config USB_FILE_STORAGE_TEST
|
|
||||||
bool "File-backed Storage Gadget testing version"
|
|
||||||
depends on USB_FILE_STORAGE
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Say "y" to generate the larger testing version of the
|
|
||||||
File-backed Storage Gadget, useful for probing the
|
|
||||||
behavior of USB Mass Storage hosts. Not needed for
|
|
||||||
normal operation.
|
|
||||||
|
|
||||||
config USB_MASS_STORAGE
|
config USB_MASS_STORAGE
|
||||||
tristate "Mass Storage Gadget"
|
tristate "Mass Storage Gadget"
|
||||||
depends on BLOCK
|
depends on BLOCK
|
||||||
@@ -756,8 +731,8 @@ config USB_MASS_STORAGE
|
|||||||
device (in much the same way as the "loop" device driver),
|
device (in much the same way as the "loop" device driver),
|
||||||
specified as a module parameter or sysfs option.
|
specified as a module parameter or sysfs option.
|
||||||
|
|
||||||
This driver is an updated replacement for the deprecated
|
This driver is a replacement for now removed File-backed
|
||||||
File-backed Storage Gadget (g_file_storage).
|
Storage Gadget (g_file_storage).
|
||||||
|
|
||||||
Say "y" to link the driver statically, or "m" to build
|
Say "y" to link the driver statically, or "m" to build
|
||||||
a dynamically linked module called "g_mass_storage".
|
a dynamically linked module called "g_mass_storage".
|
||||||
|
@@ -44,7 +44,6 @@ g_ether-y := ether.o
|
|||||||
g_serial-y := serial.o
|
g_serial-y := serial.o
|
||||||
g_midi-y := gmidi.o
|
g_midi-y := gmidi.o
|
||||||
gadgetfs-y := inode.o
|
gadgetfs-y := inode.o
|
||||||
g_file_storage-y := file_storage.o
|
|
||||||
g_mass_storage-y := mass_storage.o
|
g_mass_storage-y := mass_storage.o
|
||||||
g_printer-y := printer.o
|
g_printer-y := printer.o
|
||||||
g_cdc-y := cdc2.o
|
g_cdc-y := cdc2.o
|
||||||
@@ -62,7 +61,6 @@ obj-$(CONFIG_USB_AUDIO) += g_audio.o
|
|||||||
obj-$(CONFIG_USB_ETH) += g_ether.o
|
obj-$(CONFIG_USB_ETH) += g_ether.o
|
||||||
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
|
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
|
||||||
obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o
|
obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o
|
||||||
obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o
|
|
||||||
obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o
|
obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o
|
||||||
obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
|
obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
|
||||||
obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
|
obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
|
||||||
|
@@ -1673,7 +1673,7 @@ static void at91udc_shutdown(struct platform_device *dev)
|
|||||||
spin_unlock_irqrestore(&udc->lock, flags);
|
spin_unlock_irqrestore(&udc->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devinit at91udc_of_init(struct at91_udc *udc,
|
static void at91udc_of_init(struct at91_udc *udc,
|
||||||
struct device_node *np)
|
struct device_node *np)
|
||||||
{
|
{
|
||||||
struct at91_udc_data *board = &udc->board;
|
struct at91_udc_data *board = &udc->board;
|
||||||
@@ -1693,7 +1693,7 @@ static void __devinit at91udc_of_init(struct at91_udc *udc,
|
|||||||
board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
|
board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit at91udc_probe(struct platform_device *pdev)
|
static int at91udc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct at91_udc *udc;
|
struct at91_udc *udc;
|
||||||
|
@@ -2323,7 +2323,7 @@ static void bcm63xx_udc_gadget_release(struct device *dev)
|
|||||||
* Note that platform data is required, because pd.port_no varies from chip
|
* Note that platform data is required, because pd.port_no varies from chip
|
||||||
* to chip and is used to switch the correct USB port to device mode.
|
* to chip and is used to switch the correct USB port to device mode.
|
||||||
*/
|
*/
|
||||||
static int __devinit bcm63xx_udc_probe(struct platform_device *pdev)
|
static int bcm63xx_udc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct bcm63xx_usbd_platform_data *pd = dev->platform_data;
|
struct bcm63xx_usbd_platform_data *pd = dev->platform_data;
|
||||||
@@ -2433,7 +2433,7 @@ out_uninit:
|
|||||||
* bcm63xx_udc_remove - Remove the device from the system.
|
* bcm63xx_udc_remove - Remove the device from the system.
|
||||||
* @pdev: Platform device struct from the bcm63xx BSP code.
|
* @pdev: Platform device struct from the bcm63xx BSP code.
|
||||||
*/
|
*/
|
||||||
static int __devexit bcm63xx_udc_remove(struct platform_device *pdev)
|
static int bcm63xx_udc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct bcm63xx_udc *udc = platform_get_drvdata(pdev);
|
struct bcm63xx_udc *udc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -2450,7 +2450,7 @@ static int __devexit bcm63xx_udc_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
static struct platform_driver bcm63xx_udc_driver = {
|
static struct platform_driver bcm63xx_udc_driver = {
|
||||||
.probe = bcm63xx_udc_probe,
|
.probe = bcm63xx_udc_probe,
|
||||||
.remove = __devexit_p(bcm63xx_udc_remove),
|
.remove = bcm63xx_udc_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_MODULE_NAME,
|
.name = DRV_MODULE_NAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@@ -107,7 +107,7 @@ int config_ep_by_speed(struct usb_gadget *g,
|
|||||||
}
|
}
|
||||||
/* else: fall through */
|
/* else: fall through */
|
||||||
default:
|
default:
|
||||||
speed_desc = f->descriptors;
|
speed_desc = f->fs_descriptors;
|
||||||
}
|
}
|
||||||
/* find descriptors */
|
/* find descriptors */
|
||||||
for_each_ep_desc(speed_desc, d_spd) {
|
for_each_ep_desc(speed_desc, d_spd) {
|
||||||
@@ -200,7 +200,7 @@ int usb_add_function(struct usb_configuration *config,
|
|||||||
* as full speed ... it's the function drivers that will need
|
* as full speed ... it's the function drivers that will need
|
||||||
* to avoid bulk and ISO transfers.
|
* to avoid bulk and ISO transfers.
|
||||||
*/
|
*/
|
||||||
if (!config->fullspeed && function->descriptors)
|
if (!config->fullspeed && function->fs_descriptors)
|
||||||
config->fullspeed = true;
|
config->fullspeed = true;
|
||||||
if (!config->highspeed && function->hs_descriptors)
|
if (!config->highspeed && function->hs_descriptors)
|
||||||
config->highspeed = true;
|
config->highspeed = true;
|
||||||
@@ -363,7 +363,7 @@ static int config_buf(struct usb_configuration *config,
|
|||||||
descriptors = f->hs_descriptors;
|
descriptors = f->hs_descriptors;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
descriptors = f->descriptors;
|
descriptors = f->fs_descriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!descriptors)
|
if (!descriptors)
|
||||||
@@ -620,7 +620,7 @@ static int set_config(struct usb_composite_dev *cdev,
|
|||||||
descriptors = f->hs_descriptors;
|
descriptors = f->hs_descriptors;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
descriptors = f->descriptors;
|
descriptors = f->fs_descriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; *descriptors; ++descriptors) {
|
for (; *descriptors; ++descriptors) {
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usb/gadget.h>
|
#include <linux/usb/gadget.h>
|
||||||
|
#include <linux/usb/composite.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* usb_descriptor_fillbuf - fill buffer with descriptors
|
* usb_descriptor_fillbuf - fill buffer with descriptors
|
||||||
@@ -158,3 +158,40 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_copy_descriptors);
|
EXPORT_SYMBOL_GPL(usb_copy_descriptors);
|
||||||
|
|
||||||
|
int usb_assign_descriptors(struct usb_function *f,
|
||||||
|
struct usb_descriptor_header **fs,
|
||||||
|
struct usb_descriptor_header **hs,
|
||||||
|
struct usb_descriptor_header **ss)
|
||||||
|
{
|
||||||
|
struct usb_gadget *g = f->config->cdev->gadget;
|
||||||
|
|
||||||
|
if (fs) {
|
||||||
|
f->fs_descriptors = usb_copy_descriptors(fs);
|
||||||
|
if (!f->fs_descriptors)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (hs && gadget_is_dualspeed(g)) {
|
||||||
|
f->hs_descriptors = usb_copy_descriptors(hs);
|
||||||
|
if (!f->hs_descriptors)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (ss && gadget_is_superspeed(g)) {
|
||||||
|
f->ss_descriptors = usb_copy_descriptors(ss);
|
||||||
|
if (!f->ss_descriptors)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
usb_free_all_descriptors(f);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(usb_assign_descriptors);
|
||||||
|
|
||||||
|
void usb_free_all_descriptors(struct usb_function *f)
|
||||||
|
{
|
||||||
|
usb_free_descriptors(f->fs_descriptors);
|
||||||
|
usb_free_descriptors(f->hs_descriptors);
|
||||||
|
usb_free_descriptors(f->ss_descriptors);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
|
||||||
|
@@ -63,16 +63,20 @@ MODULE_LICENSE("GPL");
|
|||||||
struct dummy_hcd_module_parameters {
|
struct dummy_hcd_module_parameters {
|
||||||
bool is_super_speed;
|
bool is_super_speed;
|
||||||
bool is_high_speed;
|
bool is_high_speed;
|
||||||
|
unsigned int num;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dummy_hcd_module_parameters mod_data = {
|
static struct dummy_hcd_module_parameters mod_data = {
|
||||||
.is_super_speed = false,
|
.is_super_speed = false,
|
||||||
.is_high_speed = true,
|
.is_high_speed = true,
|
||||||
|
.num = 1,
|
||||||
};
|
};
|
||||||
module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
|
module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
|
||||||
MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
|
MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
|
||||||
module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
|
module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
|
||||||
MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
|
MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
|
||||||
|
module_param_named(num, mod_data.num, uint, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(num, "number of emulated controllers");
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* gadget side driver data structres */
|
/* gadget side driver data structres */
|
||||||
@@ -238,8 +242,6 @@ static inline struct dummy *gadget_dev_to_dummy(struct device *dev)
|
|||||||
return container_of(dev, struct dummy, gadget.dev);
|
return container_of(dev, struct dummy, gadget.dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dummy the_controller;
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* SLAVE/GADGET SIDE UTILITY ROUTINES */
|
/* SLAVE/GADGET SIDE UTILITY ROUTINES */
|
||||||
@@ -973,9 +975,10 @@ static void init_dummy_udc_hw(struct dummy *dum)
|
|||||||
|
|
||||||
static int dummy_udc_probe(struct platform_device *pdev)
|
static int dummy_udc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dummy *dum = &the_controller;
|
struct dummy *dum;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
dum = *((void **)dev_get_platdata(&pdev->dev));
|
||||||
dum->gadget.name = gadget_name;
|
dum->gadget.name = gadget_name;
|
||||||
dum->gadget.ops = &dummy_ops;
|
dum->gadget.ops = &dummy_ops;
|
||||||
dum->gadget.max_speed = USB_SPEED_SUPER;
|
dum->gadget.max_speed = USB_SPEED_SUPER;
|
||||||
@@ -2398,10 +2401,13 @@ static int dummy_h_get_frame(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
static int dummy_setup(struct usb_hcd *hcd)
|
static int dummy_setup(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
|
struct dummy *dum;
|
||||||
|
|
||||||
|
dum = *((void **)dev_get_platdata(hcd->self.controller));
|
||||||
hcd->self.sg_tablesize = ~0;
|
hcd->self.sg_tablesize = ~0;
|
||||||
if (usb_hcd_is_primary_hcd(hcd)) {
|
if (usb_hcd_is_primary_hcd(hcd)) {
|
||||||
the_controller.hs_hcd = hcd_to_dummy_hcd(hcd);
|
dum->hs_hcd = hcd_to_dummy_hcd(hcd);
|
||||||
the_controller.hs_hcd->dum = &the_controller;
|
dum->hs_hcd->dum = dum;
|
||||||
/*
|
/*
|
||||||
* Mark the first roothub as being USB 2.0.
|
* Mark the first roothub as being USB 2.0.
|
||||||
* The USB 3.0 roothub will be registered later by
|
* The USB 3.0 roothub will be registered later by
|
||||||
@@ -2410,8 +2416,8 @@ static int dummy_setup(struct usb_hcd *hcd)
|
|||||||
hcd->speed = HCD_USB2;
|
hcd->speed = HCD_USB2;
|
||||||
hcd->self.root_hub->speed = USB_SPEED_HIGH;
|
hcd->self.root_hub->speed = USB_SPEED_HIGH;
|
||||||
} else {
|
} else {
|
||||||
the_controller.ss_hcd = hcd_to_dummy_hcd(hcd);
|
dum->ss_hcd = hcd_to_dummy_hcd(hcd);
|
||||||
the_controller.ss_hcd->dum = &the_controller;
|
dum->ss_hcd->dum = dum;
|
||||||
hcd->speed = HCD_USB3;
|
hcd->speed = HCD_USB3;
|
||||||
hcd->self.root_hub->speed = USB_SPEED_SUPER;
|
hcd->self.root_hub->speed = USB_SPEED_SUPER;
|
||||||
}
|
}
|
||||||
@@ -2524,11 +2530,13 @@ static struct hc_driver dummy_hcd = {
|
|||||||
|
|
||||||
static int dummy_hcd_probe(struct platform_device *pdev)
|
static int dummy_hcd_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct dummy *dum;
|
||||||
struct usb_hcd *hs_hcd;
|
struct usb_hcd *hs_hcd;
|
||||||
struct usb_hcd *ss_hcd;
|
struct usb_hcd *ss_hcd;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
|
dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
|
||||||
|
dum = *((void **)dev_get_platdata(&pdev->dev));
|
||||||
|
|
||||||
if (!mod_data.is_super_speed)
|
if (!mod_data.is_super_speed)
|
||||||
dummy_hcd.flags = HCD_USB2;
|
dummy_hcd.flags = HCD_USB2;
|
||||||
@@ -2561,7 +2569,7 @@ dealloc_usb2_hcd:
|
|||||||
usb_remove_hcd(hs_hcd);
|
usb_remove_hcd(hs_hcd);
|
||||||
put_usb2_hcd:
|
put_usb2_hcd:
|
||||||
usb_put_hcd(hs_hcd);
|
usb_put_hcd(hs_hcd);
|
||||||
the_controller.hs_hcd = the_controller.ss_hcd = NULL;
|
dum->hs_hcd = dum->ss_hcd = NULL;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2579,8 +2587,8 @@ static int dummy_hcd_remove(struct platform_device *pdev)
|
|||||||
usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
|
usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
|
||||||
usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
|
usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
|
||||||
|
|
||||||
the_controller.hs_hcd = NULL;
|
dum->hs_hcd = NULL;
|
||||||
the_controller.ss_hcd = NULL;
|
dum->ss_hcd = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2627,13 +2635,15 @@ static struct platform_driver dummy_hcd_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
#define MAX_NUM_UDC 2
|
||||||
static struct platform_device *the_udc_pdev;
|
static struct platform_device *the_udc_pdev[MAX_NUM_UDC];
|
||||||
static struct platform_device *the_hcd_pdev;
|
static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
|
||||||
|
|
||||||
static int __init init(void)
|
static int __init init(void)
|
||||||
{
|
{
|
||||||
int retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
|
int i;
|
||||||
|
struct dummy *dum[MAX_NUM_UDC];
|
||||||
|
|
||||||
if (usb_disabled())
|
if (usb_disabled())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -2641,65 +2651,129 @@ static int __init init(void)
|
|||||||
if (!mod_data.is_high_speed && mod_data.is_super_speed)
|
if (!mod_data.is_high_speed && mod_data.is_super_speed)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
the_hcd_pdev = platform_device_alloc(driver_name, -1);
|
if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) {
|
||||||
if (!the_hcd_pdev)
|
pr_err("Number of emulated UDC must be in range of 1…%d\n",
|
||||||
|
MAX_NUM_UDC);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
the_hcd_pdev[i] = platform_device_alloc(driver_name, i);
|
||||||
|
if (!the_hcd_pdev[i]) {
|
||||||
|
i--;
|
||||||
|
while (i >= 0)
|
||||||
|
platform_device_put(the_hcd_pdev[i--]);
|
||||||
return retval;
|
return retval;
|
||||||
the_udc_pdev = platform_device_alloc(gadget_name, -1);
|
}
|
||||||
if (!the_udc_pdev)
|
}
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
the_udc_pdev[i] = platform_device_alloc(gadget_name, i);
|
||||||
|
if (!the_udc_pdev[i]) {
|
||||||
|
i--;
|
||||||
|
while (i >= 0)
|
||||||
|
platform_device_put(the_udc_pdev[i--]);
|
||||||
goto err_alloc_udc;
|
goto err_alloc_udc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL);
|
||||||
|
if (!dum[i])
|
||||||
|
goto err_add_pdata;
|
||||||
|
retval = platform_device_add_data(the_hcd_pdev[i], &dum[i],
|
||||||
|
sizeof(void *));
|
||||||
|
if (retval)
|
||||||
|
goto err_add_pdata;
|
||||||
|
retval = platform_device_add_data(the_udc_pdev[i], &dum[i],
|
||||||
|
sizeof(void *));
|
||||||
|
if (retval)
|
||||||
|
goto err_add_pdata;
|
||||||
|
}
|
||||||
|
|
||||||
retval = platform_driver_register(&dummy_hcd_driver);
|
retval = platform_driver_register(&dummy_hcd_driver);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_register_hcd_driver;
|
goto err_add_pdata;
|
||||||
retval = platform_driver_register(&dummy_udc_driver);
|
retval = platform_driver_register(&dummy_udc_driver);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_register_udc_driver;
|
goto err_register_udc_driver;
|
||||||
|
|
||||||
retval = platform_device_add(the_hcd_pdev);
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
if (retval < 0)
|
retval = platform_device_add(the_hcd_pdev[i]);
|
||||||
|
if (retval < 0) {
|
||||||
|
i--;
|
||||||
|
while (i >= 0)
|
||||||
|
platform_device_del(the_hcd_pdev[i--]);
|
||||||
goto err_add_hcd;
|
goto err_add_hcd;
|
||||||
if (!the_controller.hs_hcd ||
|
}
|
||||||
(!the_controller.ss_hcd && mod_data.is_super_speed)) {
|
}
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
if (!dum[i]->hs_hcd ||
|
||||||
|
(!dum[i]->ss_hcd && mod_data.is_super_speed)) {
|
||||||
/*
|
/*
|
||||||
* The hcd was added successfully but its probe function failed
|
* The hcd was added successfully but its probe
|
||||||
* for some reason.
|
* function failed for some reason.
|
||||||
*/
|
*/
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
goto err_add_udc;
|
goto err_add_udc;
|
||||||
}
|
}
|
||||||
retval = platform_device_add(the_udc_pdev);
|
}
|
||||||
if (retval < 0)
|
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
retval = platform_device_add(the_udc_pdev[i]);
|
||||||
|
if (retval < 0) {
|
||||||
|
i--;
|
||||||
|
while (i >= 0)
|
||||||
|
platform_device_del(the_udc_pdev[i]);
|
||||||
goto err_add_udc;
|
goto err_add_udc;
|
||||||
if (!platform_get_drvdata(the_udc_pdev)) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
if (!platform_get_drvdata(the_udc_pdev[i])) {
|
||||||
/*
|
/*
|
||||||
* The udc was added successfully but its probe function failed
|
* The udc was added successfully but its probe
|
||||||
* for some reason.
|
* function failed for some reason.
|
||||||
*/
|
*/
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
goto err_probe_udc;
|
goto err_probe_udc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
err_probe_udc:
|
err_probe_udc:
|
||||||
platform_device_del(the_udc_pdev);
|
for (i = 0; i < mod_data.num; i++)
|
||||||
|
platform_device_del(the_udc_pdev[i]);
|
||||||
err_add_udc:
|
err_add_udc:
|
||||||
platform_device_del(the_hcd_pdev);
|
for (i = 0; i < mod_data.num; i++)
|
||||||
|
platform_device_del(the_hcd_pdev[i]);
|
||||||
err_add_hcd:
|
err_add_hcd:
|
||||||
platform_driver_unregister(&dummy_udc_driver);
|
platform_driver_unregister(&dummy_udc_driver);
|
||||||
err_register_udc_driver:
|
err_register_udc_driver:
|
||||||
platform_driver_unregister(&dummy_hcd_driver);
|
platform_driver_unregister(&dummy_hcd_driver);
|
||||||
err_register_hcd_driver:
|
err_add_pdata:
|
||||||
platform_device_put(the_udc_pdev);
|
for (i = 0; i < mod_data.num; i++)
|
||||||
|
kfree(dum[i]);
|
||||||
|
for (i = 0; i < mod_data.num; i++)
|
||||||
|
platform_device_put(the_udc_pdev[i]);
|
||||||
err_alloc_udc:
|
err_alloc_udc:
|
||||||
platform_device_put(the_hcd_pdev);
|
for (i = 0; i < mod_data.num; i++)
|
||||||
|
platform_device_put(the_hcd_pdev[i]);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
module_init(init);
|
module_init(init);
|
||||||
|
|
||||||
static void __exit cleanup(void)
|
static void __exit cleanup(void)
|
||||||
{
|
{
|
||||||
platform_device_unregister(the_udc_pdev);
|
int i;
|
||||||
platform_device_unregister(the_hcd_pdev);
|
|
||||||
|
for (i = 0; i < mod_data.num; i++) {
|
||||||
|
struct dummy *dum;
|
||||||
|
|
||||||
|
dum = *((void **)dev_get_platdata(&the_udc_pdev[i]->dev));
|
||||||
|
|
||||||
|
platform_device_unregister(the_udc_pdev[i]);
|
||||||
|
platform_device_unregister(the_hcd_pdev[i]);
|
||||||
|
kfree(dum);
|
||||||
|
}
|
||||||
platform_driver_unregister(&dummy_udc_driver);
|
platform_driver_unregister(&dummy_udc_driver);
|
||||||
platform_driver_unregister(&dummy_hcd_driver);
|
platform_driver_unregister(&dummy_hcd_driver);
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ static inline struct f_acm *port_to_acm(struct gserial *p)
|
|||||||
|
|
||||||
/* notification endpoint uses smallish and infrequent fixed-size messages */
|
/* notification endpoint uses smallish and infrequent fixed-size messages */
|
||||||
|
|
||||||
#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
|
#define GS_NOTIFY_INTERVAL_MS 32
|
||||||
#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
|
#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
|
||||||
|
|
||||||
/* interface and class descriptors: */
|
/* interface and class descriptors: */
|
||||||
@@ -167,7 +167,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc = {
|
|||||||
.bEndpointAddress = USB_DIR_IN,
|
.bEndpointAddress = USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||||
.bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
|
.bInterval = GS_NOTIFY_INTERVAL_MS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_endpoint_descriptor acm_fs_in_desc = {
|
static struct usb_endpoint_descriptor acm_fs_in_desc = {
|
||||||
@@ -199,14 +199,13 @@ static struct usb_descriptor_header *acm_fs_function[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* high speed support: */
|
/* high speed support: */
|
||||||
|
|
||||||
static struct usb_endpoint_descriptor acm_hs_notify_desc = {
|
static struct usb_endpoint_descriptor acm_hs_notify_desc = {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = USB_DIR_IN,
|
.bEndpointAddress = USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||||
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
|
.bInterval = USB_MS_TO_HS_INTERVAL(GS_NOTIFY_INTERVAL_MS),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_endpoint_descriptor acm_hs_in_desc = {
|
static struct usb_endpoint_descriptor acm_hs_in_desc = {
|
||||||
@@ -659,37 +658,22 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
acm->notify_req->complete = acm_cdc_notify_complete;
|
acm->notify_req->complete = acm_cdc_notify_complete;
|
||||||
acm->notify_req->context = acm;
|
acm->notify_req->context = acm;
|
||||||
|
|
||||||
/* copy descriptors */
|
|
||||||
f->descriptors = usb_copy_descriptors(acm_fs_function);
|
|
||||||
if (!f->descriptors)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* support all relevant hardware speeds... we expect that when
|
/* support all relevant hardware speeds... we expect that when
|
||||||
* hardware is dual speed, all bulk-capable endpoints work at
|
* hardware is dual speed, all bulk-capable endpoints work at
|
||||||
* both speeds
|
* both speeds
|
||||||
*/
|
*/
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
|
||||||
acm_hs_in_desc.bEndpointAddress =
|
acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
|
||||||
acm_fs_in_desc.bEndpointAddress;
|
|
||||||
acm_hs_out_desc.bEndpointAddress =
|
|
||||||
acm_fs_out_desc.bEndpointAddress;
|
|
||||||
acm_hs_notify_desc.bEndpointAddress =
|
acm_hs_notify_desc.bEndpointAddress =
|
||||||
acm_fs_notify_desc.bEndpointAddress;
|
acm_fs_notify_desc.bEndpointAddress;
|
||||||
|
|
||||||
/* copy descriptors */
|
acm_ss_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
|
||||||
f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
|
acm_ss_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
|
||||||
}
|
|
||||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
|
||||||
acm_ss_in_desc.bEndpointAddress =
|
|
||||||
acm_fs_in_desc.bEndpointAddress;
|
|
||||||
acm_ss_out_desc.bEndpointAddress =
|
|
||||||
acm_fs_out_desc.bEndpointAddress;
|
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function,
|
||||||
f->ss_descriptors = usb_copy_descriptors(acm_ss_function);
|
acm_ss_function);
|
||||||
if (!f->ss_descriptors)
|
if (status)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
|
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
|
||||||
acm->port_num,
|
acm->port_num,
|
||||||
@@ -721,11 +705,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
{
|
{
|
||||||
struct f_acm *acm = func_to_acm(f);
|
struct f_acm *acm = func_to_acm(f);
|
||||||
|
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
acm_string_defs[0].id = 0;
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
usb_free_all_descriptors(f);
|
||||||
if (gadget_is_superspeed(c->cdev->gadget))
|
|
||||||
usb_free_descriptors(f->ss_descriptors);
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
gs_free_req(acm->notify, acm->notify_req);
|
gs_free_req(acm->notify, acm->notify_req);
|
||||||
kfree(acm);
|
kfree(acm);
|
||||||
}
|
}
|
||||||
@@ -762,27 +743,15 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* maybe allocate device-global string IDs, and patch descriptors */
|
/* maybe allocate device-global string IDs, and patch descriptors */
|
||||||
if (acm_string_defs[ACM_CTRL_IDX].id == 0) {
|
if (acm_string_defs[0].id == 0) {
|
||||||
status = usb_string_id(c->cdev);
|
status = usb_string_ids_tab(c->cdev, acm_string_defs);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
acm_string_defs[ACM_CTRL_IDX].id = status;
|
acm_control_interface_desc.iInterface =
|
||||||
|
acm_string_defs[ACM_CTRL_IDX].id;
|
||||||
acm_control_interface_desc.iInterface = status;
|
acm_data_interface_desc.iInterface =
|
||||||
|
acm_string_defs[ACM_DATA_IDX].id;
|
||||||
status = usb_string_id(c->cdev);
|
acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id;
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
acm_string_defs[ACM_DATA_IDX].id = status;
|
|
||||||
|
|
||||||
acm_data_interface_desc.iInterface = status;
|
|
||||||
|
|
||||||
status = usb_string_id(c->cdev);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
acm_string_defs[ACM_IAD_IDX].id = status;
|
|
||||||
|
|
||||||
acm_iad_descriptor.iFunction = status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate and initialize one new instance */
|
/* allocate and initialize one new instance */
|
||||||
|
@@ -91,7 +91,7 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g)
|
|||||||
* encapsulated commands (vendor-specific, using control-OUT).
|
* encapsulated commands (vendor-specific, using control-OUT).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
|
#define ECM_STATUS_INTERVAL_MS 32
|
||||||
#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
|
#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
|
||||||
|
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc = {
|
|||||||
.bEndpointAddress = USB_DIR_IN,
|
.bEndpointAddress = USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||||
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
|
.bInterval = ECM_STATUS_INTERVAL_MS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_endpoint_descriptor fs_ecm_in_desc = {
|
static struct usb_endpoint_descriptor fs_ecm_in_desc = {
|
||||||
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = {
|
|||||||
.bEndpointAddress = USB_DIR_IN,
|
.bEndpointAddress = USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||||
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
|
.bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_endpoint_descriptor hs_ecm_in_desc = {
|
static struct usb_endpoint_descriptor hs_ecm_in_desc = {
|
||||||
@@ -288,7 +288,7 @@ static struct usb_endpoint_descriptor ss_ecm_notify_desc = {
|
|||||||
.bEndpointAddress = USB_DIR_IN,
|
.bEndpointAddress = USB_DIR_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||||
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
|
.bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = {
|
static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = {
|
||||||
@@ -330,6 +330,7 @@ static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = {
|
|||||||
|
|
||||||
static struct usb_descriptor_header *ecm_ss_function[] = {
|
static struct usb_descriptor_header *ecm_ss_function[] = {
|
||||||
/* CDC ECM control descriptors */
|
/* CDC ECM control descriptors */
|
||||||
|
(struct usb_descriptor_header *) &ecm_iad_descriptor,
|
||||||
(struct usb_descriptor_header *) &ecm_control_intf,
|
(struct usb_descriptor_header *) &ecm_control_intf,
|
||||||
(struct usb_descriptor_header *) &ecm_header_desc,
|
(struct usb_descriptor_header *) &ecm_header_desc,
|
||||||
(struct usb_descriptor_header *) &ecm_union_desc,
|
(struct usb_descriptor_header *) &ecm_union_desc,
|
||||||
@@ -353,7 +354,7 @@ static struct usb_descriptor_header *ecm_ss_function[] = {
|
|||||||
|
|
||||||
static struct usb_string ecm_string_defs[] = {
|
static struct usb_string ecm_string_defs[] = {
|
||||||
[0].s = "CDC Ethernet Control Model (ECM)",
|
[0].s = "CDC Ethernet Control Model (ECM)",
|
||||||
[1].s = NULL /* DYNAMIC */,
|
[1].s = "",
|
||||||
[2].s = "CDC Ethernet Data",
|
[2].s = "CDC Ethernet Data",
|
||||||
[3].s = "CDC ECM",
|
[3].s = "CDC ECM",
|
||||||
{ } /* end of list */
|
{ } /* end of list */
|
||||||
@@ -742,42 +743,24 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
ecm->notify_req->context = ecm;
|
ecm->notify_req->context = ecm;
|
||||||
ecm->notify_req->complete = ecm_notify_complete;
|
ecm->notify_req->complete = ecm_notify_complete;
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
|
||||||
f->descriptors = usb_copy_descriptors(ecm_fs_function);
|
|
||||||
if (!f->descriptors)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* support all relevant hardware speeds... we expect that when
|
/* support all relevant hardware speeds... we expect that when
|
||||||
* hardware is dual speed, all bulk-capable endpoints work at
|
* hardware is dual speed, all bulk-capable endpoints work at
|
||||||
* both speeds
|
* both speeds
|
||||||
*/
|
*/
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
hs_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress;
|
||||||
hs_ecm_in_desc.bEndpointAddress =
|
hs_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress;
|
||||||
fs_ecm_in_desc.bEndpointAddress;
|
|
||||||
hs_ecm_out_desc.bEndpointAddress =
|
|
||||||
fs_ecm_out_desc.bEndpointAddress;
|
|
||||||
hs_ecm_notify_desc.bEndpointAddress =
|
hs_ecm_notify_desc.bEndpointAddress =
|
||||||
fs_ecm_notify_desc.bEndpointAddress;
|
fs_ecm_notify_desc.bEndpointAddress;
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
ss_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress;
|
||||||
f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
|
ss_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress;
|
||||||
if (!f->hs_descriptors)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
|
||||||
ss_ecm_in_desc.bEndpointAddress =
|
|
||||||
fs_ecm_in_desc.bEndpointAddress;
|
|
||||||
ss_ecm_out_desc.bEndpointAddress =
|
|
||||||
fs_ecm_out_desc.bEndpointAddress;
|
|
||||||
ss_ecm_notify_desc.bEndpointAddress =
|
ss_ecm_notify_desc.bEndpointAddress =
|
||||||
fs_ecm_notify_desc.bEndpointAddress;
|
fs_ecm_notify_desc.bEndpointAddress;
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function,
|
||||||
f->ss_descriptors = usb_copy_descriptors(ecm_ss_function);
|
ecm_ss_function);
|
||||||
if (!f->ss_descriptors)
|
if (status)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: all that is done without knowing or caring about
|
/* NOTE: all that is done without knowing or caring about
|
||||||
* the network link ... which is unavailable to this code
|
* the network link ... which is unavailable to this code
|
||||||
@@ -795,11 +778,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (f->descriptors)
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
if (f->hs_descriptors)
|
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
|
||||||
|
|
||||||
if (ecm->notify_req) {
|
if (ecm->notify_req) {
|
||||||
kfree(ecm->notify_req->buf);
|
kfree(ecm->notify_req->buf);
|
||||||
usb_ep_free_request(ecm->notify, ecm->notify_req);
|
usb_ep_free_request(ecm->notify, ecm->notify_req);
|
||||||
@@ -808,9 +786,9 @@ fail:
|
|||||||
/* we might as well release our claims on endpoints */
|
/* we might as well release our claims on endpoints */
|
||||||
if (ecm->notify)
|
if (ecm->notify)
|
||||||
ecm->notify->driver_data = NULL;
|
ecm->notify->driver_data = NULL;
|
||||||
if (ecm->port.out_ep->desc)
|
if (ecm->port.out_ep)
|
||||||
ecm->port.out_ep->driver_data = NULL;
|
ecm->port.out_ep->driver_data = NULL;
|
||||||
if (ecm->port.in_ep->desc)
|
if (ecm->port.in_ep)
|
||||||
ecm->port.in_ep->driver_data = NULL;
|
ecm->port.in_ep->driver_data = NULL;
|
||||||
|
|
||||||
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
|
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
|
||||||
@@ -825,16 +803,11 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
|
|
||||||
DBG(c->cdev, "ecm unbind\n");
|
DBG(c->cdev, "ecm unbind\n");
|
||||||
|
|
||||||
if (gadget_is_superspeed(c->cdev->gadget))
|
ecm_string_defs[0].id = 0;
|
||||||
usb_free_descriptors(f->ss_descriptors);
|
usb_free_all_descriptors(f);
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
|
|
||||||
kfree(ecm->notify_req->buf);
|
kfree(ecm->notify_req->buf);
|
||||||
usb_ep_free_request(ecm->notify, ecm->notify_req);
|
usb_ep_free_request(ecm->notify, ecm->notify_req);
|
||||||
|
|
||||||
ecm_string_defs[1].s = NULL;
|
|
||||||
kfree(ecm);
|
kfree(ecm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,36 +832,15 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
|
|||||||
if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
|
if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* maybe allocate device-global string IDs */
|
|
||||||
if (ecm_string_defs[0].id == 0) {
|
if (ecm_string_defs[0].id == 0) {
|
||||||
|
status = usb_string_ids_tab(c->cdev, ecm_string_defs);
|
||||||
/* control interface label */
|
if (status)
|
||||||
status = usb_string_id(c->cdev);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
return status;
|
||||||
ecm_string_defs[0].id = status;
|
|
||||||
ecm_control_intf.iInterface = status;
|
|
||||||
|
|
||||||
/* data interface label */
|
ecm_control_intf.iInterface = ecm_string_defs[0].id;
|
||||||
status = usb_string_id(c->cdev);
|
ecm_data_intf.iInterface = ecm_string_defs[2].id;
|
||||||
if (status < 0)
|
ecm_desc.iMACAddress = ecm_string_defs[1].id;
|
||||||
return status;
|
ecm_iad_descriptor.iFunction = ecm_string_defs[3].id;
|
||||||
ecm_string_defs[2].id = status;
|
|
||||||
ecm_data_intf.iInterface = status;
|
|
||||||
|
|
||||||
/* MAC address */
|
|
||||||
status = usb_string_id(c->cdev);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
ecm_string_defs[1].id = status;
|
|
||||||
ecm_desc.iMACAddress = status;
|
|
||||||
|
|
||||||
/* IAD label */
|
|
||||||
status = usb_string_id(c->cdev);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
ecm_string_defs[3].id = status;
|
|
||||||
ecm_iad_descriptor.iFunction = status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate and initialize one new instance */
|
/* allocate and initialize one new instance */
|
||||||
@@ -913,9 +865,7 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
|
|||||||
ecm->port.func.disable = ecm_disable;
|
ecm->port.func.disable = ecm_disable;
|
||||||
|
|
||||||
status = usb_add_function(c, &ecm->port.func);
|
status = usb_add_function(c, &ecm->port.func);
|
||||||
if (status) {
|
if (status)
|
||||||
ecm_string_defs[1].s = NULL;
|
|
||||||
kfree(ecm);
|
kfree(ecm);
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@@ -274,38 +274,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
|
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
|
||||||
f->descriptors = usb_copy_descriptors(eem_fs_function);
|
|
||||||
if (!f->descriptors)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* support all relevant hardware speeds... we expect that when
|
/* support all relevant hardware speeds... we expect that when
|
||||||
* hardware is dual speed, all bulk-capable endpoints work at
|
* hardware is dual speed, all bulk-capable endpoints work at
|
||||||
* both speeds
|
* both speeds
|
||||||
*/
|
*/
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
eem_hs_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
|
||||||
eem_hs_in_desc.bEndpointAddress =
|
eem_hs_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
|
||||||
eem_fs_in_desc.bEndpointAddress;
|
|
||||||
eem_hs_out_desc.bEndpointAddress =
|
|
||||||
eem_fs_out_desc.bEndpointAddress;
|
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
eem_ss_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
|
||||||
f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
|
eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
|
||||||
if (!f->hs_descriptors)
|
|
||||||
|
status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function,
|
||||||
|
eem_ss_function);
|
||||||
|
if (status)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
|
||||||
eem_ss_in_desc.bEndpointAddress =
|
|
||||||
eem_fs_in_desc.bEndpointAddress;
|
|
||||||
eem_ss_out_desc.bEndpointAddress =
|
|
||||||
eem_fs_out_desc.bEndpointAddress;
|
|
||||||
|
|
||||||
/* copy descriptors, and track endpoint copies */
|
|
||||||
f->ss_descriptors = usb_copy_descriptors(eem_ss_function);
|
|
||||||
if (!f->ss_descriptors)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
|
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
|
||||||
gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
||||||
@@ -314,15 +296,10 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (f->descriptors)
|
usb_free_all_descriptors(f);
|
||||||
usb_free_descriptors(f->descriptors);
|
if (eem->port.out_ep)
|
||||||
if (f->hs_descriptors)
|
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
|
||||||
|
|
||||||
/* we might as well release our claims on endpoints */
|
|
||||||
if (eem->port.out_ep->desc)
|
|
||||||
eem->port.out_ep->driver_data = NULL;
|
eem->port.out_ep->driver_data = NULL;
|
||||||
if (eem->port.in_ep->desc)
|
if (eem->port.in_ep)
|
||||||
eem->port.in_ep->driver_data = NULL;
|
eem->port.in_ep->driver_data = NULL;
|
||||||
|
|
||||||
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
|
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
|
||||||
@@ -337,11 +314,7 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
|
|
||||||
DBG(c->cdev, "eem unbind\n");
|
DBG(c->cdev, "eem unbind\n");
|
||||||
|
|
||||||
if (gadget_is_superspeed(c->cdev->gadget))
|
usb_free_all_descriptors(f);
|
||||||
usb_free_descriptors(f->ss_descriptors);
|
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
kfree(eem);
|
kfree(eem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2097,7 +2097,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
|
|||||||
if (isHS)
|
if (isHS)
|
||||||
func->function.hs_descriptors[(long)valuep] = desc;
|
func->function.hs_descriptors[(long)valuep] = desc;
|
||||||
else
|
else
|
||||||
func->function.descriptors[(long)valuep] = desc;
|
func->function.fs_descriptors[(long)valuep] = desc;
|
||||||
|
|
||||||
if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
|
if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2249,7 +2249,7 @@ static int ffs_func_bind(struct usb_configuration *c,
|
|||||||
* numbers without worrying that it may be described later on.
|
* numbers without worrying that it may be described later on.
|
||||||
*/
|
*/
|
||||||
if (likely(full)) {
|
if (likely(full)) {
|
||||||
func->function.descriptors = data->fs_descs;
|
func->function.fs_descriptors = data->fs_descs;
|
||||||
ret = ffs_do_descs(ffs->fs_descs_count,
|
ret = ffs_do_descs(ffs->fs_descs_count,
|
||||||
data->raw_descs,
|
data->raw_descs,
|
||||||
sizeof data->raw_descs,
|
sizeof data->raw_descs,
|
||||||
|
@@ -573,7 +573,6 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
goto fail;
|
goto fail;
|
||||||
hidg_interface_desc.bInterfaceNumber = status;
|
hidg_interface_desc.bInterfaceNumber = status;
|
||||||
|
|
||||||
|
|
||||||
/* allocate instance-specific endpoints */
|
/* allocate instance-specific endpoints */
|
||||||
status = -ENODEV;
|
status = -ENODEV;
|
||||||
ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
|
ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
|
||||||
@@ -609,20 +608,15 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
hidg_desc.desc[0].wDescriptorLength =
|
hidg_desc.desc[0].wDescriptorLength =
|
||||||
cpu_to_le16(hidg->report_desc_length);
|
cpu_to_le16(hidg->report_desc_length);
|
||||||
|
|
||||||
/* copy descriptors */
|
|
||||||
f->descriptors = usb_copy_descriptors(hidg_fs_descriptors);
|
|
||||||
if (!f->descriptors)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
|
||||||
hidg_hs_in_ep_desc.bEndpointAddress =
|
hidg_hs_in_ep_desc.bEndpointAddress =
|
||||||
hidg_fs_in_ep_desc.bEndpointAddress;
|
hidg_fs_in_ep_desc.bEndpointAddress;
|
||||||
hidg_hs_out_ep_desc.bEndpointAddress =
|
hidg_hs_out_ep_desc.bEndpointAddress =
|
||||||
hidg_fs_out_ep_desc.bEndpointAddress;
|
hidg_fs_out_ep_desc.bEndpointAddress;
|
||||||
f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
|
|
||||||
if (!f->hs_descriptors)
|
status = usb_assign_descriptors(f, hidg_fs_descriptors,
|
||||||
|
hidg_hs_descriptors, NULL);
|
||||||
|
if (status)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
mutex_init(&hidg->lock);
|
mutex_init(&hidg->lock);
|
||||||
spin_lock_init(&hidg->spinlock);
|
spin_lock_init(&hidg->spinlock);
|
||||||
@@ -649,9 +643,7 @@ fail:
|
|||||||
usb_ep_free_request(hidg->in_ep, hidg->req);
|
usb_ep_free_request(hidg->in_ep, hidg->req);
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
usb_free_all_descriptors(f);
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,9 +660,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
kfree(hidg->req->buf);
|
kfree(hidg->req->buf);
|
||||||
usb_ep_free_request(hidg->in_ep, hidg->req);
|
usb_ep_free_request(hidg->in_ep, hidg->req);
|
||||||
|
|
||||||
/* free descriptors copies */
|
usb_free_all_descriptors(f);
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
|
|
||||||
kfree(hidg->report_desc);
|
kfree(hidg->report_desc);
|
||||||
kfree(hidg);
|
kfree(hidg);
|
||||||
|
@@ -177,6 +177,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
struct usb_composite_dev *cdev = c->cdev;
|
struct usb_composite_dev *cdev = c->cdev;
|
||||||
struct f_loopback *loop = func_to_loop(f);
|
struct f_loopback *loop = func_to_loop(f);
|
||||||
int id;
|
int id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* allocate interface ID(s) */
|
/* allocate interface ID(s) */
|
||||||
id = usb_interface_id(c, f);
|
id = usb_interface_id(c, f);
|
||||||
@@ -201,22 +202,19 @@ autoconf_fail:
|
|||||||
loop->out_ep->driver_data = cdev; /* claim */
|
loop->out_ep->driver_data = cdev; /* claim */
|
||||||
|
|
||||||
/* support high speed hardware */
|
/* support high speed hardware */
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
|
||||||
hs_loop_source_desc.bEndpointAddress =
|
hs_loop_source_desc.bEndpointAddress =
|
||||||
fs_loop_source_desc.bEndpointAddress;
|
fs_loop_source_desc.bEndpointAddress;
|
||||||
hs_loop_sink_desc.bEndpointAddress =
|
hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
|
||||||
fs_loop_sink_desc.bEndpointAddress;
|
|
||||||
f->hs_descriptors = hs_loopback_descs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* support super speed hardware */
|
/* support super speed hardware */
|
||||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
|
||||||
ss_loop_source_desc.bEndpointAddress =
|
ss_loop_source_desc.bEndpointAddress =
|
||||||
fs_loop_source_desc.bEndpointAddress;
|
fs_loop_source_desc.bEndpointAddress;
|
||||||
ss_loop_sink_desc.bEndpointAddress =
|
ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
|
||||||
fs_loop_sink_desc.bEndpointAddress;
|
|
||||||
f->ss_descriptors = ss_loopback_descs;
|
ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs,
|
||||||
}
|
ss_loopback_descs);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
||||||
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
||||||
@@ -228,6 +226,7 @@ autoconf_fail:
|
|||||||
static void
|
static void
|
||||||
loopback_unbind(struct usb_configuration *c, struct usb_function *f)
|
loopback_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||||
{
|
{
|
||||||
|
usb_free_all_descriptors(f);
|
||||||
kfree(func_to_loop(f));
|
kfree(func_to_loop(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +378,6 @@ static int __init loopback_bind_config(struct usb_configuration *c)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
loop->function.name = "loopback";
|
loop->function.name = "loopback";
|
||||||
loop->function.descriptors = fs_loopback_descs;
|
|
||||||
loop->function.bind = loopback_bind;
|
loop->function.bind = loopback_bind;
|
||||||
loop->function.unbind = loopback_unbind;
|
loop->function.unbind = loopback_unbind;
|
||||||
loop->function.set_alt = loopback_set_alt;
|
loop->function.set_alt = loopback_set_alt;
|
||||||
|
@@ -228,10 +228,6 @@
|
|||||||
|
|
||||||
static const char fsg_string_interface[] = "Mass Storage";
|
static const char fsg_string_interface[] = "Mass Storage";
|
||||||
|
|
||||||
#define FSG_NO_DEVICE_STRINGS 1
|
|
||||||
#define FSG_NO_OTG 1
|
|
||||||
#define FSG_NO_INTR_EP 1
|
|
||||||
|
|
||||||
#include "storage_common.c"
|
#include "storage_common.c"
|
||||||
|
|
||||||
|
|
||||||
@@ -2904,9 +2900,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fsg_common_put(common);
|
fsg_common_put(common);
|
||||||
usb_free_descriptors(fsg->function.descriptors);
|
usb_free_all_descriptors(&fsg->function);
|
||||||
usb_free_descriptors(fsg->function.hs_descriptors);
|
|
||||||
usb_free_descriptors(fsg->function.ss_descriptors);
|
|
||||||
kfree(fsg);
|
kfree(fsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2916,6 +2910,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
struct usb_gadget *gadget = c->cdev->gadget;
|
struct usb_gadget *gadget = c->cdev->gadget;
|
||||||
int i;
|
int i;
|
||||||
struct usb_ep *ep;
|
struct usb_ep *ep;
|
||||||
|
unsigned max_burst;
|
||||||
|
int ret;
|
||||||
|
|
||||||
fsg->gadget = gadget;
|
fsg->gadget = gadget;
|
||||||
|
|
||||||
@@ -2939,26 +2935,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
ep->driver_data = fsg->common; /* claim the endpoint */
|
ep->driver_data = fsg->common; /* claim the endpoint */
|
||||||
fsg->bulk_out = ep;
|
fsg->bulk_out = ep;
|
||||||
|
|
||||||
/* Copy descriptors */
|
|
||||||
f->descriptors = usb_copy_descriptors(fsg_fs_function);
|
|
||||||
if (unlikely(!f->descriptors))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (gadget_is_dualspeed(gadget)) {
|
|
||||||
/* Assume endpoint addresses are the same for both speeds */
|
/* Assume endpoint addresses are the same for both speeds */
|
||||||
fsg_hs_bulk_in_desc.bEndpointAddress =
|
fsg_hs_bulk_in_desc.bEndpointAddress =
|
||||||
fsg_fs_bulk_in_desc.bEndpointAddress;
|
fsg_fs_bulk_in_desc.bEndpointAddress;
|
||||||
fsg_hs_bulk_out_desc.bEndpointAddress =
|
fsg_hs_bulk_out_desc.bEndpointAddress =
|
||||||
fsg_fs_bulk_out_desc.bEndpointAddress;
|
fsg_fs_bulk_out_desc.bEndpointAddress;
|
||||||
f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
|
|
||||||
if (unlikely(!f->hs_descriptors)) {
|
|
||||||
usb_free_descriptors(f->descriptors);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gadget_is_superspeed(gadget)) {
|
|
||||||
unsigned max_burst;
|
|
||||||
|
|
||||||
/* Calculate bMaxBurst, we know packet size is 1024 */
|
/* Calculate bMaxBurst, we know packet size is 1024 */
|
||||||
max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
|
max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
|
||||||
@@ -2971,13 +2952,10 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
fsg_fs_bulk_out_desc.bEndpointAddress;
|
fsg_fs_bulk_out_desc.bEndpointAddress;
|
||||||
fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
|
fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
|
||||||
|
|
||||||
f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
|
ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
|
||||||
if (unlikely(!f->ss_descriptors)) {
|
fsg_ss_function);
|
||||||
usb_free_descriptors(f->hs_descriptors);
|
if (ret)
|
||||||
usb_free_descriptors(f->descriptors);
|
goto autoconf_fail;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -2986,7 +2964,6 @@ autoconf_fail:
|
|||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************** ADD FUNCTION ******************************/
|
/****************************** ADD FUNCTION ******************************/
|
||||||
|
|
||||||
static struct usb_gadget_strings *fsg_strings_array[] = {
|
static struct usb_gadget_strings *fsg_strings_array[] = {
|
||||||
|
@@ -414,7 +414,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
kfree(midi->id);
|
kfree(midi->id);
|
||||||
midi->id = NULL;
|
midi->id = NULL;
|
||||||
|
|
||||||
usb_free_descriptors(f->descriptors);
|
usb_free_all_descriptors(f);
|
||||||
kfree(midi);
|
kfree(midi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,19 +881,25 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
* both speeds
|
* both speeds
|
||||||
*/
|
*/
|
||||||
/* copy descriptors, and track endpoint copies */
|
/* copy descriptors, and track endpoint copies */
|
||||||
|
f->fs_descriptors = usb_copy_descriptors(midi_function);
|
||||||
|
if (!f->fs_descriptors)
|
||||||
|
goto fail_f_midi;
|
||||||
|
|
||||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
||||||
c->highspeed = true;
|
|
||||||
bulk_in_desc.wMaxPacketSize = cpu_to_le16(512);
|
bulk_in_desc.wMaxPacketSize = cpu_to_le16(512);
|
||||||
bulk_out_desc.wMaxPacketSize = cpu_to_le16(512);
|
bulk_out_desc.wMaxPacketSize = cpu_to_le16(512);
|
||||||
f->hs_descriptors = usb_copy_descriptors(midi_function);
|
f->hs_descriptors = usb_copy_descriptors(midi_function);
|
||||||
} else {
|
if (!f->hs_descriptors)
|
||||||
f->descriptors = usb_copy_descriptors(midi_function);
|
goto fail_f_midi;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(midi_function);
|
kfree(midi_function);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail_f_midi:
|
||||||
|
kfree(midi_function);
|
||||||
|
usb_free_descriptors(f->hs_descriptors);
|
||||||
fail:
|
fail:
|
||||||
/* we might as well release our claims on endpoints */
|
/* we might as well release our claims on endpoints */
|
||||||
if (midi->out_ep)
|
if (midi->out_ep)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user