linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Add USB Host support for MPC5121 SoC
@ 2010-07-22 16:25 Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 1/3] powerpc/fsl_soc.c: remove FSL USB platform code Anatolij Gustschin
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Anatolij Gustschin @ 2010-07-22 16:25 UTC (permalink / raw)
  To: linux-usb
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
	linuxppc-dev, Anatolij Gustschin

This is new attempt to add MPC512x USB support in mainline kernel.
USB OTG support is not included in this patch series, it will be
submitted later.

Anatolij Gustschin (3):
  powerpc/fsl_soc.c: remove FSL USB platform code
  USB: add of_platform glue driver for FSL USB DR controller
  USB: add USB EHCI support for MPC5121 SoC

 Documentation/powerpc/dts-bindings/fsl/usb.txt |   22 ++
 arch/powerpc/sysdev/fsl_soc.c                  |  163 --------------
 drivers/usb/Kconfig                            |    1 +
 drivers/usb/gadget/Kconfig                     |    1 +
 drivers/usb/host/Kconfig                       |   11 +-
 drivers/usb/host/Makefile                      |    1 +
 drivers/usb/host/ehci-fsl.c                    |  107 +++++++---
 drivers/usb/host/ehci-fsl.h                    |   19 ++-
 drivers/usb/host/ehci-mem.c                    |    2 +-
 drivers/usb/host/fsl-mph-dr-of.c               |  278 ++++++++++++++++++++++++
 include/linux/fsl_devices.h                    |   15 ++
 11 files changed, 425 insertions(+), 195 deletions(-)
 create mode 100644 drivers/usb/host/fsl-mph-dr-of.c

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] powerpc/fsl_soc.c: remove FSL USB platform code
  2010-07-22 16:25 [PATCH 0/3] Add USB Host support for MPC5121 SoC Anatolij Gustschin
@ 2010-07-22 16:25 ` Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC Anatolij Gustschin
  2 siblings, 0 replies; 11+ messages in thread
From: Anatolij Gustschin @ 2010-07-22 16:25 UTC (permalink / raw)
  To: linux-usb
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
	linuxppc-dev, Anatolij Gustschin

This removed code will be replaced by simple of_platform
driver for creation of FSL USB platform devices which is
added by next patch of the series.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/sysdev/fsl_soc.c |  163 -----------------------------------------
 1 files changed, 0 insertions(+), 163 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index b91f7ac..49a51f1 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -209,169 +209,6 @@ static int __init of_add_fixed_phys(void)
 arch_initcall(of_add_fixed_phys);
 #endif /* CONFIG_FIXED_PHY */
 
-static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
-{
-	if (!phy_type)
-		return FSL_USB2_PHY_NONE;
-	if (!strcasecmp(phy_type, "ulpi"))
-		return FSL_USB2_PHY_ULPI;
-	if (!strcasecmp(phy_type, "utmi"))
-		return FSL_USB2_PHY_UTMI;
-	if (!strcasecmp(phy_type, "utmi_wide"))
-		return FSL_USB2_PHY_UTMI_WIDE;
-	if (!strcasecmp(phy_type, "serial"))
-		return FSL_USB2_PHY_SERIAL;
-
-	return FSL_USB2_PHY_NONE;
-}
-
-static int __init fsl_usb_of_init(void)
-{
-	struct device_node *np;
-	unsigned int i = 0;
-	struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
-		*usb_dev_dr_client = NULL;
-	int ret;
-
-	for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
-		struct resource r[2];
-		struct fsl_usb2_platform_data usb_data;
-		const unsigned char *prop = NULL;
-
-		memset(&r, 0, sizeof(r));
-		memset(&usb_data, 0, sizeof(usb_data));
-
-		ret = of_address_to_resource(np, 0, &r[0]);
-		if (ret)
-			goto err;
-
-		of_irq_to_resource(np, 0, &r[1]);
-
-		usb_dev_mph =
-		    platform_device_register_simple("fsl-ehci", i, r, 2);
-		if (IS_ERR(usb_dev_mph)) {
-			ret = PTR_ERR(usb_dev_mph);
-			goto err;
-		}
-
-		usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
-		usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
-
-		usb_data.operating_mode = FSL_USB2_MPH_HOST;
-
-		prop = of_get_property(np, "port0", NULL);
-		if (prop)
-			usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
-
-		prop = of_get_property(np, "port1", NULL);
-		if (prop)
-			usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
-
-		prop = of_get_property(np, "phy_type", NULL);
-		usb_data.phy_mode = determine_usb_phy(prop);
-
-		ret =
-		    platform_device_add_data(usb_dev_mph, &usb_data,
-					     sizeof(struct
-						    fsl_usb2_platform_data));
-		if (ret)
-			goto unreg_mph;
-		i++;
-	}
-
-	for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
-		struct resource r[2];
-		struct fsl_usb2_platform_data usb_data;
-		const unsigned char *prop = NULL;
-
-		if (!of_device_is_available(np))
-			continue;
-
-		memset(&r, 0, sizeof(r));
-		memset(&usb_data, 0, sizeof(usb_data));
-
-		ret = of_address_to_resource(np, 0, &r[0]);
-		if (ret)
-			goto unreg_mph;
-
-		of_irq_to_resource(np, 0, &r[1]);
-
-		prop = of_get_property(np, "dr_mode", NULL);
-
-		if (!prop || !strcmp(prop, "host")) {
-			usb_data.operating_mode = FSL_USB2_DR_HOST;
-			usb_dev_dr_host = platform_device_register_simple(
-					"fsl-ehci", i, r, 2);
-			if (IS_ERR(usb_dev_dr_host)) {
-				ret = PTR_ERR(usb_dev_dr_host);
-				goto err;
-			}
-		} else if (prop && !strcmp(prop, "peripheral")) {
-			usb_data.operating_mode = FSL_USB2_DR_DEVICE;
-			usb_dev_dr_client = platform_device_register_simple(
-					"fsl-usb2-udc", i, r, 2);
-			if (IS_ERR(usb_dev_dr_client)) {
-				ret = PTR_ERR(usb_dev_dr_client);
-				goto err;
-			}
-		} else if (prop && !strcmp(prop, "otg")) {
-			usb_data.operating_mode = FSL_USB2_DR_OTG;
-			usb_dev_dr_host = platform_device_register_simple(
-					"fsl-ehci", i, r, 2);
-			if (IS_ERR(usb_dev_dr_host)) {
-				ret = PTR_ERR(usb_dev_dr_host);
-				goto err;
-			}
-			usb_dev_dr_client = platform_device_register_simple(
-					"fsl-usb2-udc", i, r, 2);
-			if (IS_ERR(usb_dev_dr_client)) {
-				ret = PTR_ERR(usb_dev_dr_client);
-				goto err;
-			}
-		} else {
-			ret = -EINVAL;
-			goto err;
-		}
-
-		prop = of_get_property(np, "phy_type", NULL);
-		usb_data.phy_mode = determine_usb_phy(prop);
-
-		if (usb_dev_dr_host) {
-			usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
-			usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
-				dev.coherent_dma_mask;
-			if ((ret = platform_device_add_data(usb_dev_dr_host,
-						&usb_data, sizeof(struct
-						fsl_usb2_platform_data))))
-				goto unreg_dr;
-		}
-		if (usb_dev_dr_client) {
-			usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
-			usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
-				dev.coherent_dma_mask;
-			if ((ret = platform_device_add_data(usb_dev_dr_client,
-						&usb_data, sizeof(struct
-						fsl_usb2_platform_data))))
-				goto unreg_dr;
-		}
-		i++;
-	}
-	return 0;
-
-unreg_dr:
-	if (usb_dev_dr_host)
-		platform_device_unregister(usb_dev_dr_host);
-	if (usb_dev_dr_client)
-		platform_device_unregister(usb_dev_dr_client);
-unreg_mph:
-	if (usb_dev_mph)
-		platform_device_unregister(usb_dev_mph);
-err:
-	return ret;
-}
-
-arch_initcall(fsl_usb_of_init);
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static __be32 __iomem *rstcr;
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-22 16:25 [PATCH 0/3] Add USB Host support for MPC5121 SoC Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 1/3] powerpc/fsl_soc.c: remove FSL USB platform code Anatolij Gustschin
@ 2010-07-22 16:25 ` Anatolij Gustschin
  2010-07-28  8:16   ` Grant Likely
  2010-07-22 16:25 ` [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC Anatolij Gustschin
  2 siblings, 1 reply; 11+ messages in thread
From: Anatolij Gustschin @ 2010-07-22 16:25 UTC (permalink / raw)
  To: linux-usb
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
	linuxppc-dev, Anatolij Gustschin

The driver creates platform devices based on the information
from USB nodes in the flat device tree. This is the replacement
for old arch fsl_soc usb code removed by the previous patch.
It uses usual of-style binding, available EHCI-HCD and UDC
drivers can be bound to the created devices. The new of-style
driver additionaly instantiates USB OTG platform device, as the
appropriate USB OTG driver will be added soon.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 drivers/usb/gadget/Kconfig       |    1 +
 drivers/usb/host/Kconfig         |    5 +
 drivers/usb/host/Makefile        |    1 +
 drivers/usb/host/fsl-mph-dr-of.c |  189 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 196 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/host/fsl-mph-dr-of.c

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index cd27f9b..e15e314 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2
 	boolean "Freescale Highspeed USB DR Peripheral Controller"
 	depends on FSL_SOC || ARCH_MXC
 	select USB_GADGET_DUALSPEED
+	select USB_FSL_MPH_DR_OF
 	help
 	   Some of Freescale PowerPC processors have a High Speed
 	   Dual-Role(DR) USB controller, which supports device mode.
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2d926ce..6687523 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -112,10 +112,15 @@ config XPS_USB_HCD_XILINX
 		support both high speed and full speed devices, or high speed
 		devices only.
 
+config USB_FSL_MPH_DR_OF
+	bool
+	depends on PPC_OF
+
 config USB_EHCI_FSL
 	bool "Support for Freescale on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && FSL_SOC
 	select USB_EHCI_ROOT_HUB_TT
+	select USB_FSL_MPH_DR_OF
 	---help---
 	  Variation of ARC USB block used in some Freescale chips.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b6315aa..aacbe82 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,4 +33,5 @@ obj-$(CONFIG_USB_R8A66597_HCD)	+= r8a66597-hcd.o
 obj-$(CONFIG_USB_ISP1760_HCD)	+= isp1760.o
 obj-$(CONFIG_USB_HWA_HCD)	+= hwa-hc.o
 obj-$(CONFIG_USB_IMX21_HCD)	+= imx21-hcd.o
+obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
 
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
new file mode 100644
index 0000000..020a939
--- /dev/null
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -0,0 +1,189 @@
+/*
+ * Setup platform devices needed by the Freescale multi-port host
+ * and/or dual-role USB controller modules based on the description
+ * in flat device tree.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+
+struct fsl_usb2_dev_data {
+	char *dr_mode;		/* controller mode */
+	char *drivers[3];	/* drivers to instantiate for this mode */
+	enum fsl_usb2_operating_modes op_mode;	/* operating mode */
+};
+
+struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
+	{
+		"host",
+		{ "fsl-ehci", NULL, NULL, },
+		FSL_USB2_DR_HOST,
+	},
+	{
+		"otg",
+		{ "fsl-ehci", "fsl-usb2-udc", "fsl-usb2-otg", },
+		FSL_USB2_DR_OTG,
+	},
+	{
+		"periferal",
+		{ "fsl-usb2-udc", NULL, NULL, },
+		FSL_USB2_DR_DEVICE,
+	},
+};
+
+struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
+{
+	const unsigned char *prop;
+	int i;
+
+	prop = of_get_property(np, "dr_mode", NULL);
+	if (prop) {
+		for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) {
+			if (!strcmp(prop, dr_mode_data[i].dr_mode))
+				return &dr_mode_data[i];
+		}
+	}
+	return &dr_mode_data[0]; /* mode not specified, use host */
+}
+
+static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
+{
+	if (!phy_type)
+		return FSL_USB2_PHY_NONE;
+	if (!strcasecmp(phy_type, "ulpi"))
+		return FSL_USB2_PHY_ULPI;
+	if (!strcasecmp(phy_type, "utmi"))
+		return FSL_USB2_PHY_UTMI;
+	if (!strcasecmp(phy_type, "utmi_wide"))
+		return FSL_USB2_PHY_UTMI_WIDE;
+	if (!strcasecmp(phy_type, "serial"))
+		return FSL_USB2_PHY_SERIAL;
+
+	return FSL_USB2_PHY_NONE;
+}
+
+struct platform_device * __devinit
+fsl_usb2_device_register(struct of_device *ofdev,
+			 struct fsl_usb2_platform_data *pdata,
+			 const char *name, int id)
+{
+	struct platform_device *pdev;
+	const struct resource *res = ofdev->resource;
+	unsigned int num = ofdev->num_resources;
+	int retval;
+
+	pdev = platform_device_alloc(name, id);
+	if (!pdev) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	pdev->dev.parent = &ofdev->dev;
+
+	pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
+	pdev->dev.dma_mask = &pdev->archdata.dma_mask;
+	*pdev->dev.dma_mask = *ofdev->dev.dma_mask;
+
+	retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+	if (retval)
+		goto error;
+
+	if (num) {
+		retval = platform_device_add_resources(pdev, res, num);
+		if (retval)
+			goto error;
+	}
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto error;
+
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return ERR_PTR(retval);
+}
+
+static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
+					   const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct platform_device *usb_dev;
+	struct fsl_usb2_platform_data data, *pdata;
+	struct fsl_usb2_dev_data *dev_data;
+	const unsigned char *prop;
+	static unsigned int idx;
+	int i;
+
+	if (!of_device_is_available(np))
+		return -ENODEV;
+
+	pdata = match->data;
+	if (!pdata) {
+		memset(&data, 0, sizeof(data));
+		pdata = &data;
+	}
+
+	dev_data = get_dr_mode_data(np);
+
+	if (of_device_is_compatible(np, "fsl-usb2-mph")) {
+		prop = of_get_property(np, "port0", NULL);
+		if (prop)
+			pdata->port_enables |= FSL_USB2_PORT0_ENABLED;
+
+		prop = of_get_property(np, "port1", NULL);
+		if (prop)
+			pdata->port_enables |= FSL_USB2_PORT1_ENABLED;
+
+		pdata->operating_mode = FSL_USB2_MPH_HOST;
+	} else {
+		/* setup mode selected in the device tree */
+		pdata->operating_mode = dev_data->op_mode;
+	}
+
+	prop = of_get_property(np, "phy_type", NULL);
+	pdata->phy_mode = determine_usb_phy(prop);
+
+	for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
+		if (!dev_data->drivers[i])
+			continue;
+		usb_dev = fsl_usb2_device_register(ofdev, pdata,
+					dev_data->drivers[i], idx);
+		if (IS_ERR(usb_dev)) {
+			dev_err(&ofdev->dev, "Can't register usb device\n");
+			return PTR_ERR(usb_dev);
+		}
+	}
+	idx++;
+	return 0;
+}
+
+static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
+	{ .compatible = "fsl-usb2-mph", },
+	{ .compatible = "fsl-usb2-dr", },
+	{},
+};
+
+static struct of_platform_driver fsl_usb2_mph_dr_driver = {
+	.driver = {
+		.name = "fsl-usb2-mph-dr",
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_usb2_mph_dr_of_match,
+	},
+	.probe	= fsl_usb2_mph_dr_of_probe,
+};
+
+static int __init fsl_usb2_mph_dr_init(void)
+{
+	return of_register_platform_driver(&fsl_usb2_mph_dr_driver);
+}
+fs_initcall(fsl_usb2_mph_dr_init);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC
  2010-07-22 16:25 [PATCH 0/3] Add USB Host support for MPC5121 SoC Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 1/3] powerpc/fsl_soc.c: remove FSL USB platform code Anatolij Gustschin
  2010-07-22 16:25 ` [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller Anatolij Gustschin
@ 2010-07-22 16:25 ` Anatolij Gustschin
  2010-07-28  8:22   ` Grant Likely
  2 siblings, 1 reply; 11+ messages in thread
From: Anatolij Gustschin @ 2010-07-22 16:25 UTC (permalink / raw)
  To: linux-usb
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
	linuxppc-dev, Anatolij Gustschin

Extends FSL EHCI platform driver glue layer to support
MPC5121 USB controllers. MPC5121 Rev 2.0 silicon EHCI
registers are in big endian format. The appropriate flags
are set using the information in the platform data structure.
MPC83xx system interface registers are not available on
MPC512x, so the access to these registers is isolated in
MPC512x case. Furthermore the USB controller clocks
must be enabled before 512x register accesses which is
done by providing platform specific init callback.

The MPC512x internal USB PHY doesn't provide supply voltage.
For boards using different power switches allow specifying
DRVVBUS and PWR_FAULT signal polarity of the MPC5121 internal
PHY using "fsl,invert-drvvbus" and "fsl,invert-pwr-fault"
properties in the device tree USB nodes. Adds documentation
for this new device tree bindings.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
 Documentation/powerpc/dts-bindings/fsl/usb.txt |   22 +++++
 drivers/usb/Kconfig                            |    1 +
 drivers/usb/host/Kconfig                       |    6 +-
 drivers/usb/host/ehci-fsl.c                    |  107 +++++++++++++++++------
 drivers/usb/host/ehci-fsl.h                    |   19 ++++-
 drivers/usb/host/ehci-mem.c                    |    2 +-
 drivers/usb/host/fsl-mph-dr-of.c               |   89 ++++++++++++++++++++
 include/linux/fsl_devices.h                    |   15 ++++
 8 files changed, 229 insertions(+), 32 deletions(-)

diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentation/powerpc/dts-bindings/fsl/usb.txt
index b001524..bd5723f 100644
--- a/Documentation/powerpc/dts-bindings/fsl/usb.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/usb.txt
@@ -8,6 +8,7 @@ and additions :
 Required properties :
  - compatible : Should be "fsl-usb2-mph" for multi port host USB
    controllers, or "fsl-usb2-dr" for dual role USB controllers
+   or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
  - phy_type : For multi port host USB controllers, should be one of
    "ulpi", or "serial". For dual role USB controllers, should be
    one of "ulpi", "utmi", "utmi_wide", or "serial".
@@ -33,6 +34,12 @@ Recommended properties :
  - interrupt-parent : the phandle for the interrupt controller that
    services interrupts for this device.
 
+Optional properties :
+ - fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
+   port power polarity of internal PHY signal DRVVBUS is inverted.
+ - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
+   the PWR_FAULT signal polarity is inverted.
+
 Example multi port host USB controller device node :
 	usb@22000 {
 		compatible = "fsl-usb2-mph";
@@ -57,3 +64,18 @@ Example dual role USB controller device node :
 		dr_mode = "otg";
 		phy = "ulpi";
 	};
+
+Example dual role USB controller device node for MPC5121ADS:
+
+	usb@4000 {
+		compatible = "fsl,mpc5121-usb2-dr";
+		reg = <0x4000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupt-parent = < &ipic >;
+		interrupts = <44 0x8>;
+		dr_mode = "otg";
+		phy_type = "utmi_wide";
+		fsl,invert-drvvbus;
+		fsl,invert-pwr-fault;
+	};
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 6a58cb1..6e547b5 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -58,6 +58,7 @@ config USB_ARCH_HAS_OHCI
 config USB_ARCH_HAS_EHCI
 	boolean
 	default y if PPC_83xx
+	default y if PPC_MPC512x
 	default y if SOC_AU1200
 	default y if ARCH_IXP4XX
 	default y if ARCH_W90X900
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6687523..90e50f0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED
 
 config USB_EHCI_BIG_ENDIAN_MMIO
 	bool
-	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
+	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \
+				    XPS_USB_HCD_XILINX || PPC_MPC512x)
 	default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
 	bool
-	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
+	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
+				    PPC_MPC512x)
 	default y
 
 config XPS_USB_HCD_XILINX
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a416421..ff50f5c 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -116,13 +116,39 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
 		goto err3;
 	}
 
-	/* Enable USB controller */
-	temp = in_be32(hcd->regs + 0x500);
-	out_be32(hcd->regs + 0x500, temp | 0x4);
+	pdata->regs = hcd->regs;
+
+	/*
+	 * do platform specific init: check the clock, grab/config pins, etc.
+	 */
+	if (pdata->init && pdata->init(pdev)) {
+		retval = -ENODEV;
+		goto err3;
+	}
+
+	/*
+	 * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
+	 * flag for 83xx or 8536 system interface registers.
+	 */
+	if (pdata->big_endian_mmio)
+		temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
+	else
+		temp = in_le32(hcd->regs + FSL_SOC_USB_ID);
+
+	if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
+		pdata->have_sysif_regs = 1;
+
+	/* Enable USB controller, 83xx or 8536 */
+	if (pdata->have_sysif_regs)
+		setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
 
 	/* Set to Host mode */
-	temp = in_le32(hcd->regs + 0x1a8);
-	out_le32(hcd->regs + 0x1a8, temp | 0x3);
+	if (pdata->big_endian_mmio) {
+		setbits32(hcd->regs + FSL_SOC_USB_USBMODE, USBMODE_CM_HOST);
+	} else {
+		clrsetbits_le32(hcd->regs + FSL_SOC_USB_USBMODE,
+				USBMODE_CM_MASK, USBMODE_CM_HOST);
+	}
 
 	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
 	if (retval != 0)
@@ -137,6 +163,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
 	usb_put_hcd(hcd);
       err1:
 	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
+	if (pdata->exit)
+		pdata->exit(pdev);
 	return retval;
 }
 
@@ -154,17 +182,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
 static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
 			       struct platform_device *pdev)
 {
+	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
 	usb_remove_hcd(hcd);
+
+	/*
+	 * do platform specific un-initialization:
+	 * release iomux pins, disable clock, etc.
+	 */
+	if (pdata->exit)
+		pdata->exit(pdev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 }
 
-static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
-			      enum fsl_usb2_phy_modes phy_mode,
-			      unsigned int port_offset)
+static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
+			       enum fsl_usb2_phy_modes phy_mode,
+			       unsigned int port_offset)
 {
-	u32 portsc = 0;
+	u32 portsc;
+
+	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
+	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
+
 	switch (phy_mode) {
 	case FSL_USB2_PHY_ULPI:
 		portsc |= PORT_PTS_ULPI;
@@ -184,20 +225,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
 	ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
 }
 
-static void mpc83xx_usb_setup(struct usb_hcd *hcd)
+static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 {
-	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	struct usb_hcd *hcd = ehci_to_hcd(ehci);
 	struct fsl_usb2_platform_data *pdata;
 	void __iomem *non_ehci = hcd->regs;
 	u32 temp;
 
-	pdata =
-	    (struct fsl_usb2_platform_data *)hcd->self.controller->
-	    platform_data;
+	pdata = hcd->self.controller->platform_data;
+
 	/* Enable PHY interface in the control reg. */
-	temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
-	out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
-	out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+	if (pdata->have_sysif_regs) {
+		temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+		out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
+		out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+	}
 
 #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
 	/*
@@ -214,7 +256,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
 
 	if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
 			(pdata->operating_mode == FSL_USB2_DR_OTG))
-		mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+		ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
 
 	if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
 		unsigned int chip, rev, svr;
@@ -228,27 +270,31 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
 			ehci->has_fsl_port_bug = 1;
 
 		if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-			mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
 		if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
-			mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
+			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
 	}
 
 	/* put controller in host mode. */
-	ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
+	temp = USBMODE_CM_HOST | (pdata->es ? USBMODE_ES : 0);
+	ehci_writel(ehci, temp, non_ehci + FSL_SOC_USB_USBMODE);
+
+	if (pdata->have_sysif_regs) {
 #ifdef CONFIG_PPC_85xx
-	out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
-	out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
+		out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
+		out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
 #else
-	out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
-	out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
+		out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
+		out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
 #endif
-	out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
+		out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
+	}
 }
 
 /* called after powerup, by probe or system-pm "wakeup" */
 static int ehci_fsl_reinit(struct ehci_hcd *ehci)
 {
-	mpc83xx_usb_setup(ehci_to_hcd(ehci));
+	ehci_fsl_usb_setup(ehci);
 	ehci_port_power(ehci, 0);
 
 	return 0;
@@ -259,6 +305,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
 {
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	int retval;
+	struct fsl_usb2_platform_data *pdata;
+
+	pdata = hcd->self.controller->platform_data;
+	ehci->big_endian_desc = pdata->big_endian_desc;
+	ehci->big_endian_mmio = pdata->big_endian_mmio;
 
 	/* EHCI registers start at offset 0x100 */
 	ehci->caps = hcd->regs + 0x100;
@@ -372,7 +423,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
 	 * generic hardware linkage
 	 */
 	.irq = ehci_irq,
-	.flags = HCD_USB2,
+	.flags = HCD_USB2 | HCD_MEMORY,
 
 	/*
 	 * basic lifecycle operations
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index b5e59db..e56be7b 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 freescale semiconductor
+/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
  * Copyright (c) 2005 MontaVista Software
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -19,6 +19,11 @@
 #define _EHCI_FSL_H
 
 /* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_ID		0x0
+#define ID_MSK			0x3f
+#define NID_MSK			0x3f00
+#define FSL_SOC_USB_SBUSCFG	0x90
+#define FSL_SOC_USB_BURSTSIZE	0x160
 #define FSL_SOC_USB_ULPIVP	0x170
 #define FSL_SOC_USB_PORTSC1	0x184
 #define PORT_PTS_MSK		(3<<30)
@@ -26,8 +31,20 @@
 #define PORT_PTS_ULPI		(2<<30)
 #define	PORT_PTS_SERIAL		(3<<30)
 #define PORT_PTS_PTW		(1<<28)
+#define PORT_PTS_PHCD		(1<<23)
 #define FSL_SOC_USB_PORTSC2	0x188
 #define FSL_SOC_USB_USBMODE	0x1a8
+#define USBMODE_CM_MASK		(3 << 0)	/* controller mode mask */
+#define USBMODE_CM_HOST		(3 << 0)	/* controller mode: host */
+#define USBMODE_ES		(1 << 2)	/* (Big) Endian Select */
+
+#define FSL_SOC_USB_USBGENCTRL	0x200
+#define USBGENCTRL_PPP		(1 << 3)
+#define USBGENCTRL_PFP		(1 << 2)
+#define FSL_SOC_USB_ISIPHYCTRL	0x204
+#define ISIPHYCTRL_PXE		(1)
+#define ISIPHYCTRL_PHYE		(1 << 4)
+
 #define FSL_SOC_USB_SNOOP1	0x400	/* NOTE: big-endian */
 #define FSL_SOC_USB_SNOOP2	0x404	/* NOTE: big-endian */
 #define FSL_SOC_USB_AGECNTTHRSH	0x408	/* NOTE: big-endian */
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 1f3f01e..d36e4e7 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
 {
 	memset (qtd, 0, sizeof *qtd);
 	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
+	qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
 	qtd->hw_next = EHCI_LIST_END(ehci);
 	qtd->hw_alt_next = EHCI_LIST_END(ehci);
 	INIT_LIST_HEAD (&qtd->qtd_list);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 020a939..0ced9fc 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -14,6 +14,7 @@
 #include <linux/fsl_devices.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
+#include <linux/clk.h>
 
 struct fsl_usb2_dev_data {
 	char *dr_mode;		/* controller mode */
@@ -146,6 +147,12 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
 
 		pdata->operating_mode = FSL_USB2_MPH_HOST;
 	} else {
+		if (of_get_property(np, "fsl,invert-drvvbus", NULL))
+			pdata->invert_drvvbus = 1;
+
+		if (of_get_property(np, "fsl,invert-pwr-fault", NULL))
+			pdata->invert_pwr_fault = 1;
+
 		/* setup mode selected in the device tree */
 		pdata->operating_mode = dev_data->op_mode;
 	}
@@ -167,9 +174,91 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
 	return 0;
 }
 
+#ifdef CONFIG_PPC_MPC512x
+
+#define USBGENCTRL		0x200		/* NOTE: big endian */
+#define GC_WU_INT_CLR		(1 << 5)	/* Wakeup int clear */
+#define GC_ULPI_SEL		(1 << 4)	/* ULPI i/f select (usb0 only)*/
+#define GC_PPP			(1 << 3)	/* Inv. Port Power Polarity */
+#define GC_PFP			(1 << 2)	/* Inv. Power Fault Polarity */
+#define GC_WU_ULPI_EN		(1 << 1)	/* Wakeup on ULPI event */
+#define GC_WU_IE		(1 << 1)	/* Wakeup interrupt enable */
+
+#define ISIPHYCTRL		0x204		/* NOTE: big endian */
+#define PHYCTRL_PHYE		(1 << 4)	/* On-chip UTMI PHY enable */
+#define PHYCTRL_BSENH		(1 << 3)	/* Bit Stuff Enable High */
+#define PHYCTRL_BSEN		(1 << 2)	/* Bit Stuff Enable */
+#define PHYCTRL_LSFE		(1 << 1)	/* Line State Filter Enable */
+#define PHYCTRL_PXE		(1 << 0)	/* PHY oscillator enable */
+
+int fsl_usb2_mpc5121_init(struct platform_device *pdev)
+{
+	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+	struct clk *clk;
+	char clk_name[10];
+	int base, clk_num;
+
+	base = pdev->resource->start & 0xf000;
+	if (base == 0x3000)
+		clk_num = 1;
+	else if (base == 0x4000)
+		clk_num = 2;
+	else
+		return -ENODEV;
+
+	snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num);
+	clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "failed to get clk\n");
+		return PTR_ERR(clk);
+	}
+
+	clk_enable(clk);
+	pdata->clk = clk;
+
+	if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) {
+		u32 reg = 0;
+
+		if (pdata->invert_drvvbus)
+			reg |= GC_PPP;
+
+		if (pdata->invert_pwr_fault)
+			reg |= GC_PFP;
+
+		out_be32(pdata->regs + ISIPHYCTRL, PHYCTRL_PHYE | PHYCTRL_PXE);
+		out_be32(pdata->regs + USBGENCTRL, reg);
+	}
+	return 0;
+}
+
+static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
+{
+	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+	pdata->regs = NULL;
+
+	if (pdata->clk) {
+		clk_disable(pdata->clk);
+		clk_put(pdata->clk);
+	}
+}
+
+struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
+	.big_endian_desc = 1,
+	.big_endian_mmio = 1,
+	.es = 1,
+	.le_setup_buf = 1,
+	.init = fsl_usb2_mpc5121_init,
+	.exit = fsl_usb2_mpc5121_exit,
+};
+#endif /* CONFIG_PPC_MPC512x */
+
 static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
 	{ .compatible = "fsl-usb2-mph", },
 	{ .compatible = "fsl-usb2-dr", },
+#ifdef CONFIG_PPC_MPC512x
+	{ .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, },
+#endif
 	{},
 };
 
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 28e33fe..d5f9a74 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -58,11 +58,26 @@ enum fsl_usb2_phy_modes {
 	FSL_USB2_PHY_SERIAL,
 };
 
+struct clk;
+struct platform_device;
+
 struct fsl_usb2_platform_data {
 	/* board specific information */
 	enum fsl_usb2_operating_modes	operating_mode;
 	enum fsl_usb2_phy_modes		phy_mode;
 	unsigned int			port_enables;
+
+	int		(*init)(struct platform_device *);
+	void		(*exit)(struct platform_device *);
+	void __iomem	*regs;		/* ioremap'd register base */
+	struct clk	*clk;
+	unsigned	big_endian_mmio:1;
+	unsigned	big_endian_desc:1;
+	unsigned	es:1;		/* need USBMODE:ES */
+	unsigned	le_setup_buf:1;
+	unsigned	have_sysif_regs:1;
+	unsigned	invert_drvvbus:1;
+	unsigned	invert_pwr_fault:1;
 };
 
 /* Flags in fsl_usb2_mph_platform_data */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-22 16:25 ` [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller Anatolij Gustschin
@ 2010-07-28  8:16   ` Grant Likely
  2010-07-28  8:28     ` Anton Vorontsov
  2010-07-28 11:58     ` Anatolij Gustschin
  0 siblings, 2 replies; 11+ messages in thread
From: Grant Likely @ 2010-07-28  8:16 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Greg Kroah-Hartman, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, David Brownell

On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wrote:
> The driver creates platform devices based on the information
> from USB nodes in the flat device tree. This is the replacement
> for old arch fsl_soc usb code removed by the previous patch.
> It uses usual of-style binding, available EHCI-HCD and UDC
> drivers can be bound to the created devices. The new of-style
> driver additionaly instantiates USB OTG platform device, as the
> appropriate USB OTG driver will be added soon.
>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> Cc: Kumar Gala <galak@kernel.crashing.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>

Hi Anatolij,

Looks pretty good, but some comments below.

g.

> ---
> =A0drivers/usb/gadget/Kconfig =A0 =A0 =A0 | =A0 =A01 +
> =A0drivers/usb/host/Kconfig =A0 =A0 =A0 =A0 | =A0 =A05 +
> =A0drivers/usb/host/Makefile =A0 =A0 =A0 =A0| =A0 =A01 +
> =A0drivers/usb/host/fsl-mph-dr-of.c | =A0189 ++++++++++++++++++++++++++++=
++++++++++
> =A04 files changed, 196 insertions(+), 0 deletions(-)
> =A0create mode 100644 drivers/usb/host/fsl-mph-dr-of.c
>
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index cd27f9b..e15e314 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2
> =A0 =A0 =A0 =A0boolean "Freescale Highspeed USB DR Peripheral Controller"
> =A0 =A0 =A0 =A0depends on FSL_SOC || ARCH_MXC
> =A0 =A0 =A0 =A0select USB_GADGET_DUALSPEED
> + =A0 =A0 =A0 select USB_FSL_MPH_DR_OF
> =A0 =A0 =A0 =A0help
> =A0 =A0 =A0 =A0 =A0 Some of Freescale PowerPC processors have a High Spee=
d
> =A0 =A0 =A0 =A0 =A0 Dual-Role(DR) USB controller, which supports device m=
ode.
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 2d926ce..6687523 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -112,10 +112,15 @@ config XPS_USB_HCD_XILINX
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0support both high speed and full speed dev=
ices, or high speed
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0devices only.
>
> +config USB_FSL_MPH_DR_OF
> + =A0 =A0 =A0 bool
> + =A0 =A0 =A0 depends on PPC_OF

Drop the depends.  This is selected by USB_EHCI_FSL and
USB_GADGET_FSL_USB2, which are already PPC only.

> +
> =A0config USB_EHCI_FSL
> =A0 =A0 =A0 =A0bool "Support for Freescale on-chip EHCI USB controller"
> =A0 =A0 =A0 =A0depends on USB_EHCI_HCD && FSL_SOC
> =A0 =A0 =A0 =A0select USB_EHCI_ROOT_HUB_TT
> + =A0 =A0 =A0 select USB_FSL_MPH_DR_OF
> =A0 =A0 =A0 =A0---help---
> =A0 =A0 =A0 =A0 =A0Variation of ARC USB block used in some Freescale chip=
s.
>
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index b6315aa..aacbe82 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -33,4 +33,5 @@ obj-$(CONFIG_USB_R8A66597_HCD) =A0 =A0 =A0 =A0+=3D r8a6=
6597-hcd.o
> =A0obj-$(CONFIG_USB_ISP1760_HCD) =A0+=3D isp1760.o
> =A0obj-$(CONFIG_USB_HWA_HCD) =A0 =A0 =A0+=3D hwa-hc.o
> =A0obj-$(CONFIG_USB_IMX21_HCD) =A0 =A0+=3D imx21-hcd.o
> +obj-$(CONFIG_USB_FSL_MPH_DR_OF) =A0 =A0 =A0 =A0+=3D fsl-mph-dr-of.o
>
> diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-=
dr-of.c
> new file mode 100644
> index 0000000..020a939
> --- /dev/null
> +++ b/drivers/usb/host/fsl-mph-dr-of.c
> @@ -0,0 +1,189 @@
> +/*
> + * Setup platform devices needed by the Freescale multi-port host
> + * and/or dual-role USB controller modules based on the description
> + * in flat device tree.
> + *
> + * This program is free software; you can redistribute =A0it and/or modi=
fy it
> + * under =A0the terms of =A0the GNU General =A0Public License as publish=
ed by the
> + * Free Software Foundation; =A0either version 2 of the =A0License, or (=
at your
> + * option) any later version.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/fsl_devices.h>
> +#include <linux/io.h>
> +#include <linux/of_platform.h>
> +
> +struct fsl_usb2_dev_data {
> + =A0 =A0 =A0 char *dr_mode; =A0 =A0 =A0 =A0 =A0/* controller mode */
> + =A0 =A0 =A0 char *drivers[3]; =A0 =A0 =A0 /* drivers to instantiate for=
 this mode */
> + =A0 =A0 =A0 enum fsl_usb2_operating_modes op_mode; =A0/* operating mode=
 */
> +};
> +
> +struct fsl_usb2_dev_data dr_mode_data[] __devinitdata =3D {
> + =A0 =A0 =A0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "host",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-ehci", NULL, NULL, },
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_HOST,
> + =A0 =A0 =A0 },
> + =A0 =A0 =A0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "otg",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-ehci", "fsl-usb2-udc", "fsl-usb2-otg=
", },
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_OTG,
> + =A0 =A0 =A0 },
> + =A0 =A0 =A0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "periferal",

spelling.  "peripheral"

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-usb2-udc", NULL, NULL, },
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_DEVICE,
> + =A0 =A0 =A0 },
> +};

Program defensively.  Use the following form:
+ =A0 =A0 =A0 {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 .dr_mode =3D "host",
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 .drivers =3D { "fsl-ehci", NULL, NULL, },
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 .op_mode =3D FSL_USB2_DR_HOST,
+ =A0 =A0 =A0 },

> +
> +struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node=
 *np)
> +{
> + =A0 =A0 =A0 const unsigned char *prop;
> + =A0 =A0 =A0 int i;
> +
> + =A0 =A0 =A0 prop =3D of_get_property(np, "dr_mode", NULL);
> + =A0 =A0 =A0 if (prop) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D 0; i < ARRAY_SIZE(dr_mode_data);=
 i++) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!strcmp(prop, dr_mode_d=
ata[i].dr_mode))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return &dr_=
mode_data[i];
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }

Print a warning if you get through the loop, but don't match anything.
 That means that dr_mode has a bad value.

> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 return &dr_mode_data[0]; /* mode not specified, use host */
> +}
> +
> +static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *p=
hy_type)
> +{
> + =A0 =A0 =A0 if (!phy_type)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return FSL_USB2_PHY_NONE;
> + =A0 =A0 =A0 if (!strcasecmp(phy_type, "ulpi"))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return FSL_USB2_PHY_ULPI;
> + =A0 =A0 =A0 if (!strcasecmp(phy_type, "utmi"))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return FSL_USB2_PHY_UTMI;
> + =A0 =A0 =A0 if (!strcasecmp(phy_type, "utmi_wide"))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return FSL_USB2_PHY_UTMI_WIDE;
> + =A0 =A0 =A0 if (!strcasecmp(phy_type, "serial"))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return FSL_USB2_PHY_SERIAL;
> +
> + =A0 =A0 =A0 return FSL_USB2_PHY_NONE;
> +}
> +
> +struct platform_device * __devinit
> +fsl_usb2_device_register(struct of_device *ofdev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct fsl_usb2_platform=
_data *pdata,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *name, int id=
)

In general, it is better to have the function name on the same line as
the return arguements so that grep shows the relevant info.  Move the
arguments to subsequent lines.

> +{
> + =A0 =A0 =A0 struct platform_device *pdev;
> + =A0 =A0 =A0 const struct resource *res =3D ofdev->resource;
> + =A0 =A0 =A0 unsigned int num =3D ofdev->num_resources;
> + =A0 =A0 =A0 int retval;
> +
> + =A0 =A0 =A0 pdev =3D platform_device_alloc(name, id);
> + =A0 =A0 =A0 if (!pdev) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 retval =3D -ENOMEM;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 pdev->dev.parent =3D &ofdev->dev;

Good!  The sub-devices show up sanely in the device hierarchy by
setting the parent pointer.

> +
> + =A0 =A0 =A0 pdev->dev.coherent_dma_mask =3D ofdev->dev.coherent_dma_mas=
k;
> + =A0 =A0 =A0 pdev->dev.dma_mask =3D &pdev->archdata.dma_mask;
> + =A0 =A0 =A0 *pdev->dev.dma_mask =3D *ofdev->dev.dma_mask;
> +
> + =A0 =A0 =A0 retval =3D platform_device_add_data(pdev, pdata, sizeof(*pd=
ata));
> + =A0 =A0 =A0 if (retval)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> +
> + =A0 =A0 =A0 if (num) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 retval =3D platform_device_add_resources(pd=
ev, res, num);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (retval)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 retval =3D platform_device_add(pdev);
> + =A0 =A0 =A0 if (retval)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> +
> + =A0 =A0 =A0 return pdev;
> +
> +error:
> + =A0 =A0 =A0 platform_device_put(pdev);
> + =A0 =A0 =A0 return ERR_PTR(retval);
> +}
> +
> +static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0const struct of_device_id *match)
> +{
> + =A0 =A0 =A0 struct device_node *np =3D ofdev->dev.of_node;
> + =A0 =A0 =A0 struct platform_device *usb_dev;
> + =A0 =A0 =A0 struct fsl_usb2_platform_data data, *pdata;
> + =A0 =A0 =A0 struct fsl_usb2_dev_data *dev_data;
> + =A0 =A0 =A0 const unsigned char *prop;
> + =A0 =A0 =A0 static unsigned int idx;
> + =A0 =A0 =A0 int i;
> +
> + =A0 =A0 =A0 if (!of_device_is_available(np))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;

What is this for?

> +
> + =A0 =A0 =A0 pdata =3D match->data;
> + =A0 =A0 =A0 if (!pdata) {

The match table doesn't have any data, so this is a no-op.

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 memset(&data, 0, sizeof(data));
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata =3D &data;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 dev_data =3D get_dr_mode_data(np);
> +
> + =A0 =A0 =A0 if (of_device_is_compatible(np, "fsl-usb2-mph")) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 prop =3D of_get_property(np, "port0", NULL)=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (prop)

if (of_get_property())

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->port_enables |=3D FS=
L_USB2_PORT0_ENABLED;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 prop =3D of_get_property(np, "port1", NULL)=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (prop)

Ditto

> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->port_enables |=3D FS=
L_USB2_PORT1_ENABLED;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->operating_mode =3D FSL_USB2_MPH_HOST=
;
> + =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* setup mode selected in the device tree *=
/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->operating_mode =3D dev_data->op_mode=
;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 prop =3D of_get_property(np, "phy_type", NULL);
> + =A0 =A0 =A0 pdata->phy_mode =3D determine_usb_phy(prop);
> +
> + =A0 =A0 =A0 for (i =3D 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!dev_data->drivers[i])
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 usb_dev =3D fsl_usb2_device_register(ofdev,=
 pdata,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 dev_data->drivers[i], idx);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (IS_ERR(usb_dev)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&ofdev->dev, "Can't=
 register usb device\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return PTR_ERR(usb_dev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 idx++;
> + =A0 =A0 =A0 return 0;
> +}
> +
> +static const struct of_device_id fsl_usb2_mph_dr_of_match[] =3D {
> + =A0 =A0 =A0 { .compatible =3D "fsl-usb2-mph", },
> + =A0 =A0 =A0 { .compatible =3D "fsl-usb2-dr", },
> + =A0 =A0 =A0 {},
> +};
> +
> +static struct of_platform_driver fsl_usb2_mph_dr_driver =3D {
> + =A0 =A0 =A0 .driver =3D {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .name =3D "fsl-usb2-mph-dr",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .owner =3D THIS_MODULE,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .of_match_table =3D fsl_usb2_mph_dr_of_matc=
h,
> + =A0 =A0 =A0 },
> + =A0 =A0 =A0 .probe =A0=3D fsl_usb2_mph_dr_of_probe,
> +};

No remove hook?

> +
> +static int __init fsl_usb2_mph_dr_init(void)
> +{
> + =A0 =A0 =A0 return of_register_platform_driver(&fsl_usb2_mph_dr_driver)=
;
> +}
> +fs_initcall(fsl_usb2_mph_dr_init);

Why fs_initcall?  Is module_init() not sufficient?

> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC
  2010-07-22 16:25 ` [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC Anatolij Gustschin
@ 2010-07-28  8:22   ` Grant Likely
  0 siblings, 0 replies; 11+ messages in thread
From: Grant Likely @ 2010-07-28  8:22 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Greg Kroah-Hartman, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, David Brownell

On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wrote:
> Extends FSL EHCI platform driver glue layer to support
> MPC5121 USB controllers. MPC5121 Rev 2.0 silicon EHCI
> registers are in big endian format. The appropriate flags
> are set using the information in the platform data structure.
> MPC83xx system interface registers are not available on
> MPC512x, so the access to these registers is isolated in
> MPC512x case. Furthermore the USB controller clocks
> must be enabled before 512x register accesses which is
> done by providing platform specific init callback.
>
> The MPC512x internal USB PHY doesn't provide supply voltage.
> For boards using different power switches allow specifying
> DRVVBUS and PWR_FAULT signal polarity of the MPC5121 internal
> PHY using "fsl,invert-drvvbus" and "fsl,invert-pwr-fault"
> properties in the device tree USB nodes. Adds documentation
> for this new device tree bindings.
>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> Cc: Grant Likely <grant.likely@secretlab.ca>

On brief review, looks pretty good to me.

g.

> ---
> =A0Documentation/powerpc/dts-bindings/fsl/usb.txt | =A0 22 +++++
> =A0drivers/usb/Kconfig =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0| =A0 =A01 +
> =A0drivers/usb/host/Kconfig =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 |=
 =A0 =A06 +-
> =A0drivers/usb/host/ehci-fsl.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0107 +++++++++++++++++------
> =A0drivers/usb/host/ehci-fsl.h =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0 19 ++++-
> =A0drivers/usb/host/ehci-mem.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0 =A02 +-
> =A0drivers/usb/host/fsl-mph-dr-of.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 89 =
++++++++++++++++++++
> =A0include/linux/fsl_devices.h =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0 15 ++++
> =A08 files changed, 229 insertions(+), 32 deletions(-)
>
> diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentati=
on/powerpc/dts-bindings/fsl/usb.txt
> index b001524..bd5723f 100644
> --- a/Documentation/powerpc/dts-bindings/fsl/usb.txt
> +++ b/Documentation/powerpc/dts-bindings/fsl/usb.txt
> @@ -8,6 +8,7 @@ and additions :
> =A0Required properties :
> =A0- compatible : Should be "fsl-usb2-mph" for multi port host USB
> =A0 =A0controllers, or "fsl-usb2-dr" for dual role USB controllers
> + =A0 or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
> =A0- phy_type : For multi port host USB controllers, should be one of
> =A0 =A0"ulpi", or "serial". For dual role USB controllers, should be
> =A0 =A0one of "ulpi", "utmi", "utmi_wide", or "serial".
> @@ -33,6 +34,12 @@ Recommended properties :
> =A0- interrupt-parent : the phandle for the interrupt controller that
> =A0 =A0services interrupts for this device.
>
> +Optional properties :
> + - fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
> + =A0 port power polarity of internal PHY signal DRVVBUS is inverted.
> + - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
> + =A0 the PWR_FAULT signal polarity is inverted.
> +
> =A0Example multi port host USB controller device node :
> =A0 =A0 =A0 =A0usb@22000 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0compatible =3D "fsl-usb2-mph";
> @@ -57,3 +64,18 @@ Example dual role USB controller device node :
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dr_mode =3D "otg";
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0phy =3D "ulpi";
> =A0 =A0 =A0 =A0};
> +
> +Example dual role USB controller device node for MPC5121ADS:
> +
> + =A0 =A0 =A0 usb@4000 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "fsl,mpc5121-usb2-dr";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <0x4000 0x1000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 #address-cells =3D <1>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 #size-cells =3D <0>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupt-parent =3D < &ipic >;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts =3D <44 0x8>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dr_mode =3D "otg";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 phy_type =3D "utmi_wide";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 fsl,invert-drvvbus;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 fsl,invert-pwr-fault;
> + =A0 =A0 =A0 };
> diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
> index 6a58cb1..6e547b5 100644
> --- a/drivers/usb/Kconfig
> +++ b/drivers/usb/Kconfig
> @@ -58,6 +58,7 @@ config USB_ARCH_HAS_OHCI
> =A0config USB_ARCH_HAS_EHCI
> =A0 =A0 =A0 =A0boolean
> =A0 =A0 =A0 =A0default y if PPC_83xx
> + =A0 =A0 =A0 default y if PPC_MPC512x
> =A0 =A0 =A0 =A0default y if SOC_AU1200
> =A0 =A0 =A0 =A0default y if ARCH_IXP4XX
> =A0 =A0 =A0 =A0default y if ARCH_W90X900
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 6687523..90e50f0 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED
>
> =A0config USB_EHCI_BIG_ENDIAN_MMIO
> =A0 =A0 =A0 =A0bool
> - =A0 =A0 =A0 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX=
 || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
> + =A0 =A0 =A0 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX=
 || ARCH_IXP4XX || \
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 XPS=
_USB_HCD_XILINX || PPC_MPC512x)
> =A0 =A0 =A0 =A0default y
>
> =A0config USB_EHCI_BIG_ENDIAN_DESC
> =A0 =A0 =A0 =A0bool
> - =A0 =A0 =A0 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_US=
B_HCD_XILINX)
> + =A0 =A0 =A0 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_US=
B_HCD_XILINX || \
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PPC=
_MPC512x)
> =A0 =A0 =A0 =A0default y
>
> =A0config XPS_USB_HCD_XILINX
> diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
> index a416421..ff50f5c 100644
> --- a/drivers/usb/host/ehci-fsl.c
> +++ b/drivers/usb/host/ehci-fsl.c
> @@ -116,13 +116,39 @@ static int usb_hcd_fsl_probe(const struct hc_driver=
 *driver,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto err3;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 /* Enable USB controller */
> - =A0 =A0 =A0 temp =3D in_be32(hcd->regs + 0x500);
> - =A0 =A0 =A0 out_be32(hcd->regs + 0x500, temp | 0x4);
> + =A0 =A0 =A0 pdata->regs =3D hcd->regs;
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* do platform specific init: check the clock, grab/confi=
g pins, etc.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (pdata->init && pdata->init(pdev)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 retval =3D -ENODEV;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err3;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Check if it is MPC5121 SoC, otherwise set pdata->have_=
sysif_regs
> + =A0 =A0 =A0 =A0* flag for 83xx or 8536 system interface registers.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (pdata->big_endian_mmio)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 temp =3D in_be32(hcd->regs + FSL_SOC_USB_ID=
);
> + =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 temp =3D in_le32(hcd->regs + FSL_SOC_USB_ID=
);
> +
> + =A0 =A0 =A0 if ((temp & ID_MSK) !=3D (~((temp & NID_MSK) >> 8) & ID_MSK=
))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->have_sysif_regs =3D 1;
> +
> + =A0 =A0 =A0 /* Enable USB controller, 83xx or 8536 */
> + =A0 =A0 =A0 if (pdata->have_sysif_regs)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4=
);
>
> =A0 =A0 =A0 =A0/* Set to Host mode */
> - =A0 =A0 =A0 temp =3D in_le32(hcd->regs + 0x1a8);
> - =A0 =A0 =A0 out_le32(hcd->regs + 0x1a8, temp | 0x3);
> + =A0 =A0 =A0 if (pdata->big_endian_mmio) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 setbits32(hcd->regs + FSL_SOC_USB_USBMODE, =
USBMODE_CM_HOST);
> + =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clrsetbits_le32(hcd->regs + FSL_SOC_USB_USB=
MODE,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 USBMODE_CM_=
MASK, USBMODE_CM_HOST);
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0retval =3D usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHAR=
ED);
> =A0 =A0 =A0 =A0if (retval !=3D 0)
> @@ -137,6 +163,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *=
driver,
> =A0 =A0 =A0 =A0usb_put_hcd(hcd);
> =A0 =A0 =A0 err1:
> =A0 =A0 =A0 =A0dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->=
dev), retval);
> + =A0 =A0 =A0 if (pdata->exit)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->exit(pdev);
> =A0 =A0 =A0 =A0return retval;
> =A0}
>
> @@ -154,17 +182,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver=
 *driver,
> =A0static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct platfo=
rm_device *pdev)
> =A0{
> + =A0 =A0 =A0 struct fsl_usb2_platform_data *pdata =3D pdev->dev.platform=
_data;
> +
> =A0 =A0 =A0 =A0usb_remove_hcd(hcd);
> +
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* do platform specific un-initialization:
> + =A0 =A0 =A0 =A0* release iomux pins, disable clock, etc.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 if (pdata->exit)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->exit(pdev);
> =A0 =A0 =A0 =A0iounmap(hcd->regs);
> =A0 =A0 =A0 =A0release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
> =A0 =A0 =A0 =A0usb_put_hcd(hcd);
> =A0}
>
> -static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 enum fsl_usb2_p=
hy_modes phy_mode,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 unsigned int po=
rt_offset)
> +static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0enum fsl_usb=
2_phy_modes phy_mode,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unsigned int=
 port_offset)
> =A0{
> - =A0 =A0 =A0 u32 portsc =3D 0;
> + =A0 =A0 =A0 u32 portsc;
> +
> + =A0 =A0 =A0 portsc =3D ehci_readl(ehci, &ehci->regs->port_status[port_o=
ffset]);
> + =A0 =A0 =A0 portsc &=3D ~(PORT_PTS_MSK | PORT_PTS_PTW);
> +
> =A0 =A0 =A0 =A0switch (phy_mode) {
> =A0 =A0 =A0 =A0case FSL_USB2_PHY_ULPI:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0portsc |=3D PORT_PTS_ULPI;
> @@ -184,20 +225,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci=
,
> =A0 =A0 =A0 =A0ehci_writel(ehci, portsc, &ehci->regs->port_status[port_of=
fset]);
> =A0}
>
> -static void mpc83xx_usb_setup(struct usb_hcd *hcd)
> +static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
> =A0{
> - =A0 =A0 =A0 struct ehci_hcd *ehci =3D hcd_to_ehci(hcd);
> + =A0 =A0 =A0 struct usb_hcd *hcd =3D ehci_to_hcd(ehci);
> =A0 =A0 =A0 =A0struct fsl_usb2_platform_data *pdata;
> =A0 =A0 =A0 =A0void __iomem *non_ehci =3D hcd->regs;
> =A0 =A0 =A0 =A0u32 temp;
>
> - =A0 =A0 =A0 pdata =3D
> - =A0 =A0 =A0 =A0 =A0 (struct fsl_usb2_platform_data *)hcd->self.controll=
er->
> - =A0 =A0 =A0 =A0 =A0 platform_data;
> + =A0 =A0 =A0 pdata =3D hcd->self.controller->platform_data;
> +
> =A0 =A0 =A0 =A0/* Enable PHY interface in the control reg. */
> - =A0 =A0 =A0 temp =3D in_be32(non_ehci + FSL_SOC_USB_CTRL);
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
> + =A0 =A0 =A0 if (pdata->have_sysif_regs) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 temp =3D in_be32(non_ehci + FSL_SOC_USB_CTR=
L);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp =
| 0x00000004);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0=
000001b);
> + =A0 =A0 =A0 }
>
> =A0#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
> =A0 =A0 =A0 =A0/*
> @@ -214,7 +256,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
>
> =A0 =A0 =A0 =A0if ((pdata->operating_mode =3D=3D FSL_USB2_DR_HOST) ||
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(pdata->operating_mode =3D=
=3D FSL_USB2_DR_OTG))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpc83xx_setup_phy(ehci, pdata->phy_mode, 0)=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0=
);
>
> =A0 =A0 =A0 =A0if (pdata->operating_mode =3D=3D FSL_USB2_MPH_HOST) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unsigned int chip, rev, svr;
> @@ -228,27 +270,31 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ehci->has_fsl_port_bug =3D=
 1;
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (pdata->port_enables & FSL_USB2_PORT0_E=
NABLED)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpc83xx_setup_phy(ehci, pda=
ta->phy_mode, 0);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ehci_fsl_setup_phy(ehci, pd=
ata->phy_mode, 0);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (pdata->port_enables & FSL_USB2_PORT1_E=
NABLED)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpc83xx_setup_phy(ehci, pda=
ta->phy_mode, 1);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ehci_fsl_setup_phy(ehci, pd=
ata->phy_mode, 1);
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0/* put controller in host mode. */
> - =A0 =A0 =A0 ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMOD=
E);
> + =A0 =A0 =A0 temp =3D USBMODE_CM_HOST | (pdata->es ? USBMODE_ES : 0);
> + =A0 =A0 =A0 ehci_writel(ehci, temp, non_ehci + FSL_SOC_USB_USBMODE);
> +
> + =A0 =A0 =A0 if (pdata->have_sysif_regs) {
> =A0#ifdef CONFIG_PPC_85xx
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x=
00000008);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH=
, 0x00000080);
> =A0#else
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x=
0000000c);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH=
, 0x00000040);
> =A0#endif
> - =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x0=
0000001);
> + =A0 =A0 =A0 }
> =A0}
>
> =A0/* called after powerup, by probe or system-pm "wakeup" */
> =A0static int ehci_fsl_reinit(struct ehci_hcd *ehci)
> =A0{
> - =A0 =A0 =A0 mpc83xx_usb_setup(ehci_to_hcd(ehci));
> + =A0 =A0 =A0 ehci_fsl_usb_setup(ehci);
> =A0 =A0 =A0 =A0ehci_port_power(ehci, 0);
>
> =A0 =A0 =A0 =A0return 0;
> @@ -259,6 +305,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
> =A0{
> =A0 =A0 =A0 =A0struct ehci_hcd *ehci =3D hcd_to_ehci(hcd);
> =A0 =A0 =A0 =A0int retval;
> + =A0 =A0 =A0 struct fsl_usb2_platform_data *pdata;
> +
> + =A0 =A0 =A0 pdata =3D hcd->self.controller->platform_data;
> + =A0 =A0 =A0 ehci->big_endian_desc =3D pdata->big_endian_desc;
> + =A0 =A0 =A0 ehci->big_endian_mmio =3D pdata->big_endian_mmio;
>
> =A0 =A0 =A0 =A0/* EHCI registers start at offset 0x100 */
> =A0 =A0 =A0 =A0ehci->caps =3D hcd->regs + 0x100;
> @@ -372,7 +423,7 @@ static const struct hc_driver ehci_fsl_hc_driver =3D =
{
> =A0 =A0 =A0 =A0 * generic hardware linkage
> =A0 =A0 =A0 =A0 */
> =A0 =A0 =A0 =A0.irq =3D ehci_irq,
> - =A0 =A0 =A0 .flags =3D HCD_USB2,
> + =A0 =A0 =A0 .flags =3D HCD_USB2 | HCD_MEMORY,
>
> =A0 =A0 =A0 =A0/*
> =A0 =A0 =A0 =A0 * basic lifecycle operations
> diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
> index b5e59db..e56be7b 100644
> --- a/drivers/usb/host/ehci-fsl.h
> +++ b/drivers/usb/host/ehci-fsl.h
> @@ -1,4 +1,4 @@
> -/* Copyright (c) 2005 freescale semiconductor
> +/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
> =A0* Copyright (c) 2005 MontaVista Software
> =A0*
> =A0* This program is free software; you can redistribute =A0it and/or mod=
ify it
> @@ -19,6 +19,11 @@
> =A0#define _EHCI_FSL_H
>
> =A0/* offsets for the non-ehci registers in the FSL SOC USB controller */
> +#define FSL_SOC_USB_ID =A0 =A0 =A0 =A0 0x0
> +#define ID_MSK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 0x3f
> +#define NID_MSK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A00x3f00
> +#define FSL_SOC_USB_SBUSCFG =A0 =A00x90
> +#define FSL_SOC_USB_BURSTSIZE =A00x160
> =A0#define FSL_SOC_USB_ULPIVP =A0 =A0 0x170
> =A0#define FSL_SOC_USB_PORTSC1 =A0 =A00x184
> =A0#define PORT_PTS_MSK =A0 =A0 =A0 =A0 =A0 (3<<30)
> @@ -26,8 +31,20 @@
> =A0#define PORT_PTS_ULPI =A0 =A0 =A0 =A0 =A0(2<<30)
> =A0#define =A0 =A0 =A0 =A0PORT_PTS_SERIAL =A0 =A0 =A0 =A0 (3<<30)
> =A0#define PORT_PTS_PTW =A0 =A0 =A0 =A0 =A0 (1<<28)
> +#define PORT_PTS_PHCD =A0 =A0 =A0 =A0 =A0(1<<23)
> =A0#define FSL_SOC_USB_PORTSC2 =A0 =A00x188
> =A0#define FSL_SOC_USB_USBMODE =A0 =A00x1a8
> +#define USBMODE_CM_MASK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(3 << 0) =A0 =A0 =
=A0 =A0/* controller mode mask */
> +#define USBMODE_CM_HOST =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(3 << 0) =A0 =A0 =
=A0 =A0/* controller mode: host */
> +#define USBMODE_ES =A0 =A0 =A0 =A0 =A0 =A0 (1 << 2) =A0 =A0 =A0 =A0/* (B=
ig) Endian Select */
> +
> +#define FSL_SOC_USB_USBGENCTRL 0x200
> +#define USBGENCTRL_PPP =A0 =A0 =A0 =A0 (1 << 3)
> +#define USBGENCTRL_PFP =A0 =A0 =A0 =A0 (1 << 2)
> +#define FSL_SOC_USB_ISIPHYCTRL 0x204
> +#define ISIPHYCTRL_PXE =A0 =A0 =A0 =A0 (1)
> +#define ISIPHYCTRL_PHYE =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 4)
> +
> =A0#define FSL_SOC_USB_SNOOP1 =A0 =A0 0x400 =A0 /* NOTE: big-endian */
> =A0#define FSL_SOC_USB_SNOOP2 =A0 =A0 0x404 =A0 /* NOTE: big-endian */
> =A0#define FSL_SOC_USB_AGECNTTHRSH =A0 =A0 =A0 =A00x408 =A0 /* NOTE: big-=
endian */
> diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
> index 1f3f01e..d36e4e7 100644
> --- a/drivers/usb/host/ehci-mem.c
> +++ b/drivers/usb/host/ehci-mem.c
> @@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci,=
 struct ehci_qtd *qtd,
> =A0{
> =A0 =A0 =A0 =A0memset (qtd, 0, sizeof *qtd);
> =A0 =A0 =A0 =A0qtd->qtd_dma =3D dma;
> - =A0 =A0 =A0 qtd->hw_token =3D cpu_to_le32 (QTD_STS_HALT);
> + =A0 =A0 =A0 qtd->hw_token =3D cpu_to_hc32(ehci, QTD_STS_HALT);
> =A0 =A0 =A0 =A0qtd->hw_next =3D EHCI_LIST_END(ehci);
> =A0 =A0 =A0 =A0qtd->hw_alt_next =3D EHCI_LIST_END(ehci);
> =A0 =A0 =A0 =A0INIT_LIST_HEAD (&qtd->qtd_list);
> diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-=
dr-of.c
> index 020a939..0ced9fc 100644
> --- a/drivers/usb/host/fsl-mph-dr-of.c
> +++ b/drivers/usb/host/fsl-mph-dr-of.c
> @@ -14,6 +14,7 @@
> =A0#include <linux/fsl_devices.h>
> =A0#include <linux/io.h>
> =A0#include <linux/of_platform.h>
> +#include <linux/clk.h>
>
> =A0struct fsl_usb2_dev_data {
> =A0 =A0 =A0 =A0char *dr_mode; =A0 =A0 =A0 =A0 =A0/* controller mode */
> @@ -146,6 +147,12 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct=
 of_device *ofdev,
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pdata->operating_mode =3D FSL_USB2_MPH_HOS=
T;
> =A0 =A0 =A0 =A0} else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (of_get_property(np, "fsl,invert-drvvbus=
", NULL))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->invert_drvvbus =3D 1=
;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (of_get_property(np, "fsl,invert-pwr-fau=
lt", NULL))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->invert_pwr_fault =3D=
 1;
> +
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* setup mode selected in the device tree =
*/
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pdata->operating_mode =3D dev_data->op_mod=
e;
> =A0 =A0 =A0 =A0}
> @@ -167,9 +174,91 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct=
 of_device *ofdev,
> =A0 =A0 =A0 =A0return 0;
> =A0}
>
> +#ifdef CONFIG_PPC_MPC512x
> +
> +#define USBGENCTRL =A0 =A0 =A0 =A0 =A0 =A0 0x200 =A0 =A0 =A0 =A0 =A0 /* =
NOTE: big endian */
> +#define GC_WU_INT_CLR =A0 =A0 =A0 =A0 =A0(1 << 5) =A0 =A0 =A0 =A0/* Wake=
up int clear */
> +#define GC_ULPI_SEL =A0 =A0 =A0 =A0 =A0 =A0(1 << 4) =A0 =A0 =A0 =A0/* UL=
PI i/f select (usb0 only)*/
> +#define GC_PPP =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 3) =A0 =A0 =A0 =A0/=
* Inv. Port Power Polarity */
> +#define GC_PFP =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 2) =A0 =A0 =A0 =A0/=
* Inv. Power Fault Polarity */
> +#define GC_WU_ULPI_EN =A0 =A0 =A0 =A0 =A0(1 << 1) =A0 =A0 =A0 =A0/* Wake=
up on ULPI event */
> +#define GC_WU_IE =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 1) =A0 =A0 =A0 =A0/* =
Wakeup interrupt enable */
> +
> +#define ISIPHYCTRL =A0 =A0 =A0 =A0 =A0 =A0 0x204 =A0 =A0 =A0 =A0 =A0 /* =
NOTE: big endian */
> +#define PHYCTRL_PHYE =A0 =A0 =A0 =A0 =A0 (1 << 4) =A0 =A0 =A0 =A0/* On-c=
hip UTMI PHY enable */
> +#define PHYCTRL_BSENH =A0 =A0 =A0 =A0 =A0(1 << 3) =A0 =A0 =A0 =A0/* Bit =
Stuff Enable High */
> +#define PHYCTRL_BSEN =A0 =A0 =A0 =A0 =A0 (1 << 2) =A0 =A0 =A0 =A0/* Bit =
Stuff Enable */
> +#define PHYCTRL_LSFE =A0 =A0 =A0 =A0 =A0 (1 << 1) =A0 =A0 =A0 =A0/* Line=
 State Filter Enable */
> +#define PHYCTRL_PXE =A0 =A0 =A0 =A0 =A0 =A0(1 << 0) =A0 =A0 =A0 =A0/* PH=
Y oscillator enable */
> +
> +int fsl_usb2_mpc5121_init(struct platform_device *pdev)
> +{
> + =A0 =A0 =A0 struct fsl_usb2_platform_data *pdata =3D pdev->dev.platform=
_data;
> + =A0 =A0 =A0 struct clk *clk;
> + =A0 =A0 =A0 char clk_name[10];
> + =A0 =A0 =A0 int base, clk_num;
> +
> + =A0 =A0 =A0 base =3D pdev->resource->start & 0xf000;
> + =A0 =A0 =A0 if (base =3D=3D 0x3000)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clk_num =3D 1;
> + =A0 =A0 =A0 else if (base =3D=3D 0x4000)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clk_num =3D 2;
> + =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> +
> + =A0 =A0 =A0 snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num);
> + =A0 =A0 =A0 clk =3D clk_get(&pdev->dev, clk_name);
> + =A0 =A0 =A0 if (IS_ERR(clk)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to get clk\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return PTR_ERR(clk);
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 clk_enable(clk);
> + =A0 =A0 =A0 pdata->clk =3D clk;
> +
> + =A0 =A0 =A0 if (pdata->phy_mode =3D=3D FSL_USB2_PHY_UTMI_WIDE) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 u32 reg =3D 0;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (pdata->invert_drvvbus)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg |=3D GC_PPP;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (pdata->invert_pwr_fault)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg |=3D GC_PFP;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(pdata->regs + ISIPHYCTRL, PHYCTRL_=
PHYE | PHYCTRL_PXE);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 out_be32(pdata->regs + USBGENCTRL, reg);
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 return 0;
> +}
> +
> +static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
> +{
> + =A0 =A0 =A0 struct fsl_usb2_platform_data *pdata =3D pdev->dev.platform=
_data;
> +
> + =A0 =A0 =A0 pdata->regs =3D NULL;
> +
> + =A0 =A0 =A0 if (pdata->clk) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clk_disable(pdata->clk);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clk_put(pdata->clk);
> + =A0 =A0 =A0 }
> +}
> +
> +struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd =3D {
> + =A0 =A0 =A0 .big_endian_desc =3D 1,
> + =A0 =A0 =A0 .big_endian_mmio =3D 1,
> + =A0 =A0 =A0 .es =3D 1,
> + =A0 =A0 =A0 .le_setup_buf =3D 1,
> + =A0 =A0 =A0 .init =3D fsl_usb2_mpc5121_init,
> + =A0 =A0 =A0 .exit =3D fsl_usb2_mpc5121_exit,
> +};
> +#endif /* CONFIG_PPC_MPC512x */
> +
> =A0static const struct of_device_id fsl_usb2_mph_dr_of_match[] =3D {
> =A0 =A0 =A0 =A0{ .compatible =3D "fsl-usb2-mph", },
> =A0 =A0 =A0 =A0{ .compatible =3D "fsl-usb2-dr", },
> +#ifdef CONFIG_PPC_MPC512x
> + =A0 =A0 =A0 { .compatible =3D "fsl,mpc5121-usb2-dr", .data =3D &fsl_usb=
2_mpc5121_pd, },
> +#endif
> =A0 =A0 =A0 =A0{},
> =A0};
>
> diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
> index 28e33fe..d5f9a74 100644
> --- a/include/linux/fsl_devices.h
> +++ b/include/linux/fsl_devices.h
> @@ -58,11 +58,26 @@ enum fsl_usb2_phy_modes {
> =A0 =A0 =A0 =A0FSL_USB2_PHY_SERIAL,
> =A0};
>
> +struct clk;
> +struct platform_device;
> +
> =A0struct fsl_usb2_platform_data {
> =A0 =A0 =A0 =A0/* board specific information */
> =A0 =A0 =A0 =A0enum fsl_usb2_operating_modes =A0 operating_mode;
> =A0 =A0 =A0 =A0enum fsl_usb2_phy_modes =A0 =A0 =A0 =A0 phy_mode;
> =A0 =A0 =A0 =A0unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0port_e=
nables;
> +
> + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 (*init)(struct platform_device =
*);
> + =A0 =A0 =A0 void =A0 =A0 =A0 =A0 =A0 =A0(*exit)(struct platform_device =
*);
> + =A0 =A0 =A0 void __iomem =A0 =A0*regs; =A0 =A0 =A0 =A0 =A0/* ioremap'd =
register base */
> + =A0 =A0 =A0 struct clk =A0 =A0 =A0*clk;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0big_endian_mmio:1;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0big_endian_desc:1;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0es:1; =A0 =A0 =A0 =A0 =A0 /* need U=
SBMODE:ES */
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0le_setup_buf:1;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0have_sysif_regs:1;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0invert_drvvbus:1;
> + =A0 =A0 =A0 unsigned =A0 =A0 =A0 =A0invert_pwr_fault:1;
> =A0};
>
> =A0/* Flags in fsl_usb2_mph_platform_data */
> --
> 1.7.0.4
>
>



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-28  8:16   ` Grant Likely
@ 2010-07-28  8:28     ` Anton Vorontsov
  2010-07-28 11:58     ` Anatolij Gustschin
  1 sibling, 0 replies; 11+ messages in thread
From: Anton Vorontsov @ 2010-07-28  8:28 UTC (permalink / raw)
  To: Grant Likely
  Cc: Greg Kroah-Hartman, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, David Brownell, Anatolij Gustschin

On Wed, Jul 28, 2010 at 02:16:08AM -0600, Grant Likely wrote:
[...]
> > +static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
> > +                                          const struct of_device_id *match)
> > +{
> > +       struct device_node *np = ofdev->dev.of_node;
> > +       struct platform_device *usb_dev;
> > +       struct fsl_usb2_platform_data data, *pdata;
> > +       struct fsl_usb2_dev_data *dev_data;
> > +       const unsigned char *prop;
> > +       static unsigned int idx;
> > +       int i;
> > +
> > +       if (!of_device_is_available(np))
> > +               return -ENODEV;
> 
> What is this for?

USB pins/clocks might be muxed away to other peripherals, like
eSDHC. In such cases firmware marks USB as unavailable (status
= "disabled").

If you try to access USB while it is disabled the SOC will hang.

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-28  8:16   ` Grant Likely
  2010-07-28  8:28     ` Anton Vorontsov
@ 2010-07-28 11:58     ` Anatolij Gustschin
  2010-07-28 18:14       ` Grant Likely
  1 sibling, 1 reply; 11+ messages in thread
From: Anatolij Gustschin @ 2010-07-28 11:58 UTC (permalink / raw)
  To: Grant Likely
  Cc: Greg Kroah-Hartman, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, David Brownell

Hi Grant,

On Wed, 28 Jul 2010 02:16:08 -0600
Grant Likely <grant.likely@secretlab.ca> wrote:

> On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wrot=
e:
> > The driver creates platform devices based on the information
> > from USB nodes in the flat device tree. This is the replacement
> > for old arch fsl_soc usb code removed by the previous patch.
> > It uses usual of-style binding, available EHCI-HCD and UDC
> > drivers can be bound to the created devices. The new of-style
> > driver additionaly instantiates USB OTG platform device, as the
> > appropriate USB OTG driver will be added soon.
> >
> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
> > Cc: Kumar Gala <galak@kernel.crashing.org>
> > Cc: Grant Likely <grant.likely@secretlab.ca>
>=20
> Hi Anatolij,
>=20
> Looks pretty good, but some comments below.

Thanks for review and comments! Greg already merged this series and
therefore I'll submit an incremental cleanup patch to address
outstanding issues. My reply is below.

...
> > --- a/drivers/usb/host/Kconfig
> > +++ b/drivers/usb/host/Kconfig
> > @@ -112,10 +112,15 @@ config XPS_USB_HCD_XILINX
> > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0support both hig=
h speed and full speed devices, or high speed
> > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0devices only.
> >
> > +config USB_FSL_MPH_DR_OF
> > + =C2=A0 =C2=A0 =C2=A0 bool
> > + =C2=A0 =C2=A0 =C2=A0 depends on PPC_OF
>=20
> Drop the depends.  This is selected by USB_EHCI_FSL and
> USB_GADGET_FSL_USB2, which are already PPC only.

Okay, will remove it.

...
> > +struct fsl_usb2_dev_data dr_mode_data[] __devinitdata =3D {
> > + =C2=A0 =C2=A0 =C2=A0 {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "host",
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 { "fsl-ehci", NULL, =
NULL, },
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 FSL_USB2_DR_HOST,
> > + =C2=A0 =C2=A0 =C2=A0 },
> > + =C2=A0 =C2=A0 =C2=A0 {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "otg",
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 { "fsl-ehci", "fsl-u=
sb2-udc", "fsl-usb2-otg", },
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 FSL_USB2_DR_OTG,
> > + =C2=A0 =C2=A0 =C2=A0 },
> > + =C2=A0 =C2=A0 =C2=A0 {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "periferal",
>=20
> spelling.  "peripheral"

Right, thanks for catching! Will fix it.

>=20
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 { "fsl-usb2-udc", NU=
LL, NULL, },
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 FSL_USB2_DR_DEVICE,
> > + =C2=A0 =C2=A0 =C2=A0 },
> > +};
>=20
> Program defensively.  Use the following form:
> + =C2=A0 =C2=A0 =C2=A0 {
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .dr_mode =3D "host",
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .drivers =3D { "fsl-eh=
ci", NULL, NULL, },
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .op_mode =3D FSL_USB2_=
DR_HOST,
> + =C2=A0 =C2=A0 =C2=A0 },

I'll change it too as suggested.

...
> > +struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_no=
de *np)
> > +{
> > + =C2=A0 =C2=A0 =C2=A0 const unsigned char *prop;
> > + =C2=A0 =C2=A0 =C2=A0 int i;
> > +
> > + =C2=A0 =C2=A0 =C2=A0 prop =3D of_get_property(np, "dr_mode", NULL);
> > + =C2=A0 =C2=A0 =C2=A0 if (prop) {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < AR=
RAY_SIZE(dr_mode_data); i++) {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 if (!strcmp(prop, dr_mode_data[i].dr_mode))
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return &dr_mode_data[i];
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
>=20
> Print a warning if you get through the loop, but don't match anything.
>  That means that dr_mode has a bad value.

I'll add a warning here.

...
> > +struct platform_device * __devinit
> > +fsl_usb2_device_register(struct of_device *ofdev,
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0struct fsl_usb2_platform_data *pdata,
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0const char *name, int id)
>=20
> In general, it is better to have the function name on the same line as
> the return arguements so that grep shows the relevant info.  Move the
> arguments to subsequent lines.

It will be fixed in a clean-up patch.

...
> > +static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev,
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0const struct of_device_id *match)
> > +{
> > + =C2=A0 =C2=A0 =C2=A0 struct device_node *np =3D ofdev->dev.of_node;
> > + =C2=A0 =C2=A0 =C2=A0 struct platform_device *usb_dev;
> > + =C2=A0 =C2=A0 =C2=A0 struct fsl_usb2_platform_data data, *pdata;
> > + =C2=A0 =C2=A0 =C2=A0 struct fsl_usb2_dev_data *dev_data;
> > + =C2=A0 =C2=A0 =C2=A0 const unsigned char *prop;
> > + =C2=A0 =C2=A0 =C2=A0 static unsigned int idx;
> > + =C2=A0 =C2=A0 =C2=A0 int i;
> > +
> > + =C2=A0 =C2=A0 =C2=A0 if (!of_device_is_available(np))
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -ENODEV;
>=20
> What is this for?

Anton already answered this question better than I could do.

> > +
> > + =C2=A0 =C2=A0 =C2=A0 pdata =3D match->data;
> > + =C2=A0 =C2=A0 =C2=A0 if (!pdata) {
>=20
> The match table doesn't have any data, so this is a no-op.

The next patch [PATCH 3/3] of the series adds the data to the
match table.

...
> > + =C2=A0 =C2=A0 =C2=A0 if (of_device_is_compatible(np, "fsl-usb2-mph"))=
 {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prop =3D of_get_prop=
erty(np, "port0", NULL);
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (prop)
>=20
> if (of_get_property())
>=20
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 pdata->port_enables |=3D FSL_USB2_PORT0_ENABLED;
> > +
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prop =3D of_get_prop=
erty(np, "port1", NULL);
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (prop)
>=20
> Ditto

Okay, I'll clean this up.

...
> > +static struct of_platform_driver fsl_usb2_mph_dr_driver =3D {
> > + =C2=A0 =C2=A0 =C2=A0 .driver =3D {
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .name =3D "fsl-usb2-=
mph-dr",
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .owner =3D THIS_MODU=
LE,
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .of_match_table =3D =
fsl_usb2_mph_dr_of_match,
> > + =C2=A0 =C2=A0 =C2=A0 },
> > + =C2=A0 =C2=A0 =C2=A0 .probe =C2=A0=3D fsl_usb2_mph_dr_of_probe,
> > +};
>=20
> No remove hook?

Since the purpose of the driver is only creation of platform devices
according to the selected dual role controller mode described in
the device tree, I do not see much sense of making the driver a module
and provide a remove hook for destruction of created devices.

...
> > +static int __init fsl_usb2_mph_dr_init(void)
> > +{
> > + =C2=A0 =C2=A0 =C2=A0 return of_register_platform_driver(&fsl_usb2_mph=
_dr_driver);
> > +}
> > +fs_initcall(fsl_usb2_mph_dr_init);
>=20
> Why fs_initcall?  Is module_init() not sufficient?

No. Using module_init() here results in initializing the driver after
loading FLS USB OTG and EHCI-FSL drivers and reverted probing: probe()
in EHCI-FSL driver is called before probe() in OTG driver and doesn't
find OTG transceiver resource which is set and exported by probe() in
OTG driver. This breaks both USB host and device controller support
if dual role controller is configured to operate in OTG mode.

Thanks,
Anatolij

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-28 11:58     ` Anatolij Gustschin
@ 2010-07-28 18:14       ` Grant Likely
  2010-07-28 18:46         ` Greg KH
  0 siblings, 1 reply; 11+ messages in thread
From: Grant Likely @ 2010-07-28 18:14 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Greg Kroah-Hartman, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, David Brownell

On Wed, Jul 28, 2010 at 5:58 AM, Anatolij Gustschin <agust@denx.de> wrote:
> Hi Grant,
>
> On Wed, 28 Jul 2010 02:16:08 -0600
> Grant Likely <grant.likely@secretlab.ca> wrote:
>
>> On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wro=
te:
>> > The driver creates platform devices based on the information
>> > from USB nodes in the flat device tree. This is the replacement
>> > for old arch fsl_soc usb code removed by the previous patch.
>> > It uses usual of-style binding, available EHCI-HCD and UDC
>> > drivers can be bound to the created devices. The new of-style
>> > driver additionaly instantiates USB OTG platform device, as the
>> > appropriate USB OTG driver will be added soon.
>> >
>> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
>> > Cc: Kumar Gala <galak@kernel.crashing.org>
>> > Cc: Grant Likely <grant.likely@secretlab.ca>
>>
>> Hi Anatolij,
>>
>> Looks pretty good, but some comments below.
>
> Thanks for review and comments! Greg already merged this series and
> therefore I'll submit an incremental cleanup patch to address
> outstanding issues. My reply is below.

Greg maintains a patchwork tree IIRC.  I believe he drops patches from
his linux-next branch if they need to be reworked.  Greg, do I have
this right?

Also, my preference would be to see some 3rd party testing before
committing to having this merged.

>
> ...
>> > --- a/drivers/usb/host/Kconfig
>> > +++ b/drivers/usb/host/Kconfig
>> > @@ -112,10 +112,15 @@ config XPS_USB_HCD_XILINX
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0support both high speed and full speed =
devices, or high speed
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0devices only.
>> >
>> > +config USB_FSL_MPH_DR_OF
>> > + =A0 =A0 =A0 bool
>> > + =A0 =A0 =A0 depends on PPC_OF
>>
>> Drop the depends. =A0This is selected by USB_EHCI_FSL and
>> USB_GADGET_FSL_USB2, which are already PPC only.
>
> Okay, will remove it.
>
> ...
>> > +struct fsl_usb2_dev_data dr_mode_data[] __devinitdata =3D {
>> > + =A0 =A0 =A0 {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "host",
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-ehci", NULL, NULL, },
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_HOST,
>> > + =A0 =A0 =A0 },
>> > + =A0 =A0 =A0 {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "otg",
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-ehci", "fsl-usb2-udc", "fsl-usb2-=
otg", },
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_OTG,
>> > + =A0 =A0 =A0 },
>> > + =A0 =A0 =A0 {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 "periferal",
>>
>> spelling. =A0"peripheral"
>
> Right, thanks for catching! Will fix it.
>
>>
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 { "fsl-usb2-udc", NULL, NULL, },
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 FSL_USB2_DR_DEVICE,
>> > + =A0 =A0 =A0 },
>> > +};
>>
>> Program defensively. =A0Use the following form:
>> + =A0 =A0 =A0 {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .dr_mode =3D "host",
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .drivers =3D { "fsl-ehci", NULL, NULL, },
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .op_mode =3D FSL_USB2_DR_HOST,
>> + =A0 =A0 =A0 },
>
> I'll change it too as suggested.
>
> ...
>> > +struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_n=
ode *np)
>> > +{
>> > + =A0 =A0 =A0 const unsigned char *prop;
>> > + =A0 =A0 =A0 int i;
>> > +
>> > + =A0 =A0 =A0 prop =3D of_get_property(np, "dr_mode", NULL);
>> > + =A0 =A0 =A0 if (prop) {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D 0; i < ARRAY_SIZE(dr_mode_dat=
a); i++) {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!strcmp(prop, dr_mod=
e_data[i].dr_mode))
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return &=
dr_mode_data[i];
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>>
>> Print a warning if you get through the loop, but don't match anything.
>> =A0That means that dr_mode has a bad value.
>
> I'll add a warning here.
>
> ...
>> > +struct platform_device * __devinit
>> > +fsl_usb2_device_register(struct of_device *ofdev,
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct fsl_usb2_platf=
orm_data *pdata,
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *name, int=
 id)
>>
>> In general, it is better to have the function name on the same line as
>> the return arguements so that grep shows the relevant info. =A0Move the
>> arguments to subsequent lines.
>
> It will be fixed in a clean-up patch.
>
> ...
>> > +static int __devinit fsl_usb2_mph_dr_of_probe(struct of_device *ofdev=
,
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0const struct of_device_id *match)
>> > +{
>> > + =A0 =A0 =A0 struct device_node *np =3D ofdev->dev.of_node;
>> > + =A0 =A0 =A0 struct platform_device *usb_dev;
>> > + =A0 =A0 =A0 struct fsl_usb2_platform_data data, *pdata;
>> > + =A0 =A0 =A0 struct fsl_usb2_dev_data *dev_data;
>> > + =A0 =A0 =A0 const unsigned char *prop;
>> > + =A0 =A0 =A0 static unsigned int idx;
>> > + =A0 =A0 =A0 int i;
>> > +
>> > + =A0 =A0 =A0 if (!of_device_is_available(np))
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
>>
>> What is this for?
>
> Anton already answered this question better than I could do.
>
>> > +
>> > + =A0 =A0 =A0 pdata =3D match->data;
>> > + =A0 =A0 =A0 if (!pdata) {
>>
>> The match table doesn't have any data, so this is a no-op.
>
> The next patch [PATCH 3/3] of the series adds the data to the
> match table.
>
> ...
>> > + =A0 =A0 =A0 if (of_device_is_compatible(np, "fsl-usb2-mph")) {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 prop =3D of_get_property(np, "port0", NU=
LL);
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (prop)
>>
>> if (of_get_property())
>>
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pdata->port_enables |=3D=
 FSL_USB2_PORT0_ENABLED;
>> > +
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 prop =3D of_get_property(np, "port1", NU=
LL);
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (prop)
>>
>> Ditto
>
> Okay, I'll clean this up.
>
> ...
>> > +static struct of_platform_driver fsl_usb2_mph_dr_driver =3D {
>> > + =A0 =A0 =A0 .driver =3D {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .name =3D "fsl-usb2-mph-dr",
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .owner =3D THIS_MODULE,
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .of_match_table =3D fsl_usb2_mph_dr_of_m=
atch,
>> > + =A0 =A0 =A0 },
>> > + =A0 =A0 =A0 .probe =A0=3D fsl_usb2_mph_dr_of_probe,
>> > +};
>>
>> No remove hook?
>
> Since the purpose of the driver is only creation of platform devices
> according to the selected dual role controller mode described in
> the device tree, I do not see much sense of making the driver a module
> and provide a remove hook for destruction of created devices.

It is still appropriate to have a remove function so the driver can be
unbound.  The remove function should unregister the platform devices
it created in .probe().

>
> ...
>> > +static int __init fsl_usb2_mph_dr_init(void)
>> > +{
>> > + =A0 =A0 =A0 return of_register_platform_driver(&fsl_usb2_mph_dr_driv=
er);
>> > +}
>> > +fs_initcall(fsl_usb2_mph_dr_init);
>>
>> Why fs_initcall? =A0Is module_init() not sufficient?
>
> No. Using module_init() here results in initializing the driver after
> loading FLS USB OTG and EHCI-FSL drivers and reverted probing: probe()
> in EHCI-FSL driver is called before probe() in OTG driver and doesn't
> find OTG transceiver resource which is set and exported by probe() in
> OTG driver. This breaks both USB host and device controller support
> if dual role controller is configured to operate in OTG mode.

This is still broken then, and it is just luck that it is even working
now.  The three sub-devices are registered in sequence which should
handle your ordering issues if you put the OTG driver at the start of
the list; but even that is rather hacky.  You need to make the
EHCI-FSL drivers defer initialization if it has to wait for the OTG
driver.  One option might be to use a bus notifier for this.

I won't nack this patch because of this problem because the problem
already exists in the current code, but it really does need to be
fixed.

g.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-28 18:14       ` Grant Likely
@ 2010-07-28 18:46         ` Greg KH
  2010-08-02 23:01           ` Greg KH
  0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2010-07-28 18:46 UTC (permalink / raw)
  To: Grant Likely
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, Anatolij Gustschin

On Wed, Jul 28, 2010 at 12:14:14PM -0600, Grant Likely wrote:
> On Wed, Jul 28, 2010 at 5:58 AM, Anatolij Gustschin <agust@denx.de> wrote:
> > Hi Grant,
> >
> > On Wed, 28 Jul 2010 02:16:08 -0600
> > Grant Likely <grant.likely@secretlab.ca> wrote:
> >
> >> On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wrote:
> >> > The driver creates platform devices based on the information
> >> > from USB nodes in the flat device tree. This is the replacement
> >> > for old arch fsl_soc usb code removed by the previous patch.
> >> > It uses usual of-style binding, available EHCI-HCD and UDC
> >> > drivers can be bound to the created devices. The new of-style
> >> > driver additionaly instantiates USB OTG platform device, as the
> >> > appropriate USB OTG driver will be added soon.
> >> >
> >> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
> >> > Cc: Kumar Gala <galak@kernel.crashing.org>
> >> > Cc: Grant Likely <grant.likely@secretlab.ca>
> >>
> >> Hi Anatolij,
> >>
> >> Looks pretty good, but some comments below.
> >
> > Thanks for review and comments! Greg already merged this series and
> > therefore I'll submit an incremental cleanup patch to address
> > outstanding issues. My reply is below.
> 
> Greg maintains a patchwork tree IIRC.  I believe he drops patches from
> his linux-next branch if they need to be reworked.  Greg, do I have
> this right?

Yup.  I can easily drop all of these patches.

> Also, my preference would be to see some 3rd party testing before
> committing to having this merged.

Ok, I will go drop them all now, and wait for some that pass your
review.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller
  2010-07-28 18:46         ` Greg KH
@ 2010-08-02 23:01           ` Greg KH
  0 siblings, 0 replies; 11+ messages in thread
From: Greg KH @ 2010-08-02 23:01 UTC (permalink / raw)
  To: Greg KH
  Cc: David Brownell, Wolfgang Denk, Detlev Zundel, linux-usb,
	linuxppc-dev, Anatolij Gustschin

On Wed, Jul 28, 2010 at 11:46:47AM -0700, Greg KH wrote:
> On Wed, Jul 28, 2010 at 12:14:14PM -0600, Grant Likely wrote:
> > On Wed, Jul 28, 2010 at 5:58 AM, Anatolij Gustschin <agust@denx.de> wrote:
> > > Hi Grant,
> > >
> > > On Wed, 28 Jul 2010 02:16:08 -0600
> > > Grant Likely <grant.likely@secretlab.ca> wrote:
> > >
> > >> On Thu, Jul 22, 2010 at 10:25 AM, Anatolij Gustschin <agust@denx.de> wrote:
> > >> > The driver creates platform devices based on the information
> > >> > from USB nodes in the flat device tree. This is the replacement
> > >> > for old arch fsl_soc usb code removed by the previous patch.
> > >> > It uses usual of-style binding, available EHCI-HCD and UDC
> > >> > drivers can be bound to the created devices. The new of-style
> > >> > driver additionaly instantiates USB OTG platform device, as the
> > >> > appropriate USB OTG driver will be added soon.
> > >> >
> > >> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
> > >> > Cc: Kumar Gala <galak@kernel.crashing.org>
> > >> > Cc: Grant Likely <grant.likely@secretlab.ca>
> > >>
> > >> Hi Anatolij,
> > >>
> > >> Looks pretty good, but some comments below.
> > >
> > > Thanks for review and comments! Greg already merged this series and
> > > therefore I'll submit an incremental cleanup patch to address
> > > outstanding issues. My reply is below.
> > 
> > Greg maintains a patchwork tree IIRC.  I believe he drops patches from
> > his linux-next branch if they need to be reworked.  Greg, do I have
> > this right?
> 
> Yup.  I can easily drop all of these patches.
> 
> > Also, my preference would be to see some 3rd party testing before
> > committing to having this merged.
> 
> Ok, I will go drop them all now, and wait for some that pass your
> review.

All 3 now dropped.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2010-08-02 23:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-22 16:25 [PATCH 0/3] Add USB Host support for MPC5121 SoC Anatolij Gustschin
2010-07-22 16:25 ` [PATCH 1/3] powerpc/fsl_soc.c: remove FSL USB platform code Anatolij Gustschin
2010-07-22 16:25 ` [PATCH 2/3] USB: add of_platform glue driver for FSL USB DR controller Anatolij Gustschin
2010-07-28  8:16   ` Grant Likely
2010-07-28  8:28     ` Anton Vorontsov
2010-07-28 11:58     ` Anatolij Gustschin
2010-07-28 18:14       ` Grant Likely
2010-07-28 18:46         ` Greg KH
2010-08-02 23:01           ` Greg KH
2010-07-22 16:25 ` [PATCH 3/3] USB: add USB EHCI support for MPC5121 SoC Anatolij Gustschin
2010-07-28  8:22   ` Grant Likely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).