From 2cac291533d401ced0d24a9fbb46675929d4327f Mon Sep 17 00:00:00 2001
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Thu, 14 Jun 2007 17:37:31 +0200
Subject: [PATCH 3/3] AVR32: Wire up USBA device

Implement at32_add_device_usba() and use it to wire up the USBA device
on ATSTK1000 and ATNGW100.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 arch/avr32/boards/atngw100/setup.c      |    1 +
 arch/avr32/boards/atstk1000/atstk1002.c |    1 +
 arch/avr32/mach-at32ap/at32ap7000.c     |   68 +++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 9bc37d4..0f30161 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -118,6 +118,7 @@ static int __init atngw100_init(void)
 	set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
 
 	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+	at32_add_device_usba(0, NULL);
 
 	return 0;
 }
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index fe1dbe2..daa07b5 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -151,6 +151,7 @@ static int __init atstk1002_init(void)
 	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
 	at32_add_device_lcdc(0, &atstk1000_lcdc_data,
 			     fbmem_start, fbmem_size);
+	at32_add_device_usba(0, NULL);
 
 	return 0;
 }
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index 1d2bf34..8143aee 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -1001,6 +1001,74 @@ err_dup_modedb:
 }
 
 /* --------------------------------------------------------------------
+ *  USB Device Controller
+ * -------------------------------------------------------------------- */
+static struct resource usba0_resource[] __initdata = {
+	{
+		.name		= "fifo",
+		.start		= 0xff300000,
+		.end		= 0xff3fffff,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.name		= "regs",
+		.start		= 0xfff03000,
+		.end		= 0xfff033ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	IRQ(31),
+};
+static struct clk usba0_pclk = {
+	.name		= "pclk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 12,
+};
+static struct clk usba0_hclk = {
+	.name		= "hclk",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.index		= 6,
+};
+
+struct platform_device *__init
+at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_usba_udc", 0);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, usba0_resource,
+					  ARRAY_SIZE(usba0_resource)))
+		goto out_free_pdev;
+
+	if (data) {
+		if (platform_device_add_data(pdev, data, sizeof(*data)))
+			goto out_free_pdev;
+
+		if (data->vbus_pin != GPIO_PIN_NONE)
+			at32_select_gpio(data->vbus_pin, 0);
+	}
+
+	usba0_pclk.dev = &pdev->dev;
+	usba0_hclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+
+	return pdev;
+
+out_free_pdev:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
  *  GCLK
  * -------------------------------------------------------------------- */
 static struct clk gclk0 = {
-- 
1.5.2.1

