linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* am335x, multi instance and phy support, v3
@ 2013-07-30 20:16 Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 1/5] usb: phy: rename nop_usb_xceiv => usb_phy_gen_xceiv Sebastian Andrzej Siewior
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian

Hi,

patch is mostly unchanged. I also added a phy a rename. I belive Tony is okay
with taking this on a -rc4 based branch.
#2 creates exports the common functions su am335x pieces don't polute the file.
#3 is the new phy using the reset module which is similar to what omap does.
#5 has be alted for reset device node.

Sebastian


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

* [PATCH 1/5] usb: phy: rename nop_usb_xceiv => usb_phy_gen_xceiv
  2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
@ 2013-07-30 20:16 ` Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 2/5] usb: phy: phy-generic: export init functions Sebastian Andrzej Siewior
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian, Sebastian Andrzej Siewior

The "nop" driver isn't a do-nothing-stub but supports a couple functions
like clock on/off or is able to use a voltage regulator. This patch
simply renames the driver to "generic" since it is easy possible to
extend it by a simple function istead of writing a complete driver.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/arm/mach-omap2/board-omap3beagle.c  |   4 +-
 arch/arm/mach-omap2/board-omap3evm.c     |   4 +-
 arch/arm/mach-omap2/board-omap3pandora.c |   2 +-
 arch/arm/mach-omap2/usb-host.c           |  10 +-
 drivers/usb/dwc3/dwc3-exynos.c           |   8 +-
 drivers/usb/dwc3/dwc3-pci.c              |   8 +-
 drivers/usb/musb/am35x.c                 |   2 +-
 drivers/usb/musb/blackfin.c              |   2 +-
 drivers/usb/musb/da8xx.c                 |   2 +-
 drivers/usb/musb/davinci.c               |   2 +-
 drivers/usb/musb/musb_dsps.c             |   2 +-
 drivers/usb/musb/tusb6010.c              |   2 +-
 drivers/usb/phy/Makefile                 |   2 +-
 drivers/usb/phy/phy-generic.c            | 292 +++++++++++++++++++++++++++++++
 drivers/usb/phy/phy-nop.c                | 292 -------------------------------
 include/linux/usb/nop-usb-xceiv.h        |  29 ---
 include/linux/usb/usb_phy_gen_xceiv.h    |  29 +++
 17 files changed, 346 insertions(+), 346 deletions(-)
 create mode 100644 drivers/usb/phy/phy-generic.c
 delete mode 100644 drivers/usb/phy/phy-nop.c
 delete mode 100644 include/linux/usb/nop-usb-xceiv.h
 create mode 100644 include/linux/usb/usb_phy_gen_xceiv.h

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 04c1165..1c6ae5f 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -33,7 +33,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mmc/host.h>
 #include <linux/usb/phy.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
@@ -279,7 +279,7 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = {
 static struct gpio_led gpio_leds[];
 
 /* PHY's VCC regulator might be added later, so flag that we need it */
-static struct nop_usb_xceiv_platform_data hsusb2_phy_data = {
+static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = {
 	.needs_vcc = true,
 };
 
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 8c02626..52bdddd 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -33,7 +33,7 @@
 #include <linux/i2c/twl.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/musb.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 #include <linux/smsc911x.h>
 
 #include <linux/wl12xx.h>
@@ -468,7 +468,7 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
 static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = {
 	REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),	/* OMAP ISP */
 	REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),	/* OMAP ISP */
-	REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"),	/* hsusb port 2 */
+	REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"),	/* hsusb port 2 */
 	REGULATOR_SUPPLY("vaux2", NULL),
 };
 
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index b1547a0..d2b455e 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -352,7 +352,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
 };
 
 static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
-	REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"),	/* hsusb port 2 */
+	REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"),	/* hsusb port 2 */
 };
 
 /* ads7846 on SPI and 2 nub controllers on I2C */
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 2eb19d4..e83a6a4 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,7 +28,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/usb/phy.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include "soc.h"
 #include "omap_device.h"
@@ -349,7 +349,7 @@ static struct fixed_voltage_config hsusb_reg_config = {
 	/* .init_data filled later */
 };
 
-static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */
+static const char *nop_name = "usb_phy_gen_xceiv"; /* NOP PHY driver */
 static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
 
 /**
@@ -460,9 +460,9 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
 		pdevinfo.name = nop_name;
 		pdevinfo.id = phy->port;
 		pdevinfo.data = phy->platform_data;
-		pdevinfo.size_data = sizeof(struct nop_usb_xceiv_platform_data);
-
-		scnprintf(phy_id, MAX_STR, "nop_usb_xceiv.%d",
+		pdevinfo.size_data =
+			sizeof(struct usb_phy_gen_xceiv_platform_data);
+		scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d",
 					phy->port);
 		pdev = platform_device_register_full(&pdevinfo);
 		if (IS_ERR(pdev)) {
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index 9a8a5e1..2f2e88a 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -24,7 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/usb/otg.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 
@@ -38,13 +38,13 @@ struct dwc3_exynos {
 
 static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
 {
-	struct nop_usb_xceiv_platform_data pdata;
+	struct usb_phy_gen_xceiv_platform_data pdata;
 	struct platform_device	*pdev;
 	int			ret;
 
 	memset(&pdata, 0x00, sizeof(pdata));
 
-	pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO);
+	pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO);
 	if (!pdev)
 		return -ENOMEM;
 
@@ -55,7 +55,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
 	if (ret)
 		goto err1;
 
-	pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO);
+	pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO);
 	if (!pdev) {
 		ret = -ENOMEM;
 		goto err1;
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 5d746e5..6f5ac34 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -23,7 +23,7 @@
 #include <linux/platform_device.h>
 
 #include <linux/usb/otg.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 /* FIXME define these in <linux/pci_ids.h> */
 #define PCI_VENDOR_ID_SYNOPSYS		0x16c3
@@ -38,13 +38,13 @@ struct dwc3_pci {
 
 static int dwc3_pci_register_phys(struct dwc3_pci *glue)
 {
-	struct nop_usb_xceiv_platform_data pdata;
+	struct usb_phy_gen_xceiv_platform_data pdata;
 	struct platform_device	*pdev;
 	int			ret;
 
 	memset(&pdata, 0x00, sizeof(pdata));
 
-	pdev = platform_device_alloc("nop_usb_xceiv", 0);
+	pdev = platform_device_alloc("usb_phy_gen_xceiv", 0);
 	if (!pdev)
 		return -ENOMEM;
 
@@ -55,7 +55,7 @@ static int dwc3_pci_register_phys(struct dwc3_pci *glue)
 	if (ret)
 		goto err1;
 
-	pdev = platform_device_alloc("nop_usb_xceiv", 1);
+	pdev = platform_device_alloc("usb_phy_gen_xceiv", 1);
 	if (!pdev) {
 		ret = -ENOMEM;
 		goto err1;
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 2231850..5733a20 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -33,7 +33,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 #include <linux/platform_data/usb-omap.h>
 
 #include "musb_core.h"
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 6ba8439..195e966 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -19,7 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/prefetch.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include <asm/cacheflush.h>
 
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 0da6f64..ccc6b63 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -33,7 +33,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include <mach/da8xx.h>
 #include <linux/platform_data/usb-davinci.h>
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index f8aeaf2..91f300e 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -33,7 +33,7 @@
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include <mach/cputype.h>
 #include <mach/hardware.h>
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 23f511f..05c2a02 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -36,7 +36,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 #include <linux/platform_data/usb-omap.h>
 #include <linux/sizes.h>
 
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 6f8a9ca..c642f09 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -25,7 +25,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
 
 #include "musb_core.h"
 
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 070eca3..24c5816 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -14,7 +14,7 @@ phy-fsl-usb2-objs			:= phy-fsl-usb.o phy-fsm-usb.o
 obj-$(CONFIG_FSL_USB2_OTG)		+= phy-fsl-usb2.o
 obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
 obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
-obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-nop.o
+obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
 obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_OMAP_USB3)			+= phy-omap-usb3.o
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
new file mode 100644
index 0000000..f379b7d
--- /dev/null
+++ b/drivers/usb/phy/phy-generic.c
@@ -0,0 +1,292 @@
+/*
+ * drivers/usb/otg/nop-usb-xceiv.c
+ *
+ * NOP USB transceiver for all USB transceiver which are either built-in
+ * into USB IP or which are mostly autonomous.
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Current status:
+ *	This provides a "nop" transceiver for PHYs which are
+ *	autonomous such as isp1504, isp1707, etc.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+
+struct usb_phy_gen_xceiv {
+	struct usb_phy phy;
+	struct device *dev;
+	struct clk *clk;
+	struct regulator *vcc;
+	struct regulator *reset;
+};
+
+static struct platform_device *pd;
+
+void usb_nop_xceiv_register(void)
+{
+	if (pd)
+		return;
+	pd = platform_device_register_simple("usb_phy_gen_xceiv", -1, NULL, 0);
+	if (!pd) {
+		pr_err("Unable to register generic usb transceiver\n");
+		return;
+	}
+}
+EXPORT_SYMBOL(usb_nop_xceiv_register);
+
+void usb_nop_xceiv_unregister(void)
+{
+	platform_device_unregister(pd);
+	pd = NULL;
+}
+EXPORT_SYMBOL(usb_nop_xceiv_unregister);
+
+static int nop_set_suspend(struct usb_phy *x, int suspend)
+{
+	return 0;
+}
+
+static int nop_init(struct usb_phy *phy)
+{
+	struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
+
+	if (!IS_ERR(nop->vcc)) {
+		if (regulator_enable(nop->vcc))
+			dev_err(phy->dev, "Failed to enable power\n");
+	}
+
+	if (!IS_ERR(nop->clk))
+		clk_enable(nop->clk);
+
+	if (!IS_ERR(nop->reset)) {
+		/* De-assert RESET */
+		if (regulator_enable(nop->reset))
+			dev_err(phy->dev, "Failed to de-assert reset\n");
+	}
+
+	return 0;
+}
+
+static void nop_shutdown(struct usb_phy *phy)
+{
+	struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
+
+	if (!IS_ERR(nop->reset)) {
+		/* Assert RESET */
+		if (regulator_disable(nop->reset))
+			dev_err(phy->dev, "Failed to assert reset\n");
+	}
+
+	if (!IS_ERR(nop->clk))
+		clk_disable(nop->clk);
+
+	if (!IS_ERR(nop->vcc)) {
+		if (regulator_disable(nop->vcc))
+			dev_err(phy->dev, "Failed to disable power\n");
+	}
+}
+
+static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
+{
+	if (!otg)
+		return -ENODEV;
+
+	if (!gadget) {
+		otg->gadget = NULL;
+		return -ENODEV;
+	}
+
+	otg->gadget = gadget;
+	otg->phy->state = OTG_STATE_B_IDLE;
+	return 0;
+}
+
+static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+	if (!otg)
+		return -ENODEV;
+
+	if (!host) {
+		otg->host = NULL;
+		return -ENODEV;
+	}
+
+	otg->host = host;
+	return 0;
+}
+
+static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct usb_phy_gen_xceiv_platform_data *pdata = pdev->dev.platform_data;
+	struct usb_phy_gen_xceiv	*nop;
+	enum usb_phy_type	type = USB_PHY_TYPE_USB2;
+	int err;
+	u32 clk_rate = 0;
+	bool needs_vcc = false;
+	bool needs_reset = false;
+
+	nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL);
+	if (!nop)
+		return -ENOMEM;
+
+	nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg),
+							GFP_KERNEL);
+	if (!nop->phy.otg)
+		return -ENOMEM;
+
+	if (dev->of_node) {
+		struct device_node *node = dev->of_node;
+
+		if (of_property_read_u32(node, "clock-frequency", &clk_rate))
+			clk_rate = 0;
+
+		needs_vcc = of_property_read_bool(node, "vcc-supply");
+		needs_reset = of_property_read_bool(node, "reset-supply");
+
+	} else if (pdata) {
+		type = pdata->type;
+		clk_rate = pdata->clk_rate;
+		needs_vcc = pdata->needs_vcc;
+		needs_reset = pdata->needs_reset;
+	}
+
+	nop->clk = devm_clk_get(&pdev->dev, "main_clk");
+	if (IS_ERR(nop->clk)) {
+		dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n",
+					PTR_ERR(nop->clk));
+	}
+
+	if (!IS_ERR(nop->clk) && clk_rate) {
+		err = clk_set_rate(nop->clk, clk_rate);
+		if (err) {
+			dev_err(&pdev->dev, "Error setting clock rate\n");
+			return err;
+		}
+	}
+
+	if (!IS_ERR(nop->clk)) {
+		err = clk_prepare(nop->clk);
+		if (err) {
+			dev_err(&pdev->dev, "Error preparing clock\n");
+			return err;
+		}
+	}
+
+	nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	if (IS_ERR(nop->vcc)) {
+		dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n",
+					PTR_ERR(nop->vcc));
+		if (needs_vcc)
+			return -EPROBE_DEFER;
+	}
+
+	nop->reset = devm_regulator_get(&pdev->dev, "reset");
+	if (IS_ERR(nop->reset)) {
+		dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n",
+					PTR_ERR(nop->reset));
+		if (needs_reset)
+			return -EPROBE_DEFER;
+	}
+
+	nop->dev		= &pdev->dev;
+	nop->phy.dev		= nop->dev;
+	nop->phy.label		= "nop-xceiv";
+	nop->phy.set_suspend	= nop_set_suspend;
+	nop->phy.init		= nop_init;
+	nop->phy.shutdown	= nop_shutdown;
+	nop->phy.state		= OTG_STATE_UNDEFINED;
+	nop->phy.type		= type;
+
+	nop->phy.otg->phy		= &nop->phy;
+	nop->phy.otg->set_host		= nop_set_host;
+	nop->phy.otg->set_peripheral	= nop_set_peripheral;
+
+	err = usb_add_phy_dev(&nop->phy);
+	if (err) {
+		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
+			err);
+		goto err_add;
+	}
+
+	platform_set_drvdata(pdev, nop);
+
+	ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier);
+
+	return 0;
+
+err_add:
+	if (!IS_ERR(nop->clk))
+		clk_unprepare(nop->clk);
+	return err;
+}
+
+static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
+{
+	struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev);
+
+	if (!IS_ERR(nop->clk))
+		clk_unprepare(nop->clk);
+
+	usb_remove_phy(&nop->phy);
+
+	return 0;
+}
+
+static const struct of_device_id nop_xceiv_dt_ids[] = {
+	{ .compatible = "usb-nop-xceiv" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids);
+
+static struct platform_driver usb_phy_gen_xceiv_driver = {
+	.probe		= usb_phy_gen_xceiv_probe,
+	.remove		= usb_phy_gen_xceiv_remove,
+	.driver		= {
+		.name	= "usb_phy_gen_xceiv",
+		.owner	= THIS_MODULE,
+		.of_match_table = nop_xceiv_dt_ids,
+	},
+};
+
+static int __init usb_phy_gen_xceiv_init(void)
+{
+	return platform_driver_register(&usb_phy_gen_xceiv_driver);
+}
+subsys_initcall(usb_phy_gen_xceiv_init);
+
+static void __exit usb_phy_gen_xceiv_exit(void)
+{
+	platform_driver_unregister(&usb_phy_gen_xceiv_driver);
+}
+module_exit(usb_phy_gen_xceiv_exit);
+
+MODULE_ALIAS("platform:usb_phy_gen_xceiv");
+MODULE_AUTHOR("Texas Instruments Inc");
+MODULE_DESCRIPTION("NOP USB Transceiver driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/phy/phy-nop.c b/drivers/usb/phy/phy-nop.c
deleted file mode 100644
index 55445e5d..0000000
--- a/drivers/usb/phy/phy-nop.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * drivers/usb/otg/nop-usb-xceiv.c
- *
- * NOP USB transceiver for all USB transceiver which are either built-in
- * into USB IP or which are mostly autonomous.
- *
- * Copyright (C) 2009 Texas Instruments Inc
- * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Current status:
- *	This provides a "nop" transceiver for PHYs which are
- *	autonomous such as isp1504, isp1707, etc.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/nop-usb-xceiv.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
-#include <linux/of.h>
-
-struct nop_usb_xceiv {
-	struct usb_phy phy;
-	struct device *dev;
-	struct clk *clk;
-	struct regulator *vcc;
-	struct regulator *reset;
-};
-
-static struct platform_device *pd;
-
-void usb_nop_xceiv_register(void)
-{
-	if (pd)
-		return;
-	pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0);
-	if (!pd) {
-		printk(KERN_ERR "Unable to register usb nop transceiver\n");
-		return;
-	}
-}
-EXPORT_SYMBOL(usb_nop_xceiv_register);
-
-void usb_nop_xceiv_unregister(void)
-{
-	platform_device_unregister(pd);
-	pd = NULL;
-}
-EXPORT_SYMBOL(usb_nop_xceiv_unregister);
-
-static int nop_set_suspend(struct usb_phy *x, int suspend)
-{
-	return 0;
-}
-
-static int nop_init(struct usb_phy *phy)
-{
-	struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev);
-
-	if (!IS_ERR(nop->vcc)) {
-		if (regulator_enable(nop->vcc))
-			dev_err(phy->dev, "Failed to enable power\n");
-	}
-
-	if (!IS_ERR(nop->clk))
-		clk_enable(nop->clk);
-
-	if (!IS_ERR(nop->reset)) {
-		/* De-assert RESET */
-		if (regulator_enable(nop->reset))
-			dev_err(phy->dev, "Failed to de-assert reset\n");
-	}
-
-	return 0;
-}
-
-static void nop_shutdown(struct usb_phy *phy)
-{
-	struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev);
-
-	if (!IS_ERR(nop->reset)) {
-		/* Assert RESET */
-		if (regulator_disable(nop->reset))
-			dev_err(phy->dev, "Failed to assert reset\n");
-	}
-
-	if (!IS_ERR(nop->clk))
-		clk_disable(nop->clk);
-
-	if (!IS_ERR(nop->vcc)) {
-		if (regulator_disable(nop->vcc))
-			dev_err(phy->dev, "Failed to disable power\n");
-	}
-}
-
-static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
-{
-	if (!otg)
-		return -ENODEV;
-
-	if (!gadget) {
-		otg->gadget = NULL;
-		return -ENODEV;
-	}
-
-	otg->gadget = gadget;
-	otg->phy->state = OTG_STATE_B_IDLE;
-	return 0;
-}
-
-static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
-{
-	if (!otg)
-		return -ENODEV;
-
-	if (!host) {
-		otg->host = NULL;
-		return -ENODEV;
-	}
-
-	otg->host = host;
-	return 0;
-}
-
-static int nop_usb_xceiv_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
-	struct nop_usb_xceiv	*nop;
-	enum usb_phy_type	type = USB_PHY_TYPE_USB2;
-	int err;
-	u32 clk_rate = 0;
-	bool needs_vcc = false;
-	bool needs_reset = false;
-
-	nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL);
-	if (!nop)
-		return -ENOMEM;
-
-	nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg),
-							GFP_KERNEL);
-	if (!nop->phy.otg)
-		return -ENOMEM;
-
-	if (dev->of_node) {
-		struct device_node *node = dev->of_node;
-
-		if (of_property_read_u32(node, "clock-frequency", &clk_rate))
-			clk_rate = 0;
-
-		needs_vcc = of_property_read_bool(node, "vcc-supply");
-		needs_reset = of_property_read_bool(node, "reset-supply");
-
-	} else if (pdata) {
-		type = pdata->type;
-		clk_rate = pdata->clk_rate;
-		needs_vcc = pdata->needs_vcc;
-		needs_reset = pdata->needs_reset;
-	}
-
-	nop->clk = devm_clk_get(&pdev->dev, "main_clk");
-	if (IS_ERR(nop->clk)) {
-		dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n",
-					PTR_ERR(nop->clk));
-	}
-
-	if (!IS_ERR(nop->clk) && clk_rate) {
-		err = clk_set_rate(nop->clk, clk_rate);
-		if (err) {
-			dev_err(&pdev->dev, "Error setting clock rate\n");
-			return err;
-		}
-	}
-
-	if (!IS_ERR(nop->clk)) {
-		err = clk_prepare(nop->clk);
-		if (err) {
-			dev_err(&pdev->dev, "Error preparing clock\n");
-			return err;
-		}
-	}
-
-	nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
-	if (IS_ERR(nop->vcc)) {
-		dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n",
-					PTR_ERR(nop->vcc));
-		if (needs_vcc)
-			return -EPROBE_DEFER;
-	}
-
-	nop->reset = devm_regulator_get(&pdev->dev, "reset");
-	if (IS_ERR(nop->reset)) {
-		dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n",
-					PTR_ERR(nop->reset));
-		if (needs_reset)
-			return -EPROBE_DEFER;
-	}
-
-	nop->dev		= &pdev->dev;
-	nop->phy.dev		= nop->dev;
-	nop->phy.label		= "nop-xceiv";
-	nop->phy.set_suspend	= nop_set_suspend;
-	nop->phy.init		= nop_init;
-	nop->phy.shutdown	= nop_shutdown;
-	nop->phy.state		= OTG_STATE_UNDEFINED;
-	nop->phy.type		= type;
-
-	nop->phy.otg->phy		= &nop->phy;
-	nop->phy.otg->set_host		= nop_set_host;
-	nop->phy.otg->set_peripheral	= nop_set_peripheral;
-
-	err = usb_add_phy_dev(&nop->phy);
-	if (err) {
-		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
-			err);
-		goto err_add;
-	}
-
-	platform_set_drvdata(pdev, nop);
-
-	ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier);
-
-	return 0;
-
-err_add:
-	if (!IS_ERR(nop->clk))
-		clk_unprepare(nop->clk);
-	return err;
-}
-
-static int nop_usb_xceiv_remove(struct platform_device *pdev)
-{
-	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
-
-	if (!IS_ERR(nop->clk))
-		clk_unprepare(nop->clk);
-
-	usb_remove_phy(&nop->phy);
-
-	return 0;
-}
-
-static const struct of_device_id nop_xceiv_dt_ids[] = {
-	{ .compatible = "usb-nop-xceiv" },
-	{ }
-};
-
-MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids);
-
-static struct platform_driver nop_usb_xceiv_driver = {
-	.probe		= nop_usb_xceiv_probe,
-	.remove		= nop_usb_xceiv_remove,
-	.driver		= {
-		.name	= "nop_usb_xceiv",
-		.owner	= THIS_MODULE,
-		.of_match_table = nop_xceiv_dt_ids,
-	},
-};
-
-static int __init nop_usb_xceiv_init(void)
-{
-	return platform_driver_register(&nop_usb_xceiv_driver);
-}
-subsys_initcall(nop_usb_xceiv_init);
-
-static void __exit nop_usb_xceiv_exit(void)
-{
-	platform_driver_unregister(&nop_usb_xceiv_driver);
-}
-module_exit(nop_usb_xceiv_exit);
-
-MODULE_ALIAS("platform:nop_usb_xceiv");
-MODULE_AUTHOR("Texas Instruments Inc");
-MODULE_DESCRIPTION("NOP USB Transceiver driver");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/usb/nop-usb-xceiv.h b/include/linux/usb/nop-usb-xceiv.h
deleted file mode 100644
index 148d351..0000000
--- a/include/linux/usb/nop-usb-xceiv.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __LINUX_USB_NOP_XCEIV_H
-#define __LINUX_USB_NOP_XCEIV_H
-
-#include <linux/usb/otg.h>
-
-struct nop_usb_xceiv_platform_data {
-	enum usb_phy_type type;
-	unsigned long clk_rate;
-
-	/* if set fails with -EPROBE_DEFER if can't get regulator */
-	unsigned int needs_vcc:1;
-	unsigned int needs_reset:1;
-};
-
-#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
-/* sometimes transceivers are accessed only through e.g. ULPI */
-extern void usb_nop_xceiv_register(void);
-extern void usb_nop_xceiv_unregister(void);
-#else
-static inline void usb_nop_xceiv_register(void)
-{
-}
-
-static inline void usb_nop_xceiv_unregister(void)
-{
-}
-#endif
-
-#endif /* __LINUX_USB_NOP_XCEIV_H */
diff --git a/include/linux/usb/usb_phy_gen_xceiv.h b/include/linux/usb/usb_phy_gen_xceiv.h
new file mode 100644
index 0000000..f9a7e7b
--- /dev/null
+++ b/include/linux/usb/usb_phy_gen_xceiv.h
@@ -0,0 +1,29 @@
+#ifndef __LINUX_USB_NOP_XCEIV_H
+#define __LINUX_USB_NOP_XCEIV_H
+
+#include <linux/usb/otg.h>
+
+struct usb_phy_gen_xceiv_platform_data {
+	enum usb_phy_type type;
+	unsigned long clk_rate;
+
+	/* if set fails with -EPROBE_DEFER if can't get regulator */
+	unsigned int needs_vcc:1;
+	unsigned int needs_reset:1;
+};
+
+#if IS_ENABLED(CONFIG_NOP_USB_XCEIV)
+/* sometimes transceivers are accessed only through e.g. ULPI */
+extern void usb_nop_xceiv_register(void);
+extern void usb_nop_xceiv_unregister(void);
+#else
+static inline void usb_nop_xceiv_register(void)
+{
+}
+
+static inline void usb_nop_xceiv_unregister(void)
+{
+}
+#endif
+
+#endif /* __LINUX_USB_NOP_XCEIV_H */
-- 
1.8.3.2


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

* [PATCH 2/5] usb: phy: phy-generic: export init functions
  2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 1/5] usb: phy: rename nop_usb_xceiv => usb_phy_gen_xceiv Sebastian Andrzej Siewior
@ 2013-07-30 20:16 ` Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 3/5] usb: phy: Add AM335x PHY driver Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian, Sebastian Andrzej Siewior

This patch exports the mostly generic functions so they can be used from
other phy driver instead of duplicating the code.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/usb/phy/phy-generic.c | 130 ++++++++++++++++++++++++------------------
 drivers/usb/phy/phy-generic.h |  20 +++++++
 2 files changed, 93 insertions(+), 57 deletions(-)
 create mode 100644 drivers/usb/phy/phy-generic.h

diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index f379b7d..8808974 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -36,13 +36,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/of.h>
 
-struct usb_phy_gen_xceiv {
-	struct usb_phy phy;
-	struct device *dev;
-	struct clk *clk;
-	struct regulator *vcc;
-	struct regulator *reset;
-};
+#include "phy-generic.h"
 
 static struct platform_device *pd;
 
@@ -70,7 +64,7 @@ static int nop_set_suspend(struct usb_phy *x, int suspend)
 	return 0;
 }
 
-static int nop_init(struct usb_phy *phy)
+int usb_gen_phy_init(struct usb_phy *phy)
 {
 	struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
 
@@ -90,8 +84,9 @@ static int nop_init(struct usb_phy *phy)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usb_gen_phy_init);
 
-static void nop_shutdown(struct usb_phy *phy)
+void usb_gen_phy_shutdown(struct usb_phy *phy)
 {
 	struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
 
@@ -109,6 +104,7 @@ static void nop_shutdown(struct usb_phy *phy)
 			dev_err(phy->dev, "Failed to disable power\n");
 	}
 }
+EXPORT_SYMBOL_GPL(usb_gen_phy_shutdown);
 
 static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
 {
@@ -139,52 +135,27 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
 	return 0;
 }
 
-static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
+int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
+		enum usb_phy_type type, u32 clk_rate, bool needs_vcc,
+		bool needs_reset)
 {
-	struct device *dev = &pdev->dev;
-	struct usb_phy_gen_xceiv_platform_data *pdata = pdev->dev.platform_data;
-	struct usb_phy_gen_xceiv	*nop;
-	enum usb_phy_type	type = USB_PHY_TYPE_USB2;
 	int err;
-	u32 clk_rate = 0;
-	bool needs_vcc = false;
-	bool needs_reset = false;
-
-	nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL);
-	if (!nop)
-		return -ENOMEM;
 
-	nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg),
-							GFP_KERNEL);
+	nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg),
+			GFP_KERNEL);
 	if (!nop->phy.otg)
 		return -ENOMEM;
 
-	if (dev->of_node) {
-		struct device_node *node = dev->of_node;
-
-		if (of_property_read_u32(node, "clock-frequency", &clk_rate))
-			clk_rate = 0;
-
-		needs_vcc = of_property_read_bool(node, "vcc-supply");
-		needs_reset = of_property_read_bool(node, "reset-supply");
-
-	} else if (pdata) {
-		type = pdata->type;
-		clk_rate = pdata->clk_rate;
-		needs_vcc = pdata->needs_vcc;
-		needs_reset = pdata->needs_reset;
-	}
-
-	nop->clk = devm_clk_get(&pdev->dev, "main_clk");
+	nop->clk = devm_clk_get(dev, "main_clk");
 	if (IS_ERR(nop->clk)) {
-		dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n",
+		dev_dbg(dev, "Can't get phy clock: %ld\n",
 					PTR_ERR(nop->clk));
 	}
 
 	if (!IS_ERR(nop->clk) && clk_rate) {
 		err = clk_set_rate(nop->clk, clk_rate);
 		if (err) {
-			dev_err(&pdev->dev, "Error setting clock rate\n");
+			dev_err(dev, "Error setting clock rate\n");
 			return err;
 		}
 	}
@@ -192,33 +163,31 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 	if (!IS_ERR(nop->clk)) {
 		err = clk_prepare(nop->clk);
 		if (err) {
-			dev_err(&pdev->dev, "Error preparing clock\n");
+			dev_err(dev, "Error preparing clock\n");
 			return err;
 		}
 	}
 
-	nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
+	nop->vcc = devm_regulator_get(dev, "vcc");
 	if (IS_ERR(nop->vcc)) {
-		dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n",
+		dev_dbg(dev, "Error getting vcc regulator: %ld\n",
 					PTR_ERR(nop->vcc));
 		if (needs_vcc)
 			return -EPROBE_DEFER;
 	}
 
-	nop->reset = devm_regulator_get(&pdev->dev, "reset");
+	nop->reset = devm_regulator_get(dev, "reset");
 	if (IS_ERR(nop->reset)) {
-		dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n",
+		dev_dbg(dev, "Error getting reset regulator: %ld\n",
 					PTR_ERR(nop->reset));
 		if (needs_reset)
 			return -EPROBE_DEFER;
 	}
 
-	nop->dev		= &pdev->dev;
+	nop->dev		= dev;
 	nop->phy.dev		= nop->dev;
 	nop->phy.label		= "nop-xceiv";
 	nop->phy.set_suspend	= nop_set_suspend;
-	nop->phy.init		= nop_init;
-	nop->phy.shutdown	= nop_shutdown;
 	nop->phy.state		= OTG_STATE_UNDEFINED;
 	nop->phy.type		= type;
 
@@ -226,6 +195,58 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 	nop->phy.otg->set_host		= nop_set_host;
 	nop->phy.otg->set_peripheral	= nop_set_peripheral;
 
+	ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);
+
+void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop)
+{
+	if (!IS_ERR(nop->clk))
+		clk_unprepare(nop->clk);
+}
+EXPORT_SYMBOL_GPL(usb_phy_gen_cleanup_phy);
+
+static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct usb_phy_gen_xceiv_platform_data *pdata = pdev->dev.platform_data;
+	struct usb_phy_gen_xceiv	*nop;
+	enum usb_phy_type	type = USB_PHY_TYPE_USB2;
+	int err;
+	u32 clk_rate = 0;
+	bool needs_vcc = false;
+	bool needs_reset = false;
+
+	if (dev->of_node) {
+		struct device_node *node = dev->of_node;
+
+		if (of_property_read_u32(node, "clock-frequency", &clk_rate))
+			clk_rate = 0;
+
+		needs_vcc = of_property_read_bool(node, "vcc-supply");
+		needs_reset = of_property_read_bool(node, "reset-supply");
+
+	} else if (pdata) {
+		type = pdata->type;
+		clk_rate = pdata->clk_rate;
+		needs_vcc = pdata->needs_vcc;
+		needs_reset = pdata->needs_reset;
+	}
+
+	nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
+	if (!nop)
+		return -ENOMEM;
+
+
+	err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc,
+			needs_reset);
+	if (err)
+		return err;
+
+	nop->phy.init		= usb_gen_phy_init;
+	nop->phy.shutdown	= usb_gen_phy_shutdown;
+
 	err = usb_add_phy_dev(&nop->phy);
 	if (err) {
 		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
@@ -235,13 +256,10 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, nop);
 
-	ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier);
-
 	return 0;
 
 err_add:
-	if (!IS_ERR(nop->clk))
-		clk_unprepare(nop->clk);
+	usb_phy_gen_cleanup_phy(nop);
 	return err;
 }
 
@@ -249,9 +267,7 @@ static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
 {
 	struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev);
 
-	if (!IS_ERR(nop->clk))
-		clk_unprepare(nop->clk);
-
+	usb_phy_gen_cleanup_phy(nop);
 	usb_remove_phy(&nop->phy);
 
 	return 0;
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h
new file mode 100644
index 0000000..61687d5
--- /dev/null
+++ b/drivers/usb/phy/phy-generic.h
@@ -0,0 +1,20 @@
+#ifndef _PHY_GENERIC_H_
+#define _PHY_GENERIC_H_
+
+struct usb_phy_gen_xceiv {
+	struct usb_phy phy;
+	struct device *dev;
+	struct clk *clk;
+	struct regulator *vcc;
+	struct regulator *reset;
+};
+
+int usb_gen_phy_init(struct usb_phy *phy);
+void usb_gen_phy_shutdown(struct usb_phy *phy);
+
+int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
+		enum usb_phy_type type, u32 clk_rate, bool needs_vcc,
+		bool needs_reset);
+void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop);
+
+#endif
-- 
1.8.3.2


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

* [PATCH 3/5] usb: phy: Add AM335x PHY driver
  2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 1/5] usb: phy: rename nop_usb_xceiv => usb_phy_gen_xceiv Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 2/5] usb: phy: phy-generic: export init functions Sebastian Andrzej Siewior
@ 2013-07-30 20:16 ` Sebastian Andrzej Siewior
  2013-08-01  5:36   ` George Cherian
  2013-07-30 20:16 ` [PATCH 4/5] usb: musb: dsps: remove the hardcoded phy pieces Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 5/5] usb: musb: dsps: use proper child nodes Sebastian Andrzej Siewior
  4 siblings, 1 reply; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian, Sebastian Andrzej Siewior

This driver is a redo of my earlier attempt. It uses parts of the
generic PHY driver and uses the new control driver for the register
the phy needs to power on/off the phy. It also enables easy access for
the wakeup register which is not yet implemented.
The difference between the omap attempt is:
- no static holding variable
- one global visible function which exports a struct with callbacks to
  access the "control" registers.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/usb/phy/Kconfig              |  12 ++++
 drivers/usb/phy/Makefile             |   2 +
 drivers/usb/phy/am35x-phy-control.h  |  21 ++++++
 drivers/usb/phy/phy-am335x-control.c | 135 +++++++++++++++++++++++++++++++++++
 drivers/usb/phy/phy-am335x.c         |  99 +++++++++++++++++++++++++
 5 files changed, 269 insertions(+)
 create mode 100644 drivers/usb/phy/am35x-phy-control.h
 create mode 100644 drivers/usb/phy/phy-am335x-control.c
 create mode 100644 drivers/usb/phy/phy-am335x.c

diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index f5ea339..f41c3e1 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -86,6 +86,18 @@ config OMAP_USB3
 	  This driver interacts with the "OMAP Control USB Driver" to power
 	  on/off the PHY.
 
+config AM335X_CONTROL_USB
+	tristate
+
+config AM335X_PHY_USB
+	tristate "AM335x USB PHY Driver"
+	select USB_PHY
+	select AM335X_CONTROL_USB
+	select NOP_USB_XCEIV
+	help
+	  This driver provides PHY support for that phy which part for the
+	  AM335x SoC.
+
 config SAMSUNG_USBPHY
 	tristate
 	help
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 24c5816..dae321d 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
 obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
 obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
 obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
+obj-$(CONFIG_AM335X_CONTROL_USB)	+= phy-am335x-control.o
+obj-$(CONFIG_AM335X_PHY_USB)		+= phy-am335x.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_OMAP_USB3)			+= phy-omap-usb3.o
 obj-$(CONFIG_SAMSUNG_USBPHY)		+= phy-samsung-usb.o
diff --git a/drivers/usb/phy/am35x-phy-control.h b/drivers/usb/phy/am35x-phy-control.h
new file mode 100644
index 0000000..b96594d
--- /dev/null
+++ b/drivers/usb/phy/am35x-phy-control.h
@@ -0,0 +1,21 @@
+#ifndef _AM335x_PHY_CONTROL_H_
+#define _AM335x_PHY_CONTROL_H_
+
+struct phy_control {
+	void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on);
+	void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on);
+};
+
+static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, bool on)
+{
+	phy_ctrl->phy_power(phy_ctrl, id, on);
+}
+
+static inline void phy_ctrl_wkup(struct phy_control *phy_ctrl, u32 id, bool on)
+{
+	phy_ctrl->phy_wkup(phy_ctrl, id, on);
+}
+
+struct phy_control *am335x_get_phy_control(struct device *dev);
+
+#endif
diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c
new file mode 100644
index 0000000..64e5ab4
--- /dev/null
+++ b/drivers/usb/phy/phy-am335x-control.c
@@ -0,0 +1,135 @@
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+struct phy_control {
+	void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on);
+	void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on);
+};
+
+struct am335x_control_usb {
+	struct device *dev;
+	void __iomem *reset_reg;
+	spinlock_t lock;
+	struct phy_control phy_ctrl;
+};
+
+#define AM335X_USB0_CTRL		0x620
+#define AM335X_USB1_CTRL		0x628
+#define AM335x_USB_WKUP			0x648
+
+#define USBPHY_CM_PWRDN		(1 << 0)
+#define USBPHY_OTG_PWRDN	(1 << 1)
+#define USBPHY_OTGVDET_EN	(1 << 19)
+#define USBPHY_OTGSESSEND_EN	(1 << 20)
+
+static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
+{
+	struct am335x_control_usb *usb_ctrl;
+	u32 val;
+	u32 reg;
+
+	usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl);
+
+	switch (id) {
+	case 0:
+		reg = AM335X_USB0_CTRL;
+		break;
+	case 1:
+		reg = AM335X_USB1_CTRL;
+		break;
+	default:
+		__WARN();
+		 return;
+	}
+
+	val = readl(usb_ctrl->reset_reg + reg);
+	if (on) {
+		val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
+		val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
+	} else {
+		val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
+	}
+
+	writel(val, usb_ctrl->reset_reg + reg);
+}
+
+static const struct phy_control ctrl_am335x = {
+	.phy_power = am335x_phy_power,
+};
+
+static const struct of_device_id omap_control_usb_id_table[] = {
+	{ .compatible = "ti,am335x-ctrl-module", .data = &ctrl_am335x },
+	{}
+};
+MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
+
+static struct platform_driver am335x_control_driver;
+static int match(struct device *dev, void *data)
+{
+	struct device_node *node = (struct device_node *)data;
+	return dev->of_node == node &&
+		dev->driver == &am335x_control_driver.driver;
+}
+
+struct phy_control *am335x_get_phy_control(struct device *dev)
+{
+	struct device_node *node;
+	struct am335x_control_usb *ctrl_usb;
+
+	node = of_parse_phandle(dev->of_node, "ti,ctrl_mod", 0);
+	if (!node)
+		return NULL;
+
+	dev = bus_find_device(&platform_bus_type, NULL, node, match);
+	ctrl_usb = dev_get_drvdata(dev);
+	if (!ctrl_usb)
+		return NULL;
+	return &ctrl_usb->phy_ctrl;
+}
+EXPORT_SYMBOL_GPL(am335x_get_phy_control);
+
+static int am335x_control_usb_probe(struct platform_device *pdev)
+{
+	struct resource	*res;
+	struct am335x_control_usb *ctrl_usb;
+	const struct of_device_id *of_id;
+	const struct phy_control *phy_ctrl;
+
+	of_id = of_match_node(omap_control_usb_id_table, pdev->dev.of_node);
+	if (!of_id)
+		return -EINVAL;
+
+	phy_ctrl = of_id->data;
+
+	ctrl_usb = devm_kzalloc(&pdev->dev, sizeof(*ctrl_usb), GFP_KERNEL);
+	if (!ctrl_usb) {
+		dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
+		return -ENOMEM;
+	}
+
+	ctrl_usb->dev = &pdev->dev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control_dev");
+	ctrl_usb->reset_reg = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ctrl_usb->reset_reg))
+		return PTR_ERR(ctrl_usb->reset_reg);
+	spin_lock_init(&ctrl_usb->lock);
+	ctrl_usb->phy_ctrl = *phy_ctrl;
+
+	dev_set_drvdata(ctrl_usb->dev, ctrl_usb);
+	return 0;
+}
+
+static struct platform_driver am335x_control_driver = {
+	.probe		= am335x_control_usb_probe,
+	.driver		= {
+		.name	= "am335x-control-usb",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(omap_control_usb_id_table),
+	},
+};
+
+module_platform_driver(am335x_control_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
new file mode 100644
index 0000000..c4d614d
--- /dev/null
+++ b/drivers/usb/phy/phy-am335x.c
@@ -0,0 +1,99 @@
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "am35x-phy-control.h"
+#include "phy-generic.h"
+
+struct am335x_phy {
+	struct usb_phy_gen_xceiv usb_phy_gen;
+	struct phy_control *phy_ctrl;
+	int id;
+};
+
+static int am335x_init(struct usb_phy *phy)
+{
+	struct am335x_phy *am_phy = dev_get_drvdata(phy->dev);
+
+	phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true);
+	return 0;
+}
+
+static void am335x_shutdown(struct usb_phy *phy)
+{
+	struct am335x_phy *am_phy = dev_get_drvdata(phy->dev);
+
+	phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false);
+}
+
+static int am335x_phy_probe(struct platform_device *pdev)
+{
+	struct am335x_phy *am_phy;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	am_phy = devm_kzalloc(dev, sizeof(*am_phy), GFP_KERNEL);
+	if (!am_phy)
+		return -ENOMEM;
+
+	am_phy->phy_ctrl = am335x_get_phy_control(dev);
+	if (!am_phy->phy_ctrl)
+		return -EPROBE_DEFER;
+	am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy");
+	if (am_phy->id < 0) {
+		dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id);
+		return am_phy->id;
+	}
+
+	ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen,
+			USB_PHY_TYPE_USB2, 0, false, false);
+	if (ret)
+		return ret;
+
+	ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy);
+	if (ret)
+		goto err_add;
+	am_phy->usb_phy_gen.phy.init = am335x_init;
+	am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown;
+
+	platform_set_drvdata(pdev, am_phy);
+	return 0;
+
+err_add:
+	usb_phy_gen_cleanup_phy(&am_phy->usb_phy_gen);
+	return ret;
+}
+
+static int am335x_phy_remove(struct platform_device *pdev)
+{
+	struct am335x_phy *am_phy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&am_phy->usb_phy_gen.phy);
+	return 0;
+}
+
+static const struct of_device_id am335x_phy_ids[] = {
+	{ .compatible = "ti,am335x-usb-phy" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, am335x_phy_ids);
+
+static struct platform_driver am335x_phy_driver = {
+	.probe          = am335x_phy_probe,
+	.remove         = am335x_phy_remove,
+	.driver         = {
+		.name   = "am335x-phy-driver",
+		.owner  = THIS_MODULE,
+		.of_match_table = of_match_ptr(am335x_phy_ids),
+	},
+};
+
+module_platform_driver(am335x_phy_driver);
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2


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

* [PATCH 4/5] usb: musb: dsps: remove the hardcoded phy pieces
  2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2013-07-30 20:16 ` [PATCH 3/5] usb: phy: Add AM335x PHY driver Sebastian Andrzej Siewior
@ 2013-07-30 20:16 ` Sebastian Andrzej Siewior
  2013-07-30 20:16 ` [PATCH 5/5] usb: musb: dsps: use proper child nodes Sebastian Andrzej Siewior
  4 siblings, 0 replies; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian, Sebastian Andrzej Siewior

dsps uses a nop driver which is added in dsps itself and does the PHY
on/off calls within dsps. Since those calls are now moved the nop driver
itself, we can now request the phy proper phy and remove those calls.
Currently only the first musb interface is used so we only add one phy
node for now.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/usb/musb/musb_dsps.c | 97 +-------------------------------------------
 1 file changed, 1 insertion(+), 96 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 05c2a02..7f1361c 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -120,49 +120,8 @@ struct dsps_glue {
 	const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
 	struct timer_list timer[2];	/* otg_workaround timer */
 	unsigned long last_timer[2];    /* last timer data for each instance */
-	u32 __iomem *usb_ctrl[2];
 };
 
-#define	DSPS_AM33XX_CONTROL_MODULE_PHYS_0	0x44e10620
-#define	DSPS_AM33XX_CONTROL_MODULE_PHYS_1	0x44e10628
-
-static const resource_size_t dsps_control_module_phys[] = {
-	DSPS_AM33XX_CONTROL_MODULE_PHYS_0,
-	DSPS_AM33XX_CONTROL_MODULE_PHYS_1,
-};
-
-#define USBPHY_CM_PWRDN		(1 << 0)
-#define USBPHY_OTG_PWRDN	(1 << 1)
-#define USBPHY_OTGVDET_EN	(1 << 19)
-#define USBPHY_OTGSESSEND_EN	(1 << 20)
-
-/**
- * musb_dsps_phy_control - phy on/off
- * @glue: struct dsps_glue *
- * @id: musb instance
- * @on: flag for phy to be switched on or off
- *
- * This is to enable the PHY using usb_ctrl register in system control
- * module space.
- *
- * XXX: This function will be removed once we have a seperate driver for
- * control module
- */
-static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on)
-{
-	u32 usbphycfg;
-
-	usbphycfg = readl(glue->usb_ctrl[id]);
-
-	if (on) {
-		usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
-		usbphycfg |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
-	} else {
-		usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
-	}
-
-	writel(usbphycfg, glue->usb_ctrl[id]);
-}
 /**
  * dsps_musb_enable - enable interrupts
  */
@@ -407,8 +366,7 @@ static int dsps_musb_init(struct musb *musb)
 	musb->mregs += wrp->musb_core_offset;
 
 	/* NOP driver needs change if supporting dual instance */
-	usb_nop_xceiv_register();
-	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+	musb->xceiv = devm_usb_get_phy_by_phandle(glue->dev, "phys", 0);
 	if (IS_ERR_OR_NULL(musb->xceiv))
 		return -EPROBE_DEFER;
 
@@ -426,9 +384,6 @@ static int dsps_musb_init(struct musb *musb)
 	/* Reset the musb */
 	dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
 
-	/* Start the on-chip PHY and its PLL. */
-	musb_dsps_phy_control(glue, pdev->id, 1);
-
 	musb->isr = dsps_interrupt;
 
 	/* reset the otgdisable bit, needed for host mode to work */
@@ -438,8 +393,6 @@ static int dsps_musb_init(struct musb *musb)
 
 	return 0;
 err0:
-	usb_put_phy(musb->xceiv);
-	usb_nop_xceiv_unregister();
 	return status;
 }
 
@@ -451,14 +404,7 @@ static int dsps_musb_exit(struct musb *musb)
 
 	del_timer_sync(&glue->timer[pdev->id]);
 
-	/* Shutdown the on-chip PHY and its PLL. */
-	musb_dsps_phy_control(glue, pdev->id, 0);
 	usb_phy_shutdown(musb->xceiv);
-
-	/* NOP driver needs change if supporting dual instance */
-	usb_put_phy(musb->xceiv);
-	usb_nop_xceiv_unregister();
-
 	return 0;
 }
 
@@ -487,16 +433,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
 	char res_name[11];
 	int ret;
 
-	resources[0].start = dsps_control_module_phys[id];
-	resources[0].end = resources[0].start + SZ_4 - 1;
-	resources[0].flags = IORESOURCE_MEM;
-
-	glue->usb_ctrl[id] = devm_ioremap_resource(&pdev->dev, resources);
-	if (IS_ERR(glue->usb_ctrl[id])) {
-		ret = PTR_ERR(glue->usb_ctrl[id]);
-		goto err0;
-	}
-
 	/* first resource is for usbss, so start index from 1 */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
 	if (!res) {
@@ -680,36 +616,6 @@ static int dsps_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int dsps_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev->parent);
-	struct dsps_glue *glue = platform_get_drvdata(pdev);
-	const struct dsps_musb_wrapper *wrp = glue->wrp;
-	int i;
-
-	for (i = 0; i < wrp->instances; i++)
-		musb_dsps_phy_control(glue, i, 0);
-
-	return 0;
-}
-
-static int dsps_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev->parent);
-	struct dsps_glue *glue = platform_get_drvdata(pdev);
-	const struct dsps_musb_wrapper *wrp = glue->wrp;
-	int i;
-
-	for (i = 0; i < wrp->instances; i++)
-		musb_dsps_phy_control(glue, i, 1);
-
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
-
 static const struct dsps_musb_wrapper am33xx_driver_data = {
 	.revision		= 0x00,
 	.control		= 0x14,
@@ -752,7 +658,6 @@ static struct platform_driver dsps_usbss_driver = {
 	.remove         = dsps_remove,
 	.driver         = {
 		.name   = "musb-dsps",
-		.pm	= &dsps_pm_ops,
 		.of_match_table	= of_match_ptr(musb_dsps_of_match),
 	},
 };
-- 
1.8.3.2


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

* [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
                   ` (3 preceding siblings ...)
  2013-07-30 20:16 ` [PATCH 4/5] usb: musb: dsps: remove the hardcoded phy pieces Sebastian Andrzej Siewior
@ 2013-07-30 20:16 ` Sebastian Andrzej Siewior
  2013-08-01  5:24   ` George Cherian
  4 siblings, 1 reply; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-07-30 20:16 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, linux-kernel, george.cherian, Sebastian Andrzej Siewior

This moves the two instances from the big node into two child nodes. The
glue layer ontop does almost nothing.
There is one devices containing the control module for USB (2) phy,
(2) usb and later the dma engine. The usb device is the "glue device"
which contains the musb device as a child. This is what we do ever since.
The new file musb_am335x is just here to prob the new bus and populate
child devices.
There are a lot of changes to the dsps file as a result of the changes:
- musb_core_offset
  This is gone. The device tree provides memory ressources information
  for the device there is no need to "fix" things
- instances
  This is gone as well. If we have two instances then we have have two
  child enabled nodes in the device tree. For instance the SoC in beagle
  bone has two USB instances but only one has been wired up so there is
  no need to load and init the second instance since it won't be used.
- dsps_glue is now per glue device
  In the past there was one of this structs but with an array of two and
  each instance accessed its variable depending on the platform device
  id.
- no unneeded copy of structs
  I do not know why struct dsps_musb_wrapper is copied but it is not
  necessary. The same goes for musb_hdrc_platform_data which allocated
  on demand and then again by platform_device_add_data(). One copy is
  enough.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/arm/boot/dts/am335x-bone.dts  |  16 +++
 arch/arm/boot/dts/am335x-evm.dts   |  24 ++++
 arch/arm/boot/dts/am335x-evmsk.dts |  16 +++
 arch/arm/boot/dts/am33xx.dtsi      |  96 ++++++++++++--
 drivers/usb/musb/Kconfig           |   4 +
 drivers/usb/musb/Makefile          |   3 +
 drivers/usb/musb/musb_am335x.c     |  55 ++++++++
 drivers/usb/musb/musb_dsps.c       | 255 ++++++++++++++-----------------------
 8 files changed, 298 insertions(+), 171 deletions(-)
 create mode 100644 drivers/usb/musb/musb_am335x.c

diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
index 444b4ed..a8907b5 100644
--- a/arch/arm/boot/dts/am335x-bone.dts
+++ b/arch/arm/boot/dts/am335x-bone.dts
@@ -120,6 +120,22 @@
 			status = "okay";
 		};
 
+		musb: usb@47400000 {
+			status = "okay";
+
+			control@44e10000 {
+				status = "okay";
+			};
+
+			phy@47401300 {
+				status = "okay";
+			};
+
+			usb@47401000 {
+				status = "okay";
+			};
+		};
+
 		i2c0: i2c@44e0b000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c0_pins>;
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 3aee1a4..b2987e0 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -171,6 +171,30 @@
 			};
 		};
 
+		musb: usb@47400000 {
+			status = "okay";
+
+			control@44e10000 {
+				status = "okay";
+			};
+
+			phy@47401300 {
+				status = "okay";
+			};
+
+			phy@47401b00 {
+				status = "okay";
+			};
+
+			usb@47401000 {
+				status = "okay";
+			};
+
+			usb@47401800 {
+				status = "okay";
+			};
+		};
+
 		i2c1: i2c@4802a000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c1_pins>;
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index 0c8ad17..e92446c 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -207,6 +207,22 @@
 			};
 		};
 
+		musb: usb@47400000 {
+			status = "okay";
+
+			control@44e10000 {
+				status = "okay";
+			};
+
+			phy@47401300 {
+				status = "okay";
+			};
+
+			usb@47401000 {
+				status = "okay";
+			};
+		};
+
 		epwmss2: epwmss@48304000 {
 			status = "okay";
 
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 38b446b..0f756ca 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -26,6 +26,10 @@
 		serial5 = &uart5;
 		d_can0 = &dcan0;
 		d_can1 = &dcan1;
+		usb0 = &usb0;
+		usb1 = &usb1;
+		phy0 = &usb0_phy;
+		phy1 = &usb1_phy;
 	};
 
 	cpus {
@@ -333,21 +337,85 @@
 			status = "disabled";
 		};
 
-		usb@47400000 {
-			compatible = "ti,musb-am33xx";
-			reg = <0x47400000 0x1000	/* usbss */
-			       0x47401000 0x800		/* musb instance 0 */
-			       0x47401800 0x800>;	/* musb instance 1 */
-			interrupts = <17		/* usbss */
-				      18		/* musb instance 0 */
-				      19>;		/* musb instance 1 */
-			multipoint = <1>;
-			num-eps = <16>;
-			ram-bits = <12>;
-			port0-mode = <3>;
-			port1-mode = <3>;
-			power = <250>;
+		usb: usb@47400000 {
+			compatible = "ti,am33xx-usb";
+			reg = <0x47400000 0x1000>;
+			ranges;
+			#address-cells = <1>;
+			#size-cells = <1>;
 			ti,hwmods = "usb_otg_hs";
+			status = "disabled";
+
+			ctrl_mod: control@44e10000 {
+				compatible = "ti,am335x-ctrl-module";
+				reg = <0x44e10000 0x650>;
+				reg-names = "control_dev";
+				status = "disabled";
+			};
+
+			usb0_phy: phy@47401300 {
+				compatible = "ti,am335x-usb-phy";
+				reg = <0x47401300 0x100>;
+				reg-names = "phy";
+				status = "disabled";
+				ti,ctrl_mod = <&ctrl_mod>;
+			};
+
+			usb0: usb@47401000 {
+				compatible = "ti,musb-am33xx";
+				ranges;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x47401000 0x200>;
+				reg-names = "control";
+				status = "disabled";
+
+				musb0: usb@47401400 {
+					compatible = "mg,musbmhdrc";
+					reg = <0x47401400 0x400>;
+					reg-names = "mc";
+					interrupts = <18>;
+					interrupt-names = "mc";
+					multipoint = <1>;
+					num-eps = <16>;
+					ram-bits = <12>;
+					port-mode = <3>;
+					power = <250>;
+					phys = <&usb0_phy>;
+				};
+			};
+
+			usb1_phy: phy@47401b00 {
+				compatible = "ti,am335x-usb-phy";
+				reg = <0x47401b00 0x100>;
+				reg-names = "phy";
+				status = "disabled";
+				ti,ctrl_mod = <&ctrl_mod>;
+			};
+
+			usb1: usb@47401800 {
+				compatible = "ti,musb-am33xx";
+				ranges;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x47401800 0x200>;
+				reg-names = "control";
+				status = "disabled";
+
+				musb1: usb@47401c00 {
+					compatible = "mg,musbmhdrc";
+					reg = <0x47401c00 0x400>;
+					reg-names = "mc";
+					interrupts = <19>;
+					interrupt-names = "mc";
+					multipoint = <1>;
+					num-eps = <16>;
+					ram-bits = <12>;
+					port-mode = <3>;
+					power = <250>;
+					phys = <&usb1_phy>;
+				};
+			};
 		};
 
 		epwmss0: epwmss@48300000 {
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 797e3fd..b7257ae 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -83,6 +83,7 @@ config USB_MUSB_AM35X
 
 config USB_MUSB_DSPS
 	tristate "TI DSPS platforms"
+	select USB_MUSB_AM335X_CHILD
 
 config USB_MUSB_BLACKFIN
 	tristate "Blackfin"
@@ -93,6 +94,9 @@ config USB_MUSB_UX500
 
 endchoice
 
+config USB_MUSB_AM335X_CHILD
+	tristate
+
 choice
 	prompt 'MUSB DMA mode'
 	default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 2b82ed7..52f552c 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
 obj-$(CONFIG_USB_MUSB_BLACKFIN)			+= blackfin.o
 obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
 
+
+obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
+
 # the kconfig must guarantee that only one of the
 # possible I/O schemes will be enabled at a time ...
 # PIO only, or DMA (several potential schemes).
diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c
new file mode 100644
index 0000000..41ac5b5
--- /dev/null
+++ b/drivers/usb/musb/musb_am335x.c
@@ -0,0 +1,55 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+static int am335x_child_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	pm_runtime_disable(&pdev->dev);
+	return ret;
+}
+
+static int of_remove_populated_child(struct device *dev, void *d)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	of_device_unregister(pdev);
+	return 0;
+}
+
+static int am335x_child_remove(struct platform_device *pdev)
+{
+	device_for_each_child(&pdev->dev, NULL, of_remove_populated_child);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id am335x_child_of_match[] = {
+	{ .compatible = "ti,am33xx-usb" },
+	{  },
+};
+MODULE_DEVICE_TABLE(of, am335x_child_of_match);
+
+static struct platform_driver am335x_child_driver = {
+	.probe		= am335x_child_probe,
+	.remove         = am335x_child_remove,
+	.driver         = {
+		.name   = "am335x-usb-childs",
+		.of_match_table	= of_match_ptr(am335x_child_of_match),
+	},
+};
+
+module_platform_driver(am335x_child_driver);
+MODULE_DESCRIPTION("AM33xx child devices");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 7f1361c..4ffbaac 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -43,6 +43,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include "musb_core.h"
 
@@ -105,10 +106,7 @@ struct dsps_musb_wrapper {
 	/* bit positions for mode */
 	unsigned	iddig:5;
 	/* miscellaneous stuff */
-	u32		musb_core_offset;
 	u8		poll_seconds;
-	/* number of musb instances */
-	u8		instances;
 };
 
 /**
@@ -116,10 +114,10 @@ struct dsps_musb_wrapper {
  */
 struct dsps_glue {
 	struct device *dev;
-	struct platform_device *musb[2];	/* child musb pdev */
+	struct platform_device *musb;	/* child musb pdev */
 	const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
-	struct timer_list timer[2];	/* otg_workaround timer */
-	unsigned long last_timer[2];    /* last timer data for each instance */
+	struct timer_list timer;	/* otg_workaround timer */
+	unsigned long last_timer;    /* last timer data for each instance */
 };
 
 /**
@@ -168,7 +166,6 @@ static void otg_timer(unsigned long _musb)
 	struct musb *musb = (void *)_musb;
 	void __iomem *mregs = musb->mregs;
 	struct device *dev = musb->controller;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 	const struct dsps_musb_wrapper *wrp = glue->wrp;
 	u8 devctl;
@@ -205,7 +202,7 @@ static void otg_timer(unsigned long _musb)
 	case OTG_STATE_B_IDLE:
 		devctl = dsps_readb(mregs, MUSB_DEVCTL);
 		if (devctl & MUSB_DEVCTL_BDEVICE)
-			mod_timer(&glue->timer[pdev->id],
+			mod_timer(&glue->timer,
 					jiffies + wrp->poll_seconds * HZ);
 		else
 			musb->xceiv->state = OTG_STATE_A_IDLE;
@@ -219,7 +216,6 @@ static void otg_timer(unsigned long _musb)
 static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
 {
 	struct device *dev = musb->controller;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 
 	if (timeout == 0)
@@ -230,23 +226,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
 				musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
 		dev_dbg(musb->controller, "%s active, deleting timer\n",
 				usb_otg_state_string(musb->xceiv->state));
-		del_timer(&glue->timer[pdev->id]);
-		glue->last_timer[pdev->id] = jiffies;
+		del_timer(&glue->timer);
+		glue->last_timer = jiffies;
 		return;
 	}
 
-	if (time_after(glue->last_timer[pdev->id], timeout) &&
-				timer_pending(&glue->timer[pdev->id])) {
+	if (time_after(glue->last_timer, timeout) &&
+				timer_pending(&glue->timer)) {
 		dev_dbg(musb->controller,
 			"Longer idle timer already pending, ignoring...\n");
 		return;
 	}
-	glue->last_timer[pdev->id] = timeout;
+	glue->last_timer = timeout;
 
 	dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
 		usb_otg_state_string(musb->xceiv->state),
 			jiffies_to_msecs(timeout - jiffies));
-	mod_timer(&glue->timer[pdev->id], timeout);
+	mod_timer(&glue->timer, timeout);
 }
 
 static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -254,7 +250,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 	struct musb  *musb = hci;
 	void __iomem *reg_base = musb->ctrl_base;
 	struct device *dev = musb->controller;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 	const struct dsps_musb_wrapper *wrp = glue->wrp;
 	unsigned long flags;
@@ -314,7 +309,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 			 */
 			musb->int_usb &= ~MUSB_INTR_VBUSERROR;
 			musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
-			mod_timer(&glue->timer[pdev->id],
+			mod_timer(&glue->timer,
 					jiffies + wrp->poll_seconds * HZ);
 			WARNING("VBUS error workaround (delay coming)\n");
 		} else if (drvvbus) {
@@ -322,7 +317,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 			MUSB_HST_MODE(musb);
 			musb->xceiv->otg->default_a = 1;
 			musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
-			del_timer(&glue->timer[pdev->id]);
+			del_timer(&glue->timer);
 		} else {
 			musb->is_active = 0;
 			MUSB_DEV_MODE(musb);
@@ -344,8 +339,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 
 	/* Poll for ID change */
 	if (musb->xceiv->state == OTG_STATE_B_IDLE)
-		mod_timer(&glue->timer[pdev->id],
-			 jiffies + wrp->poll_seconds * HZ);
+		mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
 out:
 	spin_unlock_irqrestore(&musb->lock, flags);
 
@@ -355,31 +349,34 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 static int dsps_musb_init(struct musb *musb)
 {
 	struct device *dev = musb->controller;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+	struct platform_device *parent = to_platform_device(dev->parent);
 	const struct dsps_musb_wrapper *wrp = glue->wrp;
-	void __iomem *reg_base = musb->ctrl_base;
+	void __iomem *reg_base;
+	struct resource *r;
 	u32 rev, val;
-	int status;
 
-	/* mentor core register starts at offset of 0x400 from musb base */
-	musb->mregs += wrp->musb_core_offset;
+	r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control");
+	if (!r)
+		return -EINVAL;
+
+	reg_base = devm_ioremap_resource(dev, r);
+	if (!musb->ctrl_base)
+		return -EINVAL;
+	musb->ctrl_base = reg_base;
 
 	/* NOP driver needs change if supporting dual instance */
-	musb->xceiv = devm_usb_get_phy_by_phandle(glue->dev, "phys", 0);
-	if (IS_ERR_OR_NULL(musb->xceiv))
-		return -EPROBE_DEFER;
+	musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
+	if (IS_ERR(musb->xceiv))
+		return PTR_ERR(musb->xceiv);
 
 	/* Returns zero if e.g. not clocked */
 	rev = dsps_readl(reg_base, wrp->revision);
-	if (!rev) {
-		status = -ENODEV;
-		goto err0;
-	}
+	if (!rev)
+		return -ENODEV;
 
 	usb_phy_init(musb->xceiv);
-
-	setup_timer(&glue->timer[pdev->id], otg_timer, (unsigned long) musb);
+	setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
 
 	/* Reset the musb */
 	dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
@@ -392,17 +389,14 @@ static int dsps_musb_init(struct musb *musb)
 	dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
 
 	return 0;
-err0:
-	return status;
 }
 
 static int dsps_musb_exit(struct musb *musb)
 {
 	struct device *dev = musb->controller;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 
-	del_timer_sync(&glue->timer[pdev->id]);
+	del_timer_sync(&glue->timer);
 
 	usb_phy_shutdown(musb->xceiv);
 	return 0;
@@ -420,106 +414,98 @@ static struct musb_platform_ops dsps_ops = {
 
 static u64 musb_dmamask = DMA_BIT_MASK(32);
 
-static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
+static int get_int_prop(struct device_node *dn, const char *s)
 {
-	struct device *dev = glue->dev;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct musb_hdrc_platform_data  *pdata = dev->platform_data;
-	struct device_node *np = pdev->dev.of_node;
-	struct musb_hdrc_config	*config;
-	struct platform_device	*musb;
-	struct resource *res;
+	int ret;
+	u32 val;
+
+	ret = of_property_read_u32(dn, s, &val);
+	if (ret)
+		return 0;
+	return val;
+}
+
+static int dsps_create_musb_pdev(struct dsps_glue *glue,
+		struct platform_device *parent)
+{
+	struct musb_hdrc_platform_data pdata;
 	struct resource	resources[2];
-	char res_name[11];
+	struct device *dev = &parent->dev;
+	struct musb_hdrc_config	*config;
+	struct platform_device *musb;
+	struct device_node *dn = parent->dev.of_node;
+	struct device_node *child_node;
 	int ret;
 
-	/* first resource is for usbss, so start index from 1 */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
-	if (!res) {
-		dev_err(dev, "failed to get memory for instance %d\n", id);
-		ret = -ENODEV;
-		goto err0;
+	child_node = of_get_child_by_name(dn, "usb");
+	if (!child_node)
+		return -EINVAL;
+
+	memset(resources, 0, sizeof(resources));
+	ret = of_address_to_resource(child_node, 0, &resources[0]);
+	if (ret) {
+		dev_err(dev, "failed to get memory.\n");
+		return ret;
 	}
-	res->parent = NULL;
-	resources[0] = *res;
-
-	/* first resource is for usbss, so start index from 1 */
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1);
-	if (!res) {
-		dev_err(dev, "failed to get irq for instance %d\n", id);
-		ret = -ENODEV;
-		goto err0;
+
+	ret = of_irq_to_resource(child_node, 0, &resources[1]);
+	if (ret == 0) {
+		dev_err(dev, "failed to get irq.\n");
+		ret = -EINVAL;
+		return ret;
 	}
-	res->parent = NULL;
-	resources[1] = *res;
-	resources[1].name = "mc";
 
 	/* allocate the child platform device */
 	musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
 	if (!musb) {
 		dev_err(dev, "failed to allocate musb device\n");
-		ret = -ENOMEM;
-		goto err0;
+		return -ENOMEM;
 	}
 
 	musb->dev.parent		= dev;
 	musb->dev.dma_mask		= &musb_dmamask;
 	musb->dev.coherent_dma_mask	= musb_dmamask;
+	musb->dev.of_node		= of_node_get(child_node);
 
-	glue->musb[id]			= musb;
+	glue->musb = musb;
 
-	ret = platform_device_add_resources(musb, resources, 2);
+	ret = platform_device_add_resources(musb, resources,
+			ARRAY_SIZE(resources));
 	if (ret) {
 		dev_err(dev, "failed to add resources\n");
-		goto err2;
+		goto err;
 	}
 
-	if (np) {
-		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-		if (!pdata) {
-			dev_err(&pdev->dev,
-				"failed to allocate musb platform data\n");
-			ret = -ENOMEM;
-			goto err2;
-		}
-
-		config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
-		if (!config) {
-			dev_err(&pdev->dev,
-				"failed to allocate musb hdrc config\n");
-			ret = -ENOMEM;
-			goto err2;
-		}
-
-		of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
-		of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
-		snprintf(res_name, sizeof(res_name), "port%d-mode", id);
-		of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
-		of_property_read_u32(np, "power", (u32 *)&pdata->power);
-		config->multipoint = of_property_read_bool(np, "multipoint");
-
-		pdata->config		= config;
+	config = devm_kzalloc(&parent->dev, sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(dev, "failed to allocate musb hdrc config\n");
+		ret = -ENOMEM;
+		goto err;
 	}
+	pdata.config = config;
+	pdata.platform_ops = &dsps_ops;
 
-	pdata->platform_ops		= &dsps_ops;
+	config->num_eps = get_int_prop(child_node, "num-eps");
+	config->ram_bits = get_int_prop(child_node, "ram-bits");
+	pdata.mode = get_int_prop(child_node, "port-mode");
+	pdata.power = get_int_prop(child_node, "power");
+	config->multipoint = of_property_read_bool(child_node, "multipoint");
 
-	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+	ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
 	if (ret) {
 		dev_err(dev, "failed to add platform_data\n");
-		goto err2;
+		goto err;
 	}
 
 	ret = platform_device_add(musb);
 	if (ret) {
 		dev_err(dev, "failed to register musb device\n");
-		goto err2;
+		goto err;
 	}
-
 	return 0;
 
-err2:
+err:
 	platform_device_put(musb);
-err0:
 	return ret;
 }
 
@@ -528,14 +514,12 @@ static int dsps_probe(struct platform_device *pdev)
 	const struct of_device_id *match;
 	const struct dsps_musb_wrapper *wrp;
 	struct dsps_glue *glue;
-	struct resource *iomem;
-	int ret, i;
+	int ret;
 
 	match = of_match_node(musb_dsps_of_match, pdev->dev.of_node);
 	if (!match) {
 		dev_err(&pdev->dev, "fail to get matching of_match struct\n");
-		ret = -EINVAL;
-		goto err0;
+		return -EINVAL;
 	}
 	wrp = match->data;
 
@@ -543,29 +527,13 @@ static int dsps_probe(struct platform_device *pdev)
 	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
 	if (!glue) {
 		dev_err(&pdev->dev, "unable to allocate glue memory\n");
-		ret = -ENOMEM;
-		goto err0;
-	}
-
-	/* get memory resource */
-	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iomem) {
-		dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
-		ret = -ENODEV;
-		goto err1;
+		return -ENOMEM;
 	}
 
 	glue->dev = &pdev->dev;
+	glue->wrp = wrp;
 
-	glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
-	if (!glue->wrp) {
-		dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
-		ret = -ENOMEM;
-		goto err1;
-	}
 	platform_set_drvdata(pdev, glue);
-
-	/* enable the usbss clocks */
 	pm_runtime_enable(&pdev->dev);
 
 	ret = pm_runtime_get_sync(&pdev->dev);
@@ -574,17 +542,9 @@ static int dsps_probe(struct platform_device *pdev)
 		goto err2;
 	}
 
-	/* create the child platform device for all instances of musb */
-	for (i = 0; i < wrp->instances ; i++) {
-		ret = dsps_create_musb_pdev(glue, i);
-		if (ret != 0) {
-			dev_err(&pdev->dev, "failed to create child pdev\n");
-			/* release resources of previously created instances */
-			for (i--; i >= 0 ; i--)
-				platform_device_unregister(glue->musb[i]);
-			goto err3;
-		}
-	}
+	ret = dsps_create_musb_pdev(glue, pdev);
+	if (ret)
+		goto err3;
 
 	return 0;
 
@@ -592,26 +552,19 @@ static int dsps_probe(struct platform_device *pdev)
 	pm_runtime_put(&pdev->dev);
 err2:
 	pm_runtime_disable(&pdev->dev);
-	kfree(glue->wrp);
-err1:
 	kfree(glue);
-err0:
 	return ret;
 }
+
 static int dsps_remove(struct platform_device *pdev)
 {
 	struct dsps_glue *glue = platform_get_drvdata(pdev);
-	const struct dsps_musb_wrapper *wrp = glue->wrp;
-	int i;
 
-	/* delete the child platform device */
-	for (i = 0; i < wrp->instances ; i++)
-		platform_device_unregister(glue->musb[i]);
+	platform_device_unregister(glue->musb);
 
 	/* disable usbss clocks */
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	kfree(glue->wrp);
 	kfree(glue);
 	return 0;
 }
@@ -641,9 +594,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = {
 	.rxep_shift		= 16,
 	.rxep_mask		= 0xfffe,
 	.rxep_bitmap		= (0xfffe << 16),
-	.musb_core_offset	= 0x400,
 	.poll_seconds		= 2,
-	.instances		= 1,
 };
 
 static const struct of_device_id musb_dsps_of_match[] = {
@@ -667,14 +618,4 @@ MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
 MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
 MODULE_LICENSE("GPL v2");
 
-static int __init dsps_init(void)
-{
-	return platform_driver_register(&dsps_usbss_driver);
-}
-subsys_initcall(dsps_init);
-
-static void __exit dsps_exit(void)
-{
-	platform_driver_unregister(&dsps_usbss_driver);
-}
-module_exit(dsps_exit);
+module_platform_driver(dsps_usbss_driver);
-- 
1.8.3.2


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

* Re: [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-07-30 20:16 ` [PATCH 5/5] usb: musb: dsps: use proper child nodes Sebastian Andrzej Siewior
@ 2013-08-01  5:24   ` George Cherian
  2013-08-01 10:52     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 13+ messages in thread
From: George Cherian @ 2013-08-01  5:24 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-usb, balbi, linux-kernel

On 7/31/2013 1:46 AM, Sebastian Andrzej Siewior wrote:
> This moves the two instances from the big node into two child nodes. The
> glue layer ontop does almost nothing.
> There is one devices containing the control module for USB (2) phy,
> (2) usb and later the dma engine. The usb device is the "glue device"
> which contains the musb device as a child. This is what we do ever since.
> The new file musb_am335x is just here to prob the new bus and populate
> child devices.
> There are a lot of changes to the dsps file as a result of the changes:
> - musb_core_offset
>    This is gone. The device tree provides memory ressources information
>    for the device there is no need to "fix" things
> - instances
>    This is gone as well. If we have two instances then we have have two
>    child enabled nodes in the device tree. For instance the SoC in beagle
>    bone has two USB instances but only one has been wired up so there is
>    no need to load and init the second instance since it won't be used.
> - dsps_glue is now per glue device
>    In the past there was one of this structs but with an array of two and
>    each instance accessed its variable depending on the platform device
>    id.
> - no unneeded copy of structs
>    I do not know why struct dsps_musb_wrapper is copied but it is not
>    necessary. The same goes for musb_hdrc_platform_data which allocated
>    on demand and then again by platform_device_add_data(). One copy is
>    enough.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

<snip >

>   
> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> index 38b446b..0f756ca 100644
> --- a/arch/arm/boot/dts/am33xx.dtsi
> +++ b/arch/arm/boot/dts/am33xx.dtsi
> @@ -26,6 +26,10 @@
>   		serial5 = &uart5;
>   		d_can0 = &dcan0;
>   		d_can1 = &dcan1;
> +		usb0 = &usb0;
> +		usb1 = &usb1;
> +		phy0 = &usb0_phy;
> +		phy1 = &usb1_phy;
>   	};
>   
>   	cpus {
> @@ -333,21 +337,85 @@
>   			status = "disabled";
>   		};
>   
> -		usb@47400000 {
> -			compatible = "ti,musb-am33xx";
> -			reg = <0x47400000 0x1000	/* usbss */
> -			       0x47401000 0x800		/* musb instance 0 */
> -			       0x47401800 0x800>;	/* musb instance 1 */
> -			interrupts = <17		/* usbss */
> -				      18		/* musb instance 0 */
> -				      19>;		/* musb instance 1 */
> -			multipoint = <1>;
> -			num-eps = <16>;
> -			ram-bits = <12>;
> -			port0-mode = <3>;
> -			port1-mode = <3>;
> -			power = <250>;
> +		usb: usb@47400000 {
> +			compatible = "ti,am33xx-usb";
> +			reg = <0x47400000 0x1000>;
> +			ranges;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
>   			ti,hwmods = "usb_otg_hs";
> +			status = "disabled";
> +
> +			ctrl_mod: control@44e10000 {
> +				compatible = "ti,am335x-ctrl-module";
> +				reg = <0x44e10000 0x650>;

Do you really need to map Control Module base to 0x650? If some other driver does this mapping

we will always end returning -EPROBE_DEFER.

How about this
	reg = 	<0x44e10620 0x4> ,
		<0x44e10648 0x1>;
	reg-names = "phycontrol_dev" , "phywkup_dev";

and map for power on/off and phywkup separately in the control driver.

> +				reg-names = "control_dev";
> +				status = "disabled";
> +			};
> +

<snip>

> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> index 797e3fd..b7257ae 100644
> --- a/drivers/usb/musb/Kconfig
> +++ b/drivers/usb/musb/Kconfig
> @@ -83,6 +83,7 @@ config USB_MUSB_AM35X
>   
>   config USB_MUSB_DSPS
>   	tristate "TI DSPS platforms"
> +	select USB_MUSB_AM335X_CHILD

How about adding select AM335X_PHY_USB here?

>   
>   config USB_MUSB_BLACKFIN
>   	tristate "Blackfin"
> @@ -93,6 +94,9 @@ config USB_MUSB_UX500
>   
>   endchoice
>   
> +config USB_MUSB_AM335X_CHILD
> +	tristate
> +
>   choice
>   	prompt 'MUSB DMA mode'
>   	default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM
>

-- 
-George


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

* Re: [PATCH 3/5] usb: phy: Add AM335x PHY driver
  2013-07-30 20:16 ` [PATCH 3/5] usb: phy: Add AM335x PHY driver Sebastian Andrzej Siewior
@ 2013-08-01  5:36   ` George Cherian
  2013-08-01 10:55     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 13+ messages in thread
From: George Cherian @ 2013-08-01  5:36 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-usb, balbi, linux-kernel

On 7/31/2013 1:46 AM, Sebastian Andrzej Siewior wrote:
> This driver is a redo of my earlier attempt. It uses parts of the
> generic PHY driver and uses the new control driver for the register
> the phy needs to power on/off the phy. It also enables easy access for
> the wakeup register which is not yet implemented.
> The difference between the omap attempt is:
> - no static holding variable
> - one global visible function which exports a struct with callbacks to
>    access the "control" registers.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>   

<snip>

> +static const struct of_device_id omap_control_usb_id_table[] = {
> +	{ .compatible = "ti,am335x-ctrl-module", .data = &ctrl_am335x },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
> +
> +static struct platform_driver am335x_control_driver;
> +static int match(struct device *dev, void *data)
> +{
> +	struct device_node *node = (struct device_node *)data;
> +	return dev->of_node == node &&
> +		dev->driver == &am335x_control_driver.driver;
> +}
> +
> +struct phy_control *am335x_get_phy_control(struct device *dev)
> +{
> +	struct device_node *node;
> +	struct am335x_control_usb *ctrl_usb;
> +
> +	node = of_parse_phandle(dev->of_node, "ti,ctrl_mod", 0);
> +	if (!node)
> +		return NULL;
> +
> +	dev = bus_find_device(&platform_bus_type, NULL, node, match);

of_find_device_by_node doesn't work???

> +	ctrl_usb = dev_get_drvdata(dev);
> +	if (!ctrl_usb)
> +		return NULL;
> +	return &ctrl_usb->phy_ctrl;
> +}
> +EXPORT_SYMBOL_GPL(am335x_get_phy_control);
> +
> +static int am335x_control_usb_probe(struct platform_device *pdev)
> +{
> +	struct resource	*res;
> +	struct am335x_control_usb *ctrl_usb;
> +	const struct of_device_id *of_id;
> +	const struct phy_control *phy_ctrl;
> +
> +	of_id = of_match_node(omap_control_usb_id_table, pdev->dev.of_node);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	phy_ctrl = of_id->data;
> +
> +	ctrl_usb = devm_kzalloc(&pdev->dev, sizeof(*ctrl_usb), GFP_KERNEL);
> +	if (!ctrl_usb) {
> +		dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
> +		return -ENOMEM;
> +	}
> +
> +	ctrl_usb->dev = &pdev->dev;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control_dev");
> +	ctrl_usb->reset_reg = devm_ioremap_resource(&pdev->dev, res);

As per current DTSI in patch 5 you are mapping from control module base till 0x650.
Cant it be split to 2 registers one mapping for phy on/off and one for phy wkup?

> +	if (IS_ERR(ctrl_usb->reset_reg))
> +		return PTR_ERR(ctrl_usb->reset_reg);
> +	spin_lock_init(&ctrl_usb->lock);
> +	ctrl_usb->phy_ctrl = *phy_ctrl;
> +
> +	dev_set_drvdata(ctrl_usb->dev, ctrl_usb);
> +	return 0;
> +}
> +
> +static struct platform_driver am335x_control_driver = {
> +	.probe		= am335x_control_usb_probe,
> +	.driver		= {
> +		.name	= "am335x-control-usb",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = of_match_ptr(omap_control_usb_id_table),
> +	},
> +};
> +
> +module_platform_driver(am335x_control_driver);
> +MODULE_LICENSE("GPL v2");
>

-- 
-George


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

* Re: [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-08-01  5:24   ` George Cherian
@ 2013-08-01 10:52     ` Sebastian Andrzej Siewior
  2013-08-01 11:30       ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-08-01 10:52 UTC (permalink / raw)
  To: George Cherian; +Cc: linux-usb, balbi, linux-kernel

On 08/01/2013 07:24 AM, George Cherian wrote:
>> b/arch/arm/boot/dts/am33xx.dtsi
>> index 38b446b..0f756ca 100644
>> --- a/arch/arm/boot/dts/am33xx.dtsi
>> +++ b/arch/arm/boot/dts/am33xx.dtsi
>> @@ -333,21 +337,85 @@
>>               status = "disabled";
>>           };
>>   -        usb@47400000 {
>> -            compatible = "ti,musb-am33xx";
>> -            reg = <0x47400000 0x1000    /* usbss */
>> -                   0x47401000 0x800        /* musb instance 0 */
>> -                   0x47401800 0x800>;    /* musb instance 1 */
>> -            interrupts = <17        /* usbss */
>> -                      18        /* musb instance 0 */
>> -                      19>;        /* musb instance 1 */
>> -            multipoint = <1>;
>> -            num-eps = <16>;
>> -            ram-bits = <12>;
>> -            port0-mode = <3>;
>> -            port1-mode = <3>;
>> -            power = <250>;
>> +        usb: usb@47400000 {
>> +            compatible = "ti,am33xx-usb";
>> +            reg = <0x47400000 0x1000>;
>> +            ranges;
>> +            #address-cells = <1>;
>> +            #size-cells = <1>;
>>               ti,hwmods = "usb_otg_hs";
>> +            status = "disabled";
>> +
>> +            ctrl_mod: control@44e10000 {
>> +                compatible = "ti,am335x-ctrl-module";
>> +                reg = <0x44e10000 0x650>;
> 
> Do you really need to map Control Module base to 0x650? If some other
> driver does this mapping

This is what I cam currently not sure about. Either we minimize the
register window and introduce two (the other wakeup) or we keep using
the same reset driver for other devices.

> we will always end returning -EPROBE_DEFER.
> 
> How about this
>     reg =     <0x44e10620 0x4> ,
this has to be 16 bytes in size

>         <0x44e10648 0x1>;
this has to be 4 bytes in size.

>     reg-names = "phycontrol_dev" , "phywkup_dev";
> 
> and map for power on/off and phywkup separately in the control driver.
> 
>> +                reg-names = "control_dev";
>> +                status = "disabled";
>> +            };
>> +
> 
> <snip>
> 
>> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
>> index 797e3fd..b7257ae 100644
>> --- a/drivers/usb/musb/Kconfig
>> +++ b/drivers/usb/musb/Kconfig
>> @@ -83,6 +83,7 @@ config USB_MUSB_AM35X
>>     config USB_MUSB_DSPS
>>       tristate "TI DSPS platforms"
>> +    select USB_MUSB_AM335X_CHILD
> 
> How about adding select AM335X_PHY_USB here?

For now maybe a good think but if we do multi platform support we
should recommend them instead of forcing users. What you think?

Sebastian

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

* Re: [PATCH 3/5] usb: phy: Add AM335x PHY driver
  2013-08-01  5:36   ` George Cherian
@ 2013-08-01 10:55     ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-08-01 10:55 UTC (permalink / raw)
  To: George Cherian; +Cc: linux-usb, balbi, linux-kernel

On 08/01/2013 07:36 AM, George Cherian wrote:

please keep the file here file snipping

>> +static const struct of_device_id omap_control_usb_id_table[] = {
>> +    { .compatible = "ti,am335x-ctrl-module", .data = &ctrl_am335x },
>> +    {}
>> +};
>> +MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
>> +
>> +static struct platform_driver am335x_control_driver;
>> +static int match(struct device *dev, void *data)
>> +{
>> +    struct device_node *node = (struct device_node *)data;
>> +    return dev->of_node == node &&
>> +        dev->driver == &am335x_control_driver.driver;
>> +}
>> +
>> +struct phy_control *am335x_get_phy_control(struct device *dev)
>> +{
>> +    struct device_node *node;
>> +    struct am335x_control_usb *ctrl_usb;
>> +
>> +    node = of_parse_phandle(dev->of_node, "ti,ctrl_mod", 0);
>> +    if (!node)
>> +        return NULL;
>> +
>> +    dev = bus_find_device(&platform_bus_type, NULL, node, match);
> 
> of_find_device_by_node doesn't work???

It would but I have here a reference to the device.

> 
>> +    ctrl_usb = dev_get_drvdata(dev);
>> +    if (!ctrl_usb)
>> +        return NULL;
>> +    return &ctrl_usb->phy_ctrl;
>> +}
>> +EXPORT_SYMBOL_GPL(am335x_get_phy_control);
>> +
>> +static int am335x_control_usb_probe(struct platform_device *pdev)
>> +{
>> +    struct resource    *res;
>> +    struct am335x_control_usb *ctrl_usb;
>> +    const struct of_device_id *of_id;
>> +    const struct phy_control *phy_ctrl;
>> +
>> +    of_id = of_match_node(omap_control_usb_id_table, pdev->dev.of_node);
>> +    if (!of_id)
>> +        return -EINVAL;
>> +
>> +    phy_ctrl = of_id->data;
>> +
>> +    ctrl_usb = devm_kzalloc(&pdev->dev, sizeof(*ctrl_usb), GFP_KERNEL);
>> +    if (!ctrl_usb) {
>> +        dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
>> +        return -ENOMEM;
>> +    }
>> +
>> +    ctrl_usb->dev = &pdev->dev;
>> +
>> +    res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>> "control_dev");
>> +    ctrl_usb->reset_reg = devm_ioremap_resource(&pdev->dev, res);
> 
> As per current DTSI in patch 5 you are mapping from control module base
> till 0x650.
> Cant it be split to 2 registers one mapping for phy on/off and one for
> phy wkup?

You asked the same question in the other pathch. It could but please
refer to the other patch.

Sebastian

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

* Re: [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-08-01 10:52     ` Sebastian Andrzej Siewior
@ 2013-08-01 11:30       ` Sebastian Andrzej Siewior
  2013-08-02 10:29         ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-08-01 11:30 UTC (permalink / raw)
  To: George Cherian; +Cc: linux-usb, balbi, linux-kernel

On 08/01/2013 12:52 PM, Sebastian Andrzej Siewior wrote:
> On 08/01/2013 07:24 AM, George Cherian wrote:
>>> b/arch/arm/boot/dts/am33xx.dtsi
>>> index 38b446b..0f756ca 100644
>>> --- a/arch/arm/boot/dts/am33xx.dtsi
>>> +++ b/arch/arm/boot/dts/am33xx.dtsi
>>> @@ -333,21 +337,85 @@
>>>               status = "disabled";
>>>           };
>>>   -        usb@47400000 {
>>> -            compatible = "ti,musb-am33xx";
>>> -            reg = <0x47400000 0x1000    /* usbss */
>>> -                   0x47401000 0x800        /* musb instance 0 */
>>> -                   0x47401800 0x800>;    /* musb instance 1 */
>>> -            interrupts = <17        /* usbss */
>>> -                      18        /* musb instance 0 */
>>> -                      19>;        /* musb instance 1 */
>>> -            multipoint = <1>;
>>> -            num-eps = <16>;
>>> -            ram-bits = <12>;
>>> -            port0-mode = <3>;
>>> -            port1-mode = <3>;
>>> -            power = <250>;
>>> +        usb: usb@47400000 {
>>> +            compatible = "ti,am33xx-usb";
>>> +            reg = <0x47400000 0x1000>;
>>> +            ranges;
>>> +            #address-cells = <1>;
>>> +            #size-cells = <1>;
>>>               ti,hwmods = "usb_otg_hs";
>>> +            status = "disabled";
>>> +
>>> +            ctrl_mod: control@44e10000 {
>>> +                compatible = "ti,am335x-ctrl-module";
>>> +                reg = <0x44e10000 0x650>;
>>
>> Do you really need to map Control Module base to 0x650? If some other
>> driver does this mapping
> 
> This is what I cam currently not sure about. Either we minimize the
> register window and introduce two (the other wakeup) or we keep using
> the same reset driver for other devices.

I mean drivers/reset or something like that.



Sebastian

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

* Re: [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-08-01 11:30       ` Sebastian Andrzej Siewior
@ 2013-08-02 10:29         ` Sebastian Andrzej Siewior
  2013-08-02 14:49           ` George Cherian
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-08-02 10:29 UTC (permalink / raw)
  To: George Cherian; +Cc: linux-usb, balbi, linux-omap, linux-kernel

On 08/01/2013 01:30 PM, Sebastian Andrzej Siewior wrote:
> On 08/01/2013 12:52 PM, Sebastian Andrzej Siewior wrote:
>> On 08/01/2013 07:24 AM, George Cherian wrote:
>>>> b/arch/arm/boot/dts/am33xx.dtsi
>>>> index 38b446b..0f756ca 100644
>>>> --- a/arch/arm/boot/dts/am33xx.dtsi
>>>> +++ b/arch/arm/boot/dts/am33xx.dtsi
>>>> @@ -333,21 +337,85 @@
>>>>               status = "disabled";
>>>>           };
>>>>   -        usb@47400000 {
>>>> -            compatible = "ti,musb-am33xx";
>>>> -            reg = <0x47400000 0x1000    /* usbss */
>>>> -                   0x47401000 0x800        /* musb instance 0 */
>>>> -                   0x47401800 0x800>;    /* musb instance 1 */
>>>> -            interrupts = <17        /* usbss */
>>>> -                      18        /* musb instance 0 */
>>>> -                      19>;        /* musb instance 1 */
>>>> -            multipoint = <1>;
>>>> -            num-eps = <16>;
>>>> -            ram-bits = <12>;
>>>> -            port0-mode = <3>;
>>>> -            port1-mode = <3>;
>>>> -            power = <250>;
>>>> +        usb: usb@47400000 {
>>>> +            compatible = "ti,am33xx-usb";
>>>> +            reg = <0x47400000 0x1000>;
>>>> +            ranges;
>>>> +            #address-cells = <1>;
>>>> +            #size-cells = <1>;
>>>>               ti,hwmods = "usb_otg_hs";
>>>> +            status = "disabled";
>>>> +
>>>> +            ctrl_mod: control@44e10000 {
>>>> +                compatible = "ti,am335x-ctrl-module";
>>>> +                reg = <0x44e10000 0x650>;
>>>
>>> Do you really need to map Control Module base to 0x650? If some other
>>> driver does this mapping
>>
>> This is what I cam currently not sure about. Either we minimize the
>> register window and introduce two (the other wakeup) or we keep using
>> the same reset driver for other devices.
> 
> I mean drivers/reset or something like that.

If there are no further comments / preferences on this I'm going to
shrink to registers and make usb only.

> 
Sebastian


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

* Re: [PATCH 5/5] usb: musb: dsps: use proper child nodes
  2013-08-02 10:29         ` Sebastian Andrzej Siewior
@ 2013-08-02 14:49           ` George Cherian
  0 siblings, 0 replies; 13+ messages in thread
From: George Cherian @ 2013-08-02 14:49 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-usb, balbi, linux-omap, linux-kernel

On 8/2/2013 3:59 PM, Sebastian Andrzej Siewior wrote:
> On 08/01/2013 01:30 PM, Sebastian Andrzej Siewior wrote:
>> On 08/01/2013 12:52 PM, Sebastian Andrzej Siewior wrote:
>>> On 08/01/2013 07:24 AM, George Cherian wrote:
>>>>> b/arch/arm/boot/dts/am33xx.dtsi
>>>>> index 38b446b..0f756ca 100644
>>>>> --- a/arch/arm/boot/dts/am33xx.dtsi
>>>>> +++ b/arch/arm/boot/dts/am33xx.dtsi
>>>>> @@ -333,21 +337,85 @@
>>>>>                status = "disabled";
>>>>>            };
>>>>>    -        usb@47400000 {
>>>>> -            compatible = "ti,musb-am33xx";
>>>>> -            reg = <0x47400000 0x1000    /* usbss */
>>>>> -                   0x47401000 0x800        /* musb instance 0 */
>>>>> -                   0x47401800 0x800>;    /* musb instance 1 */
>>>>> -            interrupts = <17        /* usbss */
>>>>> -                      18        /* musb instance 0 */
>>>>> -                      19>;        /* musb instance 1 */
>>>>> -            multipoint = <1>;
>>>>> -            num-eps = <16>;
>>>>> -            ram-bits = <12>;
>>>>> -            port0-mode = <3>;
>>>>> -            port1-mode = <3>;
>>>>> -            power = <250>;
>>>>> +        usb: usb@47400000 {
>>>>> +            compatible = "ti,am33xx-usb";
>>>>> +            reg = <0x47400000 0x1000>;
>>>>> +            ranges;
>>>>> +            #address-cells = <1>;
>>>>> +            #size-cells = <1>;
>>>>>                ti,hwmods = "usb_otg_hs";
>>>>> +            status = "disabled";
>>>>> +
>>>>> +            ctrl_mod: control@44e10000 {
>>>>> +                compatible = "ti,am335x-ctrl-module";
>>>>> +                reg = <0x44e10000 0x650>;
>>>> Do you really need to map Control Module base to 0x650? If some other
>>>> driver does this mapping
>>> This is what I cam currently not sure about. Either we minimize the
>>> register window and introduce two (the other wakeup) or we keep using
>>> the same reset driver for other devices.
>> I mean drivers/reset or something like that.
> If there are no further comments / preferences on this I'm going to
> shrink to registers and make usb only.

Yes, USB only makes sense for now.
>
> Sebastian
>


-- 
-George


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

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

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-30 20:16 am335x, multi instance and phy support, v3 Sebastian Andrzej Siewior
2013-07-30 20:16 ` [PATCH 1/5] usb: phy: rename nop_usb_xceiv => usb_phy_gen_xceiv Sebastian Andrzej Siewior
2013-07-30 20:16 ` [PATCH 2/5] usb: phy: phy-generic: export init functions Sebastian Andrzej Siewior
2013-07-30 20:16 ` [PATCH 3/5] usb: phy: Add AM335x PHY driver Sebastian Andrzej Siewior
2013-08-01  5:36   ` George Cherian
2013-08-01 10:55     ` Sebastian Andrzej Siewior
2013-07-30 20:16 ` [PATCH 4/5] usb: musb: dsps: remove the hardcoded phy pieces Sebastian Andrzej Siewior
2013-07-30 20:16 ` [PATCH 5/5] usb: musb: dsps: use proper child nodes Sebastian Andrzej Siewior
2013-08-01  5:24   ` George Cherian
2013-08-01 10:52     ` Sebastian Andrzej Siewior
2013-08-01 11:30       ` Sebastian Andrzej Siewior
2013-08-02 10:29         ` Sebastian Andrzej Siewior
2013-08-02 14:49           ` George Cherian

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).