All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5 v3] ARM: at91: dt: add USBA support
@ 2013-05-17 14:14 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:14 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: devicetree-discuss, linux-usb, Nicolas Ferre

HI,

	v3:
	rebase againt 3.10-rc1 + dt macro cleanup

	This patch serie finish to add the usb device support to dt for at91
	with the usba support present on the last at91 generation since sam9g45

The following changes since commit b3f442b0eedbc20b5ce3f4a96530588d14901199:

  ARM: at91: udpate defconfigs (2013-05-17 15:05:08 +0200)

are available in the git repository at:

  git://github.com/at91linux/linux-at91.git j/for-3.11-usba

for you to fetch changes up to f24c9792c29803420a7bf7204223ef028191d449:

  ARM: at91: sam9m10g45ek add udc DT support (2013-05-17 22:05:46 +0800)

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (5):
      usb: add Atmel USBA UDC DT support
      ARM: at91: sam9x5 add udc DT support
      ARM: at91: sam9x5ek add udc DT support
      ARM: at91: sam9g45 add udc DT support
      ARM: at91: sam9m10g45ek add udc DT support

 Documentation/devicetree/bindings/usb/atmel-usb.txt |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9g45.dtsi                  |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9m10g45ek.dts              |    5 +++++
 arch/arm/boot/dts/at91sam9x5.dtsi                   |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9x5ek.dtsi                 |    5 +++++
 arch/arm/mach-at91/at91sam9g45.c                    |    2 ++
 arch/arm/mach-at91/at91sam9x5.c                     |    2 ++
 drivers/usb/gadget/Kconfig                          |    2 +-
 drivers/usb/gadget/atmel_usba_udc.c                 |  214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------
 drivers/usb/gadget/atmel_usba_udc.h                 |    1 +
 10 files changed, 382 insertions(+), 55 deletions(-)

Best Regards,
J.

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

* [PATCH 0/5 v3] ARM: at91: dt: add USBA support
@ 2013-05-17 14:14 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

HI,

	v3:
	rebase againt 3.10-rc1 + dt macro cleanup

	This patch serie finish to add the usb device support to dt for at91
	with the usba support present on the last at91 generation since sam9g45

The following changes since commit b3f442b0eedbc20b5ce3f4a96530588d14901199:

  ARM: at91: udpate defconfigs (2013-05-17 15:05:08 +0200)

are available in the git repository at:

  git://github.com/at91linux/linux-at91.git j/for-3.11-usba

for you to fetch changes up to f24c9792c29803420a7bf7204223ef028191d449:

  ARM: at91: sam9m10g45ek add udc DT support (2013-05-17 22:05:46 +0800)

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (5):
      usb: add Atmel USBA UDC DT support
      ARM: at91: sam9x5 add udc DT support
      ARM: at91: sam9x5ek add udc DT support
      ARM: at91: sam9g45 add udc DT support
      ARM: at91: sam9m10g45ek add udc DT support

 Documentation/devicetree/bindings/usb/atmel-usb.txt |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9g45.dtsi                  |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9m10g45ek.dts              |    5 +++++
 arch/arm/boot/dts/at91sam9x5.dtsi                   |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9x5ek.dtsi                 |    5 +++++
 arch/arm/mach-at91/at91sam9g45.c                    |    2 ++
 arch/arm/mach-at91/at91sam9x5.c                     |    2 ++
 drivers/usb/gadget/Kconfig                          |    2 +-
 drivers/usb/gadget/atmel_usba_udc.c                 |  214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------
 drivers/usb/gadget/atmel_usba_udc.h                 |    1 +
 10 files changed, 382 insertions(+), 55 deletions(-)

Best Regards,
J.

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

* [PATCH 1/5] usb: add Atmel USBA UDC DT support
  2013-05-17 14:14 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Jean-Christophe PLAGNIOL-VILLARD, Nicolas Ferre,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

Allow to compile the driver all the time if AT91 enabled.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>
Cc: Nicolas Ferre <nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
 .../devicetree/bindings/usb/atmel-usb.txt          |   82 ++++++++
 drivers/usb/gadget/Kconfig                         |    2 +-
 drivers/usb/gadget/atmel_usba_udc.c                |  214 +++++++++++++++-----
 drivers/usb/gadget/atmel_usba_udc.h                |    1 +
 4 files changed, 244 insertions(+), 55 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
index 60bd215..878556b2 100644
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
@@ -47,3 +47,85 @@ usb1: gadget@fffa4000 {
 	interrupts = <10 4>;
 	atmel,vbus-gpio = <&pioC 5 0>;
 };
+
+Atmel High-Speed USB device controller
+
+Required properties:
+ - compatible: Should be "atmel,at91sam9rl-udc"
+ - reg: Address and length of the register set for the device
+ - interrupts: Should contain macb interrupt
+ - ep childnode: To specifiy the number of endpoints and their properties.
+
+Optional properties:
+ - atmel,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+
+Required child node properties:
+ - name: Name of the endpoint.
+ - reg: Num of the endpoint.
+ - atmel,fifo-size: Size of the fifo.
+ - atmel,nb-banks: Number of banks.
+ - atmel,can-dma: Boolean to specify if the endpoint support DMA.
+ - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
+
+usb2: gadget at fff78000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "atmel,at91sam9rl-udc";
+	reg = <0x00600000 0x80000
+	       0xfff78000 0x400>;
+	interrupts = <27 4>;
+	atmel,vbus-gpio = <&pioB 19 0>;
+
+	ep0 {
+		reg = <0>;
+		atmel,fifo-size = <64>;
+		atmel,nb-banks = <1>;
+	};
+
+	ep1 {
+		reg = <1>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep2 {
+		reg = <2>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep3 {
+		reg = <3>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep4 {
+		reg = <4>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep5 {
+		reg = <5>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep6 {
+		reg = <6>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+};
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 83300d9..5e47d50 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -156,7 +156,7 @@ config USB_LPC32XX
 
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
-	depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+	depends on AVR32 || ARCH_AT91
 	help
 	  USBA is the integrated high-speed USB Device controller on
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index f2a970f..b3084b9 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -22,6 +22,8 @@
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/delay.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <asm/gpio.h>
 
@@ -1835,9 +1837,143 @@ static int atmel_usba_stop(struct usb_gadget *gadget,
 	return 0;
 }
 
-static int __init usba_udc_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
+						    struct usba_udc *udc)
+{
+	u32 val;
+	const char *name;
+	enum of_gpio_flags flags;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *pp;
+	int i, ret;
+	struct usba_ep *eps, *ep;
+
+	udc->num_ep = 0;
+
+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
+						&flags);
+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
+	pp = NULL;
+	while ((pp = of_get_next_child(np, pp)))
+		udc->num_ep++;
+
+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
+			   GFP_KERNEL);
+	if (!eps)
+		return ERR_PTR(-ENOMEM);
+
+	udc->gadget.ep0 = &eps[0].ep;
+
+	INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+	pp = NULL;
+	i = 0;
+	while ((pp = of_get_next_child(np, pp))) {
+		ep = &eps[i];
+
+		ret = of_property_read_u32(pp, "reg", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret);
+			goto err;
+		}
+		ep->index = val;
+
+		ret = of_property_read_u32(pp, "atmel,fifo-size", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret);
+			goto err;
+		}
+		ep->fifo_size = val;
+
+		ret = of_property_read_u32(pp, "atmel,nb-banks", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret);
+			goto err;
+		}
+		ep->nr_banks = val;
+
+		ep->can_dma = of_property_read_bool(pp, "atmel,can-dma");
+		ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc");
+
+		ret = of_property_read_string(pp, "name", &name);
+		ep->ep.name = name;
+
+		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+		ep->ep.ops = &usba_ep_ops;
+		ep->ep.maxpacket = ep->fifo_size;
+		ep->udc = udc;
+		INIT_LIST_HEAD(&ep->queue);
+
+		if (i)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+
+		i++;
+	}
+
+	return eps;
+err:
+	return ERR_PTR(ret);
+}
+#else
+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
+						    struct usba_udc *udc)
+{
+	return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static struct usba_ep * usba_udc_pdata(struct platform_device *pdev,
+						 struct usba_udc *udc)
 {
 	struct usba_platform_data *pdata = pdev->dev.platform_data;
+	struct usba_ep *eps;
+	int i;
+
+	if (!pdata)
+		return ERR_PTR(-ENXIO);
+
+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep,
+			   GFP_KERNEL);
+	if (!eps)
+		return ERR_PTR(-ENOMEM);
+
+	udc->gadget.ep0 = &eps[0].ep;
+
+	udc->vbus_pin = pdata->vbus_pin;
+	udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
+	udc->num_ep = pdata->num_ep;
+
+	INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+	for (i = 0; i < pdata->num_ep; i++) {
+		struct usba_ep *ep = &eps[i];
+
+		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+		ep->ep.ops = &usba_ep_ops;
+		ep->ep.name = pdata->ep[i].name;
+		ep->fifo_size = ep->ep.maxpacket = pdata->ep[i].fifo_size;
+		ep->udc = udc;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->nr_banks = pdata->ep[i].nr_banks;
+		ep->index = pdata->ep[i].index;
+		ep->can_dma = pdata->ep[i].can_dma;
+		ep->can_isoc = pdata->ep[i].can_isoc;
+
+		if (i)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	}
+
+	return eps;
+}
+
+static int __init usba_udc_probe(struct platform_device *pdev)
+{
 	struct resource *regs, *fifo;
 	struct clk *pclk, *hclk;
 	struct usba_udc *udc = &the_udc;
@@ -1845,7 +1981,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
 	fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
-	if (!regs || !fifo || !pdata)
+	if (!regs || !fifo)
 		return -ENXIO;
 
 	irq = platform_get_irq(pdev, 0);
@@ -1891,46 +2027,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
 	clk_disable(pclk);
 
-	usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
-			  GFP_KERNEL);
-	if (!usba_ep)
-		goto err_alloc_ep;
-
-	the_udc.gadget.ep0 = &usba_ep[0].ep;
-
-	INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
-	usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
-	usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
-	usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
-	usba_ep[0].ep.ops = &usba_ep_ops;
-	usba_ep[0].ep.name = pdata->ep[0].name;
-	usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
-	usba_ep[0].udc = &the_udc;
-	INIT_LIST_HEAD(&usba_ep[0].queue);
-	usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
-	usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
-	usba_ep[0].index = pdata->ep[0].index;
-	usba_ep[0].can_dma = pdata->ep[0].can_dma;
-	usba_ep[0].can_isoc = pdata->ep[0].can_isoc;
-
-	for (i = 1; i < pdata->num_ep; i++) {
-		struct usba_ep *ep = &usba_ep[i];
-
-		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
-		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
-		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
-		ep->ep.ops = &usba_ep_ops;
-		ep->ep.name = pdata->ep[i].name;
-		ep->ep.maxpacket = pdata->ep[i].fifo_size;
-		ep->udc = &the_udc;
-		INIT_LIST_HEAD(&ep->queue);
-		ep->fifo_size = pdata->ep[i].fifo_size;
-		ep->nr_banks = pdata->ep[i].nr_banks;
-		ep->index = pdata->ep[i].index;
-		ep->can_dma = pdata->ep[i].can_dma;
-		ep->can_isoc = pdata->ep[i].can_isoc;
+	if (pdev->dev.of_node)
+		usba_ep = atmel_udc_of_init(pdev, udc);
+	else
+		usba_ep = usba_udc_pdata(pdev, udc);
 
-		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	if (IS_ERR(usba_ep)) {
+		ret = PTR_ERR(usba_ep);
+		goto err_alloc_ep;
 	}
 
 	ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc);
@@ -1941,16 +2045,12 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 	}
 	udc->irq = irq;
 
-	if (gpio_is_valid(pdata->vbus_pin)) {
-		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
-			udc->vbus_pin = pdata->vbus_pin;
-			udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
-
+	if (gpio_is_valid(udc->vbus_pin)) {
+		if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) {
 			ret = request_irq(gpio_to_irq(udc->vbus_pin),
 					usba_vbus_irq, 0,
 					"atmel_usba_udc", udc);
 			if (ret) {
-				gpio_free(udc->vbus_pin);
 				udc->vbus_pin = -ENODEV;
 				dev_warn(&udc->pdev->dev,
 					 "failed to request vbus irq; "
@@ -1969,16 +2069,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 		goto err_add_udc;
 
 	usba_init_debugfs(udc);
-	for (i = 1; i < pdata->num_ep; i++)
+	for (i = 1; i < udc->num_ep; i++)
 		usba_ep_init_debugfs(udc, &usba_ep[i]);
 
 	return 0;
 
 err_add_udc:
-	if (gpio_is_valid(pdata->vbus_pin)) {
+	if (gpio_is_valid(udc->vbus_pin))
 		free_irq(gpio_to_irq(udc->vbus_pin), udc);
-		gpio_free(udc->vbus_pin);
-	}
 
 	free_irq(irq, udc);
 err_request_irq:
@@ -2001,19 +2099,17 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
 {
 	struct usba_udc *udc;
 	int i;
-	struct usba_platform_data *pdata = pdev->dev.platform_data;
 
 	udc = platform_get_drvdata(pdev);
 
 	usb_del_gadget_udc(&udc->gadget);
 
-	for (i = 1; i < pdata->num_ep; i++)
+	for (i = 1; i < udc->num_ep; i++)
 		usba_ep_cleanup_debugfs(&usba_ep[i]);
 	usba_cleanup_debugfs(udc);
 
 	if (gpio_is_valid(udc->vbus_pin)) {
 		free_irq(gpio_to_irq(udc->vbus_pin), udc);
-		gpio_free(udc->vbus_pin);
 	}
 
 	free_irq(udc->irq, udc);
@@ -2026,11 +2122,21 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_udc_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9rl-udc" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
+#endif
+
 static struct platform_driver udc_driver = {
 	.remove		= __exit_p(usba_udc_remove),
 	.driver		= {
 		.name		= "atmel_usba_udc",
 		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_udc_dt_ids),
 	},
 };
 
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
index d65a618..6999a26 100644
--- a/drivers/usb/gadget/atmel_usba_udc.h
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -317,6 +317,7 @@ struct usba_udc {
 	int irq;
 	int vbus_pin;
 	int vbus_pin_inverted;
+	int num_ep;
 	struct clk *pclk;
 	struct clk *hclk;
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/5] usb: add Atmel USBA UDC DT support
@ 2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Allow to compile the driver all the time if AT91 enabled.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: linux-usb at vger.kernel.org
---
 .../devicetree/bindings/usb/atmel-usb.txt          |   82 ++++++++
 drivers/usb/gadget/Kconfig                         |    2 +-
 drivers/usb/gadget/atmel_usba_udc.c                |  214 +++++++++++++++-----
 drivers/usb/gadget/atmel_usba_udc.h                |    1 +
 4 files changed, 244 insertions(+), 55 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
index 60bd215..878556b2 100644
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
@@ -47,3 +47,85 @@ usb1: gadget at fffa4000 {
 	interrupts = <10 4>;
 	atmel,vbus-gpio = <&pioC 5 0>;
 };
+
+Atmel High-Speed USB device controller
+
+Required properties:
+ - compatible: Should be "atmel,at91sam9rl-udc"
+ - reg: Address and length of the register set for the device
+ - interrupts: Should contain macb interrupt
+ - ep childnode: To specifiy the number of endpoints and their properties.
+
+Optional properties:
+ - atmel,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+
+Required child node properties:
+ - name: Name of the endpoint.
+ - reg: Num of the endpoint.
+ - atmel,fifo-size: Size of the fifo.
+ - atmel,nb-banks: Number of banks.
+ - atmel,can-dma: Boolean to specify if the endpoint support DMA.
+ - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
+
+usb2: gadget at fff78000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "atmel,at91sam9rl-udc";
+	reg = <0x00600000 0x80000
+	       0xfff78000 0x400>;
+	interrupts = <27 4>;
+	atmel,vbus-gpio = <&pioB 19 0>;
+
+	ep0 {
+		reg = <0>;
+		atmel,fifo-size = <64>;
+		atmel,nb-banks = <1>;
+	};
+
+	ep1 {
+		reg = <1>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep2 {
+		reg = <2>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep3 {
+		reg = <3>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep4 {
+		reg = <4>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep5 {
+		reg = <5>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep6 {
+		reg = <6>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+};
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 83300d9..5e47d50 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -156,7 +156,7 @@ config USB_LPC32XX
 
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
-	depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+	depends on AVR32 || ARCH_AT91
 	help
 	  USBA is the integrated high-speed USB Device controller on
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index f2a970f..b3084b9 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -22,6 +22,8 @@
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/delay.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <asm/gpio.h>
 
@@ -1835,9 +1837,143 @@ static int atmel_usba_stop(struct usb_gadget *gadget,
 	return 0;
 }
 
-static int __init usba_udc_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
+						    struct usba_udc *udc)
+{
+	u32 val;
+	const char *name;
+	enum of_gpio_flags flags;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *pp;
+	int i, ret;
+	struct usba_ep *eps, *ep;
+
+	udc->num_ep = 0;
+
+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
+						&flags);
+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
+	pp = NULL;
+	while ((pp = of_get_next_child(np, pp)))
+		udc->num_ep++;
+
+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
+			   GFP_KERNEL);
+	if (!eps)
+		return ERR_PTR(-ENOMEM);
+
+	udc->gadget.ep0 = &eps[0].ep;
+
+	INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+	pp = NULL;
+	i = 0;
+	while ((pp = of_get_next_child(np, pp))) {
+		ep = &eps[i];
+
+		ret = of_property_read_u32(pp, "reg", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret);
+			goto err;
+		}
+		ep->index = val;
+
+		ret = of_property_read_u32(pp, "atmel,fifo-size", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret);
+			goto err;
+		}
+		ep->fifo_size = val;
+
+		ret = of_property_read_u32(pp, "atmel,nb-banks", &val);
+		if (ret) {
+			dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret);
+			goto err;
+		}
+		ep->nr_banks = val;
+
+		ep->can_dma = of_property_read_bool(pp, "atmel,can-dma");
+		ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc");
+
+		ret = of_property_read_string(pp, "name", &name);
+		ep->ep.name = name;
+
+		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+		ep->ep.ops = &usba_ep_ops;
+		ep->ep.maxpacket = ep->fifo_size;
+		ep->udc = udc;
+		INIT_LIST_HEAD(&ep->queue);
+
+		if (i)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+
+		i++;
+	}
+
+	return eps;
+err:
+	return ERR_PTR(ret);
+}
+#else
+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
+						    struct usba_udc *udc)
+{
+	return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static struct usba_ep * usba_udc_pdata(struct platform_device *pdev,
+						 struct usba_udc *udc)
 {
 	struct usba_platform_data *pdata = pdev->dev.platform_data;
+	struct usba_ep *eps;
+	int i;
+
+	if (!pdata)
+		return ERR_PTR(-ENXIO);
+
+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep,
+			   GFP_KERNEL);
+	if (!eps)
+		return ERR_PTR(-ENOMEM);
+
+	udc->gadget.ep0 = &eps[0].ep;
+
+	udc->vbus_pin = pdata->vbus_pin;
+	udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
+	udc->num_ep = pdata->num_ep;
+
+	INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+	for (i = 0; i < pdata->num_ep; i++) {
+		struct usba_ep *ep = &eps[i];
+
+		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+		ep->ep.ops = &usba_ep_ops;
+		ep->ep.name = pdata->ep[i].name;
+		ep->fifo_size = ep->ep.maxpacket = pdata->ep[i].fifo_size;
+		ep->udc = udc;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->nr_banks = pdata->ep[i].nr_banks;
+		ep->index = pdata->ep[i].index;
+		ep->can_dma = pdata->ep[i].can_dma;
+		ep->can_isoc = pdata->ep[i].can_isoc;
+
+		if (i)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	}
+
+	return eps;
+}
+
+static int __init usba_udc_probe(struct platform_device *pdev)
+{
 	struct resource *regs, *fifo;
 	struct clk *pclk, *hclk;
 	struct usba_udc *udc = &the_udc;
@@ -1845,7 +1981,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
 	fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
-	if (!regs || !fifo || !pdata)
+	if (!regs || !fifo)
 		return -ENXIO;
 
 	irq = platform_get_irq(pdev, 0);
@@ -1891,46 +2027,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
 	clk_disable(pclk);
 
-	usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
-			  GFP_KERNEL);
-	if (!usba_ep)
-		goto err_alloc_ep;
-
-	the_udc.gadget.ep0 = &usba_ep[0].ep;
-
-	INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
-	usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
-	usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
-	usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
-	usba_ep[0].ep.ops = &usba_ep_ops;
-	usba_ep[0].ep.name = pdata->ep[0].name;
-	usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
-	usba_ep[0].udc = &the_udc;
-	INIT_LIST_HEAD(&usba_ep[0].queue);
-	usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
-	usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
-	usba_ep[0].index = pdata->ep[0].index;
-	usba_ep[0].can_dma = pdata->ep[0].can_dma;
-	usba_ep[0].can_isoc = pdata->ep[0].can_isoc;
-
-	for (i = 1; i < pdata->num_ep; i++) {
-		struct usba_ep *ep = &usba_ep[i];
-
-		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
-		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
-		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
-		ep->ep.ops = &usba_ep_ops;
-		ep->ep.name = pdata->ep[i].name;
-		ep->ep.maxpacket = pdata->ep[i].fifo_size;
-		ep->udc = &the_udc;
-		INIT_LIST_HEAD(&ep->queue);
-		ep->fifo_size = pdata->ep[i].fifo_size;
-		ep->nr_banks = pdata->ep[i].nr_banks;
-		ep->index = pdata->ep[i].index;
-		ep->can_dma = pdata->ep[i].can_dma;
-		ep->can_isoc = pdata->ep[i].can_isoc;
+	if (pdev->dev.of_node)
+		usba_ep = atmel_udc_of_init(pdev, udc);
+	else
+		usba_ep = usba_udc_pdata(pdev, udc);
 
-		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	if (IS_ERR(usba_ep)) {
+		ret = PTR_ERR(usba_ep);
+		goto err_alloc_ep;
 	}
 
 	ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc);
@@ -1941,16 +2045,12 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 	}
 	udc->irq = irq;
 
-	if (gpio_is_valid(pdata->vbus_pin)) {
-		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
-			udc->vbus_pin = pdata->vbus_pin;
-			udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
-
+	if (gpio_is_valid(udc->vbus_pin)) {
+		if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) {
 			ret = request_irq(gpio_to_irq(udc->vbus_pin),
 					usba_vbus_irq, 0,
 					"atmel_usba_udc", udc);
 			if (ret) {
-				gpio_free(udc->vbus_pin);
 				udc->vbus_pin = -ENODEV;
 				dev_warn(&udc->pdev->dev,
 					 "failed to request vbus irq; "
@@ -1969,16 +2069,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
 		goto err_add_udc;
 
 	usba_init_debugfs(udc);
-	for (i = 1; i < pdata->num_ep; i++)
+	for (i = 1; i < udc->num_ep; i++)
 		usba_ep_init_debugfs(udc, &usba_ep[i]);
 
 	return 0;
 
 err_add_udc:
-	if (gpio_is_valid(pdata->vbus_pin)) {
+	if (gpio_is_valid(udc->vbus_pin))
 		free_irq(gpio_to_irq(udc->vbus_pin), udc);
-		gpio_free(udc->vbus_pin);
-	}
 
 	free_irq(irq, udc);
 err_request_irq:
@@ -2001,19 +2099,17 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
 {
 	struct usba_udc *udc;
 	int i;
-	struct usba_platform_data *pdata = pdev->dev.platform_data;
 
 	udc = platform_get_drvdata(pdev);
 
 	usb_del_gadget_udc(&udc->gadget);
 
-	for (i = 1; i < pdata->num_ep; i++)
+	for (i = 1; i < udc->num_ep; i++)
 		usba_ep_cleanup_debugfs(&usba_ep[i]);
 	usba_cleanup_debugfs(udc);
 
 	if (gpio_is_valid(udc->vbus_pin)) {
 		free_irq(gpio_to_irq(udc->vbus_pin), udc);
-		gpio_free(udc->vbus_pin);
 	}
 
 	free_irq(udc->irq, udc);
@@ -2026,11 +2122,21 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_udc_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9rl-udc" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
+#endif
+
 static struct platform_driver udc_driver = {
 	.remove		= __exit_p(usba_udc_remove),
 	.driver		= {
 		.name		= "atmel_usba_udc",
 		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_udc_dt_ids),
 	},
 };
 
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
index d65a618..6999a26 100644
--- a/drivers/usb/gadget/atmel_usba_udc.h
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -317,6 +317,7 @@ struct usba_udc {
 	int irq;
 	int vbus_pin;
 	int vbus_pin_inverted;
+	int num_ep;
 	struct clk *pclk;
 	struct clk *hclk;
 
-- 
1.7.10.4

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

* [PATCH 2/5] ARM: at91: sam9x5 add udc DT support
  2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Nicolas Ferre, devicetree-discuss, Jean-Christophe PLAGNIOL-VILLARD

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9x5.dtsi |   62 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-at91/at91sam9x5.c   |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index af91599..01a815d 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -645,6 +645,68 @@
 				status = "disabled";
 			};
 
+			usb2: gadget@f803c000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00500000 0x80000
+				       0xf803c000 0x400>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
+
 			rtc@fffffeb0 {
 				compatible = "atmel,at91rm9200-rtc";
 				reg = <0xfffffeb0 0x40>;
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index e631fec..2abee66 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -249,6 +249,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
 	CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
+	CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
 };
 
 /*
-- 
1.7.10.4

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

* [PATCH 2/5] ARM: at91: sam9x5 add udc DT support
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9x5.dtsi |   62 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-at91/at91sam9x5.c   |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index af91599..01a815d 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -645,6 +645,68 @@
 				status = "disabled";
 			};
 
+			usb2: gadget at f803c000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00500000 0x80000
+				       0xf803c000 0x400>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
+
 			rtc at fffffeb0 {
 				compatible = "atmel,at91rm9200-rtc";
 				reg = <0xfffffeb0 0x40>;
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index e631fec..2abee66 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -249,6 +249,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
 	CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
+	CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
 };
 
 /*
-- 
1.7.10.4

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

* [PATCH 3/5] ARM: at91: sam9x5ek add udc DT support
  2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Nicolas Ferre, devicetree-discuss, Jean-Christophe PLAGNIOL-VILLARD

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9x5ek.dtsi |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
index 19c8ebb..5e10027 100644
--- a/arch/arm/boot/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -52,6 +52,11 @@
 				status = "okay";
 			};
 
+			usb2: gadget@f803c000 {
+				atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
+
 			i2c0: i2c@f8010000 {
 				status = "okay";
 			};
-- 
1.7.10.4

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

* [PATCH 3/5] ARM: at91: sam9x5ek add udc DT support
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9x5ek.dtsi |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
index 19c8ebb..5e10027 100644
--- a/arch/arm/boot/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -52,6 +52,11 @@
 				status = "okay";
 			};
 
+			usb2: gadget at f803c000 {
+				atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
+
 			i2c0: i2c at f8010000 {
 				status = "okay";
 			};
-- 
1.7.10.4

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

* [PATCH 4/5] ARM: at91: sam9g45 add udc DT support
  2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Nicolas Ferre, devicetree-discuss, Jean-Christophe PLAGNIOL-VILLARD

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9g45.dtsi |   62 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-at91/at91sam9g45.c   |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index f0091af..fccc488 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -582,6 +582,68 @@
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
 			};
+
+			usb2: gadget@fff78000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00600000 0x80000
+				       0xfff78000 0x400>;
+				interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 8b7fce0..95a418a 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -266,6 +266,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
 	CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+	CLKDEV_CON_DEV_ID("hclk", "600000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "600000.gadget", &udphs_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
-- 
1.7.10.4

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

* [PATCH 4/5] ARM: at91: sam9g45 add udc DT support
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9g45.dtsi |   62 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-at91/at91sam9g45.c   |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index f0091af..fccc488 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -582,6 +582,68 @@
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
 			};
+
+			usb2: gadget at fff78000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00600000 0x80000
+				       0xfff78000 0x400>;
+				interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
 		};
 
 		nand0: nand at 40000000 {
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 8b7fce0..95a418a 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -266,6 +266,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
 	CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+	CLKDEV_CON_DEV_ID("hclk", "600000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "600000.gadget", &udphs_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
-- 
1.7.10.4

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

* [PATCH 5/5] ARM: at91: sam9m10g45ek add udc DT support
  2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Nicolas Ferre, devicetree-discuss, Jean-Christophe PLAGNIOL-VILLARD

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9m10g45ek.dts |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 89c50d1..17665ef 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -112,6 +112,11 @@
 					reg = <0>;
 				};
 			};
+
+			usb2: gadget@fff78000 {
+				atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
-- 
1.7.10.4

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

* [PATCH 5/5] ARM: at91: sam9m10g45ek add udc DT support
@ 2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-17 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/at91sam9m10g45ek.dts |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 89c50d1..17665ef 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -112,6 +112,11 @@
 					reg = <0>;
 				};
 			};
+
+			usb2: gadget at fff78000 {
+				atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
 		};
 
 		nand0: nand at 40000000 {
-- 
1.7.10.4

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

* Re: [PATCH 1/5] usb: add Atmel USBA UDC DT support
  2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-20  3:26         ` Bo Shen
  -1 siblings, 0 replies; 18+ messages in thread
From: Bo Shen @ 2013-05-20  3:26 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Nicolas Ferre,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

Hi Jean-Christophe,

On 5/17/2013 22:42, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Allow to compile the driver all the time if AT91 enabled.
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>
> Cc: Nicolas Ferre <nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
> Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
>   .../devicetree/bindings/usb/atmel-usb.txt          |   82 ++++++++
>   drivers/usb/gadget/Kconfig                         |    2 +-
>   drivers/usb/gadget/atmel_usba_udc.c                |  214 +++++++++++++++-----
>   drivers/usb/gadget/atmel_usba_udc.h                |    1 +
>   4 files changed, 244 insertions(+), 55 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
> index 60bd215..878556b2 100644
> --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
> +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
> @@ -47,3 +47,85 @@ usb1: gadget@fffa4000 {
>   	interrupts = <10 4>;
>   	atmel,vbus-gpio = <&pioC 5 0>;
>   };
> +
> +Atmel High-Speed USB device controller
> +
> +Required properties:
> + - compatible: Should be "atmel,at91sam9rl-udc"
> + - reg: Address and length of the register set for the device
> + - interrupts: Should contain macb interrupt

s/macb/udphs

> + - ep childnode: To specifiy the number of endpoints and their properties.

s/specifiy/specify

> +
> +Optional properties:
> + - atmel,vbus-gpio: If present, specifies a gpio that needs to be
> +   activated for the bus to be powered.
> +
> +Required child node properties:
> + - name: Name of the endpoint.
> + - reg: Num of the endpoint.
> + - atmel,fifo-size: Size of the fifo.
> + - atmel,nb-banks: Number of banks.
> + - atmel,can-dma: Boolean to specify if the endpoint support DMA.
> + - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
> +
> +usb2: gadget at fff78000 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "atmel,at91sam9rl-udc";
> +	reg = <0x00600000 0x80000
> +	       0xfff78000 0x400>;
> +	interrupts = <27 4>;

s/interrupts = <27 4>/interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;

> +	atmel,vbus-gpio = <&pioB 19 0>;
> +
> +	ep0 {
> +		reg = <0>;
> +		atmel,fifo-size = <64>;
> +		atmel,nb-banks = <1>;
> +	};
> +
> +	ep1 {
> +		reg = <1>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <2>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep2 {
> +		reg = <2>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <2>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep3 {
> +		reg = <3>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +	};
> +
> +	ep4 {
> +		reg = <4>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +	};
> +
> +	ep5 {
> +		reg = <5>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep6 {
> +		reg = <6>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +};
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index 83300d9..5e47d50 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -156,7 +156,7 @@ config USB_LPC32XX
>
>   config USB_ATMEL_USBA
>   	tristate "Atmel USBA"
> -	depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
> +	depends on AVR32 || ARCH_AT91
>   	help
>   	  USBA is the integrated high-speed USB Device controller on
>   	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
> diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
> index f2a970f..b3084b9 100644
> --- a/drivers/usb/gadget/atmel_usba_udc.c
> +++ b/drivers/usb/gadget/atmel_usba_udc.c
> @@ -22,6 +22,8 @@
>   #include <linux/usb/atmel_usba_udc.h>
>   #include <linux/delay.h>
>   #include <linux/platform_data/atmel.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
>
>   #include <asm/gpio.h>
>
> @@ -1835,9 +1837,143 @@ static int atmel_usba_stop(struct usb_gadget *gadget,
>   	return 0;
>   }
>
> -static int __init usba_udc_probe(struct platform_device *pdev)
> +#ifdef CONFIG_OF
> +static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> +						    struct usba_udc *udc)
> +{
> +	u32 val;
> +	const char *name;
> +	enum of_gpio_flags flags;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct device_node *pp;
> +	int i, ret;
> +	struct usba_ep *eps, *ep;
> +
> +	udc->num_ep = 0;
> +
> +	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> +						&flags);
> +	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> +
> +	pp = NULL;
> +	while ((pp = of_get_next_child(np, pp)))
> +		udc->num_ep++;
> +
> +	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> +			   GFP_KERNEL);

Using devm_kzalloc will cause issue when build as modules, and load and 
unload this driver, the second time unload, it will come out following 
segment fault, log as following. Using kzalloc will fix it.

---8>---
Unable to handle kernel NULL pointer dereference at virtual address 00000054
pgd = c7bac000
[00000054] *pgd=27b6f831, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] ARM
Modules linked in: atmel_usba_udc(-) [last unloaded: atmel_usba_udc]
CPU: 0 PID: 519 Comm: rmmod Not tainted 3.10.0-rc1+ #13
task: c796d580 ti: c7b68000 task.ti: c7b68000
PC is at kfree+0x4c/0xb4
LR is at free_module+0xe4/0x168
pc : [<c007470c>]    lr : [<c0045884>]    psr: 40000093
sp : c7b69f10  ip : 00000010  fp : 00000000
r10: 00000000  r9 : c7b68000  r8 : c0009484
r7 : 00000000  r6 : c7ba0c00  r5 : a0000013  r4 : bf009240
r3 : c061d400  r2 : 00000000  r1 : 00007ba0  r0 : c7ba0c00
Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 27bac000  DAC: 00000015
Process rmmod (pid: 519, stack limit = 0xc7b681b8)
Stack: (0xc7b69f10 to 0xc7b6a000)
9f00:                                     0000000f bf009240 000000a8 
bf009288
9f20: c7afe6a8 c0045884 bf009240 00000000 00000013 becbfbd0 c0009484 
c0045c10
9f40: 00000000 656d7461 73755f6c 755f6162 b6006364 b6f1c000 c796d580 
b6f1c000
9f60: b6f1c000 c7afb140 00000000 becbf984 00005401 00000001 c7b68000 
00000000
9f80: bf009240 00000880 c7b69f8c 00000000 becbf9bc b6f0a380 00000880 
becbfbd0
9fa0: 00000081 c0009320 b6f0a380 00000880 becbfbd0 00000880 0000000e 
00000000
9fc0: b6f0a380 00000880 becbfbd0 00000081 0000009c 0000ce8c 0000b7f0 
00000000
9fe0: b6ebda20 becbfbc0 00019750 b6ebda2c a0000010 becbfbd0 00000000 
00000000
[<c007470c>] (kfree+0x4c/0xb4) from [<c0045884>] (free_module+0xe4/0x168)
[<c0045884>] (free_module+0xe4/0x168) from [<c0045c10>] 
(SyS_delete_module+0x1d8/0x210)
[<c0045c10>] (SyS_delete_module+0x1d8/0x210) from [<c0009320>] 
(ret_fast_syscall+0x0/0x2c)
Code: e7922281 e3120902 1593301c e593701c (e5974054)
---[ end trace cb98ff9cd16ea901 ]---
Segmentation fault
---<8---

> +	if (!eps)
> +		return ERR_PTR(-ENOMEM);
> +
> +	udc->gadget.ep0 = &eps[0].ep;
> +
> +	INIT_LIST_HEAD(&eps[0].ep.ep_list);
> +
> +	pp = NULL;
> +	i = 0;
> +	while ((pp = of_get_next_child(np, pp))) {
> +		ep = &eps[i];
> +
> +		ret = of_property_read_u32(pp, "reg", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->index = val;
> +
> +		ret = of_property_read_u32(pp, "atmel,fifo-size", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->fifo_size = val;
> +
> +		ret = of_property_read_u32(pp, "atmel,nb-banks", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->nr_banks = val;
> +
> +		ep->can_dma = of_property_read_bool(pp, "atmel,can-dma");
> +		ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc");
> +
> +		ret = of_property_read_string(pp, "name", &name);
> +		ep->ep.name = name;
> +
> +		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> +		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> +		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> +		ep->ep.ops = &usba_ep_ops;
> +		ep->ep.maxpacket = ep->fifo_size;
> +		ep->udc = udc;
> +		INIT_LIST_HEAD(&ep->queue);
> +
> +		if (i)
> +			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +
> +		i++;
> +	}
> +
> +	return eps;
> +err:
> +	return ERR_PTR(ret);
> +}
> +#else
> +static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> +						    struct usba_udc *udc)
> +{
> +	return ERR_PTR(-ENOSYS);
> +}
> +#endif
> +
> +static struct usba_ep * usba_udc_pdata(struct platform_device *pdev,
> +						 struct usba_udc *udc)
>   {
>   	struct usba_platform_data *pdata = pdev->dev.platform_data;
> +	struct usba_ep *eps;
> +	int i;
> +
> +	if (!pdata)
> +		return ERR_PTR(-ENXIO);
> +
> +	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep,
> +			   GFP_KERNEL);
> +	if (!eps)
> +		return ERR_PTR(-ENOMEM);
> +
> +	udc->gadget.ep0 = &eps[0].ep;
> +
> +	udc->vbus_pin = pdata->vbus_pin;
> +	udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
> +	udc->num_ep = pdata->num_ep;
> +
> +	INIT_LIST_HEAD(&eps[0].ep.ep_list);
> +
> +	for (i = 0; i < pdata->num_ep; i++) {
> +		struct usba_ep *ep = &eps[i];
> +
> +		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> +		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> +		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> +		ep->ep.ops = &usba_ep_ops;
> +		ep->ep.name = pdata->ep[i].name;
> +		ep->fifo_size = ep->ep.maxpacket = pdata->ep[i].fifo_size;
> +		ep->udc = udc;
> +		INIT_LIST_HEAD(&ep->queue);
> +		ep->nr_banks = pdata->ep[i].nr_banks;
> +		ep->index = pdata->ep[i].index;
> +		ep->can_dma = pdata->ep[i].can_dma;
> +		ep->can_isoc = pdata->ep[i].can_isoc;
> +
> +		if (i)
> +			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +	}
> +
> +	return eps;
> +}
> +
> +static int __init usba_udc_probe(struct platform_device *pdev)
> +{
>   	struct resource *regs, *fifo;
>   	struct clk *pclk, *hclk;
>   	struct usba_udc *udc = &the_udc;
> @@ -1845,7 +1981,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>
>   	regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
>   	fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
> -	if (!regs || !fifo || !pdata)
> +	if (!regs || !fifo)
>   		return -ENXIO;
>
>   	irq = platform_get_irq(pdev, 0);
> @@ -1891,46 +2027,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
>   	clk_disable(pclk);
>
> -	usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
> -			  GFP_KERNEL);
> -	if (!usba_ep)
> -		goto err_alloc_ep;
> -
> -	the_udc.gadget.ep0 = &usba_ep[0].ep;
> -
> -	INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
> -	usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
> -	usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
> -	usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
> -	usba_ep[0].ep.ops = &usba_ep_ops;
> -	usba_ep[0].ep.name = pdata->ep[0].name;
> -	usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
> -	usba_ep[0].udc = &the_udc;
> -	INIT_LIST_HEAD(&usba_ep[0].queue);
> -	usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
> -	usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
> -	usba_ep[0].index = pdata->ep[0].index;
> -	usba_ep[0].can_dma = pdata->ep[0].can_dma;
> -	usba_ep[0].can_isoc = pdata->ep[0].can_isoc;
> -
> -	for (i = 1; i < pdata->num_ep; i++) {
> -		struct usba_ep *ep = &usba_ep[i];
> -
> -		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> -		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> -		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> -		ep->ep.ops = &usba_ep_ops;
> -		ep->ep.name = pdata->ep[i].name;
> -		ep->ep.maxpacket = pdata->ep[i].fifo_size;
> -		ep->udc = &the_udc;
> -		INIT_LIST_HEAD(&ep->queue);
> -		ep->fifo_size = pdata->ep[i].fifo_size;
> -		ep->nr_banks = pdata->ep[i].nr_banks;
> -		ep->index = pdata->ep[i].index;
> -		ep->can_dma = pdata->ep[i].can_dma;
> -		ep->can_isoc = pdata->ep[i].can_isoc;
> +	if (pdev->dev.of_node)
> +		usba_ep = atmel_udc_of_init(pdev, udc);
> +	else
> +		usba_ep = usba_udc_pdata(pdev, udc);
>
> -		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +	if (IS_ERR(usba_ep)) {
> +		ret = PTR_ERR(usba_ep);
> +		goto err_alloc_ep;
>   	}
>
>   	ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc);
> @@ -1941,16 +2045,12 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   	}
>   	udc->irq = irq;
>
> -	if (gpio_is_valid(pdata->vbus_pin)) {
> -		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
> -			udc->vbus_pin = pdata->vbus_pin;
> -			udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
> -
> +	if (gpio_is_valid(udc->vbus_pin)) {
> +		if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) {
>   			ret = request_irq(gpio_to_irq(udc->vbus_pin),
>   					usba_vbus_irq, 0,
>   					"atmel_usba_udc", udc);
>   			if (ret) {
> -				gpio_free(udc->vbus_pin);
>   				udc->vbus_pin = -ENODEV;
>   				dev_warn(&udc->pdev->dev,
>   					 "failed to request vbus irq; "
> @@ -1969,16 +2069,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   		goto err_add_udc;
>
>   	usba_init_debugfs(udc);
> -	for (i = 1; i < pdata->num_ep; i++)
> +	for (i = 1; i < udc->num_ep; i++)
>   		usba_ep_init_debugfs(udc, &usba_ep[i]);
>
>   	return 0;
>
>   err_add_udc:
> -	if (gpio_is_valid(pdata->vbus_pin)) {
> +	if (gpio_is_valid(udc->vbus_pin))
>   		free_irq(gpio_to_irq(udc->vbus_pin), udc);
> -		gpio_free(udc->vbus_pin);
> -	}
>
>   	free_irq(irq, udc);
>   err_request_irq:
> @@ -2001,19 +2099,17 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
>   {
>   	struct usba_udc *udc;
>   	int i;
> -	struct usba_platform_data *pdata = pdev->dev.platform_data;
>
>   	udc = platform_get_drvdata(pdev);
>
>   	usb_del_gadget_udc(&udc->gadget);
>
> -	for (i = 1; i < pdata->num_ep; i++)
> +	for (i = 1; i < udc->num_ep; i++)
>   		usba_ep_cleanup_debugfs(&usba_ep[i]);
>   	usba_cleanup_debugfs(udc);
>
>   	if (gpio_is_valid(udc->vbus_pin)) {
>   		free_irq(gpio_to_irq(udc->vbus_pin), udc);
> -		gpio_free(udc->vbus_pin);
>   	}
>
>   	free_irq(udc->irq, udc);
> @@ -2026,11 +2122,21 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> +#if defined(CONFIG_OF)
> +static const struct of_device_id atmel_udc_dt_ids[] = {
> +	{ .compatible = "atmel,at91sam9rl-udc" },
> +	{ /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
> +#endif
> +
>   static struct platform_driver udc_driver = {
>   	.remove		= __exit_p(usba_udc_remove),
>   	.driver		= {
>   		.name		= "atmel_usba_udc",
>   		.owner		= THIS_MODULE,
> +		.of_match_table	= of_match_ptr(atmel_udc_dt_ids),
>   	},
>   };
>
> diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
> index d65a618..6999a26 100644
> --- a/drivers/usb/gadget/atmel_usba_udc.h
> +++ b/drivers/usb/gadget/atmel_usba_udc.h
> @@ -317,6 +317,7 @@ struct usba_udc {
>   	int irq;
>   	int vbus_pin;
>   	int vbus_pin_inverted;
> +	int num_ep;
>   	struct clk *pclk;
>   	struct clk *hclk;
>
>

Best Regards,
Bo Shen

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/5] usb: add Atmel USBA UDC DT support
@ 2013-05-20  3:26         ` Bo Shen
  0 siblings, 0 replies; 18+ messages in thread
From: Bo Shen @ 2013-05-20  3:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jean-Christophe,

On 5/17/2013 22:42, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Allow to compile the driver all the time if AT91 enabled.
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: linux-usb at vger.kernel.org
> ---
>   .../devicetree/bindings/usb/atmel-usb.txt          |   82 ++++++++
>   drivers/usb/gadget/Kconfig                         |    2 +-
>   drivers/usb/gadget/atmel_usba_udc.c                |  214 +++++++++++++++-----
>   drivers/usb/gadget/atmel_usba_udc.h                |    1 +
>   4 files changed, 244 insertions(+), 55 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
> index 60bd215..878556b2 100644
> --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
> +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
> @@ -47,3 +47,85 @@ usb1: gadget at fffa4000 {
>   	interrupts = <10 4>;
>   	atmel,vbus-gpio = <&pioC 5 0>;
>   };
> +
> +Atmel High-Speed USB device controller
> +
> +Required properties:
> + - compatible: Should be "atmel,at91sam9rl-udc"
> + - reg: Address and length of the register set for the device
> + - interrupts: Should contain macb interrupt

s/macb/udphs

> + - ep childnode: To specifiy the number of endpoints and their properties.

s/specifiy/specify

> +
> +Optional properties:
> + - atmel,vbus-gpio: If present, specifies a gpio that needs to be
> +   activated for the bus to be powered.
> +
> +Required child node properties:
> + - name: Name of the endpoint.
> + - reg: Num of the endpoint.
> + - atmel,fifo-size: Size of the fifo.
> + - atmel,nb-banks: Number of banks.
> + - atmel,can-dma: Boolean to specify if the endpoint support DMA.
> + - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
> +
> +usb2: gadget at fff78000 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "atmel,at91sam9rl-udc";
> +	reg = <0x00600000 0x80000
> +	       0xfff78000 0x400>;
> +	interrupts = <27 4>;

s/interrupts = <27 4>/interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;

> +	atmel,vbus-gpio = <&pioB 19 0>;
> +
> +	ep0 {
> +		reg = <0>;
> +		atmel,fifo-size = <64>;
> +		atmel,nb-banks = <1>;
> +	};
> +
> +	ep1 {
> +		reg = <1>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <2>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep2 {
> +		reg = <2>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <2>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep3 {
> +		reg = <3>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +	};
> +
> +	ep4 {
> +		reg = <4>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +	};
> +
> +	ep5 {
> +		reg = <5>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +
> +	ep6 {
> +		reg = <6>;
> +		atmel,fifo-size = <1024>;
> +		atmel,nb-banks = <3>;
> +		atmel,can-dma;
> +		atmel,can-isoc;
> +	};
> +};
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index 83300d9..5e47d50 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -156,7 +156,7 @@ config USB_LPC32XX
>
>   config USB_ATMEL_USBA
>   	tristate "Atmel USBA"
> -	depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
> +	depends on AVR32 || ARCH_AT91
>   	help
>   	  USBA is the integrated high-speed USB Device controller on
>   	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
> diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
> index f2a970f..b3084b9 100644
> --- a/drivers/usb/gadget/atmel_usba_udc.c
> +++ b/drivers/usb/gadget/atmel_usba_udc.c
> @@ -22,6 +22,8 @@
>   #include <linux/usb/atmel_usba_udc.h>
>   #include <linux/delay.h>
>   #include <linux/platform_data/atmel.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
>
>   #include <asm/gpio.h>
>
> @@ -1835,9 +1837,143 @@ static int atmel_usba_stop(struct usb_gadget *gadget,
>   	return 0;
>   }
>
> -static int __init usba_udc_probe(struct platform_device *pdev)
> +#ifdef CONFIG_OF
> +static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> +						    struct usba_udc *udc)
> +{
> +	u32 val;
> +	const char *name;
> +	enum of_gpio_flags flags;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct device_node *pp;
> +	int i, ret;
> +	struct usba_ep *eps, *ep;
> +
> +	udc->num_ep = 0;
> +
> +	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> +						&flags);
> +	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> +
> +	pp = NULL;
> +	while ((pp = of_get_next_child(np, pp)))
> +		udc->num_ep++;
> +
> +	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> +			   GFP_KERNEL);

Using devm_kzalloc will cause issue when build as modules, and load and 
unload this driver, the second time unload, it will come out following 
segment fault, log as following. Using kzalloc will fix it.

---8>---
Unable to handle kernel NULL pointer dereference at virtual address 00000054
pgd = c7bac000
[00000054] *pgd=27b6f831, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] ARM
Modules linked in: atmel_usba_udc(-) [last unloaded: atmel_usba_udc]
CPU: 0 PID: 519 Comm: rmmod Not tainted 3.10.0-rc1+ #13
task: c796d580 ti: c7b68000 task.ti: c7b68000
PC is at kfree+0x4c/0xb4
LR is at free_module+0xe4/0x168
pc : [<c007470c>]    lr : [<c0045884>]    psr: 40000093
sp : c7b69f10  ip : 00000010  fp : 00000000
r10: 00000000  r9 : c7b68000  r8 : c0009484
r7 : 00000000  r6 : c7ba0c00  r5 : a0000013  r4 : bf009240
r3 : c061d400  r2 : 00000000  r1 : 00007ba0  r0 : c7ba0c00
Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 27bac000  DAC: 00000015
Process rmmod (pid: 519, stack limit = 0xc7b681b8)
Stack: (0xc7b69f10 to 0xc7b6a000)
9f00:                                     0000000f bf009240 000000a8 
bf009288
9f20: c7afe6a8 c0045884 bf009240 00000000 00000013 becbfbd0 c0009484 
c0045c10
9f40: 00000000 656d7461 73755f6c 755f6162 b6006364 b6f1c000 c796d580 
b6f1c000
9f60: b6f1c000 c7afb140 00000000 becbf984 00005401 00000001 c7b68000 
00000000
9f80: bf009240 00000880 c7b69f8c 00000000 becbf9bc b6f0a380 00000880 
becbfbd0
9fa0: 00000081 c0009320 b6f0a380 00000880 becbfbd0 00000880 0000000e 
00000000
9fc0: b6f0a380 00000880 becbfbd0 00000081 0000009c 0000ce8c 0000b7f0 
00000000
9fe0: b6ebda20 becbfbc0 00019750 b6ebda2c a0000010 becbfbd0 00000000 
00000000
[<c007470c>] (kfree+0x4c/0xb4) from [<c0045884>] (free_module+0xe4/0x168)
[<c0045884>] (free_module+0xe4/0x168) from [<c0045c10>] 
(SyS_delete_module+0x1d8/0x210)
[<c0045c10>] (SyS_delete_module+0x1d8/0x210) from [<c0009320>] 
(ret_fast_syscall+0x0/0x2c)
Code: e7922281 e3120902 1593301c e593701c (e5974054)
---[ end trace cb98ff9cd16ea901 ]---
Segmentation fault
---<8---

> +	if (!eps)
> +		return ERR_PTR(-ENOMEM);
> +
> +	udc->gadget.ep0 = &eps[0].ep;
> +
> +	INIT_LIST_HEAD(&eps[0].ep.ep_list);
> +
> +	pp = NULL;
> +	i = 0;
> +	while ((pp = of_get_next_child(np, pp))) {
> +		ep = &eps[i];
> +
> +		ret = of_property_read_u32(pp, "reg", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->index = val;
> +
> +		ret = of_property_read_u32(pp, "atmel,fifo-size", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->fifo_size = val;
> +
> +		ret = of_property_read_u32(pp, "atmel,nb-banks", &val);
> +		if (ret) {
> +			dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret);
> +			goto err;
> +		}
> +		ep->nr_banks = val;
> +
> +		ep->can_dma = of_property_read_bool(pp, "atmel,can-dma");
> +		ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc");
> +
> +		ret = of_property_read_string(pp, "name", &name);
> +		ep->ep.name = name;
> +
> +		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> +		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> +		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> +		ep->ep.ops = &usba_ep_ops;
> +		ep->ep.maxpacket = ep->fifo_size;
> +		ep->udc = udc;
> +		INIT_LIST_HEAD(&ep->queue);
> +
> +		if (i)
> +			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +
> +		i++;
> +	}
> +
> +	return eps;
> +err:
> +	return ERR_PTR(ret);
> +}
> +#else
> +static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> +						    struct usba_udc *udc)
> +{
> +	return ERR_PTR(-ENOSYS);
> +}
> +#endif
> +
> +static struct usba_ep * usba_udc_pdata(struct platform_device *pdev,
> +						 struct usba_udc *udc)
>   {
>   	struct usba_platform_data *pdata = pdev->dev.platform_data;
> +	struct usba_ep *eps;
> +	int i;
> +
> +	if (!pdata)
> +		return ERR_PTR(-ENXIO);
> +
> +	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep,
> +			   GFP_KERNEL);
> +	if (!eps)
> +		return ERR_PTR(-ENOMEM);
> +
> +	udc->gadget.ep0 = &eps[0].ep;
> +
> +	udc->vbus_pin = pdata->vbus_pin;
> +	udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
> +	udc->num_ep = pdata->num_ep;
> +
> +	INIT_LIST_HEAD(&eps[0].ep.ep_list);
> +
> +	for (i = 0; i < pdata->num_ep; i++) {
> +		struct usba_ep *ep = &eps[i];
> +
> +		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> +		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> +		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> +		ep->ep.ops = &usba_ep_ops;
> +		ep->ep.name = pdata->ep[i].name;
> +		ep->fifo_size = ep->ep.maxpacket = pdata->ep[i].fifo_size;
> +		ep->udc = udc;
> +		INIT_LIST_HEAD(&ep->queue);
> +		ep->nr_banks = pdata->ep[i].nr_banks;
> +		ep->index = pdata->ep[i].index;
> +		ep->can_dma = pdata->ep[i].can_dma;
> +		ep->can_isoc = pdata->ep[i].can_isoc;
> +
> +		if (i)
> +			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +	}
> +
> +	return eps;
> +}
> +
> +static int __init usba_udc_probe(struct platform_device *pdev)
> +{
>   	struct resource *regs, *fifo;
>   	struct clk *pclk, *hclk;
>   	struct usba_udc *udc = &the_udc;
> @@ -1845,7 +1981,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>
>   	regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
>   	fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
> -	if (!regs || !fifo || !pdata)
> +	if (!regs || !fifo)
>   		return -ENXIO;
>
>   	irq = platform_get_irq(pdev, 0);
> @@ -1891,46 +2027,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
>   	clk_disable(pclk);
>
> -	usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
> -			  GFP_KERNEL);
> -	if (!usba_ep)
> -		goto err_alloc_ep;
> -
> -	the_udc.gadget.ep0 = &usba_ep[0].ep;
> -
> -	INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
> -	usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
> -	usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
> -	usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
> -	usba_ep[0].ep.ops = &usba_ep_ops;
> -	usba_ep[0].ep.name = pdata->ep[0].name;
> -	usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
> -	usba_ep[0].udc = &the_udc;
> -	INIT_LIST_HEAD(&usba_ep[0].queue);
> -	usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
> -	usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
> -	usba_ep[0].index = pdata->ep[0].index;
> -	usba_ep[0].can_dma = pdata->ep[0].can_dma;
> -	usba_ep[0].can_isoc = pdata->ep[0].can_isoc;
> -
> -	for (i = 1; i < pdata->num_ep; i++) {
> -		struct usba_ep *ep = &usba_ep[i];
> -
> -		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
> -		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
> -		ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
> -		ep->ep.ops = &usba_ep_ops;
> -		ep->ep.name = pdata->ep[i].name;
> -		ep->ep.maxpacket = pdata->ep[i].fifo_size;
> -		ep->udc = &the_udc;
> -		INIT_LIST_HEAD(&ep->queue);
> -		ep->fifo_size = pdata->ep[i].fifo_size;
> -		ep->nr_banks = pdata->ep[i].nr_banks;
> -		ep->index = pdata->ep[i].index;
> -		ep->can_dma = pdata->ep[i].can_dma;
> -		ep->can_isoc = pdata->ep[i].can_isoc;
> +	if (pdev->dev.of_node)
> +		usba_ep = atmel_udc_of_init(pdev, udc);
> +	else
> +		usba_ep = usba_udc_pdata(pdev, udc);
>
> -		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
> +	if (IS_ERR(usba_ep)) {
> +		ret = PTR_ERR(usba_ep);
> +		goto err_alloc_ep;
>   	}
>
>   	ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc);
> @@ -1941,16 +2045,12 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   	}
>   	udc->irq = irq;
>
> -	if (gpio_is_valid(pdata->vbus_pin)) {
> -		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
> -			udc->vbus_pin = pdata->vbus_pin;
> -			udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
> -
> +	if (gpio_is_valid(udc->vbus_pin)) {
> +		if (!devm_gpio_request(&pdev->dev, udc->vbus_pin, "atmel_usba_udc")) {
>   			ret = request_irq(gpio_to_irq(udc->vbus_pin),
>   					usba_vbus_irq, 0,
>   					"atmel_usba_udc", udc);
>   			if (ret) {
> -				gpio_free(udc->vbus_pin);
>   				udc->vbus_pin = -ENODEV;
>   				dev_warn(&udc->pdev->dev,
>   					 "failed to request vbus irq; "
> @@ -1969,16 +2069,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
>   		goto err_add_udc;
>
>   	usba_init_debugfs(udc);
> -	for (i = 1; i < pdata->num_ep; i++)
> +	for (i = 1; i < udc->num_ep; i++)
>   		usba_ep_init_debugfs(udc, &usba_ep[i]);
>
>   	return 0;
>
>   err_add_udc:
> -	if (gpio_is_valid(pdata->vbus_pin)) {
> +	if (gpio_is_valid(udc->vbus_pin))
>   		free_irq(gpio_to_irq(udc->vbus_pin), udc);
> -		gpio_free(udc->vbus_pin);
> -	}
>
>   	free_irq(irq, udc);
>   err_request_irq:
> @@ -2001,19 +2099,17 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
>   {
>   	struct usba_udc *udc;
>   	int i;
> -	struct usba_platform_data *pdata = pdev->dev.platform_data;
>
>   	udc = platform_get_drvdata(pdev);
>
>   	usb_del_gadget_udc(&udc->gadget);
>
> -	for (i = 1; i < pdata->num_ep; i++)
> +	for (i = 1; i < udc->num_ep; i++)
>   		usba_ep_cleanup_debugfs(&usba_ep[i]);
>   	usba_cleanup_debugfs(udc);
>
>   	if (gpio_is_valid(udc->vbus_pin)) {
>   		free_irq(gpio_to_irq(udc->vbus_pin), udc);
> -		gpio_free(udc->vbus_pin);
>   	}
>
>   	free_irq(udc->irq, udc);
> @@ -2026,11 +2122,21 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> +#if defined(CONFIG_OF)
> +static const struct of_device_id atmel_udc_dt_ids[] = {
> +	{ .compatible = "atmel,at91sam9rl-udc" },
> +	{ /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
> +#endif
> +
>   static struct platform_driver udc_driver = {
>   	.remove		= __exit_p(usba_udc_remove),
>   	.driver		= {
>   		.name		= "atmel_usba_udc",
>   		.owner		= THIS_MODULE,
> +		.of_match_table	= of_match_ptr(atmel_udc_dt_ids),
>   	},
>   };
>
> diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
> index d65a618..6999a26 100644
> --- a/drivers/usb/gadget/atmel_usba_udc.h
> +++ b/drivers/usb/gadget/atmel_usba_udc.h
> @@ -317,6 +317,7 @@ struct usba_udc {
>   	int irq;
>   	int vbus_pin;
>   	int vbus_pin_inverted;
> +	int num_ep;
>   	struct clk *pclk;
>   	struct clk *hclk;
>
>

Best Regards,
Bo Shen

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

* Re: [PATCH 1/5] usb: add Atmel USBA UDC DT support
  2013-05-20  3:26         ` Bo Shen
@ 2013-05-20 10:12             ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-20 10:12 UTC (permalink / raw)
  To: Bo Shen
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

> >
> >-static int __init usba_udc_probe(struct platform_device *pdev)
> >+#ifdef CONFIG_OF
> >+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> >+						    struct usba_udc *udc)
> >+{
> >+	u32 val;
> >+	const char *name;
> >+	enum of_gpio_flags flags;
> >+	struct device_node *np = pdev->dev.of_node;
> >+	struct device_node *pp;
> >+	int i, ret;
> >+	struct usba_ep *eps, *ep;
> >+
> >+	udc->num_ep = 0;
> >+
> >+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> >+						&flags);
> >+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> >+
> >+	pp = NULL;
> >+	while ((pp = of_get_next_child(np, pp)))
> >+		udc->num_ep++;
> >+
> >+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> >+			   GFP_KERNEL);
> 
> Using devm_kzalloc will cause issue when build as modules, and load
> and unload this driver, the second time unload, it will come out
> following segment fault, log as following. Using kzalloc will fix
> it.

no devm_kzalloc is the right one to use

if there is a this not in the drivers and kzalloc is not the solution
we need to find the real reason as devm_xxx are used everywhere by now

Best Regards,
J.

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

* [PATCH 1/5] usb: add Atmel USBA UDC DT support
@ 2013-05-20 10:12             ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-20 10:12 UTC (permalink / raw)
  To: linux-arm-kernel

> >
> >-static int __init usba_udc_probe(struct platform_device *pdev)
> >+#ifdef CONFIG_OF
> >+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> >+						    struct usba_udc *udc)
> >+{
> >+	u32 val;
> >+	const char *name;
> >+	enum of_gpio_flags flags;
> >+	struct device_node *np = pdev->dev.of_node;
> >+	struct device_node *pp;
> >+	int i, ret;
> >+	struct usba_ep *eps, *ep;
> >+
> >+	udc->num_ep = 0;
> >+
> >+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> >+						&flags);
> >+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> >+
> >+	pp = NULL;
> >+	while ((pp = of_get_next_child(np, pp)))
> >+		udc->num_ep++;
> >+
> >+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> >+			   GFP_KERNEL);
> 
> Using devm_kzalloc will cause issue when build as modules, and load
> and unload this driver, the second time unload, it will come out
> following segment fault, log as following. Using kzalloc will fix
> it.

no devm_kzalloc is the right one to use

if there is a this not in the drivers and kzalloc is not the solution
we need to find the real reason as devm_xxx are used everywhere by now

Best Regards,
J.

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

* Re: [PATCH 1/5] usb: add Atmel USBA UDC DT support
  2013-05-20 10:12             ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-05-20 15:44                 ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-20 15:44 UTC (permalink / raw)
  To: Bo Shen
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 12:12 Mon 20 May     , Jean-Christophe PLAGNIOL-VILLARD wrote:
> > >
> > >-static int __init usba_udc_probe(struct platform_device *pdev)
> > >+#ifdef CONFIG_OF
> > >+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> > >+						    struct usba_udc *udc)
> > >+{
> > >+	u32 val;
> > >+	const char *name;
> > >+	enum of_gpio_flags flags;
> > >+	struct device_node *np = pdev->dev.of_node;
> > >+	struct device_node *pp;
> > >+	int i, ret;
> > >+	struct usba_ep *eps, *ep;
> > >+
> > >+	udc->num_ep = 0;
> > >+
> > >+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> > >+						&flags);
> > >+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> > >+
> > >+	pp = NULL;
> > >+	while ((pp = of_get_next_child(np, pp)))
> > >+		udc->num_ep++;
> > >+
> > >+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> > >+			   GFP_KERNEL);
> > 
> > Using devm_kzalloc will cause issue when build as modules, and load
> > and unload this driver, the second time unload, it will come out
> > following segment fault, log as following. Using kzalloc will fix
> > it.
> 
> no devm_kzalloc is the right one to use
> 
> if there is a this not in the drivers and kzalloc is not the solution
> we need to find the real reason as devm_xxx are used everywhere by now

The issue come from that the current driver have some hack that forbiden
multi-instance

I'll drop that

so yes devm_kzalloc is the right alloc to use

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

* [PATCH 1/5] usb: add Atmel USBA UDC DT support
@ 2013-05-20 15:44                 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 18+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-20 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 12:12 Mon 20 May     , Jean-Christophe PLAGNIOL-VILLARD wrote:
> > >
> > >-static int __init usba_udc_probe(struct platform_device *pdev)
> > >+#ifdef CONFIG_OF
> > >+static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
> > >+						    struct usba_udc *udc)
> > >+{
> > >+	u32 val;
> > >+	const char *name;
> > >+	enum of_gpio_flags flags;
> > >+	struct device_node *np = pdev->dev.of_node;
> > >+	struct device_node *pp;
> > >+	int i, ret;
> > >+	struct usba_ep *eps, *ep;
> > >+
> > >+	udc->num_ep = 0;
> > >+
> > >+	udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
> > >+						&flags);
> > >+	udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
> > >+
> > >+	pp = NULL;
> > >+	while ((pp = of_get_next_child(np, pp)))
> > >+		udc->num_ep++;
> > >+
> > >+	eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
> > >+			   GFP_KERNEL);
> > 
> > Using devm_kzalloc will cause issue when build as modules, and load
> > and unload this driver, the second time unload, it will come out
> > following segment fault, log as following. Using kzalloc will fix
> > it.
> 
> no devm_kzalloc is the right one to use
> 
> if there is a this not in the drivers and kzalloc is not the solution
> we need to find the real reason as devm_xxx are used everywhere by now

The issue come from that the current driver have some hack that forbiden
multi-instance

I'll drop that

so yes devm_kzalloc is the right alloc to use

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

end of thread, other threads:[~2013-05-20 15:44 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-17 14:14 [PATCH 0/5 v3] ARM: at91: dt: add USBA support Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:14 ` Jean-Christophe PLAGNIOL-VILLARD
     [not found] ` <20130517141443.GB16804-RQcB7r2h9QmfDR2tN2SG5Ni2O/JbrIOy@public.gmane.org>
2013-05-17 14:42   ` [PATCH 1/5] usb: add Atmel USBA UDC DT support Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42     ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42     ` [PATCH 2/5] ARM: at91: sam9x5 add udc " Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42     ` [PATCH 3/5] ARM: at91: sam9x5ek " Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42     ` [PATCH 4/5] ARM: at91: sam9g45 " Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42     ` [PATCH 5/5] ARM: at91: sam9m10g45ek " Jean-Christophe PLAGNIOL-VILLARD
2013-05-17 14:42       ` Jean-Christophe PLAGNIOL-VILLARD
     [not found]     ` <1368801730-31383-1-git-send-email-plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>
2013-05-20  3:26       ` [PATCH 1/5] usb: add Atmel USBA UDC " Bo Shen
2013-05-20  3:26         ` Bo Shen
     [not found]         ` <519997CA.8010503-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
2013-05-20 10:12           ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-20 10:12             ` Jean-Christophe PLAGNIOL-VILLARD
     [not found]             ` <20130520101237.GA9937-RQcB7r2h9QmfDR2tN2SG5Ni2O/JbrIOy@public.gmane.org>
2013-05-20 15:44               ` Jean-Christophe PLAGNIOL-VILLARD
2013-05-20 15:44                 ` Jean-Christophe PLAGNIOL-VILLARD

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.