Pull more USB fixes from Greg Kroah-Hartman: "Here are some more USB fixes for the 3.8-rc4 tree. Some gadget driver fixes, and finally resolved the ehci-mxc driver build issues (it's just some code moving around and being deleted)." * tag 'usb-3.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: USB: EHCI: fix build error in ehci-mxc USB: EHCI: add a name for the platform-private field USB: EHCI: fix incorrect configuration test USB: EHCI: Move definition of EHCI_STATS to ehci.h USB: UHCI: fix IRQ race during initialization usb: gadget: FunctionFS: Fix missing braces in parse_opts usb: dwc3: gadget: fix ep->maxburst for ep0 ARM: i.MX clock: Change the connection-id for fsl-usb2-udc usb: gadget: fsl_mxc_udc: replace MX35_IO_ADDRESS to ioremap usb: gadget: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id usb: musb: cppi_dma: drop '__init' annotation
Unified · Split
| @@ -254,9 +254,9 @@ int __init mx25_clocks_init(void) · 253 unmodified lines | ||
| 254 | 254 | clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); |
| 255 | 255 | clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2"); |
| 256 | 256 | clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); |
| 257 | − clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); | |
| 258 | − clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc"); | |
| 259 | − clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); | |
| 257 | + clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27"); | |
| 258 | + clk_register_clkdev(clk[usbotg_ahb], "ahb", "imx-udc-mx27"); | |
| 259 | + clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27"); | |
| 260 | 260 | clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0"); |
| 261 | 261 | /* i.mx25 has the i.mx35 type cspi */ |
| 262 | 262 | clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0"); |
| @@ -236,9 +236,9 @@ int __init mx27_clocks_init(unsigned long fref) · 235 unmodified lines | ||
| 236 | 236 | clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0"); |
| 237 | 237 | clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0"); |
| 238 | 238 | clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0"); |
| 239 | − clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); | |
| 240 | − clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); | |
| 241 | − clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); | |
| 239 | + clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27"); | |
| 240 | + clk_register_clkdev(clk[usb_ipg_gate], "ipg", "imx-udc-mx27"); | |
| 241 | + clk_register_clkdev(clk[usb_ahb_gate], "ahb", "imx-udc-mx27"); | |
| 242 | 242 | clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); |
| 243 | 243 | clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0"); |
| 244 | 244 | clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0"); |
| @@ -139,9 +139,9 @@ int __init mx31_clocks_init(unsigned long fref) · 138 unmodified lines | ||
| 139 | 139 | clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2"); |
| 140 | 140 | clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2"); |
| 141 | 141 | clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); |
| 142 | − clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc"); | |
| 143 | − clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc"); | |
| 144 | − clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); | |
| 142 | + clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx27"); | |
| 143 | + clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx27"); | |
| 144 | + clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27"); | |
| 145 | 145 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); |
| 146 | 146 | /* i.mx31 has the i.mx21 type uart */ |
| 147 | 147 | clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); |
| @@ -251,9 +251,9 @@ int __init mx35_clocks_init() · 250 unmodified lines | ||
| 251 | 251 | clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); |
| 252 | 252 | clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); |
| 253 | 253 | clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2"); |
| 254 | − clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); | |
| 255 | − clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); | |
| 256 | − clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc"); | |
| 254 | + clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27"); | |
| 255 | + clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27"); | |
| 256 | + clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx27"); | |
| 257 | 257 | clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); |
| 258 | 258 | clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); |
| 259 | 259 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); |
| @@ -269,9 +269,9 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, · 268 unmodified lines | ||
| 269 | 269 | clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2"); |
| 270 | 270 | clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2"); |
| 271 | 271 | clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2"); |
| 272 | − clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc"); | |
| 273 | − clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc"); | |
| 274 | − clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc"); | |
| 272 | + clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51"); | |
| 273 | + clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51"); | |
| 274 | + clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51"); | |
| 275 | 275 | clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand"); |
| 276 | 276 | clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0"); |
| 277 | 277 | clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1"); |
| @@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan( · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | #include <linux/fsl_devices.h> |
| 65 | 65 | struct imx_fsl_usb2_udc_data { |
| 66 | + const char *devid; | |
| 66 | 67 | resource_size_t iobase; |
| 67 | 68 | resource_size_t irq; |
| 68 | 69 | }; |
| @@ -11,35 +11,36 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "../hardware.h" |
| 12 | 12 | #include "devices-common.h" |
| 13 | 13 | |
| 14 | −#define imx_fsl_usb2_udc_data_entry_single(soc) \ | |
| 14 | +#define imx_fsl_usb2_udc_data_entry_single(soc, _devid) \ | |
| 15 | 15 | { \ |
| 16 | + .devid = _devid, \ | |
| 16 | 17 | .iobase = soc ## _USB_OTG_BASE_ADDR, \ |
| 17 | 18 | .irq = soc ## _INT_USB_OTG, \ |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | 21 | #ifdef CONFIG_SOC_IMX25 |
| 21 | 22 | const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst = |
| 22 | − imx_fsl_usb2_udc_data_entry_single(MX25); | |
| 23 | + imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx27"); | |
| 23 | 24 | #endif /* ifdef CONFIG_SOC_IMX25 */ |
| 24 | 25 | |
| 25 | 26 | #ifdef CONFIG_SOC_IMX27 |
| 26 | 27 | const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst = |
| 27 | − imx_fsl_usb2_udc_data_entry_single(MX27); | |
| 28 | + imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27"); | |
| 28 | 29 | #endif /* ifdef CONFIG_SOC_IMX27 */ |
| 29 | 30 | |
| 30 | 31 | #ifdef CONFIG_SOC_IMX31 |
| 31 | 32 | const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst = |
| 32 | − imx_fsl_usb2_udc_data_entry_single(MX31); | |
| 33 | + imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx27"); | |
| 33 | 34 | #endif /* ifdef CONFIG_SOC_IMX31 */ |
| 34 | 35 | |
| 35 | 36 | #ifdef CONFIG_SOC_IMX35 |
| 36 | 37 | const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst = |
| 37 | − imx_fsl_usb2_udc_data_entry_single(MX35); | |
| 38 | + imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx27"); | |
| 38 | 39 | #endif /* ifdef CONFIG_SOC_IMX35 */ |
| 39 | 40 | |
| 40 | 41 | #ifdef CONFIG_SOC_IMX51 |
| 41 | 42 | const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst = |
| 42 | − imx_fsl_usb2_udc_data_entry_single(MX51); | |
| 43 | + imx_fsl_usb2_udc_data_entry_single(MX51, "imx-udc-mx51"); | |
| 43 | 44 | #endif |
| 44 | 45 | |
| 45 | 46 | struct platform_device *__init imx_add_fsl_usb2_udc( |
| @@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc( · 11 unmodified lines | ||
| 57 | 58 | .flags = IORESOURCE_IRQ, |
| 58 | 59 | }, |
| 59 | 60 | }; |
| 60 | − return imx_add_platform_device_dmamask("fsl-usb2-udc", -1, | |
| 61 | + return imx_add_platform_device_dmamask(data->devid, -1, | |
| 61 | 62 | res, ARRAY_SIZE(res), |
| 62 | 63 | pdata, sizeof(*pdata), DMA_BIT_MASK(32)); |
| 63 | 64 | } |
| @@ -1605,6 +1605,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) · 1604 unmodified lines | ||
| 1605 | 1605 | |
| 1606 | 1606 | if (epnum == 0 || epnum == 1) { |
| 1607 | 1607 | dep->endpoint.maxpacket = 512; |
| 1608 | + dep->endpoint.maxburst = 1; | |
| 1608 | 1609 | dep->endpoint.ops = &dwc3_gadget_ep0_ops; |
| 1609 | 1610 | if (!epnum) |
| 1610 | 1611 | dwc->gadget.ep0 = &dep->endpoint; |
| @@ -1153,15 +1153,15 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) · 1152 unmodified lines | ||
| 1153 | 1153 | pr_err("%s: unmapped value: %lu\n", opts, value); |
| 1154 | 1154 | return -EINVAL; |
| 1155 | 1155 | } |
| 1156 | − } | |
| 1157 | − else if (!memcmp(opts, "gid", 3)) | |
| 1156 | + } else if (!memcmp(opts, "gid", 3)) { | |
| 1158 | 1157 | data->perms.gid = make_kgid(current_user_ns(), value); |
| 1159 | 1158 | if (!gid_valid(data->perms.gid)) { |
| 1160 | 1159 | pr_err("%s: unmapped value: %lu\n", opts, value); |
| 1161 | 1160 | return -EINVAL; |
| 1162 | 1161 | } |
| 1163 | − else | |
| 1162 | + } else { | |
| 1164 | 1163 | goto invalid; |
| 1164 | + } | |
| 1165 | 1165 | break; |
| 1166 | 1166 | |
| 1167 | 1167 | default: |
| @@ -18,14 +18,13 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/platform_device.h> |
| 19 | 19 | #include <linux/io.h> |
| 20 | 20 | |
| 21 | −#include <mach/hardware.h> | |
| 22 | − | |
| 23 | 21 | static struct clk *mxc_ahb_clk; |
| 24 | 22 | static struct clk *mxc_per_clk; |
| 25 | 23 | static struct clk *mxc_ipg_clk; |
| 26 | 24 | |
| 27 | 25 | /* workaround ENGcm09152 for i.MX35 */ |
| 28 | −#define USBPHYCTRL_OTGBASE_OFFSET 0x608 | |
| 26 | +#define MX35_USBPHYCTRL_OFFSET 0x600 | |
| 27 | +#define USBPHYCTRL_OTGBASE_OFFSET 0x8 | |
| 29 | 28 | #define USBPHYCTRL_EVDO (1 << 23) |
| 30 | 29 | |
| 31 | 30 | int fsl_udc_clk_init(struct platform_device *pdev) |
| @@ -59,7 +58,7 @@ int fsl_udc_clk_init(struct platform_device *pdev) · 27 unmodified lines | ||
| 59 | 58 | clk_prepare_enable(mxc_per_clk); |
| 60 | 59 | |
| 61 | 60 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ |
| 62 | − if (!cpu_is_mx51()) { | |
| 61 | + if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) { | |
| 63 | 62 | freq = clk_get_rate(mxc_per_clk); |
| 64 | 63 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && |
| 65 | 64 | (freq < 59999000 || freq > 60001000)) { |
| @@ -79,27 +78,40 @@ eclkrate: · 13 unmodified lines | ||
| 79 | 78 | return ret; |
| 80 | 79 | } |
| 81 | 80 | |
| 82 | −void fsl_udc_clk_finalize(struct platform_device *pdev) | |
| 81 | +int fsl_udc_clk_finalize(struct platform_device *pdev) | |
| 83 | 82 | { |
| 84 | 83 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; |
| 85 | − if (cpu_is_mx35()) { | |
| 86 | − unsigned int v; | |
| 84 | + int ret = 0; | |
| 87 | 85 | |
| 88 | − /* workaround ENGcm09152 for i.MX35 */ | |
| 89 | − if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { | |
| 90 | − v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + | |
| 91 | − USBPHYCTRL_OTGBASE_OFFSET)); | |
| 92 | − writel(v | USBPHYCTRL_EVDO, | |
| 93 | − MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + | |
| 94 | − USBPHYCTRL_OTGBASE_OFFSET)); | |
| 86 | + /* workaround ENGcm09152 for i.MX35 */ | |
| 87 | + if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { | |
| 88 | + unsigned int v; | |
| 89 | + struct resource *res = platform_get_resource | |
| 90 | + (pdev, IORESOURCE_MEM, 0); | |
| 91 | + void __iomem *phy_regs = ioremap(res->start + | |
| 92 | + MX35_USBPHYCTRL_OFFSET, 512); | |
| 93 | + if (!phy_regs) { | |
| 94 | + dev_err(&pdev->dev, "ioremap for phy address fails\n"); | |
| 95 | + ret = -EINVAL; | |
| 96 | + goto ioremap_err; | |
| 95 | 97 | } |
| 98 | + | |
| 99 | + v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | |
| 100 | + writel(v | USBPHYCTRL_EVDO, | |
| 101 | + phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | |
| 102 | + | |
| 103 | + iounmap(phy_regs); | |
| 96 | 104 | } |
| 97 | 105 | |
| 106 | + | |
| 107 | +ioremap_err: | |
| 98 | 108 | /* ULPI transceivers don't need usbpll */ |
| 99 | 109 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { |
| 100 | 110 | clk_disable_unprepare(mxc_per_clk); |
| 101 | 111 | mxc_per_clk = NULL; |
| 102 | 112 | } |
| 113 | + | |
| 114 | + return ret; | |
| 103 | 115 | } |
| 104 | 116 | |
| 105 | 117 | void fsl_udc_clk_release(void) |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/fsl_devices.h> |
| 42 | 42 | #include <linux/dmapool.h> |
| 43 | 43 | #include <linux/delay.h> |
| 44 | +#include <linux/of_device.h> | |
| 44 | 45 | |
| 45 | 46 | #include <asm/byteorder.h> |
| 46 | 47 | #include <asm/io.h> |
| @@ -2438,11 +2439,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) · 2391 unmodified lines | ||
| 2438 | 2439 | unsigned int i; |
| 2439 | 2440 | u32 dccparams; |
| 2440 | 2441 | |
| 2441 | − if (strcmp(pdev->name, driver_name)) { | |
| 2442 | − VDBG("Wrong device"); | |
| 2443 | − return -ENODEV; | |
| 2444 | − } | |
| 2445 | − | |
| 2446 | 2442 | udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); |
| 2447 | 2443 | if (udc_controller == NULL) { |
| 2448 | 2444 | ERR("malloc udc failed\n"); |
| @@ -2547,7 +2543,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) · 98 unmodified lines | ||
| 2547 | 2543 | dr_controller_setup(udc_controller); |
| 2548 | 2544 | } |
| 2549 | 2545 | |
| 2550 | − fsl_udc_clk_finalize(pdev); | |
| 2546 | + ret = fsl_udc_clk_finalize(pdev); | |
| 2547 | + if (ret) | |
| 2548 | + goto err_free_irq; | |
| 2551 | 2549 | |
| 2552 | 2550 | /* Setup gadget structure */ |
| 2553 | 2551 | udc_controller->gadget.ops = &fsl_gadget_ops; |
| @@ -2756,22 +2754,32 @@ static int fsl_udc_otg_resume(struct device *dev) · 202 unmodified lines | ||
| 2756 | 2754 | |
| 2757 | 2755 | return fsl_udc_resume(NULL); |
| 2758 | 2756 | } |
| 2759 | − | |
| 2760 | 2757 | /*------------------------------------------------------------------------- |
| 2761 | 2758 | Register entry point for the peripheral controller driver |
| 2762 | 2759 | --------------------------------------------------------------------------*/ |
| 2763 | − | |
| 2760 | +static const struct platform_device_id fsl_udc_devtype[] = { | |
| 2761 | + { | |
| 2762 | + .name = "imx-udc-mx27", | |
| 2763 | + }, { | |
| 2764 | + .name = "imx-udc-mx51", | |
| 2765 | + }, { | |
| 2766 | + /* sentinel */ | |
| 2767 | + } | |
| 2768 | +}; | |
| 2769 | +MODULE_DEVICE_TABLE(platform, fsl_udc_devtype); | |
| 2764 | 2770 | static struct platform_driver udc_driver = { |
| 2765 | − .remove = __exit_p(fsl_udc_remove), | |
| 2771 | + .remove = __exit_p(fsl_udc_remove), | |
| 2772 | + /* Just for FSL i.mx SoC currently */ | |
| 2773 | + .id_table = fsl_udc_devtype, | |
| 2766 | 2774 | /* these suspend and resume are not usb suspend and resume */ |
| 2767 | − .suspend = fsl_udc_suspend, | |
| 2768 | − .resume = fsl_udc_resume, | |
| 2769 | − .driver = { | |
| 2770 | − .name = (char *)driver_name, | |
| 2771 | − .owner = THIS_MODULE, | |
| 2772 | − /* udc suspend/resume called from OTG driver */ | |
| 2773 | − .suspend = fsl_udc_otg_suspend, | |
| 2774 | − .resume = fsl_udc_otg_resume, | |
| 2775 | + .suspend = fsl_udc_suspend, | |
| 2776 | + .resume = fsl_udc_resume, | |
| 2777 | + .driver = { | |
| 2778 | + .name = (char *)driver_name, | |
| 2779 | + .owner = THIS_MODULE, | |
| 2780 | + /* udc suspend/resume called from OTG driver */ | |
| 2781 | + .suspend = fsl_udc_otg_suspend, | |
| 2782 | + .resume = fsl_udc_otg_resume, | |
| 2775 | 2783 | }, |
| 2776 | 2784 | }; |
| 2777 | 2785 | |
| @@ -592,15 +592,16 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep) · 591 unmodified lines | ||
| 592 | 592 | struct platform_device; |
| 593 | 593 | #ifdef CONFIG_ARCH_MXC |
| 594 | 594 | int fsl_udc_clk_init(struct platform_device *pdev); |
| 595 | −void fsl_udc_clk_finalize(struct platform_device *pdev); | |
| 595 | +int fsl_udc_clk_finalize(struct platform_device *pdev); | |
| 596 | 596 | void fsl_udc_clk_release(void); |
| 597 | 597 | #else |
| 598 | 598 | static inline int fsl_udc_clk_init(struct platform_device *pdev) |
| 599 | 599 | { |
| 600 | 600 | return 0; |
| 601 | 601 | } |
| 602 | −static inline void fsl_udc_clk_finalize(struct platform_device *pdev) | |
| 602 | +static inline int fsl_udc_clk_finalize(struct platform_device *pdev) | |
| 603 | 603 | { |
| 604 | + return 0; | |
| 604 | 605 | } |
| 605 | 606 | static inline void fsl_udc_clk_release(void) |
| 606 | 607 | { |
| @@ -148,7 +148,7 @@ config USB_EHCI_FSL · 147 unmodified lines | ||
| 148 | 148 | Variation of ARC USB block used in some Freescale chips. |
| 149 | 149 | |
| 150 | 150 | config USB_EHCI_MXC |
| 151 | − bool "Support for Freescale i.MX on-chip EHCI USB controller" | |
| 151 | + tristate "Support for Freescale i.MX on-chip EHCI USB controller" | |
| 152 | 152 | depends on USB_EHCI_HCD && ARCH_MXC |
| 153 | 153 | select USB_EHCI_ROOT_HUB_TT |
| 154 | 154 | ---help--- |
| @@ -26,6 +26,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o · 25 unmodified lines | ||
| 26 | 26 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
| 27 | 27 | obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o |
| 28 | 28 | obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o |
| 29 | +obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o | |
| 29 | 30 | |
| 30 | 31 | obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o |
| 31 | 32 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o |
| @@ -74,10 +74,6 @@ static const char hcd_name [] = "ehci_hcd"; · 73 unmodified lines | ||
| 74 | 74 | #undef VERBOSE_DEBUG |
| 75 | 75 | #undef EHCI_URB_TRACE |
| 76 | 76 | |
| 77 | −#ifdef DEBUG | |
| 78 | −#define EHCI_STATS | |
| 79 | −#endif | |
| 80 | − | |
| 81 | 77 | /* magic numbers that can affect system performance */ |
| 82 | 78 | #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ |
| 83 | 79 | #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ |
| @@ -1250,11 +1246,6 @@ MODULE_LICENSE ("GPL"); · 1166 unmodified lines | ||
| 1250 | 1246 | #define PLATFORM_DRIVER ehci_fsl_driver |
| 1251 | 1247 | #endif |
| 1252 | 1248 | |
| 1253 | −#ifdef CONFIG_USB_EHCI_MXC | |
| 1254 | −#include "ehci-mxc.c" | |
| 1255 | −#define PLATFORM_DRIVER ehci_mxc_driver | |
| 1256 | −#endif | |
| 1257 | − | |
| 1258 | 1249 | #ifdef CONFIG_USB_EHCI_SH |
| 1259 | 1250 | #include "ehci-sh.c" |
| 1260 | 1251 | #define PLATFORM_DRIVER ehci_hcd_sh_driver |
| @@ -1352,7 +1343,8 @@ MODULE_LICENSE ("GPL"); · 91 unmodified lines | ||
| 1352 | 1343 | |
| 1353 | 1344 | #if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ |
| 1354 | 1345 | !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ |
| 1355 | − !defined(CONFIG_USB_CHIPIDEA_HOST) && \ | |
| 1346 | + !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \ | |
| 1347 | + !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \ | |
| 1356 | 1348 | !defined(PLATFORM_DRIVER) && \ |
| 1357 | 1349 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ |
| 1358 | 1350 | !defined(OF_PLATFORM_DRIVER) && \ |
| @@ -17,75 +17,38 @@ · 16 unmodified lines | ||
| 17 | 17 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | +#include <linux/kernel.h> | |
| 21 | +#include <linux/module.h> | |
| 22 | +#include <linux/io.h> | |
| 20 | 23 | #include <linux/platform_device.h> |
| 21 | 24 | #include <linux/clk.h> |
| 22 | 25 | #include <linux/delay.h> |
| 23 | 26 | #include <linux/usb/otg.h> |
| 24 | 27 | #include <linux/usb/ulpi.h> |
| 25 | 28 | #include <linux/slab.h> |
| 29 | +#include <linux/usb.h> | |
| 30 | +#include <linux/usb/hcd.h> | |
| 26 | 31 | |
| 27 | 32 | #include <linux/platform_data/usb-ehci-mxc.h> |
| 28 | 33 | |
| 29 | 34 | #include <asm/mach-types.h> |
| 30 | 35 | |
| 36 | +#include "ehci.h" | |
| 37 | + | |
| 38 | +#define DRIVER_DESC "Freescale On-Chip EHCI Host driver" | |
| 39 | + | |
| 40 | +static const char hcd_name[] = "ehci-mxc"; | |
| 41 | + | |
| 31 | 42 | #define ULPI_VIEWPORT_OFFSET 0x170 |
| 32 | 43 | |
| 33 | 44 | struct ehci_mxc_priv { |
| 34 | 45 | struct clk *usbclk, *ahbclk, *phyclk; |
| 35 | − struct usb_hcd *hcd; | |
| 36 | 46 | }; |
| 37 | 47 | |
| 38 | −/* called during probe() after chip reset completes */ | |
| 39 | −static int ehci_mxc_setup(struct usb_hcd *hcd) | |
| 40 | −{ | |
| 41 | − hcd->has_tt = 1; | |
| 42 | − | |
| 43 | − return ehci_setup(hcd); | |
| 44 | −} | |
| 48 | +static struct hc_driver __read_mostly ehci_mxc_hc_driver; | |
| 45 | 49 | |
| 46 | −static const struct hc_driver ehci_mxc_hc_driver = { | |
| 47 | − .description = hcd_name, | |
| 48 | − .product_desc = "Freescale On-Chip EHCI Host Controller", | |
| 49 | − .hcd_priv_size = sizeof(struct ehci_hcd), | |
| 50 | − | |
| 51 | − /* | |
| 52 | − * generic hardware linkage | |
| 53 | − */ | |
| 54 | − .irq = ehci_irq, | |
| 55 | − .flags = HCD_USB2 | HCD_MEMORY, | |
| 56 | − | |
| 57 | − /* | |
| 58 | − * basic lifecycle operations | |
| 59 | − */ | |
| 60 | − .reset = ehci_mxc_setup, | |
| 61 | − .start = ehci_run, | |
| 62 | − .stop = ehci_stop, | |
| 63 | − .shutdown = ehci_shutdown, | |
| 64 | − | |
| 65 | − /* | |
| 66 | − * managing i/o requests and associated device resources | |
| 67 | − */ | |
| 68 | − .urb_enqueue = ehci_urb_enqueue, | |
| 69 | − .urb_dequeue = ehci_urb_dequeue, | |
| 70 | − .endpoint_disable = ehci_endpoint_disable, | |
| 71 | − .endpoint_reset = ehci_endpoint_reset, | |
| 72 | − | |
| 73 | − /* | |
| 74 | − * scheduling support | |
| 75 | − */ | |
| 76 | − .get_frame_number = ehci_get_frame, | |
| 77 | − | |
| 78 | − /* | |
| 79 | − * root hub support | |
| 80 | − */ | |
| 81 | − .hub_status_data = ehci_hub_status_data, | |
| 82 | − .hub_control = ehci_hub_control, | |
| 83 | − .bus_suspend = ehci_bus_suspend, | |
| 84 | − .bus_resume = ehci_bus_resume, | |
| 85 | − .relinquish_port = ehci_relinquish_port, | |
| 86 | − .port_handed_over = ehci_port_handed_over, | |
| 87 | − | |
| 88 | − .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | |
| 50 | +static const struct ehci_driver_overrides ehci_mxc_overrides __initdata = { | |
| 51 | + .extra_priv_size = sizeof(struct ehci_mxc_priv), | |
| 89 | 52 | }; |
| 90 | 53 | |
| 91 | 54 | static int ehci_mxc_drv_probe(struct platform_device *pdev) |
| @@ -112,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) · 20 unmodified lines | ||
| 112 | 75 | if (!hcd) |
| 113 | 76 | return -ENOMEM; |
| 114 | 77 | |
| 115 | − priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | |
| 116 | − if (!priv) { | |
| 117 | − ret = -ENOMEM; | |
| 118 | − goto err_alloc; | |
| 119 | − } | |
| 120 | − | |
| 121 | 78 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 122 | 79 | if (!res) { |
| 123 | 80 | dev_err(dev, "Found HC with no register addr. Check setup!\n"); |
| @@ -135,6 +92,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 135 | 92 | goto err_alloc; |
| 136 | 93 | } |
| 137 | 94 | |
| 95 | + hcd->has_tt = 1; | |
| 96 | + ehci = hcd_to_ehci(hcd); | |
| 97 | + priv = (struct ehci_mxc_priv *) ehci->priv; | |
| 98 | + | |
| 138 | 99 | /* enable clocks */ |
| 139 | 100 | priv->usbclk = devm_clk_get(&pdev->dev, "ipg"); |
| 140 | 101 | if (IS_ERR(priv->usbclk)) { |
| @@ -169,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) · 28 unmodified lines | ||
| 169 | 130 | mdelay(10); |
| 170 | 131 | } |
| 171 | 132 | |
| 172 | − ehci = hcd_to_ehci(hcd); | |
| 173 | − | |
| 174 | 133 | /* EHCI registers start at offset 0x100 */ |
| 175 | 134 | ehci->caps = hcd->regs + 0x100; |
| 176 | 135 | ehci->regs = hcd->regs + 0x100 + |
| @@ -198,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) · 21 unmodified lines | ||
| 198 | 157 | } |
| 199 | 158 | } |
| 200 | 159 | |
| 201 | − priv->hcd = hcd; | |
| 202 | − platform_set_drvdata(pdev, priv); | |
| 160 | + platform_set_drvdata(pdev, hcd); | |
| 203 | 161 | |
| 204 | 162 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
| 205 | 163 | if (ret) |
| @@ -244,8 +202,11 @@ err_alloc: · 38 unmodified lines | ||
| 244 | 202 | static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) |
| 245 | 203 | { |
| 246 | 204 | struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; |
| 247 | − struct ehci_mxc_priv *priv = platform_get_drvdata(pdev); | |
| 248 | − struct usb_hcd *hcd = priv->hcd; | |
| 205 | + struct usb_hcd *hcd = platform_get_drvdata(pdev); | |
| 206 | + struct ehci_hcd *ehci = hcd_to_ehci(hcd); | |
| 207 | + struct ehci_mxc_priv *priv = (struct ehci_mxc_priv *) ehci->priv; | |
| 208 | + | |
| 209 | + usb_remove_hcd(hcd); | |
| 249 | 210 | |
| 250 | 211 | if (pdata && pdata->exit) |
| 251 | 212 | pdata->exit(pdev); |
| @@ -253,23 +214,20 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) · 1 unmodified line | ||
| 253 | 214 | if (pdata->otg) |
| 254 | 215 | usb_phy_shutdown(pdata->otg); |
| 255 | 216 | |
| 256 | − usb_remove_hcd(hcd); | |
| 257 | − usb_put_hcd(hcd); | |
| 258 | − platform_set_drvdata(pdev, NULL); | |
| 259 | − | |
| 260 | 217 | clk_disable_unprepare(priv->usbclk); |
| 261 | 218 | clk_disable_unprepare(priv->ahbclk); |
| 262 | 219 | |
| 263 | 220 | if (priv->phyclk) |
| 264 | 221 | clk_disable_unprepare(priv->phyclk); |
| 265 | 222 | |
| 223 | + usb_put_hcd(hcd); | |
| 224 | + platform_set_drvdata(pdev, NULL); | |
| 266 | 225 | return 0; |
| 267 | 226 | } |
| 268 | 227 | |
| 269 | 228 | static void ehci_mxc_drv_shutdown(struct platform_device *pdev) |
| 270 | 229 | { |
| 271 | − struct ehci_mxc_priv *priv = platform_get_drvdata(pdev); | |
| 272 | − struct usb_hcd *hcd = priv->hcd; | |
| 230 | + struct usb_hcd *hcd = platform_get_drvdata(pdev); | |
| 273 | 231 | |
| 274 | 232 | if (hcd->driver->shutdown) |
| 275 | 233 | hcd->driver->shutdown(hcd); |
| @@ -279,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci"); · 3 unmodified lines | ||
| 279 | 237 | |
| 280 | 238 | static struct platform_driver ehci_mxc_driver = { |
| 281 | 239 | .probe = ehci_mxc_drv_probe, |
| 282 | − .remove = __exit_p(ehci_mxc_drv_remove), | |
| 240 | + .remove = ehci_mxc_drv_remove, | |
| 283 | 241 | .shutdown = ehci_mxc_drv_shutdown, |
| 284 | 242 | .driver = { |
| 285 | 243 | .name = "mxc-ehci", |
| 286 | 244 | }, |
| 287 | 245 | }; |
| 246 | + | |
| 247 | +static int __init ehci_mxc_init(void) | |
| 248 | +{ | |
| 249 | + if (usb_disabled()) | |
| 250 | + return -ENODEV; | |
| 251 | + | |
| 252 | + pr_info("%s: " DRIVER_DESC "\n", hcd_name); | |
| 253 | + | |
| 254 | + ehci_init_driver(&ehci_mxc_hc_driver, &ehci_mxc_overrides); | |
| 255 | + return platform_driver_register(&ehci_mxc_driver); | |
| 256 | +} | |
| 257 | +module_init(ehci_mxc_init); | |
| 258 | + | |
| 259 | +static void __exit ehci_mxc_cleanup(void) | |
| 260 | +{ | |
| 261 | + platform_driver_unregister(&ehci_mxc_driver); | |
| 262 | +} | |
| 263 | +module_exit(ehci_mxc_cleanup); | |
| 264 | + | |
| 265 | +MODULE_DESCRIPTION(DRIVER_DESC); | |
| 266 | +MODULE_AUTHOR("Sascha Hauer"); | |
| 267 | +MODULE_LICENSE("GPL"); | |
| @@ -38,6 +38,10 @@ typedef __u16 __bitwise __hc16; · 37 unmodified lines | ||
| 38 | 38 | #endif |
| 39 | 39 | |
| 40 | 40 | /* statistics can be kept for tuning/monitoring */ |
| 41 | +#ifdef DEBUG | |
| 42 | +#define EHCI_STATS | |
| 43 | +#endif | |
| 44 | + | |
| 41 | 45 | struct ehci_stats { |
| 42 | 46 | /* irq usage */ |
| 43 | 47 | unsigned long normal; |
| @@ -221,6 +225,9 @@ struct ehci_hcd { /* one per controller */ · 177 unmodified lines | ||
| 221 | 225 | #ifdef DEBUG |
| 222 | 226 | struct dentry *debug_dir; |
| 223 | 227 | #endif |
| 228 | + | |
| 229 | + /* platform-specific data -- must come last */ | |
| 230 | + unsigned long priv[0] __aligned(sizeof(s64)); | |
| 224 | 231 | }; |
| 225 | 232 | |
| 226 | 233 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
| @@ -447,6 +447,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) · 446 unmodified lines | ||
| 447 | 447 | return IRQ_NONE; |
| 448 | 448 | uhci_writew(uhci, status, USBSTS); /* Clear it */ |
| 449 | 449 | |
| 450 | + spin_lock(&uhci->lock); | |
| 451 | + if (unlikely(!uhci->is_initialized)) /* not yet configured */ | |
| 452 | + goto done; | |
| 453 | + | |
| 450 | 454 | if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { |
| 451 | 455 | if (status & USBSTS_HSE) |
| 452 | 456 | dev_err(uhci_dev(uhci), "host system error, " |
| @@ -455,7 +459,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) · 2 unmodified lines | ||
| 455 | 459 | dev_err(uhci_dev(uhci), "host controller process " |
| 456 | 460 | "error, something bad happened!\n"); |
| 457 | 461 | if (status & USBSTS_HCH) { |
| 458 | − spin_lock(&uhci->lock); | |
| 459 | 462 | if (uhci->rh_state >= UHCI_RH_RUNNING) { |
| 460 | 463 | dev_err(uhci_dev(uhci), |
| 461 | 464 | "host controller halted, " |
| @@ -473,15 +476,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) · 11 unmodified lines | ||
| 473 | 476 | * pending unlinks */ |
| 474 | 477 | mod_timer(&hcd->rh_timer, jiffies); |
| 475 | 478 | } |
| 476 | − spin_unlock(&uhci->lock); | |
| 477 | 479 | } |
| 478 | 480 | } |
| 479 | 481 | |
| 480 | − if (status & USBSTS_RD) | |
| 482 | + if (status & USBSTS_RD) { | |
| 483 | + spin_unlock(&uhci->lock); | |
| 481 | 484 | usb_hcd_poll_rh_status(hcd); |
| 482 | − else { | |
| 483 | − spin_lock(&uhci->lock); | |
| 485 | + } else { | |
| 484 | 486 | uhci_scan_schedule(uhci); |
| 487 | + done: | |
| 485 | 488 | spin_unlock(&uhci->lock); |
| 486 | 489 | } |
| 487 | 490 | |
| @@ -662,9 +665,9 @@ static int uhci_start(struct usb_hcd *hcd) · 174 unmodified lines | ||
| 662 | 665 | */ |
| 663 | 666 | mb(); |
| 664 | 667 | |
| 668 | + spin_lock_irq(&uhci->lock); | |
| 665 | 669 | configure_hc(uhci); |
| 666 | 670 | uhci->is_initialized = 1; |
| 667 | − spin_lock_irq(&uhci->lock); | |
| 668 | 671 | start_rh(uhci); |
| 669 | 672 | spin_unlock_irq(&uhci->lock); |
| 670 | 673 | return 0; |
| @@ -105,7 +105,7 @@ static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr) · 104 unmodified lines | ||
| 105 | 105 | musb_writel(&tx->tx_complete, 0, ptr); |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | −static void __init cppi_pool_init(struct cppi *cppi, struct cppi_channel *c) | |
| 108 | +static void cppi_pool_init(struct cppi *cppi, struct cppi_channel *c) | |
| 109 | 109 | { |
| 110 | 110 | int j; |
| 111 | 111 | |
| @@ -150,7 +150,7 @@ static void cppi_pool_free(struct cppi_channel *c) · 38 unmodified lines | ||
| 150 | 150 | c->last_processed = NULL; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | −static int __init cppi_controller_start(struct dma_controller *c) | |
| 153 | +static int cppi_controller_start(struct dma_controller *c) | |
| 154 | 154 | { |
| 155 | 155 | struct cppi *controller; |
| 156 | 156 | void __iomem *tibase; |