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 ag...@denx.de
Cc: Kumar Gala ga...@kernel.crashing.org
Cc: Grant Likely grant.lik...@secretlab.ca
---
v2:
- drop unneeded PPC_OF dependency
- fix spelling bug in mode table and fix coding style
- print a warning if no valid dr_mode found
- add remove hook to unregister platform devices
created by probe. So the driver can be unbound
- fix OTG platform device creation order
- drop fs_initcall, replaced by module_init() now
- add module_exit(), MODULE_DESCRIPTION, MODULE_LICENSE
drivers/usb/gadget/Kconfig |1 +
drivers/usb/host/Kconfig |4 +
drivers/usb/host/Makefile|1 +
drivers/usb/host/fsl-mph-dr-of.c | 213 ++
4 files changed, 219 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 fab765d..0fe5bc8 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..f3a90b0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -112,10 +112,14 @@ config XPS_USB_HCD_XILINX
support both high speed and full speed devices, or high speed
devices only.
+config USB_FSL_MPH_DR_OF
+ tristate
+
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 000..ee8cb94
--- /dev/null
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -0,0 +1,213 @@
+/*
+ * 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/err.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 = {
+ {
+ .dr_mode = host,
+ .drivers = { fsl-ehci, NULL, NULL, },
+ .op_mode = FSL_USB2_DR_HOST,
+ },
+ {
+ .dr_mode = otg,
+ .drivers = { fsl-usb2-otg, fsl-ehci, fsl-usb2-udc, },
+ .op_mode = FSL_USB2_DR_OTG,
+ },
+ {
+ .dr_mode = peripheral,
+ .drivers = { fsl-usb2-udc, NULL, NULL, },
+ .op_mode = 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];
+ }
+ }
+ pr_warn(%s: Invalid 'dr_mode' property, fallback to host mode\n,
+ np-full_name);
+ return