Skip to contentSkip to conversation

usb: add CSR SiRFSoC usb controller and phy support

PATCH New Barry Song 5 participants 12 messages Jun 9, 2013 – Jun 14, 2013

Subsystems (3)
lore
Share & tools
lore

Barry Song

author
#0 lore raw

cover usb: add CSR SiRFSoC usb controller and phy support

This patchset adds CSR SiRFSoC usb controller and phy support. For USB controller, CSR licensed chipidea IP core.

Rong Wang (3):
usb: chipidea: add CSR SiRFSoC ci13xxx usb driver
usb: phy: add driver for CSR SiRFSoC internal phy arm/dts: atlas6: fix the stuff of USB controller and phy

 arch/arm/boot/dts/atlas6.dtsi       |   18 ++--
 drivers/usb/Kconfig                 |    1 +
 drivers/usb/chipidea/Kconfig        |   25 ++++
 drivers/usb/chipidea/Makefile       |    5 +-
 drivers/usb/chipidea/ci13xxx_sirf.c |  223 +++++++++++++++++++++++++++++++++++
 drivers/usb/phy/Kconfig             |   10 ++
 drivers/usb/phy/Makefile            |    1 +
 drivers/usb/phy/phy-sirf-usb.c      |  198 +++++++++++++++++++++++++++++++
 8 files changed, 471 insertions(+), 10 deletions(-)
 create mode 100644 drivers/usb/chipidea/ci13xxx_sirf.c
 create mode 100644 drivers/usb/phy/phy-sirf-usb.c
Signature · 1 line
1.7.5.4
author
#1 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

From: Rong Wang <[email protected]>

CSR SiRF SoCs licensed chipidea ci13xxx USB IP, this patch makes the chipidea drivers support CSR SiRF SoCS.

It also changes the Kconfig, only compile MSM and IMX if related drivers are enabled. Otherwise, we always need to enable all clients of chipidea drivers.

---
 drivers/usb/Kconfig                 |    1 +
 drivers/usb/chipidea/Kconfig        |   25 ++++
 drivers/usb/chipidea/Makefile       |    5 +-
 drivers/usb/chipidea/ci13xxx_sirf.c |  223 +++++++++++++++++++++++++++++++++++
 4 files changed, 252 insertions(+), 2 deletions(-)
 create mode 100644 drivers/usb/chipidea/ci13xxx_sirf.c
drivers/usb/Kconfig +1 -0
index 92e1dc9..9cbe1e0 100644
@@ -49,6 +49,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_MMP
 	default y if MACH_LOONGSON1
 	default y if PLAT_ORION
+	default y if ARCH_SIRF
 	default PCI
 
 # some non-PCI HCDs implement xHCI
drivers/usb/chipidea/Kconfig +25 -0
index b2df442..847b9f7 100644
@@ -31,4 +31,29 @@ config USB_CHIPIDEA_DEBUG
 	help
 	  Say Y here to enable debugging output of the ChipIdea driver.
 
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+	depends on ARCH_SIRF
+	bool "SiRF USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+	depends on ARCH_MSM
+	bool "MSM USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+	depends on ARCH_MXC || ARCH_MXS
+	bool "i.MX USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable imx usb ChipIdea driver binding.
+
+endif
+
 endif
drivers/usb/chipidea/Makefile +3 -2
index 4ab83e9..7004fde 100644
@@ -9,7 +9,7 @@ ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
 
 # Glue/Bridge layers go here
 
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_msm.o
+obj-$(CONFIG_USB_CHIPIDEA_MSM)	+= ci13xxx_msm.o
 
 # PCI doesn't provide stubs, need to check
 ifneq ($(CONFIG_PCI),)
@@ -17,5 +17,6 @@ ifneq ($(CONFIG_PCI),)
 endif
 
 ifneq ($(CONFIG_OF_DEVICE),)
-	obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_IMX)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_SIRF)	+= ci13xxx_sirf.o
 endif
drivers/usb/chipidea/ci13xxx_sirf.c new file +223 -0

223 lines not on this page · raw message

Signature · 1 line
1.7.5.4
#2 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

Quoted 8 lines · On Sunday 09 June 2013 11:25:36 Barry Song wrote:

From: Rong Wang <[email protected]>

CSR SiRF SoCs licensed chipidea ci13xxx USB IP, this patch makes the chipidea drivers support CSR SiRF SoCS.

It also changes the Kconfig, only compile MSM and IMX if related drivers are enabled. Otherwise, we always need to enable all clients of chipidea drivers.

Can't you use the same driver as for imx and make it more generic? I don't actually see anything in here that is really specific to SiRF and most of the code is the same as for imx.

If there are bits that are truly SiRF specific, at least that can be a much smaller part I think.

drivers/usb/chipidea/ci13xxx_sirf.c line 30

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+#define RSC_USB_UART_SHARE	0x0
+#define USB1_MODE_SEL		BIT(2)
+#define pdev_to_phy(pdev)	((struct usb_phy *)platform_get_drvdata(pdev))
+
+static int sirfsoc_vbus_gpio;

What do you need static data for? This seems like a bad idea because it makes it impossible to support multiple such devices.

Quoted 26 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +26 -0
+struct ci13xxx_sirf_data {
+	struct platform_device	*ci_pdev;
+	struct clk		*clk;
+};
+
+static inline int ci13xxx_sirf_drive_vbus(int value)
+{
+	return gpio_direction_output(sirfsoc_vbus_gpio, value ? 0 : 1);
+}
+
+static void ci13xxx_sirf_notify_event(struct ci13xxx *ci, unsigned event)
+{
+	switch (event) {
+	case CI13XXX_CONTROLLER_RESET_EVENT:
+		ci13xxx_sirf_drive_vbus(1);
+		break;
+	case CI13XXX_CONTROLLER_STOPPED_EVENT:
+		ci13xxx_sirf_drive_vbus(0);
+		break;
+	default:
+		dev_info(ci->dev, "Unknown Event\n");
+		break;
+	}
+}
+
+static struct ci13xxx_platform_data ci13xxx_sirf_platdata = {

drivers/usb/chipidea/ci13xxx_sirf.c line 67

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+	.name			= "ci13xxx_sirf",
+	.flags			= CI13XXX_DISABLE_STREAMING,
+	.capoffset		= DEF_CAPOFFSET,
+	.notify_event		= ci13xxx_sirf_notify_event,
+};
+
+static struct of_device_id rsc_ids[] = {
+	{ .compatible = "sirf,prima2-rsc", },
+	{ /* sentinel */ }
+};

This is the reset controller, right? You already use the reset API below, why do you need to open-code the gpio

Quoted 39 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +39 -0
+static int ci13xxx_sirf_probe(struct platform_device *pdev)
+{
+	struct platform_device *plat_ci, *phy_pdev;
+	struct device_node *rsc_np, *phy_np;
+	struct ci13xxx_sirf_data *data;
+	struct usb_phy *phy;
+	void __iomem *rsc_vbase;
+	int ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&pdev->dev, "Failed to allocate ci13xxx_sirf_data!\n");
+		return -ENOMEM;
+	}
+
+	/* 1. set usb controller clock */
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		dev_err(&pdev->dev,
+			"Failed to get clock, err=%ld\n", PTR_ERR(data->clk));
+		return PTR_ERR(data->clk);
+	}
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to prepare or enable clock, err=%d\n", ret);
+		return ret;
+	}
+
+	/* 2. software reset */
+	ret = device_reset(&pdev->dev);
+	if (ret)
+		dev_info(&pdev->dev,
+			"Failed to reset device, err=%d\n", ret);
+
+	/* 3. vbus configuration */
+	sirfsoc_vbus_gpio = of_get_named_gpio(pdev->dev.of_node,
+							"vbus-gpios", 0);
+	if (sirfsoc_vbus_gpio < 0) {

drivers/usb/chipidea/ci13xxx_sirf.c line 117

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+		dev_err(&pdev->dev, "Can't get vbus gpio from DT\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	ret = gpio_request(sirfsoc_vbus_gpio, "ci13xxx_sirf");
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get gpio control\n");
+		goto err;
+	}
+

This seems totally generic so far, better put it into a common file.

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+	/* 4. rsc control */
+	rsc_np = of_find_matching_node(NULL, rsc_ids);
+	if (!rsc_np) {
+		dev_err(&pdev->dev, "Failed to get rsc device node\n");
+		ret = -ENODEV;

drivers/usb/chipidea/ci13xxx_sirf.c line 132

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+		goto err;
+	}
+	rsc_vbase = of_iomap(rsc_np, 0);
+	if (!rsc_vbase) {
+		dev_err(&pdev->dev, "Failed to iomap rsc memory\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	writel(readl(rsc_vbase + RSC_USB_UART_SHARE) | USB1_MODE_SEL,
+					rsc_vbase + RSC_USB_UART_SHARE);

And this seems out of place.

drivers/usb/chipidea/ci13xxx_sirf.c line 153

Quoted 7 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +7 -0
+	/* 6. get phy for controller */
+	phy_np = of_parse_phandle(pdev->dev.of_node, "sirf,ci13xxx-usbphy", 0);
+	if (!phy_np) {
+		dev_err(&pdev->dev, "Failed to get phy device node\n");
+		ret = -ENODEV;
+		goto err;
+	}

I think "sirf,ci13xxx-usbphy" is a particularly bad identifier for the phy here. Please have a look at the generic phy binding that is being proposed.

drivers/usb/chipidea/ci13xxx_sirf.c line 207

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+static const struct of_device_id ci13xxx_sirf_dt_ids[] = {
+	{ .compatible = "sirf,ci13xxx-usbcontroller", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ci13xxx_sirf_dt_ids);

Please take the 'xxx' strings out of the 'compatible' string and use the specific device you are doing this for. If there are multiple ones, you can either list all of them or ensure they are all marked as compatible with the original design.

Arnd

author
#3 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

Hi Arnd,

2013/6/9 Arnd Bergmann <[email protected]>:

Quoted 6 lines · On Sunday 09 June 2013 11:25:36 Barry Song wrote:
Quoted 5 lines

From: Rong Wang <[email protected]>

CSR SiRF SoCs licensed chipidea ci13xxx USB IP, this patch makes the chipidea drivers support CSR SiRF SoCS.

Quoted 7 lines
Quoted 3 lines

It also changes the Kconfig, only compile MSM and IMX if related drivers are enabled. Otherwise, we always need to enable all clients of chipidea drivers.

Can't you use the same driver as for imx and make it more generic? I don't actually see anything in here that is really specific to SiRF and most of the code is the same as for imx.

it seems you means a common driver like drivers/mmc/host/sdhci-pltfm.c for mmc host.
it is a good idea.

Quoted 4 lines

If there are bits that are truly SiRF specific, at least that can be a much smaller part I think.

Quoted 8 lines

drivers/usb/chipidea/ci13xxx_sirf.c line 30

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+#define RSC_USB_UART_SHARE   0x0
+#define USB1_MODE_SEL                BIT(2)
+#define pdev_to_phy(pdev)    ((struct usb_phy *)platform_get_drvdata(pdev))
+
+static int sirfsoc_vbus_gpio;

What do you need static data for? This seems like a bad idea because it makes it impossible to support multiple such devices.

this should be attached to the data struct. sorry for my carelessness. rong did a very good job at first glance, then i took easy and missed to read one line by one line before i sent and missed some issues.

Quoted 32 lines
Quoted 32 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +31 -0
+struct ci13xxx_sirf_data {
+     struct platform_device  *ci_pdev;
+     struct clk              *clk;
+};
+
+static inline int ci13xxx_sirf_drive_vbus(int value)
+{
+     return gpio_direction_output(sirfsoc_vbus_gpio, value ? 0 : 1);
+}
+
+static void ci13xxx_sirf_notify_event(struct ci13xxx *ci, unsigned event)
+{
+     switch (event) {
+     case CI13XXX_CONTROLLER_RESET_EVENT:
+             ci13xxx_sirf_drive_vbus(1);
+             break;
+     case CI13XXX_CONTROLLER_STOPPED_EVENT:
+             ci13xxx_sirf_drive_vbus(0);
+             break;
+     default:
+             dev_info(ci->dev, "Unknown Event\n");
+             break;
+     }
+}
+
+static struct ci13xxx_platform_data ci13xxx_sirf_platdata = {
+     .name                   = "ci13xxx_sirf",
+     .flags                  = CI13XXX_DISABLE_STREAMING,
+     .capoffset              = DEF_CAPOFFSET,
+     .notify_event           = ci13xxx_sirf_notify_event,
+};
Quoted 8 lines

drivers/usb/chipidea/ci13xxx_sirf.c line 67

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+
+static struct of_device_id rsc_ids[] = {
+     { .compatible = "sirf,prima2-rsc", },
+     { /* sentinel */ }
+};

This is the reset controller, right? You already use the reset API below, why do you need to open-code the gpio

it's not reset controller. this is a Resource Sharing Control Module involved with pinmux, we have sirf pinctrl driver, so we should move to that.
here the problem is the driver is still hardcoding the pinmux between uart and usb.

Quoted 44 lines
Quoted 44 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +43 -0
+static int ci13xxx_sirf_probe(struct platform_device *pdev)
+{
+     struct platform_device *plat_ci, *phy_pdev;
+     struct device_node *rsc_np, *phy_np;
+     struct ci13xxx_sirf_data *data;
+     struct usb_phy *phy;
+     void __iomem *rsc_vbase;
+     int ret;
+
+     data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+     if (!data) {
+             dev_err(&pdev->dev, "Failed to allocate ci13xxx_sirf_data!\n");
+             return -ENOMEM;
+     }
+
+     /* 1. set usb controller clock */
+     data->clk = devm_clk_get(&pdev->dev, NULL);
+     if (IS_ERR(data->clk)) {
+             dev_err(&pdev->dev,
+                     "Failed to get clock, err=%ld\n", PTR_ERR(data->clk));
+             return PTR_ERR(data->clk);
+     }
+     ret = clk_prepare_enable(data->clk);
+     if (ret) {
+             dev_err(&pdev->dev,
+                     "Failed to prepare or enable clock, err=%d\n", ret);
+             return ret;
+     }
+
+     /* 2. software reset */
+     ret = device_reset(&pdev->dev);
+     if (ret)
+             dev_info(&pdev->dev,
+                     "Failed to reset device, err=%d\n", ret);
+
+     /* 3. vbus configuration */
+     sirfsoc_vbus_gpio = of_get_named_gpio(pdev->dev.of_node,
+                                                     "vbus-gpios", 0);
+     if (sirfsoc_vbus_gpio < 0) {
+             dev_err(&pdev->dev, "Can't get vbus gpio from DT\n");
+             ret = -ENODEV;
+             goto err;
+     }
Quoted 8 lines

drivers/usb/chipidea/ci13xxx_sirf.c line 117

Quoted 6 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +6 -0
+     ret = gpio_request(sirfsoc_vbus_gpio, "ci13xxx_sirf");
+     if (ret) {
+             dev_err(&pdev->dev, "Failed to get gpio control\n");
+             goto err;
+     }
+

This seems totally generic so far, better put it into a common file.

not so generic, it seems. i think we might need some comments here to explain why.

Quoted 17 lines
Quoted 6 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+     /* 4. rsc control */
+     rsc_np = of_find_matching_node(NULL, rsc_ids);
+     if (!rsc_np) {
+             dev_err(&pdev->dev, "Failed to get rsc device node\n");
+             ret = -ENODEV;

drivers/usb/chipidea/ci13xxx_sirf.c line 132

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+             goto err;
+     }
+     rsc_vbase = of_iomap(rsc_np, 0);
+     if (!rsc_vbase) {
+             dev_err(&pdev->dev, "Failed to iomap rsc memory\n");
+             ret = -ENOMEM;
+             goto err;
+     }
+     writel(readl(rsc_vbase + RSC_USB_UART_SHARE) | USB1_MODE_SEL,
+                                     rsc_vbase + RSC_USB_UART_SHARE);
Quoted 1 line

And this seems out of place.

this issue came from the pinmux issue i mentioned.

Quoted 9 lines

drivers/usb/chipidea/ci13xxx_sirf.c line 153

Quoted 8 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +7 -0
+     /* 6. get phy for controller */
+     phy_np = of_parse_phandle(pdev->dev.of_node, "sirf,ci13xxx-usbphy", 0);
+     if (!phy_np) {
+             dev_err(&pdev->dev, "Failed to get phy device node\n");
+             ret = -ENODEV;
+             goto err;
+     }
Quoted 4 lines

I think "sirf,ci13xxx-usbphy" is a particularly bad identifier for the phy here. Please have a look at the generic phy binding that is being proposed.

ok.

Quoted 10 lines

drivers/usb/chipidea/ci13xxx_sirf.c line 207

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +5 -0
+static const struct of_device_id ci13xxx_sirf_dt_ids[] = {
+     { .compatible = "sirf,ci13xxx-usbcontroller", },
+     { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ci13xxx_sirf_dt_ids);

Please take the 'xxx' strings out of the 'compatible' string and use the specific device you are doing this for. If there are multiple ones, you can either list all of them or ensure they are all marked as compatible with the original design.

agree. i would think the old name "chipidea,ci13611a-prima2" in dts should be right.

Quoted 2 lines

Arnd

-barry

#4 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

In reply to Barry Song
Quoted 112 lines · Barry Song

From: Rong Wang <[email protected]>

CSR SiRF SoCs licensed chipidea ci13xxx USB IP, this patch makes the chipidea drivers support CSR SiRF SoCS.

It also changes the Kconfig, only compile MSM and IMX if related drivers are enabled. Otherwise, we always need to enable all clients of chipidea drivers.

---
 drivers/usb/Kconfig                 |    1 +
 drivers/usb/chipidea/Kconfig        |   25 ++++
 drivers/usb/chipidea/Makefile       |    5 +-
 drivers/usb/chipidea/ci13xxx_sirf.c |  223 +++++++++++++++++++++++++++++++++++
 4 files changed, 252 insertions(+), 2 deletions(-)
 create mode 100644 drivers/usb/chipidea/ci13xxx_sirf.c
drivers/usb/Kconfig +1 -0
index 92e1dc9..9cbe1e0 100644
@@ -49,6 +49,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_MMP
 	default y if MACH_LOONGSON1
 	default y if PLAT_ORION
+	default y if ARCH_SIRF
 	default PCI
 
 # some non-PCI HCDs implement xHCI
drivers/usb/chipidea/Kconfig +25 -0
index b2df442..847b9f7 100644
@@ -31,4 +31,29 @@ config USB_CHIPIDEA_DEBUG
 	help
 	  Say Y here to enable debugging output of the ChipIdea driver.
 
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+	depends on ARCH_SIRF
+	bool "SiRF USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+	depends on ARCH_MSM
+	bool "MSM USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+	depends on ARCH_MXC || ARCH_MXS
+	bool "i.MX USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable imx usb ChipIdea driver binding.
+
+endif
+
 endif
drivers/usb/chipidea/Makefile +3 -2
index 4ab83e9..7004fde 100644
@@ -9,7 +9,7 @@ ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
 
 # Glue/Bridge layers go here
 
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_msm.o
+obj-$(CONFIG_USB_CHIPIDEA_MSM)	+= ci13xxx_msm.o
 
 # PCI doesn't provide stubs, need to check
 ifneq ($(CONFIG_PCI),)
@@ -17,5 +17,6 @@ ifneq ($(CONFIG_PCI),)
 endif
 
 ifneq ($(CONFIG_OF_DEVICE),)
-	obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_IMX)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_SIRF)	+= ci13xxx_sirf.o
 endif
drivers/usb/chipidea/ci13xxx_sirf.c new file +18 -0
new file mode 100644
index 0000000..1d84a2f
@@ -0,0 +1,223 @@
+/*
+ * USB Controller Driver for CSR SiRF SoC
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ * Rong Wang<[email protected]>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>

drivers/usb/chipidea/ci13xxx_sirf.c line 28

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/reset.h>
+
+#include <linux/usb/chipidea.h>
+#include "ci.h"
+
+#define RSC_USB_UART_SHARE	0x0
+#define USB1_MODE_SEL		BIT(2)
+#define pdev_to_phy(pdev)	((struct usb_phy *)platform_get_drvdata(pdev))

sorry, no go. This is not the right way to handle USB PHYs.

drivers/usb/chipidea/ci13xxx_sirf.c line 30

Quoted 1 line
drivers/usb/chipidea/ci13xxx_sirf.c new file +1 -0
+static int sirfsoc_vbus_gpio;

this should be removed too, add it as a member of ci13xx_sirf_data.

drivers/usb/chipidea/ci13xxx_sirf.c line 33

Quoted 2 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +2 -0
+struct ci13xxx_sirf_data {
+	struct platform_device	*ci_pdev;

most likely you don't need the platform_device, you need the struct device only.

drivers/usb/chipidea/ci13xxx_sirf.c line 37

Quoted 4 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +4 -0
+	struct clk		*clk;
+};
+
+static inline int ci13xxx_sirf_drive_vbus(int value)

NACK, you should pass your ci13xx_sirf_data as argument here.

Quoted 136 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +136 -0
+{
+	return gpio_direction_output(sirfsoc_vbus_gpio, value ? 0 : 1);
+}
+
+static void ci13xxx_sirf_notify_event(struct ci13xxx *ci, unsigned event)
+{
+	switch (event) {
+	case CI13XXX_CONTROLLER_RESET_EVENT:
+		ci13xxx_sirf_drive_vbus(1);
+		break;
+	case CI13XXX_CONTROLLER_STOPPED_EVENT:
+		ci13xxx_sirf_drive_vbus(0);
+		break;
+	default:
+		dev_info(ci->dev, "Unknown Event\n");
+		break;
+	}
+}
+
+static struct ci13xxx_platform_data ci13xxx_sirf_platdata = {
+	.name			= "ci13xxx_sirf",
+	.flags			= CI13XXX_DISABLE_STREAMING,
+	.capoffset		= DEF_CAPOFFSET,
+	.notify_event		= ci13xxx_sirf_notify_event,
+};
+
+static struct of_device_id rsc_ids[] = {
+	{ .compatible = "sirf,prima2-rsc", },
+	{ /* sentinel */ }
+};
+
+static int ci13xxx_sirf_probe(struct platform_device *pdev)
+{
+	struct platform_device *plat_ci, *phy_pdev;
+	struct device_node *rsc_np, *phy_np;
+	struct ci13xxx_sirf_data *data;
+	struct usb_phy *phy;
+	void __iomem *rsc_vbase;
+	int ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&pdev->dev, "Failed to allocate ci13xxx_sirf_data!\n");
+		return -ENOMEM;
+	}
+
+	/* 1. set usb controller clock */
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		dev_err(&pdev->dev,
+			"Failed to get clock, err=%ld\n", PTR_ERR(data->clk));
+		return PTR_ERR(data->clk);
+	}
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to prepare or enable clock, err=%d\n", ret);
+		return ret;
+	}
+
+	/* 2. software reset */
+	ret = device_reset(&pdev->dev);
+	if (ret)
+		dev_info(&pdev->dev,
+			"Failed to reset device, err=%d\n", ret);
+
+	/* 3. vbus configuration */
+	sirfsoc_vbus_gpio = of_get_named_gpio(pdev->dev.of_node,
+							"vbus-gpios", 0);
+	if (sirfsoc_vbus_gpio < 0) {
+		dev_err(&pdev->dev, "Can't get vbus gpio from DT\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	ret = gpio_request(sirfsoc_vbus_gpio, "ci13xxx_sirf");
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get gpio control\n");
+		goto err;
+	}
+
+	/* 4. rsc control */
+	rsc_np = of_find_matching_node(NULL, rsc_ids);
+	if (!rsc_np) {
+		dev_err(&pdev->dev, "Failed to get rsc device node\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	rsc_vbase = of_iomap(rsc_np, 0);
+	if (!rsc_vbase) {
+		dev_err(&pdev->dev, "Failed to iomap rsc memory\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	writel(readl(rsc_vbase + RSC_USB_UART_SHARE) | USB1_MODE_SEL,
+					rsc_vbase + RSC_USB_UART_SHARE);
+
+	/* 5. set device dma mask */
+	if (!pdev->dev.dma_mask) {
+		pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
+				      sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+		if (!pdev->dev.dma_mask) {
+			dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
+			ret = -ENOMEM;
+			goto err;
+		}
+		*pdev->dev.dma_mask = DMA_BIT_MASK(32);
+		dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);
+	}
+
+	/* 6. get phy for controller */
+	phy_np = of_parse_phandle(pdev->dev.of_node, "sirf,ci13xxx-usbphy", 0);
+	if (!phy_np) {
+		dev_err(&pdev->dev, "Failed to get phy device node\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	phy_pdev = of_find_device_by_node(phy_np);
+	if (!phy_pdev) {
+		dev_err(&pdev->dev, "Failed to get phy platform device\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	phy = pdev_to_phy(phy_pdev);
+	if (!phy || !try_module_get(phy_pdev->dev.driver->owner)) {
+		dev_err(&pdev->dev, "Failed to get phy control\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	usb_phy_init(phy);
+	ci13xxx_sirf_platdata.phy = phy;
+
+	/* 7. register to ci13xxx core */
+	plat_ci = ci13xxx_add_device(&pdev->dev,
+				pdev->resource, pdev->num_resources,
+				&ci13xxx_sirf_platdata);
+	if (IS_ERR(plat_ci)) {

drivers/usb/chipidea/ci13xxx_sirf.c line 183

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+		dev_err(&pdev->dev, "ci13xxx_add_device failed!\n");
+		return PTR_ERR(plat_ci);
+	}
+
+	platform_set_drvdata(pdev, plat_ci);
+
+	pm_runtime_no_callbacks(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	dev_info(&pdev->dev, "Ready\n");

remove this dev_info()

Signature · 8 lines
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130612/0fae6d4c/attachment.sig>
#5 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

In reply to Barry Song
Quoted 8 lines · Barry Song

CSR SiRF SoCs licensed chipidea ci13xxx USB IP, this patch makes the chipidea drivers support CSR SiRF SoCS.

It also changes the Kconfig, only compile MSM and IMX if related drivers are enabled. Otherwise, we always need to enable all clients of chipidea drivers.

drivers/usb/chipidea/ci13xxx_sirf.c new file +1 -0
+       /* 5. set device dma mask */

drivers/usb/chipidea/ci13xxx_sirf.c line 144

Quoted 10 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +10 -0
+       if (!pdev->dev.dma_mask) {
+               pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
+                                     sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+               if (!pdev->dev.dma_mask) {
+                       dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
+                       ret = -ENOMEM;
+                       goto err;
+               }
+               *pdev->dev.dma_mask = DMA_BIT_MASK(32);
+               dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);

Perhaps you could avoid this allocation if you apply coherent mask first and its address will be used as dma_mask value.

drivers/usb/chipidea/ci13xxx_sirf.c line 188

Quoted 5 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +4 -0
+       }
 
+err:
+       clk_disable_unprepare(data->clk);
+       return ret;

Please, check, but if I remember correctly devm_clk* is doing this for you on release stage.

drivers/usb/chipidea/ci13xxx_sirf.c line 198

Quoted 8 lines
drivers/usb/chipidea/ci13xxx_sirf.c new file +8 -0
+static int ci13xxx_sirf_remove(struct platform_device *pdev)
+{
+       struct ci13xxx_sirf_data *data = platform_get_drvdata(pdev);
+
+       pm_runtime_disable(&pdev->dev);
+       ci13xxx_remove_device(data->ci_pdev);
+
+       clk_disable_unprepare(data->clk);

Ditto.

--
With Best Regards,
Andy Shevchenko

#6 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

In reply to Barry Song
Quoted 14 lines · Barry Song
drivers/usb/chipidea/Kconfig +14 -0
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+	depends on ARCH_SIRF
+	bool "SiRF USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+	depends on ARCH_MSM
+	bool "MSM USB controller ChipIdea driver binding"
+	default y
+	help

drivers/usb/chipidea/Kconfig config USB_CHIPIDEA_DEBUG · line 57

Quoted 10 lines
drivers/usb/chipidea/Kconfig +10 -0
+	  Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+	depends on ARCH_MXC || ARCH_MXS
+	bool "i.MX USB controller ChipIdea driver binding"
+	default y
+	help
+	  Say Y here to enable imx usb ChipIdea driver binding.
+
+endif

No. This is wrong on at least 3 different levels.

drivers/usb/chipidea/Makefile ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o · line 12

Quoted 12 lines
(quoted diff) +1 -0
+
 endif
drivers/usb/chipidea/Makefile +1 -1
index 4ab83e9..7004fde 100644
@@ -9,7 +9,7 @@ ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
 
 # Glue/Bridge layers go here
 
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_msm.o
+obj-$(CONFIG_USB_CHIPIDEA_MSM)	+= ci13xxx_msm.o

No.

drivers/usb/chipidea/Makefile ifneq ($(CONFIG_PCI),) · line 22

Quoted 10 lines
drivers/usb/chipidea/Makefile +2 -1
 # PCI doesn't provide stubs, need to check
 ifneq ($(CONFIG_PCI),)
@@ -17,5 +17,6 @@ ifneq ($(CONFIG_PCI),)
 endif
 
 ifneq ($(CONFIG_OF_DEVICE),)
-	obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_IMX)	+= ci13xxx_imx.o usbmisc_imx.o
+	obj-$(CONFIG_USB_CHIPIDEA_SIRF)	+= ci13xxx_sirf.o
 endif

No.

Regards,
--
Alex

author
#7 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

2013/6/14 Alexander Shishkin <[email protected]>:

Quoted 20 lines
Quoted 18 lines · Barry Song
drivers/usb/chipidea/Kconfig +18 -0
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+     depends on ARCH_SIRF
+     bool "SiRF USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+     depends on ARCH_MSM
+     bool "MSM USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+     depends on ARCH_MXC || ARCH_MXS
Quoted 8 lines

drivers/usb/chipidea/Kconfig config USB_CHIPIDEA_DEBUG · line 57

Quoted 6 lines
drivers/usb/chipidea/Kconfig +6 -0
+     bool "i.MX USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable imx usb ChipIdea driver binding.
+
+endif

No. This is wrong on at least 3 different levels.

the point is we don't directly include MSM, IMX, SiRF and all other drivers once we enable chipidea. that makes these drivers optional, not always be built-in.

-barry

#8 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

Quoted 30 lines · Barry Song

2013/6/14 Alexander Shishkin <[email protected]>:

Quoted 20 lines
Quoted 18 lines · Barry Song
drivers/usb/chipidea/Kconfig +18 -0
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+     depends on ARCH_SIRF
+     bool "SiRF USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+     depends on ARCH_MSM
+     bool "MSM USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+     depends on ARCH_MXC || ARCH_MXS
Quoted 8 lines

drivers/usb/chipidea/Kconfig config USB_CHIPIDEA_DEBUG · line 57

Quoted 6 lines
drivers/usb/chipidea/Kconfig +6 -0
+     bool "i.MX USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable imx usb ChipIdea driver binding.
+
+endif

No. This is wrong on at least 3 different levels.

Quoted 3 lines

the point is we don't directly include MSM, IMX, SiRF and all other drivers once we enable chipidea. that makes these drivers optional, not always be built-in.

This has been discussed several times already. Just set the USB_CHIPIDEA=m and then everything will be built as modules and nothing will be built in. What exactly is the problem you're trying to solve with this?

The only way something like this will go in is with Jiri's COMPILE_TEST patchset. This snippet above is just buggy.

Regards,
--
Alex

author
#9 lore raw

PATCH 1/3 usb: chipidea: add CSR SiRFSoC ci13xxx usb driver

2013/6/14 Alexander Shishkin <[email protected]>:

Quoted 32 lines
Quoted 30 lines · Barry Song

2013/6/14 Alexander Shishkin <[email protected]>:

Quoted 28 lines
Quoted 14 lines · Barry Song
drivers/usb/chipidea/Kconfig +14 -0
+if USB_CHIPIDEA_UDC && USB_CHIPIDEA_HOST
+
+config USB_CHIPIDEA_SIRF
+     depends on ARCH_SIRF
+     bool "SiRF USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable sirf usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_MSM
+     depends on ARCH_MSM
+     bool "MSM USB controller ChipIdea driver binding"
+     default y
+     help

drivers/usb/chipidea/Kconfig config USB_CHIPIDEA_DEBUG · line 57

Quoted 10 lines
drivers/usb/chipidea/Kconfig +10 -0
+       Say Y here to enable msm usb ChipIdea driver binding.
+
+config USB_CHIPIDEA_IMX
+     depends on ARCH_MXC || ARCH_MXS
+     bool "i.MX USB controller ChipIdea driver binding"
+     default y
+     help
+       Say Y here to enable imx usb ChipIdea driver binding.
+
+endif

No. This is wrong on at least 3 different levels.

Quoted 9 lines
Quoted 3 lines

the point is we don't directly include MSM, IMX, SiRF and all other drivers once we enable chipidea. that makes these drivers optional, not always be built-in.

This has been discussed several times already. Just set the USB_CHIPIDEA=m and then everything will be built as modules and nothing will be built in. What exactly is the problem you're trying to solve with this?

Alex, it seems it is not much a generic way to use building-module to avoid all involved components built-in.
but since you have discussed several times and got agreement, i'll follow it and don't re-open it.

Quoted 6 lines

The only way something like this will go in is with Jiri's COMPILE_TEST patchset. This snippet above is just buggy.

Regards,
--
Alex

-barry

author
#10 lore raw

PATCH 2/3 usb: phy: add driver for CSR SiRFSoC internal phy

In reply to Barry Song

From: Rong Wang <[email protected]>

This patch adds a driver for CSR SiRFSoC internal phy support for USB Controller 1.

---
 drivers/usb/phy/Kconfig        |   10 ++
 drivers/usb/phy/Makefile       |    1 +
 drivers/usb/phy/phy-sirf-usb.c |  198 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/phy/phy-sirf-usb.c
drivers/usb/phy/Kconfig +10 -0
index 7ef3eb8..ea30195 100644
@@ -179,6 +179,16 @@ config USB_MXS_PHY
 
 	  MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x.
 
+config USB_SIRF_PHY
+	tristate "SiRF USB PHY support"
+	depends on ARCH_SIRF
+	help
+	  Say Y here if you want to build SiRF USB OTG transciever
+	  driver in kernel (including Prima and Atlas series). This driver
+	  implements role switch between EHCI host driver and gadget driver.
+
+	  To compile this driver as a module, choose M here.
+
 config USB_RCAR_PHY
 	tristate "Renesas R-Car USB phy support"
 	depends on USB || USB_GADGET
drivers/usb/phy/Makefile +1 -0
index a9169cb..6caa29c 100644
@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_ISP1301)		+= phy-isp1301.o
 obj-$(CONFIG_USB_MSM_OTG)		+= phy-msm-usb.o
 obj-$(CONFIG_USB_MV_OTG)		+= phy-mv-usb.o
 obj-$(CONFIG_USB_MXS_PHY)		+= phy-mxs-usb.o
+obj-$(CONFIG_USB_SIRF_PHY)		+= phy-sirf-usb.o
 obj-$(CONFIG_USB_RCAR_PHY)		+= phy-rcar-usb.o
 obj-$(CONFIG_USB_ULPI)			+= phy-ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)		+= phy-ulpi-viewport.o
drivers/usb/phy/phy-sirf-usb.c new file +198 -0

198 lines not on this page · raw message

Signature · 1 line
1.7.5.4
author
#11 lore raw

PATCH 3/3 arm/dts: atlas6: fix the stuff of USB controller and phy

In reply to Barry Song

From: Rong Wang <[email protected]>

this patch fixes the USB stuff in atlas6.dtsi, and matches with sirfsoc usb controller and phy drivers to work.

---
 arch/arm/boot/dts/atlas6.dtsi |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)
arch/arm/boot/dts/atlas6.dtsi +10 -8
index 7d1a279..a84b760 100644
@@ -643,18 +643,20 @@
 			#size-cells = <1>;
 			ranges = <0xb8000000 0xb8000000 0x40000>;
 
-			usb0: usb at b00e0000 {
-				compatible = "chipidea,ci13611a-prima2";
-				reg = <0xb8000000 0x10000>;
-				interrupts = <10>;
-				clocks = <&clks 40>;
+			usbphy: usbphy at b8010200 {
+				compatible = "sirf,ci13xxx-usbphy";
+				reg = <0xb8010200 0x100>;
+				clocks = <&clks 39>;
 			};
 
-			usb1: usb at b00f0000 {
-				compatible = "chipidea,ci13611a-prima2";
-				reg = <0xb8010000 0x10000>;
+			usbcontroller: usbcontroller at b8010000 {
+				compatible = "sirf,ci13xxx-usbcontroller";
+				reg = <0xb8010000 0x200>;
 				interrupts = <11>;
 				clocks = <&clks 41>;
+				resets = <&rstc 9>;
+				vbus-gpios = <&gpio 0 14>;
+				sirf,ci13xxx-usbphy = <&usbphy>;
 			};
 
 			security at b00f0000 {
Signature · 1 line
1.7.5.4