提交 ff7532ca 编写于 作者: L Linus Torvalds

Merge tag 'usb-3.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

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
...@@ -254,9 +254,9 @@ int __init mx25_clocks_init(void) ...@@ -254,9 +254,9 @@ int __init mx25_clocks_init(void)
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2"); clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[usbotg_ahb], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0"); clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0");
/* i.mx25 has the i.mx35 type cspi */ /* i.mx25 has the i.mx35 type cspi */
clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0"); clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
......
...@@ -236,9 +236,9 @@ int __init mx27_clocks_init(unsigned long fref) ...@@ -236,9 +236,9 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0"); clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0"); clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0");
clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0"); clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_ipg_gate], "ipg", "imx-udc-mx27");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_ahb_gate], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0"); clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0"); clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
......
...@@ -139,9 +139,9 @@ int __init mx31_clocks_init(unsigned long fref) ...@@ -139,9 +139,9 @@ int __init mx31_clocks_init(unsigned long fref)
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2"); clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2"); clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx27");
clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
/* i.mx31 has the i.mx21 type uart */ /* i.mx31 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
......
...@@ -251,9 +251,9 @@ int __init mx35_clocks_init() ...@@ -251,9 +251,9 @@ int __init mx35_clocks_init()
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2"); clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); 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, ...@@ -269,9 +269,9 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2"); clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2"); clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2"); clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc"); clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51");
clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc"); clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51");
clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51");
clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand"); clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand");
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0"); clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1"); clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
......
...@@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan( ...@@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan(
#include <linux/fsl_devices.h> #include <linux/fsl_devices.h>
struct imx_fsl_usb2_udc_data { struct imx_fsl_usb2_udc_data {
const char *devid;
resource_size_t iobase; resource_size_t iobase;
resource_size_t irq; resource_size_t irq;
}; };
......
...@@ -11,35 +11,36 @@ ...@@ -11,35 +11,36 @@
#include "../hardware.h" #include "../hardware.h"
#include "devices-common.h" #include "devices-common.h"
#define imx_fsl_usb2_udc_data_entry_single(soc) \ #define imx_fsl_usb2_udc_data_entry_single(soc, _devid) \
{ \ { \
.devid = _devid, \
.iobase = soc ## _USB_OTG_BASE_ADDR, \ .iobase = soc ## _USB_OTG_BASE_ADDR, \
.irq = soc ## _INT_USB_OTG, \ .irq = soc ## _INT_USB_OTG, \
} }
#ifdef CONFIG_SOC_IMX25 #ifdef CONFIG_SOC_IMX25
const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX25); imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX25 */ #endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27 #ifdef CONFIG_SOC_IMX27
const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX27); imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX27 */ #endif /* ifdef CONFIG_SOC_IMX27 */
#ifdef CONFIG_SOC_IMX31 #ifdef CONFIG_SOC_IMX31
const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX31); imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX31 */ #endif /* ifdef CONFIG_SOC_IMX31 */
#ifdef CONFIG_SOC_IMX35 #ifdef CONFIG_SOC_IMX35
const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX35); imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX35 */ #endif /* ifdef CONFIG_SOC_IMX35 */
#ifdef CONFIG_SOC_IMX51 #ifdef CONFIG_SOC_IMX51
const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst = const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX51); imx_fsl_usb2_udc_data_entry_single(MX51, "imx-udc-mx51");
#endif #endif
struct platform_device *__init imx_add_fsl_usb2_udc( struct platform_device *__init imx_add_fsl_usb2_udc(
...@@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc( ...@@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc(
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
}; };
return imx_add_platform_device_dmamask("fsl-usb2-udc", -1, return imx_add_platform_device_dmamask(data->devid, -1,
res, ARRAY_SIZE(res), res, ARRAY_SIZE(res),
pdata, sizeof(*pdata), DMA_BIT_MASK(32)); pdata, sizeof(*pdata), DMA_BIT_MASK(32));
} }
...@@ -1605,6 +1605,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) ...@@ -1605,6 +1605,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc)
if (epnum == 0 || epnum == 1) { if (epnum == 0 || epnum == 1) {
dep->endpoint.maxpacket = 512; dep->endpoint.maxpacket = 512;
dep->endpoint.maxburst = 1;
dep->endpoint.ops = &dwc3_gadget_ep0_ops; dep->endpoint.ops = &dwc3_gadget_ep0_ops;
if (!epnum) if (!epnum)
dwc->gadget.ep0 = &dep->endpoint; dwc->gadget.ep0 = &dep->endpoint;
......
...@@ -1153,15 +1153,15 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) ...@@ -1153,15 +1153,15 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
pr_err("%s: unmapped value: %lu\n", opts, value); pr_err("%s: unmapped value: %lu\n", opts, value);
return -EINVAL; return -EINVAL;
} }
} } else if (!memcmp(opts, "gid", 3)) {
else if (!memcmp(opts, "gid", 3))
data->perms.gid = make_kgid(current_user_ns(), value); data->perms.gid = make_kgid(current_user_ns(), value);
if (!gid_valid(data->perms.gid)) { if (!gid_valid(data->perms.gid)) {
pr_err("%s: unmapped value: %lu\n", opts, value); pr_err("%s: unmapped value: %lu\n", opts, value);
return -EINVAL; return -EINVAL;
} }
else } else {
goto invalid; goto invalid;
}
break; break;
default: default:
......
...@@ -18,14 +18,13 @@ ...@@ -18,14 +18,13 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h>
static struct clk *mxc_ahb_clk; static struct clk *mxc_ahb_clk;
static struct clk *mxc_per_clk; static struct clk *mxc_per_clk;
static struct clk *mxc_ipg_clk; static struct clk *mxc_ipg_clk;
/* workaround ENGcm09152 for i.MX35 */ /* workaround ENGcm09152 for i.MX35 */
#define USBPHYCTRL_OTGBASE_OFFSET 0x608 #define MX35_USBPHYCTRL_OFFSET 0x600
#define USBPHYCTRL_OTGBASE_OFFSET 0x8
#define USBPHYCTRL_EVDO (1 << 23) #define USBPHYCTRL_EVDO (1 << 23)
int fsl_udc_clk_init(struct platform_device *pdev) int fsl_udc_clk_init(struct platform_device *pdev)
...@@ -59,7 +58,7 @@ int fsl_udc_clk_init(struct platform_device *pdev) ...@@ -59,7 +58,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
clk_prepare_enable(mxc_per_clk); clk_prepare_enable(mxc_per_clk);
/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
if (!cpu_is_mx51()) { if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) {
freq = clk_get_rate(mxc_per_clk); freq = clk_get_rate(mxc_per_clk);
if (pdata->phy_mode != FSL_USB2_PHY_ULPI && if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
(freq < 59999000 || freq > 60001000)) { (freq < 59999000 || freq > 60001000)) {
...@@ -79,27 +78,40 @@ int fsl_udc_clk_init(struct platform_device *pdev) ...@@ -79,27 +78,40 @@ int fsl_udc_clk_init(struct platform_device *pdev)
return ret; return ret;
} }
void fsl_udc_clk_finalize(struct platform_device *pdev) int fsl_udc_clk_finalize(struct platform_device *pdev)
{ {
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
if (cpu_is_mx35()) { int ret = 0;
unsigned int v;
/* workaround ENGcm09152 for i.MX35 */ /* workaround ENGcm09152 for i.MX35 */
if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + unsigned int v;
USBPHYCTRL_OTGBASE_OFFSET)); struct resource *res = platform_get_resource
writel(v | USBPHYCTRL_EVDO, (pdev, IORESOURCE_MEM, 0);
MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + void __iomem *phy_regs = ioremap(res->start +
USBPHYCTRL_OTGBASE_OFFSET)); MX35_USBPHYCTRL_OFFSET, 512);
if (!phy_regs) {
dev_err(&pdev->dev, "ioremap for phy address fails\n");
ret = -EINVAL;
goto ioremap_err;
} }
v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
writel(v | USBPHYCTRL_EVDO,
phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
iounmap(phy_regs);
} }
ioremap_err:
/* ULPI transceivers don't need usbpll */ /* ULPI transceivers don't need usbpll */
if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
clk_disable_unprepare(mxc_per_clk); clk_disable_unprepare(mxc_per_clk);
mxc_per_clk = NULL; mxc_per_clk = NULL;
} }
return ret;
} }
void fsl_udc_clk_release(void) void fsl_udc_clk_release(void)
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/fsl_devices.h> #include <linux/fsl_devices.h>
#include <linux/dmapool.h> #include <linux/dmapool.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of_device.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -2438,11 +2439,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) ...@@ -2438,11 +2439,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
unsigned int i; unsigned int i;
u32 dccparams; u32 dccparams;
if (strcmp(pdev->name, driver_name)) {
VDBG("Wrong device");
return -ENODEV;
}
udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
if (udc_controller == NULL) { if (udc_controller == NULL) {
ERR("malloc udc failed\n"); ERR("malloc udc failed\n");
...@@ -2547,7 +2543,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) ...@@ -2547,7 +2543,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
dr_controller_setup(udc_controller); dr_controller_setup(udc_controller);
} }
fsl_udc_clk_finalize(pdev); ret = fsl_udc_clk_finalize(pdev);
if (ret)
goto err_free_irq;
/* Setup gadget structure */ /* Setup gadget structure */
udc_controller->gadget.ops = &fsl_gadget_ops; udc_controller->gadget.ops = &fsl_gadget_ops;
...@@ -2756,22 +2754,32 @@ static int fsl_udc_otg_resume(struct device *dev) ...@@ -2756,22 +2754,32 @@ static int fsl_udc_otg_resume(struct device *dev)
return fsl_udc_resume(NULL); return fsl_udc_resume(NULL);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
Register entry point for the peripheral controller driver Register entry point for the peripheral controller driver
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
static const struct platform_device_id fsl_udc_devtype[] = {
{
.name = "imx-udc-mx27",
}, {
.name = "imx-udc-mx51",
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(platform, fsl_udc_devtype);
static struct platform_driver udc_driver = { static struct platform_driver udc_driver = {
.remove = __exit_p(fsl_udc_remove), .remove = __exit_p(fsl_udc_remove),
/* Just for FSL i.mx SoC currently */
.id_table = fsl_udc_devtype,
/* these suspend and resume are not usb suspend and resume */ /* these suspend and resume are not usb suspend and resume */
.suspend = fsl_udc_suspend, .suspend = fsl_udc_suspend,
.resume = fsl_udc_resume, .resume = fsl_udc_resume,
.driver = { .driver = {
.name = (char *)driver_name, .name = (char *)driver_name,
.owner = THIS_MODULE, .owner = THIS_MODULE,
/* udc suspend/resume called from OTG driver */ /* udc suspend/resume called from OTG driver */
.suspend = fsl_udc_otg_suspend, .suspend = fsl_udc_otg_suspend,
.resume = fsl_udc_otg_resume, .resume = fsl_udc_otg_resume,
}, },
}; };
......
...@@ -592,15 +592,16 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep) ...@@ -592,15 +592,16 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
struct platform_device; struct platform_device;
#ifdef CONFIG_ARCH_MXC #ifdef CONFIG_ARCH_MXC
int fsl_udc_clk_init(struct platform_device *pdev); int fsl_udc_clk_init(struct platform_device *pdev);
void fsl_udc_clk_finalize(struct platform_device *pdev); int fsl_udc_clk_finalize(struct platform_device *pdev);
void fsl_udc_clk_release(void); void fsl_udc_clk_release(void);
#else #else
static inline int fsl_udc_clk_init(struct platform_device *pdev) static inline int fsl_udc_clk_init(struct platform_device *pdev)
{ {
return 0; return 0;
} }
static inline void fsl_udc_clk_finalize(struct platform_device *pdev) static inline int fsl_udc_clk_finalize(struct platform_device *pdev)
{ {
return 0;
} }
static inline void fsl_udc_clk_release(void) static inline void fsl_udc_clk_release(void)
{ {
......
...@@ -148,7 +148,7 @@ config USB_EHCI_FSL ...@@ -148,7 +148,7 @@ config USB_EHCI_FSL
Variation of ARC USB block used in some Freescale chips. Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_MXC config USB_EHCI_MXC
bool "Support for Freescale i.MX on-chip EHCI USB controller" tristate "Support for Freescale i.MX on-chip EHCI USB controller"
depends on USB_EHCI_HCD && ARCH_MXC depends on USB_EHCI_HCD && ARCH_MXC
select USB_EHCI_ROOT_HUB_TT select USB_EHCI_ROOT_HUB_TT
---help--- ---help---
......
...@@ -26,6 +26,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o ...@@ -26,6 +26,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o
obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
......
...@@ -74,10 +74,6 @@ static const char hcd_name [] = "ehci_hcd"; ...@@ -74,10 +74,6 @@ static const char hcd_name [] = "ehci_hcd";
#undef VERBOSE_DEBUG #undef VERBOSE_DEBUG
#undef EHCI_URB_TRACE #undef EHCI_URB_TRACE
#ifdef DEBUG
#define EHCI_STATS
#endif
/* magic numbers that can affect system performance */ /* magic numbers that can affect system performance */
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
...@@ -1250,11 +1246,6 @@ MODULE_LICENSE ("GPL"); ...@@ -1250,11 +1246,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_fsl_driver #define PLATFORM_DRIVER ehci_fsl_driver
#endif #endif
#ifdef CONFIG_USB_EHCI_MXC
#include "ehci-mxc.c"
#define PLATFORM_DRIVER ehci_mxc_driver
#endif
#ifdef CONFIG_USB_EHCI_SH #ifdef CONFIG_USB_EHCI_SH
#include "ehci-sh.c" #include "ehci-sh.c"
#define PLATFORM_DRIVER ehci_hcd_sh_driver #define PLATFORM_DRIVER ehci_hcd_sh_driver
...@@ -1352,7 +1343,8 @@ MODULE_LICENSE ("GPL"); ...@@ -1352,7 +1343,8 @@ MODULE_LICENSE ("GPL");
#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ #if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
!IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
!defined(CONFIG_USB_CHIPIDEA_HOST) && \ !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
!IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
!defined(PLATFORM_DRIVER) && \ !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && \
!defined(OF_PLATFORM_DRIVER) && \ !defined(OF_PLATFORM_DRIVER) && \
......
...@@ -17,75 +17,38 @@ ...@@ -17,75 +17,38 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/usb/ulpi.h> #include <linux/usb/ulpi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/platform_data/usb-ehci-mxc.h> #include <linux/platform_data/usb-ehci-mxc.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "ehci.h"
#define DRIVER_DESC "Freescale On-Chip EHCI Host driver"
static const char hcd_name[] = "ehci-mxc";
#define ULPI_VIEWPORT_OFFSET 0x170 #define ULPI_VIEWPORT_OFFSET 0x170
struct ehci_mxc_priv { struct ehci_mxc_priv {
struct clk *usbclk, *ahbclk, *phyclk; struct clk *usbclk, *ahbclk, *phyclk;
struct usb_hcd *hcd;
}; };
/* called during probe() after chip reset completes */ static struct hc_driver __read_mostly ehci_mxc_hc_driver;
static int ehci_mxc_setup(struct usb_hcd *hcd)
{
hcd->has_tt = 1;
return ehci_setup(hcd);
}
static const struct hc_driver ehci_mxc_hc_driver = { static const struct ehci_driver_overrides ehci_mxc_overrides __initdata = {
.description = hcd_name, .extra_priv_size = sizeof(struct ehci_mxc_priv),
.product_desc = "Freescale On-Chip EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
/*
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_USB2 | HCD_MEMORY,
/*
* basic lifecycle operations
*/
.reset = ehci_mxc_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support
*/
.get_frame_number = ehci_get_frame,
/*
* root hub support
*/
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
}; };
static int ehci_mxc_drv_probe(struct platform_device *pdev) static int ehci_mxc_drv_probe(struct platform_device *pdev)
...@@ -112,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -112,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
if (!hcd) if (!hcd)
return -ENOMEM; return -ENOMEM;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
goto err_alloc;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res) {
dev_err(dev, "Found HC with no register addr. Check setup!\n"); 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) ...@@ -135,6 +92,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
goto err_alloc; goto err_alloc;
} }
hcd->has_tt = 1;
ehci = hcd_to_ehci(hcd);
priv = (struct ehci_mxc_priv *) ehci->priv;
/* enable clocks */ /* enable clocks */
priv->usbclk = devm_clk_get(&pdev->dev, "ipg"); priv->usbclk = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(priv->usbclk)) { if (IS_ERR(priv->usbclk)) {
...@@ -169,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -169,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
mdelay(10); mdelay(10);
} }
ehci = hcd_to_ehci(hcd);
/* EHCI registers start at offset 0x100 */ /* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100; ehci->caps = hcd->regs + 0x100;
ehci->regs = hcd->regs + 0x100 + ehci->regs = hcd->regs + 0x100 +
...@@ -198,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -198,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
} }
} }
priv->hcd = hcd; platform_set_drvdata(pdev, hcd);
platform_set_drvdata(pdev, priv);
ret = usb_add_hcd(hcd, irq, IRQF_SHARED); ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret) if (ret)
...@@ -244,8 +202,11 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -244,8 +202,11 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
{ {
struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
struct ehci_mxc_priv *priv = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = priv->hcd; struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct ehci_mxc_priv *priv = (struct ehci_mxc_priv *) ehci->priv;
usb_remove_hcd(hcd);
if (pdata && pdata->exit) if (pdata && pdata->exit)
pdata->exit(pdev); pdata->exit(pdev);
...@@ -253,23 +214,20 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) ...@@ -253,23 +214,20 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
if (pdata->otg) if (pdata->otg)
usb_phy_shutdown(pdata->otg); usb_phy_shutdown(pdata->otg);
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
platform_set_drvdata(pdev, NULL);
clk_disable_unprepare(priv->usbclk); clk_disable_unprepare(priv->usbclk);
clk_disable_unprepare(priv->ahbclk); clk_disable_unprepare(priv->ahbclk);
if (priv->phyclk) if (priv->phyclk)
clk_disable_unprepare(priv->phyclk); clk_disable_unprepare(priv->phyclk);
usb_put_hcd(hcd);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
static void ehci_mxc_drv_shutdown(struct platform_device *pdev) static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
{ {
struct ehci_mxc_priv *priv = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct usb_hcd *hcd = priv->hcd;
if (hcd->driver->shutdown) if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd); hcd->driver->shutdown(hcd);
...@@ -279,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci"); ...@@ -279,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci");
static struct platform_driver ehci_mxc_driver = { static struct platform_driver ehci_mxc_driver = {
.probe = ehci_mxc_drv_probe, .probe = ehci_mxc_drv_probe,
.remove = __exit_p(ehci_mxc_drv_remove), .remove = ehci_mxc_drv_remove,
.shutdown = ehci_mxc_drv_shutdown, .shutdown = ehci_mxc_drv_shutdown,
.driver = { .driver = {
.name = "mxc-ehci", .name = "mxc-ehci",
}, },
}; };
static int __init ehci_mxc_init(void)
{
if (usb_disabled())
return -ENODEV;
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
ehci_init_driver(&ehci_mxc_hc_driver, &ehci_mxc_overrides);
return platform_driver_register(&ehci_mxc_driver);
}
module_init(ehci_mxc_init);
static void __exit ehci_mxc_cleanup(void)
{
platform_driver_unregister(&ehci_mxc_driver);
}
module_exit(ehci_mxc_cleanup);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Sascha Hauer");
MODULE_LICENSE("GPL");
...@@ -38,6 +38,10 @@ typedef __u16 __bitwise __hc16; ...@@ -38,6 +38,10 @@ typedef __u16 __bitwise __hc16;
#endif #endif
/* statistics can be kept for tuning/monitoring */ /* statistics can be kept for tuning/monitoring */
#ifdef DEBUG
#define EHCI_STATS
#endif
struct ehci_stats { struct ehci_stats {
/* irq usage */ /* irq usage */
unsigned long normal; unsigned long normal;
...@@ -221,6 +225,9 @@ struct ehci_hcd { /* one per controller */ ...@@ -221,6 +225,9 @@ struct ehci_hcd { /* one per controller */
#ifdef DEBUG #ifdef DEBUG
struct dentry *debug_dir; struct dentry *debug_dir;
#endif #endif
/* platform-specific data -- must come last */
unsigned long priv[0] __aligned(sizeof(s64));
}; };
/* convert between an HCD pointer and the corresponding EHCI_HCD */ /* convert between an HCD pointer and the corresponding EHCI_HCD */
......
...@@ -447,6 +447,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) ...@@ -447,6 +447,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
return IRQ_NONE; return IRQ_NONE;
uhci_writew(uhci, status, USBSTS); /* Clear it */ uhci_writew(uhci, status, USBSTS); /* Clear it */
spin_lock(&uhci->lock);
if (unlikely(!uhci->is_initialized)) /* not yet configured */
goto done;
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
if (status & USBSTS_HSE) if (status & USBSTS_HSE)
dev_err(uhci_dev(uhci), "host system error, " dev_err(uhci_dev(uhci), "host system error, "
...@@ -455,7 +459,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) ...@@ -455,7 +459,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
dev_err(uhci_dev(uhci), "host controller process " dev_err(uhci_dev(uhci), "host controller process "
"error, something bad happened!\n"); "error, something bad happened!\n");
if (status & USBSTS_HCH) { if (status & USBSTS_HCH) {
spin_lock(&uhci->lock);
if (uhci->rh_state >= UHCI_RH_RUNNING) { if (uhci->rh_state >= UHCI_RH_RUNNING) {
dev_err(uhci_dev(uhci), dev_err(uhci_dev(uhci),
"host controller halted, " "host controller halted, "
...@@ -473,15 +476,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) ...@@ -473,15 +476,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
* pending unlinks */ * pending unlinks */
mod_timer(&hcd->rh_timer, jiffies); mod_timer(&hcd->rh_timer, jiffies);
} }
spin_unlock(&uhci->lock);
} }
} }
if (status & USBSTS_RD) if (status & USBSTS_RD) {
spin_unlock(&uhci->lock);
usb_hcd_poll_rh_status(hcd); usb_hcd_poll_rh_status(hcd);
else { } else {
spin_lock(&uhci->lock);
uhci_scan_schedule(uhci); uhci_scan_schedule(uhci);
done:
spin_unlock(&uhci->lock); spin_unlock(&uhci->lock);
} }
...@@ -662,9 +665,9 @@ static int uhci_start(struct usb_hcd *hcd) ...@@ -662,9 +665,9 @@ static int uhci_start(struct usb_hcd *hcd)
*/ */
mb(); mb();
spin_lock_irq(&uhci->lock);
configure_hc(uhci); configure_hc(uhci);
uhci->is_initialized = 1; uhci->is_initialized = 1;
spin_lock_irq(&uhci->lock);
start_rh(uhci); start_rh(uhci);
spin_unlock_irq(&uhci->lock); spin_unlock_irq(&uhci->lock);
return 0; return 0;
......
...@@ -105,7 +105,7 @@ static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr) ...@@ -105,7 +105,7 @@ static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr)
musb_writel(&tx->tx_complete, 0, ptr); musb_writel(&tx->tx_complete, 0, ptr);
} }
static void __init cppi_pool_init(struct cppi *cppi, struct cppi_channel *c) static void cppi_pool_init(struct cppi *cppi, struct cppi_channel *c)
{ {
int j; int j;
...@@ -150,7 +150,7 @@ static void cppi_pool_free(struct cppi_channel *c) ...@@ -150,7 +150,7 @@ static void cppi_pool_free(struct cppi_channel *c)
c->last_processed = NULL; c->last_processed = NULL;
} }
static int __init cppi_controller_start(struct dma_controller *c) static int cppi_controller_start(struct dma_controller *c)
{ {
struct cppi *controller; struct cppi *controller;
void __iomem *tibase; void __iomem *tibase;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册