linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] usb: gadget: s3c2410: add device tree support
@ 2016-12-09 19:06 Sergio Prado
  2016-12-09 19:06 ` [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller Sergio Prado
  2016-12-09 19:06 ` [PATCH 2/2] usb: gadget: s3c2410: allow probing from device tree Sergio Prado
  0 siblings, 2 replies; 5+ messages in thread
From: Sergio Prado @ 2016-12-09 19:06 UTC (permalink / raw)
  To: gregkh, robh+dt, mark.rutland, balbi, linux-usb, devicetree,
	linux-kernel
  Cc: Sergio Prado

This series adds support for configuring Samsung's s3c2410 and
compatible USB device controller via devicetree.

Tested on FriendlyARM mini2440, based on s3c2440 SoC.

Sergio Prado (2):
  dt-bindings: usb: add DT binding for s3c2410 USB device controller
  usb: gadget: s3c2410: allow probing from device tree

 .../devicetree/bindings/usb/s3c2410-usb.txt        |  28 ++++
 drivers/usb/gadget/udc/s3c2410_udc.c               | 142 +++++++++++++++++----
 drivers/usb/gadget/udc/s3c2410_udc.h               |   4 +
 3 files changed, 151 insertions(+), 23 deletions(-)

-- 
1.9.1

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

* [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller
  2016-12-09 19:06 [PATCH 0/2] usb: gadget: s3c2410: add device tree support Sergio Prado
@ 2016-12-09 19:06 ` Sergio Prado
  2016-12-13 18:59   ` Rob Herring
  2016-12-09 19:06 ` [PATCH 2/2] usb: gadget: s3c2410: allow probing from device tree Sergio Prado
  1 sibling, 1 reply; 5+ messages in thread
From: Sergio Prado @ 2016-12-09 19:06 UTC (permalink / raw)
  To: gregkh, robh+dt, mark.rutland, balbi, linux-usb, devicetree,
	linux-kernel
  Cc: Sergio Prado

Adds the device tree bindings description for Samsung S3C2410 and
compatible USB device controller.

Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
 .../devicetree/bindings/usb/s3c2410-usb.txt        | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/s3c2410-usb.txt b/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
index e45b38ce2986..4d3f9894c2d4 100644
--- a/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
+++ b/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
@@ -20,3 +20,31 @@ usb0: ohci@49000000 {
 	clocks = <&clocks UCLK>, <&clocks HCLK_USBH>;
 	clock-names = "usb-bus-host", "usb-host";
 };
+
+Samsung S3C2410 and compatible USB device controller
+
+Required properties:
+ - compatible: Should be one of the following
+	       "samsung,s3c2410-udc"
+	       "samsung,s3c2440-udc"
+ - reg: address and length of the controller memory mapped region
+ - interrupts: interrupt number for the USB device controller
+ - clocks: Should reference the bus and host clocks
+ - clock-names: Should contain two strings
+		"usb-bus-gadget" for the USB bus clock
+		"usb-device" for the USB device clock
+
+Optional properties:
+ - samsung,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+ - samsung,pullup-gpio: If present, specifies a gpio to control the
+   USB D+ pullup.
+
+usb1: udc@52000000 {
+	compatible = "samsung,s3c2440-udc";
+	reg = <0x52000000 0x100000>;
+	interrupts = <0 0 25 3>;
+	clocks = <&clocks UCLK>, <&clocks HCLK_USBD>;
+	clock-names = "usb-bus-gadget", "usb-device";
+	samsung,pullup-gpio = <&gpc 5 GPIO_ACTIVE_HIGH>;
+};
-- 
1.9.1

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

* [PATCH 2/2] usb: gadget: s3c2410: allow probing from device tree
  2016-12-09 19:06 [PATCH 0/2] usb: gadget: s3c2410: add device tree support Sergio Prado
  2016-12-09 19:06 ` [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller Sergio Prado
@ 2016-12-09 19:06 ` Sergio Prado
  1 sibling, 0 replies; 5+ messages in thread
From: Sergio Prado @ 2016-12-09 19:06 UTC (permalink / raw)
  To: gregkh, robh+dt, mark.rutland, balbi, linux-usb, devicetree,
	linux-kernel
  Cc: Sergio Prado

Allows configuring Samsung's s3c2410 and compatible USB device
controller using a devicetree.

Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
 drivers/usb/gadget/udc/s3c2410_udc.c | 142 +++++++++++++++++++++++++++++------
 drivers/usb/gadget/udc/s3c2410_udc.h |   4 +
 2 files changed, 123 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c
index 4643a01262b4..e3b5a0e6646e 100644
--- a/drivers/usb/gadget/udc/s3c2410_udc.c
+++ b/drivers/usb/gadget/udc/s3c2410_udc.c
@@ -30,6 +30,9 @@
 #include <linux/gpio.h>
 #include <linux/prefetch.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -55,6 +58,18 @@
 #define DRIVER_AUTHOR	"Herbert Pötzl <herbert@13thfloor.at>, " \
 			"Arnaud Patard <arnaud.patard@rtp-net.org>"
 
+struct s3c2410_udc_drv_data {
+	int ep_fifo_size;
+};
+
+static const struct s3c2410_udc_drv_data s3c2410_udc_2410_drv_data = {
+	.ep_fifo_size = EP_FIFO_SIZE,
+};
+
+static const struct s3c2410_udc_drv_data s3c2410_udc_2440_drv_data = {
+	.ep_fifo_size = S3C2440_EP_FIFO_SIZE,
+};
+
 static const char		gadget_name[] = "s3c2410_udc";
 static const char		driver_desc[] = DRIVER_DESC;
 
@@ -62,8 +77,6 @@
 static struct clk		*udc_clock;
 static struct clk		*usb_bus_clock;
 static void __iomem		*base_addr;
-static u64			rsrc_start;
-static u64			rsrc_len;
 static struct dentry		*s3c2410_udc_debugfs_root;
 
 static inline u32 udc_read(u32 reg)
@@ -997,7 +1010,7 @@ static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev)
 		}
 	}
 
-	dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", IRQ_USBD);
+	dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", dev->irq);
 
 	/* Restore old index */
 	udc_write(idx, S3C2410_UDC_INDEX_REG);
@@ -1757,6 +1770,49 @@ static int s3c2410_udc_stop(struct usb_gadget *g)
 
 };
 
+static int s3c2410_udc_probe_dt(struct s3c2410_udc *udc)
+{
+	const struct s3c2410_udc_drv_data *drvdata;
+	struct platform_device *pdev = udc->pdev;
+	struct s3c2410_udc_mach_info *pdata;
+	int gpio;
+
+	drvdata = of_device_get_match_data(&pdev->dev);
+
+	if (drvdata)
+		udc->ep_fifo_size = drvdata->ep_fifo_size;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	gpio = of_get_named_gpio(pdev->dev.of_node, "samsung,vbus-gpio", 0);
+	if (gpio_is_valid(gpio))
+		pdata->vbus_pin = gpio;
+
+	gpio = of_get_named_gpio(pdev->dev.of_node, "samsung,pullup-gpio", 0);
+	if (gpio_is_valid(gpio))
+		pdata->pullup_pin = gpio;
+
+	pdev->dev.platform_data = pdata;
+
+	return 0;
+}
+
+static int s3c2410_udc_probe_pdata(struct s3c2410_udc *udc)
+{
+	const struct s3c2410_udc_drv_data *drvdata;
+	struct platform_device *pdev = udc->pdev;
+
+	drvdata = (struct s3c2410_udc_drv_data *)
+		platform_get_device_id(pdev)->driver_data;
+
+	if (drvdata)
+		udc->ep_fifo_size = drvdata->ep_fifo_size;
+
+	return 0;
+}
+
 /*
  *	probe - binds to the platform device
  */
@@ -1769,6 +1825,16 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
 
 	dev_dbg(dev, "%s()\n", __func__);
 
+	udc->pdev = pdev;
+
+	if (pdev->dev.of_node)
+		retval = s3c2410_udc_probe_dt(udc);
+	else
+		retval = s3c2410_udc_probe_pdata(udc);
+
+	if (retval)
+		return retval;
+
 	usb_bus_clock = clk_get(NULL, "usb-bus-gadget");
 	if (IS_ERR(usb_bus_clock)) {
 		dev_err(dev, "failed to get usb bus clock source\n");
@@ -1789,24 +1855,27 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
 
 	dev_dbg(dev, "got and enabled clocks\n");
 
-	if (strncmp(pdev->name, "s3c2440", 7) == 0) {
-		dev_info(dev, "S3C2440: increasing FIFO to 128 bytes\n");
-		memory.ep[1].fifo_size = S3C2440_EP_FIFO_SIZE;
-		memory.ep[2].fifo_size = S3C2440_EP_FIFO_SIZE;
-		memory.ep[3].fifo_size = S3C2440_EP_FIFO_SIZE;
-		memory.ep[4].fifo_size = S3C2440_EP_FIFO_SIZE;
+	if (udc->ep_fifo_size) {
+		dev_info(dev, "setting FIFO to %d bytes\n", udc->ep_fifo_size);
+		memory.ep[1].fifo_size = udc->ep_fifo_size;
+		memory.ep[2].fifo_size = udc->ep_fifo_size;
+		memory.ep[3].fifo_size = udc->ep_fifo_size;
+		memory.ep[4].fifo_size = udc->ep_fifo_size;
 	}
 
 	spin_lock_init(&udc->lock);
 	udc_info = dev_get_platdata(&pdev->dev);
 
-	rsrc_start = S3C2410_PA_USBDEV;
-	rsrc_len   = S3C24XX_SZ_USBDEV;
+	udc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!udc->mem) {
+		dev_err(dev, "failed to get I/O memory region\n");
+		return -ENOENT;
+	}
 
-	if (!request_mem_region(rsrc_start, rsrc_len, gadget_name))
+	if (!request_mem_region(udc->mem->start, resource_size(udc->mem), gadget_name))
 		return -EBUSY;
 
-	base_addr = ioremap(rsrc_start, rsrc_len);
+	base_addr = ioremap(udc->mem->start, resource_size(udc->mem));
 	if (!base_addr) {
 		retval = -ENOMEM;
 		goto err_mem;
@@ -1818,17 +1887,24 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
 	s3c2410_udc_disable(udc);
 	s3c2410_udc_reinit(udc);
 
+	udc->irq = platform_get_irq(pdev, 0);
+	if (udc->irq == 0) {
+		dev_err(dev, "failed to get interrupt\n");
+		retval = -EINVAL;
+		goto err_map;
+	}
+
 	/* irq setup after old hardware state is cleaned up */
-	retval = request_irq(IRQ_USBD, s3c2410_udc_irq,
+	retval = request_irq(udc->irq, s3c2410_udc_irq,
 			     0, gadget_name, udc);
 
 	if (retval != 0) {
-		dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval);
+		dev_err(dev, "cannot get irq %i, err %d\n", udc->irq, retval);
 		retval = -EBUSY;
 		goto err_map;
 	}
 
-	dev_dbg(dev, "got irq %i\n", IRQ_USBD);
+	dev_dbg(dev, "got irq %i\n", udc->irq);
 
 	if (udc_info && udc_info->vbus_pin > 0) {
 		retval = gpio_request(udc_info->vbus_pin, "udc vbus");
@@ -1899,11 +1975,11 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
 	if (udc_info && udc_info->vbus_pin > 0)
 		gpio_free(udc_info->vbus_pin);
 err_int:
-	free_irq(IRQ_USBD, udc);
+	free_irq(udc->irq, udc);
 err_map:
 	iounmap(base_addr);
 err_mem:
-	release_mem_region(rsrc_start, rsrc_len);
+	release_mem_region(udc->mem->start, resource_size(udc->mem));
 
 	return retval;
 }
@@ -1933,10 +2009,10 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
 		free_irq(irq, udc);
 	}
 
-	free_irq(IRQ_USBD, udc);
+	free_irq(udc->irq, udc);
 
 	iounmap(base_addr);
-	release_mem_region(rsrc_start, rsrc_len);
+	release_mem_region(udc->mem->start, resource_size(udc->mem));
 
 	if (!IS_ERR(udc_clock) && udc_clock != NULL) {
 		clk_disable_unprepare(udc_clock);
@@ -1974,16 +2050,36 @@ static int s3c2410_udc_resume(struct platform_device *pdev)
 #define s3c2410_udc_resume	NULL
 #endif
 
+static const struct of_device_id s3c_udc_dt_ids[] = {
+	{
+		.compatible = "samsung,s3c2410-udc",
+		.data = &s3c2410_udc_2410_drv_data,
+	},
+	{
+		.compatible = "samsung,s3c2440-udc",
+		.data = &s3c2410_udc_2440_drv_data,
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, s3c_udc_dt_ids);
+
 static const struct platform_device_id s3c_udc_ids[] = {
-	{ "s3c2410-usbgadget", },
-	{ "s3c2440-usbgadget", },
-	{ }
+	{
+		.name = "s3c2410-usbgadget",
+		.driver_data = (kernel_ulong_t) &s3c2410_udc_2410_drv_data,
+	},
+	{
+		.name = "s3c2440-usbgadget",
+		.driver_data = (kernel_ulong_t) &s3c2410_udc_2440_drv_data,
+	},
+	{ /* sentinel */},
 };
 MODULE_DEVICE_TABLE(platform, s3c_udc_ids);
 
 static struct platform_driver udc_driver_24x0 = {
 	.driver		= {
 		.name	= "s3c24x0-usbgadget",
+		.of_match_table = s3c_udc_dt_ids,
 	},
 	.probe		= s3c2410_udc_probe,
 	.remove		= s3c2410_udc_remove,
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.h b/drivers/usb/gadget/udc/s3c2410_udc.h
index 93bf225f1969..8fdbe77a804d 100644
--- a/drivers/usb/gadget/udc/s3c2410_udc.h
+++ b/drivers/usb/gadget/udc/s3c2410_udc.h
@@ -94,6 +94,10 @@ struct s3c2410_udc {
 	unsigned			req_pending : 1;
 	u8				vbus;
 	struct dentry			*regs_info;
+	struct platform_device		*pdev;
+	struct resource			*mem;
+	int				irq;
+	unsigned int			ep_fifo_size;
 };
 #define to_s3c2410(g)	(container_of((g), struct s3c2410_udc, gadget))
 
-- 
1.9.1

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

* Re: [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller
  2016-12-09 19:06 ` [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller Sergio Prado
@ 2016-12-13 18:59   ` Rob Herring
  2016-12-17 12:50     ` Sergio Prado
  0 siblings, 1 reply; 5+ messages in thread
From: Rob Herring @ 2016-12-13 18:59 UTC (permalink / raw)
  To: Sergio Prado
  Cc: gregkh, mark.rutland, balbi, linux-usb, devicetree, linux-kernel

On Fri, Dec 09, 2016 at 05:06:39PM -0200, Sergio Prado wrote:
> Adds the device tree bindings description for Samsung S3C2410 and
> compatible USB device controller.
> 
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
> ---
>  .../devicetree/bindings/usb/s3c2410-usb.txt        | 28 ++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/s3c2410-usb.txt b/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
> index e45b38ce2986..4d3f9894c2d4 100644
> --- a/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
> +++ b/Documentation/devicetree/bindings/usb/s3c2410-usb.txt
> @@ -20,3 +20,31 @@ usb0: ohci@49000000 {
>  	clocks = <&clocks UCLK>, <&clocks HCLK_USBH>;
>  	clock-names = "usb-bus-host", "usb-host";
>  };
> +
> +Samsung S3C2410 and compatible USB device controller
> +
> +Required properties:
> + - compatible: Should be one of the following
> +	       "samsung,s3c2410-udc"
> +	       "samsung,s3c2440-udc"
> + - reg: address and length of the controller memory mapped region
> + - interrupts: interrupt number for the USB device controller
> + - clocks: Should reference the bus and host clocks
> + - clock-names: Should contain two strings
> +		"usb-bus-gadget" for the USB bus clock

Pretty sure the h/w clock name in the datasheet does not use the Linux 
term gadget.

> +		"usb-device" for the USB device clock
> +
> +Optional properties:
> + - samsung,vbus-gpio: If present, specifies a gpio that needs to be
> +   activated for the bus to be powered.

Isn't it the host side that controls Vbus?

> + - samsung,pullup-gpio: If present, specifies a gpio to control the

Both GPIOs need to specify the active state.

> +   USB D+ pullup.
> +
> +usb1: udc@52000000 {
> +	compatible = "samsung,s3c2440-udc";
> +	reg = <0x52000000 0x100000>;
> +	interrupts = <0 0 25 3>;
> +	clocks = <&clocks UCLK>, <&clocks HCLK_USBD>;
> +	clock-names = "usb-bus-gadget", "usb-device";
> +	samsung,pullup-gpio = <&gpc 5 GPIO_ACTIVE_HIGH>;
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller
  2016-12-13 18:59   ` Rob Herring
@ 2016-12-17 12:50     ` Sergio Prado
  0 siblings, 0 replies; 5+ messages in thread
From: Sergio Prado @ 2016-12-17 12:50 UTC (permalink / raw)
  To: Rob Herring
  Cc: gregkh, mark.rutland, balbi, linux-usb, devicetree, linux-kernel

On Tue, Dec 13, 2016 at 12:59:15PM -0600, Rob Herring wrote:
> > +Samsung S3C2410 and compatible USB device controller
> > +
> > +Required properties:
> > + - compatible: Should be one of the following
> > +	       "samsung,s3c2410-udc"
> > +	       "samsung,s3c2440-udc"
> > + - reg: address and length of the controller memory mapped region
> > + - interrupts: interrupt number for the USB device controller
> > + - clocks: Should reference the bus and host clocks
> > + - clock-names: Should contain two strings
> > +		"usb-bus-gadget" for the USB bus clock
> 
> Pretty sure the h/w clock name in the datasheet does not use the Linux 
> term gadget.

You are right. The datasheet calls it UCLK. In the S3c24010 clock driver
(clk-s3c2410.c), there's is a clock alias to UCLK called
"usb-bus-gadget" that was used in the USB device controller's driver.
We can change the driver and the DT binding to use "uclk" to
better reflect the name used in the datasheet. What do you think?

> 
> > +		"usb-device" for the USB device clock
> > +
> > +Optional properties:
> > + - samsung,vbus-gpio: If present, specifies a gpio that needs to be
> > +   activated for the bus to be powered.
> 
> Isn't it the host side that controls Vbus?

Yes. I'll change the description to "specifies a gpio that allows to
detect whether vbus is present (USB is connected)."

> 
> > + - samsung,pullup-gpio: If present, specifies a gpio to control the
> 
> Both GPIOs need to specify the active state.

OK.

> 
> > +   USB D+ pullup.
> > +
> > +usb1: udc@52000000 {
> > +	compatible = "samsung,s3c2440-udc";
> > +	reg = <0x52000000 0x100000>;
> > +	interrupts = <0 0 25 3>;
> > +	clocks = <&clocks UCLK>, <&clocks HCLK_USBD>;
> > +	clock-names = "usb-bus-gadget", "usb-device";
> > +	samsung,pullup-gpio = <&gpc 5 GPIO_ACTIVE_HIGH>;
> > +};
> > -- 
> > 1.9.1
> > 

Best regards,

-- 
Sergio Prado
Embedded Labworks

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

end of thread, other threads:[~2016-12-17 12:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-09 19:06 [PATCH 0/2] usb: gadget: s3c2410: add device tree support Sergio Prado
2016-12-09 19:06 ` [PATCH 1/2] dt-bindings: usb: add DT binding for s3c2410 USB device controller Sergio Prado
2016-12-13 18:59   ` Rob Herring
2016-12-17 12:50     ` Sergio Prado
2016-12-09 19:06 ` [PATCH 2/2] usb: gadget: s3c2410: allow probing from device tree Sergio Prado

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