linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V6 00/17] Adding devices support for all spear machines
@ 2011-03-01 11:27 Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 01/17] ST SPEAr13xx: Added ARM PL061 GPIO Support Viresh Kumar
                   ` (16 more replies)
  0 siblings, 17 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds device drivers and their machine support for all SPEAr
Families.

Note: These patches were earlier sent as part of a larger patchset:
"Updating SPEAr Support"

Now it is divided into smaller patchsets. In order to apply these patches
cleanly following order of patchsets must be maintained.
- SPEAr3xx & SPEAr6xx Fixes
- SPEAr3xx & SPEAr6xx: Single Image solution and padmux updates
- Adding SPEAr13xx support
- Adding devices support for all spear machines
- Clock Framework & CPU Freq Updates

Deepak Sikri (2):
  ST SPEAr: Adding machine support for USB host
  ST SPEAr Power Management: Added the support for Standby mode.

Pratyush Anand (1):
  ST SPEAr13xx: Added PCIe host controller base driver support.

Rajeev Kumar (3):
  ST SPEAr: Adding machine support for rtc-spear
  ST SPEAr: adding support for synopsis i2c designware
  ST SPEAr: Adding machine support for keyboard

Vipin Kumar (2):
  ST SPEAr3xx: EMI (External Memory Interface) controller driver
  ST SPEAr: Adding machine support for nand

Viresh Kumar (9):
  ST SPEAr13xx: Added ARM PL061 GPIO Support
  ST SPEAr: Adding PLGPIO driver for spear platform
  ST SPEAr3xx: Adding support for ST's PWM IP
  ST SPEAr: Adding Watchdog support on spear3xx & spear6xx machines
  ST SPEAr3xx: Adding RAS uart devices
  ST SPEAr320: Adding support for CAN
  ST SPEAr: Adding support for SSP PL022
  ST SPEAr: Adding support for SDHCI (SDIO)
  ST SPEAr: Updating defconfigs

 arch/arm/Kconfig                                |    1 +
 arch/arm/configs/spear13xx_defconfig            |   78 ++-
 arch/arm/configs/spear3xx_defconfig             |   80 ++-
 arch/arm/configs/spear6xx_defconfig             |   72 ++-
 arch/arm/mach-spear13xx/Makefile                |    2 +
 arch/arm/mach-spear13xx/include/mach/generic.h  |   15 +
 arch/arm/mach-spear13xx/include/mach/gpio.h     |   18 +
 arch/arm/mach-spear13xx/include/mach/hardware.h |    7 +
 arch/arm/mach-spear13xx/include/mach/irqs.h     |   27 +-
 arch/arm/mach-spear13xx/include/mach/pcie.h     |  170 +++++
 arch/arm/mach-spear13xx/include/mach/suspend.h  |   47 ++
 arch/arm/mach-spear13xx/pcie.c                  |  861 +++++++++++++++++++++++
 arch/arm/mach-spear13xx/pm.c                    |  107 +++
 arch/arm/mach-spear13xx/sleep.S                 |  435 ++++++++++++
 arch/arm/mach-spear13xx/spear1300_evb.c         |   90 +++
 arch/arm/mach-spear13xx/spear1310.c             |   22 +
 arch/arm/mach-spear13xx/spear1310_evb.c         |   91 +++
 arch/arm/mach-spear13xx/spear13xx.c             |  355 ++++++++++
 arch/arm/mach-spear3xx/Makefile                 |    4 +
 arch/arm/mach-spear3xx/emi.c                    |   98 +++
 arch/arm/mach-spear3xx/include/mach/emi.h       |   61 ++
 arch/arm/mach-spear3xx/include/mach/generic.h   |   35 +
 arch/arm/mach-spear3xx/include/mach/gpio.h      |  143 ++++
 arch/arm/mach-spear3xx/include/mach/spear310.h  |    9 +
 arch/arm/mach-spear3xx/include/mach/spear320.h  |    6 +
 arch/arm/mach-spear3xx/include/mach/suspend.h   |   44 ++
 arch/arm/mach-spear3xx/spear300.c               |  146 ++++
 arch/arm/mach-spear3xx/spear300_evb.c           |   85 +++
 arch/arm/mach-spear3xx/spear310.c               |  155 ++++
 arch/arm/mach-spear3xx/spear310_evb.c           |  102 +++
 arch/arm/mach-spear3xx/spear320.c               |  216 ++++++
 arch/arm/mach-spear3xx/spear320_evb.c           |   92 +++
 arch/arm/mach-spear3xx/spear3xx.c               |  168 +++++-
 arch/arm/mach-spear6xx/include/mach/generic.h   |   10 +
 arch/arm/mach-spear6xx/include/mach/gpio.h      |   27 +
 arch/arm/mach-spear6xx/include/mach/suspend.h   |   44 ++
 arch/arm/mach-spear6xx/spear600_evb.c           |   37 +
 arch/arm/mach-spear6xx/spear6xx.c               |  260 +++++++-
 arch/arm/plat-spear/Kconfig                     |    9 +
 arch/arm/plat-spear/Makefile                    |   17 +
 arch/arm/plat-spear/i2c_eval_board.c            |   29 +
 arch/arm/plat-spear/include/plat/gpio.h         |   35 +
 arch/arm/plat-spear/include/plat/keyboard.h     |    7 -
 arch/arm/plat-spear/include/plat/spi.h          |   74 ++
 arch/arm/plat-spear/plgpio.c                    |  473 +++++++++++++
 arch/arm/plat-spear/pm.c                        |  104 +++
 arch/arm/plat-spear/pwm.c                       |  484 +++++++++++++
 arch/arm/plat-spear/sleep.S                     |  288 ++++++++
 48 files changed, 5711 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/include/mach/pcie.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/suspend.h
 create mode 100644 arch/arm/mach-spear13xx/pcie.c
 create mode 100644 arch/arm/mach-spear13xx/pm.c
 create mode 100644 arch/arm/mach-spear13xx/sleep.S
 create mode 100644 arch/arm/mach-spear3xx/emi.c
 create mode 100644 arch/arm/mach-spear3xx/include/mach/emi.h
 create mode 100644 arch/arm/mach-spear3xx/include/mach/suspend.h
 create mode 100644 arch/arm/mach-spear6xx/include/mach/suspend.h
 create mode 100644 arch/arm/plat-spear/i2c_eval_board.c
 create mode 100644 arch/arm/plat-spear/include/plat/spi.h
 create mode 100644 arch/arm/plat-spear/plgpio.c
 create mode 100644 arch/arm/plat-spear/pm.c
 create mode 100644 arch/arm/plat-spear/pwm.c
 create mode 100644 arch/arm/plat-spear/sleep.S

-- 
1.7.2.2

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

* [PATCH V6 01/17] ST SPEAr13xx: Added ARM PL061 GPIO Support
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support Viresh Kumar
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/include/mach/gpio.h    |   18 +++++++++++
 arch/arm/mach-spear13xx/include/mach/irqs.h    |   10 +++++-
 arch/arm/mach-spear13xx/spear1300_evb.c        |    2 +
 arch/arm/mach-spear13xx/spear1310_evb.c        |    2 +
 arch/arm/mach-spear13xx/spear13xx.c            |   38 ++++++++++++++++++++++++
 6 files changed, 70 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index a75de93..de9de17 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -221,6 +221,7 @@ extern struct pmx_dev pmx_uart1_modem;
 #define SPEAR_GPT0_CHAN1_IRQ	IRQ_GPT0_TMR1
 
 /* Add spear13xx family device structure declarations here */
+extern struct amba_device spear13xx_gpio_device[];
 extern struct amba_device spear13xx_uart_device;
 extern struct sys_timer spear13xx_timer;
 
diff --git a/arch/arm/mach-spear13xx/include/mach/gpio.h b/arch/arm/mach-spear13xx/include/mach/gpio.h
index 43fa541..2f8ad23 100644
--- a/arch/arm/mach-spear13xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear13xx/include/mach/gpio.h
@@ -16,4 +16,22 @@
 
 #include <plat/gpio.h>
 
+#define GPIO0_0			0
+#define GPIO0_1			1
+#define GPIO0_2			2
+#define GPIO0_3			3
+#define GPIO0_4			4
+#define GPIO0_5			5
+#define GPIO0_6			6
+#define GPIO0_7			7
+
+#define GPIO1_0			8
+#define GPIO1_1			9
+#define GPIO1_2			10
+#define GPIO1_3			11
+#define GPIO1_4			12
+#define GPIO1_5			13
+#define GPIO1_6			14
+#define GPIO1_7			15
+
 #endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index c175175..c4f0c9d 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -123,6 +123,14 @@
 
 #define IRQ_GIC_END		(IRQ_SHPI_START + 128)
 
-#define NR_IRQS			IRQ_GIC_END
+#define VIRQ_START		IRQ_GIC_END
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO0_INT_BASE	(VIRQ_START + 0)
+#define SPEAR_GPIO1_INT_BASE	(SPEAR_GPIO0_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END	(SPEAR_GPIO1_INT_BASE + 8)
+
+#define VIRQ_END		SPEAR_GPIO_INT_END
+#define NR_IRQS			VIRQ_END
 
 #endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 2e966cf..cba0fee 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -37,6 +37,8 @@ static struct pmx_dev *pmx_devs[] = {
 };
 
 static struct amba_device *amba_devs[] __initdata = {
+	&spear13xx_gpio_device[0],
+	&spear13xx_gpio_device[1],
 	&spear13xx_uart_device,
 };
 
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 42625c8..62af911 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -44,6 +44,8 @@ static struct pmx_dev *pmx_devs[] = {
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
+	&spear13xx_gpio_device[0],
+	&spear13xx_gpio_device[1],
 	&spear13xx_uart_device,
 
 	/* spear1310 specific devices */
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 7832c1a..35582a6 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/amba/pl061.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
 #include <asm/hardware/gic.h>
@@ -25,6 +26,43 @@
 #include <mach/irqs.h>
 
 /* Add spear13xx machines common devices here */
+/* gpio device registeration */
+static struct pl061_platform_data gpio_plat_data[] = {
+	{
+		.gpio_base	= 0,
+		.irq_base	= SPEAR_GPIO0_INT_BASE,
+	}, {
+		.gpio_base	= 8,
+		.irq_base	= SPEAR_GPIO1_INT_BASE,
+	},
+};
+
+struct amba_device spear13xx_gpio_device[] = {
+	{
+		.dev = {
+			.init_name = "gpio0",
+			.platform_data = &gpio_plat_data[0],
+		},
+		.res = {
+			.start = SPEAR13XX_GPIO0_BASE,
+			.end = SPEAR13XX_GPIO0_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_GPIO0, NO_IRQ},
+	}, {
+		.dev = {
+			.init_name = "gpio1",
+			.platform_data = &gpio_plat_data[1],
+		},
+		.res = {
+			.start = SPEAR13XX_GPIO1_BASE,
+			.end = SPEAR13XX_GPIO1_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_GPIO1, NO_IRQ},
+	}
+};
+
 /* uart device registeration */
 struct amba_device spear13xx_uart_device = {
 	.dev = {
-- 
1.7.2.2

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

* [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support.
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 01/17] ST SPEAr13xx: Added ARM PL061 GPIO Support Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 15:10   ` Arnd Bergmann
  2011-03-01 11:27 ` [PATCH V6 03/17] ST SPEAr: Adding PLGPIO driver for spear platform Viresh Kumar
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr13xx family contains Synopsys designware PCIe version 3.30a. This
patch adds support for this PCIe module for spear platform.

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/Kconfig                                |    1 +
 arch/arm/mach-spear13xx/Makefile                |    1 +
 arch/arm/mach-spear13xx/include/mach/hardware.h |    7 +
 arch/arm/mach-spear13xx/include/mach/irqs.h     |   19 +-
 arch/arm/mach-spear13xx/include/mach/pcie.h     |  170 +++++
 arch/arm/mach-spear13xx/pcie.c                  |  861 +++++++++++++++++++++++
 arch/arm/mach-spear13xx/spear1300_evb.c         |   31 +
 arch/arm/mach-spear13xx/spear1310_evb.c         |   31 +
 arch/arm/mach-spear13xx/spear13xx.c             |   28 +
 arch/arm/plat-spear/Kconfig                     |    2 +
 10 files changed, 1150 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/include/mach/pcie.h
 create mode 100644 arch/arm/mach-spear13xx/pcie.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d9efe86..0aca70d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1263,6 +1263,7 @@ config PCI_HOST_ITE8152
 	select DMABOUNCE
 
 source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
index 24bbe16..2a113b0 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -7,6 +7,7 @@ obj-y					+= spear13xx.o clock.o
 obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
+obj-$(CONFIG_PCIEPORTBUS)		+= pcie.o
 
 # spear1300 specific files
 obj-$(CONFIG_MACH_SPEAR1300)		+= spear1300.o
diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
index fd8c2dc..c3fb454 100644
--- a/arch/arm/mach-spear13xx/include/mach/hardware.h
+++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
@@ -28,4 +28,11 @@
 /* typesafe io address */
 #define __io_address(n)		__io(IO_ADDRESS(n))
 
+#if defined(CONFIG_PCI)
+#define PCIBIOS_MIN_IO		0
+#define PCIBIOS_MIN_MEM		0
+#define pcibios_assign_all_busses()	0
+#endif
+
+
 #endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index c4f0c9d..59bf61a 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -130,7 +130,24 @@
 #define SPEAR_GPIO1_INT_BASE	(SPEAR_GPIO0_INT_BASE + 8)
 #define SPEAR_GPIO_INT_END	(SPEAR_GPIO1_INT_BASE + 8)
 
-#define VIRQ_END		SPEAR_GPIO_INT_END
+/* PCIE MSI virtual irqs */
+#define SPEAR_NUM_MSI_IRQS	64
+#define SPEAR_MSI0_INT_BASE	(SPEAR_GPIO_INT_END + 0)
+#define SPEAR_MSI0_INT_END	(SPEAR_MSI0_INT_BASE + SPEAR_NUM_MSI_IRQS)
+#define SPEAR_MSI1_INT_BASE	(SPEAR_MSI0_INT_END + 0)
+#define SPEAR_MSI1_INT_END	(SPEAR_MSI1_INT_BASE + SPEAR_NUM_MSI_IRQS)
+#define SPEAR_MSI2_INT_BASE	(SPEAR_MSI1_INT_END + 0)
+#define SPEAR_MSI2_INT_END	(SPEAR_MSI2_INT_BASE + SPEAR_NUM_MSI_IRQS)
+
+#define SPEAR_NUM_INTX_IRQS	4
+#define SPEAR_INTX0_BASE	(SPEAR_MSI2_INT_END + 0)
+#define SPEAR_INTX0_END		(SPEAR_INTX0_BASE + SPEAR_NUM_INTX_IRQS)
+#define SPEAR_INTX1_BASE	(SPEAR_INTX0_END + 0)
+#define SPEAR_INTX1_END		(SPEAR_INTX1_BASE + SPEAR_NUM_INTX_IRQS)
+#define SPEAR_INTX2_BASE	(SPEAR_INTX1_END + 0)
+#define SPEAR_INTX2_END		(SPEAR_INTX2_BASE + SPEAR_NUM_INTX_IRQS)
+
+#define VIRQ_END		SPEAR_INTX2_END
 #define NR_IRQS			VIRQ_END
 
 #endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/pcie.h b/arch/arm/mach-spear13xx/include/mach/pcie.h
new file mode 100644
index 0000000..fa302e5
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/pcie.h
@@ -0,0 +1,170 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/pcie.h
+ *
+ * Spear SoC PCIe handling.
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_PCIE_H
+#define __MACH_PCIE_H
+
+extern int (*pcie_port_is_host)(int port);
+extern int enable_pcie0_clk(void);
+
+
+struct pcie_port {
+	u8			port;
+	u8			root_bus_nr;
+	void __iomem		*base;
+	void __iomem		*app_base;
+	void __iomem		*va_app_base;
+	void __iomem		*va_dbi_base;
+	void __iomem		*va_cfg0_base;
+	spinlock_t		conf_lock;
+	char			mem_space_name[16];
+	char			io_space_name[16];
+	struct resource		res[2];
+};
+
+struct pcie_app_reg {
+	u32	app_ctrl_0;		/*cr0*/
+	u32	app_ctrl_1;		/*cr1*/
+	u32	app_status_0;		/*cr2*/
+	u32	app_status_1;		/*cr3*/
+	u32	msg_status;		/*cr4*/
+	u32	msg_payload;		/*cr5*/
+	u32	int_sts;		/*cr6*/
+	u32	int_clr;		/*cr7*/
+	u32	int_mask;		/*cr8*/
+	u32	mst_bmisc;		/*cr9*/
+	u32	phy_ctrl;		/*cr10*/
+	u32	phy_status;		/*cr11*/
+	u32	cxpl_debug_info_0;	/*cr12*/
+	u32	cxpl_debug_info_1;	/*cr13*/
+	u32	ven_msg_ctrl_0;		/*cr14*/
+	u32	ven_msg_ctrl_1;		/*cr15*/
+	u32	ven_msg_data_0;		/*cr16*/
+	u32	ven_msg_data_1;		/*cr17*/
+	u32	ven_msi_0;		/*cr18*/
+	u32	ven_msi_1;		/*cr19*/
+	u32	mst_rmisc;		/*cr 20*/
+	u32	slv_awmisc;		/*cr 21*/
+	u32	slv_armisc;		/*cr 22*/
+	u32	pom0_mem_addr_start;	/*cr23*/
+	u32	pom1_mem_addr_start;	/*cr24*/
+	u32	pom_io_addr_start;	/*cr25*/
+	u32	pom_cfg0_addr_start;	/*cr26*/
+	u32	pom_cfg1_addr_start;	/*cr27*/
+	u32	in0_mem_addr_start;	/*cr28*/
+	u32	in1_mem_addr_start;	/*cr29*/
+	u32	in_io_addr_start;	/*cr30*/
+	u32	in_cfg0_addr_start;	/*cr31*/
+	u32	in_cfg1_addr_start;	/*cr32*/
+	u32	in_msg_addr_start;	/*cr33*/
+	u32	in0_mem_addr_limit;	/*cr34*/
+	u32	in1_mem_addr_limit;	/*cr35*/
+	u32	in_io_addr_limit;	/*cr36*/
+	u32	in_cfg0_addr_limit;	/*cr37*/
+	u32	in_cfg1_addr_limit;	/*cr38*/
+	u32	in_msg_addr_limit;	/*cr39*/
+	u32	mem0_addr_offset_limit;	/*cr40*/
+	u32	pim0_mem_addr_start;	/*cr41*/
+	u32	pim1_mem_addr_start;	/*cr42*/
+	u32	pim_io_addr_start;	/*cr43*/
+	u32	pim_rom_addr_start;	/*cr44*/
+};
+
+/*CR0 ID*/
+#define RX_LANE_FLIP_EN_ID	0
+#define TX_LANE_FLIP_EN_ID	1
+#define SYS_AUX_PWR_DET_ID	2
+#define APP_LTSSM_ENABLE_ID	3
+#define SYS_ATTEN_BUTTON_PRESSED_ID	4
+#define SYS_MRL_SENSOR_STATE_ID 5
+#define SYS_PWR_FAULT_DET_ID	6
+#define SYS_MRL_SENSOR_CHGED_ID 7
+#define SYS_PRE_DET_CHGED_ID	8
+#define SYS_CMD_CPLED_INT_ID	9
+#define APP_INIT_RST_0_ID	11
+#define APP_REQ_ENTR_L1_ID	12
+#define APP_READY_ENTR_L23_ID	13
+#define APP_REQ_EXIT_L1_ID	14
+#define DEVICE_TYPE_EP		(0 << 25)
+#define DEVICE_TYPE_LEP		(1 << 25)
+#define DEVICE_TYPE_RC		(4 << 25)
+#define SYS_INT_ID		29
+#define MISCTRL_EN_ID		30
+#define REG_TRANSLATION_ENABLE	31
+
+/*CR1 ID*/
+#define APPS_PM_XMT_TURNOFF_ID	2
+#define APPS_PM_XMT_PME_ID	5
+
+/*CR3 ID*/
+#define XMLH_LTSSM_STATE_ID	0
+#define XMLH_LTSSM_STATE_L0	((u32)0x11 << XMLH_LTSSM_STATE_ID)
+#define XMLH_LTSSM_STATE_MASK	((u32)0x1F << XMLH_LTSSM_STATE_ID)
+#define XMLH_LINK_UP_ID	5
+
+/*CR4 ID*/
+#define CFG_MSI_EN_ID	18
+
+/*CR6*/
+#define INTA_CTRL_INT	(1 << 7)
+#define INTB_CTRL_INT	(1 << 8)
+#define INTC_CTRL_INT	(1 << 9)
+#define INTD_CTRL_INT	(1 << 10)
+#define MSI_CTRL_INT	(1 << 26)
+
+/*CR19 ID*/
+#define VEN_MSI_REQ_ID	11
+#define VEN_MSI_FUN_NUM_ID	8
+#define VEN_MSI_TC_ID	5
+#define VEN_MSI_VECTOR_ID	0
+#define VEN_MSI_REQ_EN	((u32)0x1 << VEN_MSI_REQ_ID)
+#define VEN_MSI_FUN_NUM_MASK	((u32)0x7 << VEN_MSI_FUN_NUM_ID)
+#define VEN_MSI_TC_MASK	((u32)0x7 << VEN_MSI_TC_ID)
+#define VEN_MSI_VECTOR_MASK	((u32)0x1F << VEN_MSI_VECTOR_ID)
+#endif
+
+/*CE21-22 ID*/
+/*ID definitio of ARMISC*/
+#define AXI_OP_TYPE_ID	0
+#define AXI_OP_BCM_ID	5
+#define AXI_OP_EP_ID	6
+#define AXI_OP_TD_ID	7
+#define AXI_OP_ATTRIBUTE_ID	8
+#define AXI_OP_TC_ID	10
+#define AXI_OP_MSG_CODE_ID	13
+#define AXI_OP_DBI_ACCESS_ID	21
+#define AXI_OP_TYPE_MASK	0x1F
+#define AXI_OP_TYPE_MEM_RDRW	0
+#define AXI_OP_TYPE_MEM_RDRW_LOCKED	1
+#define AXI_OP_TYPE_IO_RDRW	2
+#define AXI_OP_TYPE_CONFIG_RDRW_TYPE0	4
+#define AXI_OP_TYPE_CONFIG_RDRW_TYPE1	5
+#define AXI_OP_TYPE_MSG_REQ	16
+#define AXI_OP_TYPE_COMPLETION	10
+#define AXI_OP_TYPE_COMPLETION_LOCKED	11
+#define AXI_OP_TYPE_DBI_ELBI_ENABLE	1
+
+/* synopsis specific PCIE configuration registers*/
+#define PCIE_MSI_ADDR_LO	0x820	/* 32 bits */
+#define PCIE_MSI_ADDR_HI	0x824	/* 32 bits */
+#define PCIE_MSI_INTR0_ENABLE	0x828	/* 32 bits */
+#define PCIE_MSI_INTR0_MASK	0x82C	/* 32 bits */
+#define PCIE_MSI_INTR0_STATUS	0x830	/* 32 bits */
+
+/*BAR MASK registers*/
+#define PCIE_BAR0_MASK_REG	0x1010
+
+static inline void pcie_init(int (*fptr)(int port))
+{
+	pcie_port_is_host = fptr;
+}
diff --git a/arch/arm/mach-spear13xx/pcie.c b/arch/arm/mach-spear13xx/pcie.c
new file mode 100644
index 0000000..3528830
--- /dev/null
+++ b/arch/arm/mach-spear13xx/pcie.c
@@ -0,0 +1,861 @@
+/*
+ * arch/arm/mach-spear13xx/pcie.c
+ *
+ * PCIe functions for SPEAr 13xx SoCs
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/mbus.h>
+#include <linux/sched.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/pci.h>
+#include <mach/misc_regs.h>
+#include <mach/pcie.h>
+
+#define NUM_PCIE_PORTS	3
+
+/* Sum of all these space can maximum be 256MB*/
+#define IN0_MEM_SIZE	(200 * 1024 * 1024 - 1)
+/* In current implementation address translation is done using IN0 only.
+ * So IN1 start address and IN0 end address has been kept same
+*/
+#define IN1_MEM_SIZE	(0 * 1024 * 1024 - 1)
+#define IN_IO_SIZE	(20 * 1024 * 1024 - 1)
+#define IN_CFG0_SIZE	(1 * 1024 * 1024 - 1)
+#define IN_CFG1_SIZE	(1 * 1024 * 1024 - 1)
+#define IN_MSG_SIZE	(1 * 1024 * 1024 - 1)
+
+#define MAX_LINK_UP_WAIT_JIFFIES	10
+
+int (*pcie_port_is_host)(int port);
+static struct pcie_port pcie_port[NUM_PCIE_PORTS];
+static u32 spr_pcie_base[NUM_PCIE_PORTS] = {
+	SPEAR13XX_PCIE0_BASE,
+	SPEAR13XX_PCIE1_BASE,
+	SPEAR13XX_PCIE2_BASE,
+};
+static u32 spr_pcie_app_base[NUM_PCIE_PORTS] = {
+	SPEAR13XX_PCIE0_APP_BASE,
+	SPEAR13XX_PCIE1_APP_BASE,
+	SPEAR13XX_PCIE2_APP_BASE,
+};
+
+/* Keeping all DDR area of 256MB accesible for inbound transaction */
+#define INBOUND_ADDR_MASK	0xFFFFFFF
+
+#ifdef CONFIG_PCI_MSI
+static DECLARE_BITMAP(msi_irq_in_use[NUM_PCIE_PORTS], SPEAR_NUM_MSI_IRQS);
+static unsigned int spear_msi_data[NUM_PCIE_PORTS];
+
+static void spear13xx_msi_init(struct pcie_port *pp);
+#endif
+
+static void spear_pcie_int_handler(unsigned int irq, struct irq_desc *desc);
+
+static void enable_dbi_access(struct pcie_app_reg *app_reg)
+{
+	/* Enable DBI access */
+	writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_armisc);
+	writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_awmisc);
+
+}
+
+static void disable_dbi_access(struct pcie_app_reg *app_reg)
+{
+	/* disable DBI access */
+	writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_armisc);
+	writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_awmisc);
+
+}
+
+static void spear_dbi_read_reg(struct pcie_port *pp, int where, int size,
+		u32 *val)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)pp->va_dbi_base + (where & ~0x3);
+
+	*val = readl(va_address);
+
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	/* Disable DBI access */
+	disable_dbi_access(app_reg);
+}
+
+static void spear_dbi_write_reg(struct pcie_port *pp, int where, int size,
+		u32 val)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)pp->va_dbi_base + (where & ~0x3);
+
+	if (size == 4)
+		writel(val, va_address);
+	else if (size == 2)
+		writew(val, va_address + (where & 2));
+	else if (size == 1)
+		writeb(val, va_address + (where & 3));
+
+	/* Disable DBI access */
+	disable_dbi_access(app_reg);
+}
+
+static int spear13xx_pcie_link_up(void __iomem *va_app_base)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *) va_app_base;
+	unsigned long deadline = jiffies + MAX_LINK_UP_WAIT_JIFFIES;
+
+	do {
+		if (readl(&app_reg->app_status_1) &
+				((u32)1 << XMLH_LINK_UP_ID))
+			return 1;
+
+		cond_resched();
+	} while (!time_after_eq(jiffies, deadline));
+
+	return 0;
+}
+
+static void spear13xx_pcie_host_init(struct pcie_port *pp)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *)pp->va_app_base;
+
+	/*setup registers for outbound translation */
+
+	writel(pp->base, &app_reg->in0_mem_addr_start);
+	writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
+			&app_reg->in0_mem_addr_limit);
+	writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
+	writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
+			&app_reg->in1_mem_addr_limit);
+	writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
+	writel(app_reg->in_io_addr_start + IN_IO_SIZE,
+			&app_reg->in_io_addr_limit);
+	writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
+	writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
+			&app_reg->in_cfg0_addr_limit);
+	writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
+	writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
+			&app_reg->in_cfg1_addr_limit);
+	writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
+	writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
+			&app_reg->in_msg_addr_limit);
+
+	writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
+	writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
+	writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
+
+	/*setup registers for inbound translation */
+
+	writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
+	writel(0, &app_reg->pim0_mem_addr_start);
+	writel(0, &app_reg->pim1_mem_addr_start);
+	spear_dbi_write_reg(pp, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
+	spear_dbi_write_reg(pp, PCI_BASE_ADDRESS_0, 4, 0);
+
+	writel(0x0, &app_reg->pim_io_addr_start);
+	writel(0x0, &app_reg->pim_io_addr_start);
+	writel(0x0, &app_reg->pim_rom_addr_start);
+
+	writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID)
+			| (1 << APP_LTSSM_ENABLE_ID)
+			| ((u32)1 << REG_TRANSLATION_ENABLE),
+			&app_reg->app_ctrl_0);
+}
+
+static void __init spear13xx_pcie_preinit(void)
+{
+	int i;
+	struct pcie_port *pp;
+	struct pcie_app_reg *app_reg;
+
+	for (i = 0; i < NUM_PCIE_PORTS; i++) {
+		pp = pcie_port + i;
+		app_reg = (struct pcie_app_reg *) (pp->va_app_base);
+
+		/* init hosts only */
+		if ((*pcie_port_is_host)(i) != 1)
+			continue;
+		snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+			"PCIe %d MEM", pp->port);
+		pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+		pp->res[0].name = pp->mem_space_name;
+		pp->res[0].start = app_reg->in0_mem_addr_start;
+		pp->res[0].end = app_reg->in0_mem_addr_limit;
+		pp->res[0].flags = IORESOURCE_MEM;
+
+		snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+			"PCIe %d I/O", pp->port);
+		pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+		pp->res[1].name = pp->io_space_name;
+		pp->res[1].start = app_reg->in_io_addr_start;
+		pp->res[1].end = app_reg->in_io_addr_limit;
+		pp->res[1].flags = IORESOURCE_IO;
+
+		if (request_resource(&iomem_resource, &pp->res[0]))
+			panic("can't allocate PCIe I/O space");
+		if (request_resource(&iomem_resource, &pp->res[1]))
+			panic("can't allocate PCIe MEM space");
+	}
+}
+
+static int __init spear13xx_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	struct pcie_port *pp;
+	u32 val = 0;
+
+	if (nr >= NUM_PCIE_PORTS)
+		return 0;
+
+	if ((*pcie_port_is_host)(nr) != 1)
+		return 0;
+
+	pp = &pcie_port[nr];
+	if (!spear13xx_pcie_link_up((void __iomem *)pp->va_app_base))
+		return 0;
+	pp->root_bus_nr = sys->busnr;
+
+	/* Generic PCIe unit setup.*/
+
+	/* Enable own BME. It is necessary to enable own BME to do a
+	 * memory transaction on a downstream device
+	 */
+	spear_dbi_read_reg(pp, PCI_COMMAND, 2, &val);
+	val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+			| PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+	spear_dbi_write_reg(pp, PCI_COMMAND, 2, val);
+
+	/* Need to come back here*/
+
+	sys->resource[0] = &pp->res[0];
+	sys->resource[1] = &pp->res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static struct pcie_port *bus_to_port(int bus)
+{
+	int i;
+
+	for (i = NUM_PCIE_PORTS - 1; i >= 0; i--) {
+		int rbus = pcie_port[i].root_bus_nr;
+		if ((*pcie_port_is_host)(i) != 1)
+			continue;
+		if (rbus != -1 && rbus <= bus)
+			break;
+	}
+
+	return i >= 0 ? pcie_port + i : NULL;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+	/*If there is no link, then there is no device*/
+	if (!spear13xx_pcie_link_up((void __iomem *)pp->va_app_base))
+		return 0;
+	/*
+	 * Don't go out when trying to access nonexisting devices
+	 * on the local bus.
+	 * we have only one slot on each root port.
+	 */
+	if (bus == pp->root_bus_nr && dev > 0)
+		return 0;
+	return 1;
+}
+
+static int spear13xx_pcie_rd_conf(struct pcie_port *pp, struct pci_bus *bus,
+		u32 devfn, int where, int size, u32 *val)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base;
+	u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16)
+		| (where & 0xFFFC);
+
+	writel((bus->number << 24) | (PCI_SLOT(devfn) << 19),
+			&app_reg->pom_cfg0_addr_start);
+	writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK),
+			&app_reg->slv_armisc);
+	writel(readl(&app_reg->slv_armisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0,
+			&app_reg->slv_armisc);
+
+	*val = readl(address);
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK),
+			&app_reg->slv_armisc);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+			int size, u32 *val)
+{
+	struct pcie_port *pp = bus_to_port(bus->number);
+	unsigned long flags;
+	int ret;
+
+	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	ret = spear13xx_pcie_rd_conf(pp, bus, devfn, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static int spear13xx_pcie_wr_conf(struct pcie_port *pp, struct pci_bus *bus,
+		u32 devfn, int where, int size, u32 val)
+{
+	int ret = PCIBIOS_SUCCESSFUL;
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base;
+	u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16)
+			| (where & 0xFFFC);
+
+	writel((bus->number << 24) | (PCI_SLOT(devfn) << 19),
+			&app_reg->pom_cfg0_addr_start);
+	writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK),
+			&app_reg->slv_awmisc);
+	writel(readl(&app_reg->slv_awmisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0,
+			&app_reg->slv_awmisc);
+	if (size == 4)
+		writel(val, address);
+	else if (size == 2)
+		writew(val, address + (where & 2));
+	else if (size == 1)
+		writeb(val, address + (where & 3));
+	else
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK),
+			&app_reg->slv_awmisc);
+	return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+			int where, int size, u32 val)
+{
+	struct pcie_port *pp = bus_to_port(bus->number);
+	unsigned long flags;
+	int ret;
+
+	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	ret = spear13xx_pcie_wr_conf(pp, bus, devfn, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static struct pci_ops pcie_ops = {
+	.read = pcie_rd_conf,
+	.write = pcie_wr_conf,
+};
+
+static struct pci_bus __init *
+spear13xx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct pci_bus *bus;
+
+	if ((nr < NUM_PCIE_PORTS) && ((*pcie_port_is_host)(nr)) == 1) {
+		bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+	} else {
+		bus = NULL;
+		BUG();
+	}
+
+	return bus;
+}
+
+static int __init spear13xx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pcie_port *pp = bus_to_port(dev->bus->number);
+	int irq = (SPEAR_INTX0_BASE + pp->port * SPEAR_NUM_INTX_IRQS + pin - 1);
+
+	return irq;
+}
+
+static struct hw_pci spear13xx_pci __initdata = {
+	.nr_controllers	= NUM_PCIE_PORTS,
+	.preinit	= spear13xx_pcie_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= spear13xx_pcie_setup,
+	.scan		= spear13xx_pcie_scan_bus,
+	.map_irq	= spear13xx_pcie_map_irq,
+};
+
+void mask_intx_irq(unsigned int irq)
+{
+	int irq_offset = (irq - SPEAR_INTX0_BASE) % SPEAR_NUM_INTX_IRQS;
+	int port = (irq - SPEAR_INTX0_BASE) / SPEAR_NUM_INTX_IRQS;
+	struct pcie_port *pp = &pcie_port[port];
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *)pp->va_app_base;
+
+	switch (irq_offset) {
+	case 0:
+		writel(readl(&app_reg->int_mask) & ~INTA_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 1:
+		writel(readl(&app_reg->int_mask) & ~INTB_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 2:
+		writel(readl(&app_reg->int_mask) & ~INTC_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 3:
+		writel(readl(&app_reg->int_mask) & ~INTD_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	}
+}
+
+void unmask_intx_irq(unsigned int irq)
+{
+	int irq_offset = (irq - SPEAR_INTX0_BASE) % SPEAR_NUM_INTX_IRQS;
+	int port = (irq - SPEAR_INTX0_BASE) / SPEAR_NUM_INTX_IRQS;
+	struct pcie_port *pp = &pcie_port[port];
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *)pp->va_app_base;
+
+	switch (irq_offset) {
+	case 0:
+		writel(readl(&app_reg->int_mask) | INTA_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 1:
+		writel(readl(&app_reg->int_mask) | INTB_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 2:
+		writel(readl(&app_reg->int_mask) | INTC_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	case 3:
+		writel(readl(&app_reg->int_mask) | INTD_CTRL_INT,
+				&app_reg->int_mask);
+		break;
+	}
+}
+
+static struct irq_chip spear13xx_intx_chip = {
+	.name = "PCI-INTX",
+	.mask = mask_intx_irq,
+	.unmask = unmask_intx_irq,
+};
+
+static void spear13xx_int_init(struct pcie_port *pp)
+{
+	int i, irq;
+	struct pcie_app_reg *app_reg;
+
+	set_irq_chained_handler(IRQ_PCIE0 + pp->port, spear_pcie_int_handler);
+
+#ifdef CONFIG_PCI_MSI
+	spear13xx_msi_init(pp);
+#endif
+	/* Enbale INTX interrupt*/
+	app_reg = (struct pcie_app_reg *)pp->va_app_base;
+	writel(readl(&app_reg->int_mask) | INTA_CTRL_INT
+			| INTB_CTRL_INT	| INTC_CTRL_INT
+			| INTD_CTRL_INT, &app_reg->int_mask);
+
+	/* initilize INTX chip here only. MSI chip will be
+	 * initilized dynamically.*/
+	irq = (SPEAR_INTX0_BASE + pp->port * SPEAR_NUM_INTX_IRQS);
+	for (i = 0; i < SPEAR_NUM_INTX_IRQS; i++) {
+		set_irq_chip_and_handler(irq + i, &spear13xx_intx_chip,
+				handle_simple_irq);
+		set_irq_flags(irq + i, IRQF_VALID);
+	}
+}
+
+static void __init add_pcie_port(int port, u32 base, u32 app_base)
+{
+	struct pcie_port *pp = &pcie_port[port];
+	struct pcie_app_reg *app_reg;
+
+	pp->port = port;
+	pp->root_bus_nr = -1;
+	pp->base = (void __iomem *)base;
+	pp->app_base = (void __iomem *)app_base;
+	pp->va_app_base = (void __iomem *) ioremap(app_base, 0x200);
+	if (!pp->va_app_base) {
+		pr_err("error with ioremap in function %s\n", __func__);
+		return;
+	}
+	pp->va_dbi_base = (void __iomem *) ioremap(base, 0x2000);
+	if (!pp->va_dbi_base) {
+		pr_err("error with ioremap in function %s\n", __func__);
+		return;
+	}
+	spin_lock_init(&pp->conf_lock);
+	memset(pp->res, 0, sizeof(pp->res));
+	pr_info("spear13xx PCIe port %d\n", port);
+	if (spear13xx_pcie_link_up((void __iomem *)pp->va_app_base)) {
+		pr_info("link up in bios\n");
+	} else {
+		pr_info("link down in bios\n");
+		spear13xx_pcie_host_init(pp);
+		spear13xx_int_init(pp);
+		app_reg = (struct pcie_app_reg *)pp->va_app_base;
+		pp->va_cfg0_base = (void __iomem *)
+			ioremap(app_reg->in_cfg0_addr_start, IN_CFG0_SIZE);
+		if (!pp->va_cfg0_base) {
+			pr_err("error with ioremap in function %s\n", __func__);
+			return;
+		}
+
+	}
+}
+
+static int __init spear13xx_pcie_init(void)
+{
+	int port;
+	struct clk *clk;
+
+	for (port = 0; port < NUM_PCIE_PORTS; port++) {
+		/* do not enable clock if it is PCIE0. Ideally , all controller
+		 * should have been independent from others with respect to
+		 * clock. But PCIE1 and 2 depends on PCIE0.So PCIE0 clk
+		 * is provided during board init.*/
+		if (port == 1) {
+			/* Ideally CFG Clock should have been also enabled
+			 * here. But it is done currently during board
+			 * init routne*/
+			clk = clk_get_sys("pcie1", NULL);
+			if (IS_ERR(clk)) {
+				pr_err("%s:couldn't get clk for pcie1\n",
+						__func__);
+				continue;
+			}
+			if (clk_enable(clk)) {
+				pr_err("%s:couldn't enable clk for pcie1\n",
+						__func__);
+				continue;
+			}
+		} else if (port == 2) {
+			/* Ideally CFG Clock should have been also enabled
+			 * here. But it is done currently during board
+			 * init routne*/
+			clk = clk_get_sys("pcie2", NULL);
+			if (IS_ERR(clk)) {
+				pr_err("%s:couldn't get clk for pcie2\n",
+						__func__);
+				continue;
+			}
+			if (clk_enable(clk)) {
+				pr_err("%s:couldn't enable clk for pcie2\n",
+						__func__);
+				continue;
+			}
+		}
+
+		if ((*pcie_port_is_host)(port) == 1)
+			add_pcie_port(port, spr_pcie_base[port],
+					spr_pcie_app_base[port]);
+	}
+
+	pci_common_init(&spear13xx_pci);
+
+	return 0;
+}
+subsys_initcall(spear13xx_pcie_init);
+
+#ifdef CONFIG_PCI_MSI
+/* MSI int handler
+ */
+static void handle_msi(struct pcie_port *pp)
+{
+	unsigned long val;
+	int i, pos;
+
+	for (i = 0; i < 8; i++) {
+		spear_dbi_read_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4,
+				(u32 *)&val);
+		if (val) {
+			pos = 0;
+			while ((pos = find_next_bit(&val, 32, pos)) != 32) {
+				generic_handle_irq(SPEAR_MSI0_INT_BASE
+					+ pp->port * SPEAR_NUM_MSI_IRQS
+					+ (i * 32) + pos);
+				pos++;
+			}
+		}
+		spear_dbi_write_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, val);
+	}
+}
+#else
+static void handle_msi(struct pcie_port *pp)
+{
+}
+#endif
+
+static void spear_pcie_int_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct pcie_port *pp = &pcie_port[irq - IRQ_PCIE0];
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *)pp->va_app_base;
+	unsigned int status;
+
+	status = readl(&app_reg->int_sts);
+
+	desc->chip->ack(irq);
+
+	if (status & MSI_CTRL_INT) {
+		handle_msi(pp);
+		writel(MSI_CTRL_INT, &app_reg->int_clr);
+	} else if (status & INTA_CTRL_INT)
+		generic_handle_irq(SPEAR_INTX0_BASE
+				+ pp->port * SPEAR_NUM_INTX_IRQS);
+	else if (status & INTB_CTRL_INT)
+		generic_handle_irq(SPEAR_INTX0_BASE
+				+ pp->port * SPEAR_NUM_INTX_IRQS + 1);
+	else if (status & INTC_CTRL_INT)
+		generic_handle_irq(SPEAR_INTX0_BASE
+				+ pp->port * SPEAR_NUM_INTX_IRQS + 2);
+	else if (status & INTD_CTRL_INT)
+		generic_handle_irq(SPEAR_INTX0_BASE
+				+ pp->port * SPEAR_NUM_INTX_IRQS + 3);
+	else
+		writel(status, &app_reg->int_clr);
+
+	desc->chip->unmask(irq);
+}
+
+#ifdef CONFIG_PCI_MSI
+static int find_valid_pos0(int port, int nvec, int pos, int *pos0)
+{
+	int flag = 1;
+	do {
+		pos = find_next_zero_bit(msi_irq_in_use[port],
+				SPEAR_NUM_MSI_IRQS, pos);
+		/*if you have reached to the end then get out from here.*/
+		if (pos == SPEAR_NUM_MSI_IRQS)
+			return -ENOSPC;
+		/* Check if this position is at correct offset.nvec is always a
+		 * power of two. pos0 must be nvec bit alligned.
+		 */
+		if (pos % nvec)
+			pos += nvec - (pos % nvec);
+		else
+			flag = 0;
+	} while (flag);
+
+	*pos0 = pos;
+	return 0;
+}
+
+static void spear13xx_msi_nop(unsigned int irq)
+{
+	return;
+}
+
+static struct irq_chip spear13xx_msi_chip = {
+	.name = "PCI-MSI",
+	.ack = spear13xx_msi_nop,
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
+};
+
+/*
+ * Dynamic irq allocate and deallocation
+ */
+static int get_irq(int nvec, struct msi_desc *desc, int *pos)
+{
+	int res, bit, irq, pos0, pos1, i;
+	u32 val;
+	struct pcie_port *pp = bus_to_port(desc->dev->bus->number);
+
+	pos0 = find_first_zero_bit(msi_irq_in_use[pp->port],
+			SPEAR_NUM_MSI_IRQS);
+	if (pos0 % nvec) {
+		if (find_valid_pos0(pp->port, nvec, pos0, &pos0))
+			goto no_valid_irq;
+	}
+	if (nvec > 1) {
+		pos1 = find_next_bit(msi_irq_in_use[pp->port],
+				SPEAR_NUM_MSI_IRQS, pos0);
+		/* there must be nvec number of consecutive free bits */
+		while ((pos1 - pos0) < nvec) {
+			if (find_valid_pos0(pp->port, nvec, pos1, &pos0))
+				goto no_valid_irq;
+			pos1 = find_next_bit(msi_irq_in_use[pp->port],
+					SPEAR_NUM_MSI_IRQS, pos0);
+		}
+	}
+
+	irq = (SPEAR_MSI0_INT_BASE + (pp->port * SPEAR_NUM_MSI_IRQS)) + pos0;
+
+	if ((irq + nvec) > (SPEAR_MSI0_INT_END
+				+ (pp->port * SPEAR_NUM_MSI_IRQS)))
+		goto no_valid_irq;
+
+	i = 0;
+	while (i < nvec) {
+		set_bit(pos0 + i, msi_irq_in_use[pp->port]);
+		dynamic_irq_init(irq + i);
+		set_irq_msi(irq + i, desc);
+		set_irq_chip_and_handler(irq + i, &spear13xx_msi_chip,
+				handle_simple_irq);
+
+		/* Enable corresponding interrupt on MSI interrupt
+		 * controller.
+		 */
+		res = ((pos0 + i) / 32) * 12;
+		bit = (pos0 + i) % 32;
+		spear_dbi_read_reg(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
+		val |= 1 << bit;
+		spear_dbi_write_reg(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+
+		i++;
+	}
+
+	*pos = pos0;
+	return irq;
+no_valid_irq:
+	*pos = pos0;
+	return -ENOSPC;
+}
+
+static void clean_irq(unsigned int irq)
+{
+	int res, bit, val, pos;
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct pcie_port *pp = bus_to_port(desc->msi_desc->dev->bus->number);
+
+	pos = irq - (SPEAR_MSI0_INT_BASE + (pp->port * SPEAR_NUM_MSI_IRQS));
+
+	dynamic_irq_cleanup(irq);
+
+	clear_bit(pos, msi_irq_in_use[pp->port]);
+
+	/* Disable corresponding interrupt on MSI interrupt
+	 * controller.
+	 */
+	res = (pos / 32) * 12;
+	bit = pos % 32;
+	spear_dbi_read_reg(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
+	val &= ~(1 << bit);
+	spear_dbi_write_reg(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+
+}
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+	int cvec, rvec, irq, pos;
+	struct msi_msg msg;
+	uint16_t control;
+	struct pcie_port *pp = bus_to_port(pdev->bus->number);
+
+	/*
+	 * Read the MSI config to figure out how many IRQs this device
+	 * wants.Most devices only want 1, which will give
+	 * configured_private_bits and request_private_bits equal 0.
+	 */
+	pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+			&control);
+
+	/*
+	 * If the number of private bits has been configured then use
+	 * that value instead of the requested number. This gives the
+	 * driver the chance to override the number of interrupts
+	 * before calling pci_enable_msi().
+	 */
+
+	cvec = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
+
+	if (cvec == 0) {
+		/* Nothing is configured, so use the hardware requested size */
+		rvec = (control & PCI_MSI_FLAGS_QMASK) >> 1;
+	} else {
+		/*
+		 * Use the number of configured bits, assuming the
+		 * driver wanted to override the hardware request
+		 * value.
+		 */
+		rvec = cvec;
+	}
+
+	/*
+	 * The PCI 2.3 spec mandates that there are at most 32
+	 * interrupts. If this device asks for more, only give it one.
+	 */
+	if (rvec > 5)
+		rvec = 0;
+
+	irq = get_irq((1 << rvec), desc, &pos);
+
+	 if (irq < 0)
+		return irq;
+
+	 /* Update the number of IRQs the device has available to it */
+	 control &= ~PCI_MSI_FLAGS_QSIZE;
+	 control |= rvec << 4;
+	 pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+			 control);
+	 desc->msi_attrib.multiple = rvec;
+
+	/* An EP will modify lower 8 bits(max) of msi data while
+	 * sending any msi interrupt
+	 */
+	msg.address_hi = 0x0;
+	msg.address_lo = __virt_to_phys((u32)(&spear_msi_data[pp->port]));
+	msg.data = pos;
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	clean_irq(irq);
+}
+
+static void spear13xx_msi_init(struct pcie_port *pp)
+{
+	struct pcie_app_reg *app_reg = (struct pcie_app_reg *)pp->va_app_base;
+
+	spear_dbi_write_reg(pp, PCIE_MSI_ADDR_LO, 4,
+			__virt_to_phys((u32)(&spear_msi_data[pp->port])));
+	spear_dbi_write_reg(pp, PCIE_MSI_ADDR_HI, 4, 0);
+	/* Enbale MSI interrupt*/
+	writel(readl(&app_reg->int_mask) | MSI_CTRL_INT,
+			&app_reg->int_mask);
+}
+#endif
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index cba0fee..4799ae1 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -16,6 +16,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
+#include <mach/pcie.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -45,6 +46,30 @@ static struct amba_device *amba_devs[] __initdata = {
 static struct platform_device *plat_devs[] __initdata = {
 };
 
+#ifdef CONFIG_PCIEPORTBUS
+/*
+ * This function is needed for PCIE host and device driver. Same
+ * controller can not be programmed as host as well as device. So host
+ * driver must call this function and if this function returns 1 then
+ * only host should add that particular port as RC.
+ * A port to be added as device, one must also add device's information
+ * in plat_devs array defined in this file.
+ */
+static int spear1300_pcie_port_is_host(int port)
+{
+	switch (port) {
+	case 0:
+		return 0;
+	case 1:
+		return 1;
+	case 2:
+		return 1;
+	}
+
+	return -EINVAL;
+}
+#endif
+
 static void __init spear1300_evb_init(void)
 {
 	unsigned int i;
@@ -52,6 +77,12 @@ static void __init spear1300_evb_init(void)
 	/* call spear1300 machine init function */
 	spear1300_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+#ifdef CONFIG_PCIEPORTBUS
+	/* Enable PCIE0 clk */
+	enable_pcie0_clk();
+	pcie_init(spear1300_pcie_port_is_host);
+#endif
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 62af911..2e74879 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -16,6 +16,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
+#include <mach/pcie.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -64,6 +65,30 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear1310_can1_device,
 };
 
+#ifdef CONFIG_PCIEPORTBUS
+/*
+ * This function is needed for PCIE host and device driver. Same
+ * controller can not be programmed as host as well as device. So host
+ * driver must call this function and if this function returns 1 then
+ * only host should add that particular port as RC.
+ * A port to be added as device, one must also add device's information
+ * in plat_devs array defined in this file.
+ */
+static int spear1310_pcie_port_is_host(int port)
+{
+	switch (port) {
+	case 0:
+		return 0;
+	case 1:
+		return 1;
+	case 2:
+		return 1;
+	}
+
+	return -EINVAL;
+}
+#endif
+
 static void __init spear1310_evb_init(void)
 {
 	unsigned int i;
@@ -71,6 +96,12 @@ static void __init spear1310_evb_init(void)
 	/* call spear1310 machine init function */
 	spear1310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+#ifdef CONFIG_PCIEPORTBUS
+	/* Enable PCIE0 clk */
+	enable_pcie0_clk();
+	pcie_init(spear1310_pcie_port_is_host);
+#endif
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 35582a6..6c2525a 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -76,6 +76,34 @@ struct amba_device spear13xx_uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+#ifdef CONFIG_PCIEPORTBUS
+/* PCIE0 clock always needs to be enabled if any of the three PCIE port
+ * have to be used. So call this function from the board initilization
+ * file. Ideally , all controller should have been independent from
+ * others with respect to clock.
+ */
+int enable_pcie0_clk(void)
+{
+	struct clk *clk;
+	/*Enable all CLK in CFG registers here only. Idealy only PCIE0
+	 * should have been enabled. But Controler does not work
+	 * properly if PCIE1 and PCIE2's CFG CLK is enabled in stages.
+	 */
+	writel(PCIE0_CFG_VAL | PCIE1_CFG_VAL | PCIE2_CFG_VAL, PCIE_CFG);
+	clk = clk_get_sys("pcie0", NULL);
+	if (IS_ERR(clk)) {
+		pr_err("%s:couldn't get clk for pcie0\n", __func__);
+		return -ENODEV;
+	}
+	if (clk_enable(clk)) {
+		pr_err("%s:couldn't enable clk for pcie0\n", __func__);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+#endif
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 29a25d2..ee5fd4a 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,6 +12,8 @@ config ARCH_SPEAR13XX
 	bool "SPEAr13XX"
 	select ARM_GIC
 	select CPU_V7
+	select ARCH_SUPPORTS_MSI
+	select MIGHT_HAVE_PCI
 	help
 	  Supports for ARM's SPEAR13XX family
 
-- 
1.7.2.2

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

* [PATCH V6 03/17] ST SPEAr: Adding PLGPIO driver for spear platform
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 01/17] ST SPEAr13xx: Added ARM PL061 GPIO Support Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 04/17] ST SPEAr3xx: Adding support for ST's PWM IP Viresh Kumar
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Plgpio pads on few spear machines can be configured as gpios. This patch add
support for configuring these PLGPIOs.

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    2 +
 arch/arm/mach-spear3xx/include/mach/gpio.h    |  143 ++++++++
 arch/arm/mach-spear3xx/spear310.c             |   68 ++++
 arch/arm/mach-spear3xx/spear310_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear320.c             |   28 ++
 arch/arm/mach-spear3xx/spear320_evb.c         |    1 +
 arch/arm/mach-spear6xx/include/mach/gpio.h    |   27 ++
 arch/arm/plat-spear/Makefile                  |    2 +
 arch/arm/plat-spear/include/plat/gpio.h       |   35 ++
 arch/arm/plat-spear/plgpio.c                  |  473 +++++++++++++++++++++++++
 10 files changed, 780 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/plgpio.c

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 5320ab6..31e7a03 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -145,6 +145,7 @@ void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear310 declarations */
 #ifdef CONFIG_MACH_SPEAR310
 /* Add spear310 machine device structure declarations here */
+extern struct platform_device spear310_plgpio_device;
 
 /* pad mux devices */
 extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
@@ -166,6 +167,7 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear320 declarations */
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
+extern struct platform_device spear320_plgpio_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear320_auto_net_smii_mode;
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
index 451b208..1881f70 100644
--- a/arch/arm/mach-spear3xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -16,4 +16,147 @@
 
 #include <plat/gpio.h>
 
+#ifdef CONFIG_MACH_SPEAR310
+#define SPEAR310_PLGPIO_ENB		0x0010
+#define SPEAR310_PLGPIO_WDATA		0x0020
+#define SPEAR310_PLGPIO_DIR		0x0030
+#define SPEAR310_PLGPIO_IE		0x0040
+#define SPEAR310_PLGPIO_RDATA		0x0050
+#define SPEAR310_PLGPIO_MIS		0x0060
+#endif /* CONFIG_MACH_SPEAR310 */
+
+#ifdef CONFIG_MACH_SPEAR320
+#define SPEAR320_PLGPIO_ENB		0x0024
+#define SPEAR320_PLGPIO_WDATA		0x0034
+#define SPEAR320_PLGPIO_DIR		0x0044
+#define SPEAR320_PLGPIO_RDATA		0x0054
+#define SPEAR320_PLGPIO_IE		0x0064
+#define SPEAR320_PLGPIO_MIS		0x0074
+#endif /* CONFIG_MACH_SPEAR320 */
+
+#define BASIC_GPIO_0		0
+#define BASIC_GPIO_1		1
+#define BASIC_GPIO_2		2
+#define BASIC_GPIO_3		3
+#define BASIC_GPIO_4		4
+#define BASIC_GPIO_5		5
+#define BASIC_GPIO_6		6
+#define BASIC_GPIO_7		7
+
+#ifdef CONFIG_MACH_SPEAR300
+#define RAS_GPIO_0		8
+#define RAS_GPIO_1		9
+#define RAS_GPIO_2		10
+#define RAS_GPIO_3		11
+#define RAS_GPIO_4		12
+#define RAS_GPIO_5		13
+#define RAS_GPIO_6		14
+#define RAS_GPIO_7		15
+#endif /* CONFIG_MACH_SPEAR300 */
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#define PLGPIO_0		8
+#define PLGPIO_1		9
+#define PLGPIO_2		10
+#define PLGPIO_3		11
+#define PLGPIO_4		12
+#define PLGPIO_5		13
+#define PLGPIO_6		14
+#define PLGPIO_7		15
+#define PLGPIO_8		16
+#define PLGPIO_9		17
+#define PLGPIO_10		18
+#define PLGPIO_11		19
+#define PLGPIO_12		20
+#define PLGPIO_13		21
+#define PLGPIO_14		22
+#define PLGPIO_15		23
+#define PLGPIO_16		24
+#define PLGPIO_17		25
+#define PLGPIO_18		26
+#define PLGPIO_19		27
+#define PLGPIO_20		28
+#define PLGPIO_21		29
+#define PLGPIO_22		30
+#define PLGPIO_23		31
+#define PLGPIO_24		32
+#define PLGPIO_25		33
+#define PLGPIO_26		34
+#define PLGPIO_27		35
+#define PLGPIO_28		36
+#define PLGPIO_29		37
+#define PLGPIO_30		38
+#define PLGPIO_31		39
+#define PLGPIO_32		40
+#define PLGPIO_33		41
+#define PLGPIO_34		42
+#define PLGPIO_35		43
+#define PLGPIO_36		44
+#define PLGPIO_37		45
+#define PLGPIO_38		46
+#define PLGPIO_39		47
+#define PLGPIO_40		48
+#define PLGPIO_41		49
+#define PLGPIO_42		50
+#define PLGPIO_43		51
+#define PLGPIO_44		52
+#define PLGPIO_45		53
+#define PLGPIO_46		54
+#define PLGPIO_47		55
+#define PLGPIO_48		56
+#define PLGPIO_49		57
+#define PLGPIO_50		58
+#define PLGPIO_51		59
+#define PLGPIO_52		60
+#define PLGPIO_53		61
+#define PLGPIO_54		62
+#define PLGPIO_55		63
+#define PLGPIO_56		64
+#define PLGPIO_57		65
+#define PLGPIO_58		66
+#define PLGPIO_59		67
+#define PLGPIO_60		68
+#define PLGPIO_61		69
+#define PLGPIO_62		70
+#define PLGPIO_63		71
+#define PLGPIO_64		72
+#define PLGPIO_65		73
+#define PLGPIO_66		74
+#define PLGPIO_67		75
+#define PLGPIO_68		76
+#define PLGPIO_69		77
+#define PLGPIO_70		78
+#define PLGPIO_71		79
+#define PLGPIO_72		80
+#define PLGPIO_73		81
+#define PLGPIO_74		82
+#define PLGPIO_75		83
+#define PLGPIO_76		84
+#define PLGPIO_77		85
+#define PLGPIO_78		86
+#define PLGPIO_79		87
+#define PLGPIO_80		88
+#define PLGPIO_81		89
+#define PLGPIO_82		90
+#define PLGPIO_83		91
+#define PLGPIO_84		92
+#define PLGPIO_85		93
+#define PLGPIO_86		94
+#define PLGPIO_87		95
+#define PLGPIO_88		96
+#define PLGPIO_89		97
+#define PLGPIO_90		98
+#define PLGPIO_91		99
+#define PLGPIO_92		100
+#define PLGPIO_93		101
+#define PLGPIO_94		102
+#define PLGPIO_95		103
+#define PLGPIO_96		104
+#define PLGPIO_97		105
+#define PLGPIO_98		106
+#define PLGPIO_99		107
+#define PLGPIO_100		108
+#define PLGPIO_101		109
+#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
+
 #endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 4522e48..a4cd44c 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -13,6 +13,7 @@
 
 #include <linux/ptrace.h>
 #include <asm/irq.h>
+#include <plat/gpio.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
@@ -308,6 +309,73 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* Add spear310 specific devices here */
+/* plgpio device registeration */
+/*
+ * pin to offset and offset to pin converter functions
+ *
+ * In spear310 there is inconsistency among bit positions in plgpio regiseters,
+ * for different plgpio pins. For example: for pin 27, bit offset is 23, pin
+ * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
+ */
+static int spear300_p2o(int pin)
+{
+	int offset = pin;
+
+	if (pin <= 27)
+		offset += 4;
+	else if (pin <= 33)
+		offset = -1;
+	else if (pin <= 97)
+		offset -= 2;
+	else if (pin <= 101)
+		offset = 101 - pin;
+	else
+		offset = -1;
+
+	return offset;
+}
+
+int spear300_o2p(int offset)
+{
+	if (offset <= 3)
+		return 101 - offset;
+	else if (offset <= 31)
+		return offset - 4;
+	else
+		return offset + 2;
+}
+
+static struct plgpio_platform_data plgpio_plat_data = {
+	.gpio_base = 8,
+	.irq_base = SPEAR3XX_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR3XX_PLGPIO_COUNT,
+	.p2o = spear300_p2o,
+	.o2p = spear300_o2p,
+	/* list of registers with inconsistency */
+	.p2o_regs = PTO_RDATA_REG | PTO_WDATA_REG | PTO_DIR_REG |
+		PTO_IE_REG | PTO_RDATA_REG | PTO_MIS_REG,
+};
+
+static struct resource plgpio_resources[] = {
+	{
+		.start = SPEAR310_SOC_CONFIG_BASE,
+		.end = SPEAR310_SOC_CONFIG_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR310_VIRQ_PLGPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear310_plgpio_device = {
+	.name = "plgpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &plgpio_plat_data,
+	},
+	.num_resources = ARRAY_SIZE(plgpio_resources),
+	.resource = plgpio_resources,
+};
 
 /* spear310 routines */
 void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index c8684ce..f6832c4 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -52,6 +52,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 
 	/* spear310 specific devices */
+	&spear310_plgpio_device,
 };
 
 static void __init spear310_evb_init(void)
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index a99cf7c..06b3332 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -13,6 +13,7 @@
 
 #include <linux/ptrace.h>
 #include <asm/irq.h>
+#include <plat/gpio.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
@@ -711,6 +712,33 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* Add spear320 specific devices here */
+/* plgpio device registeration */
+static struct plgpio_platform_data plgpio_plat_data = {
+	.gpio_base = 8,
+	.irq_base = SPEAR3XX_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR3XX_PLGPIO_COUNT,
+};
+
+static struct resource plgpio_resources[] = {
+	{
+		.start = SPEAR320_SOC_CONFIG_BASE,
+		.end = SPEAR320_SOC_CONFIG_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR320_VIRQ_PLGPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear320_plgpio_device = {
+	.name = "plgpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &plgpio_plat_data,
+	},
+	.num_resources = ARRAY_SIZE(plgpio_resources),
+	.resource = plgpio_resources,
+};
 
 /* spear320 routines */
 void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index a12b353..4d747db 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -49,6 +49,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 
 	/* spear320 specific devices */
+	&spear320_plgpio_device,
 };
 
 static void __init spear320_evb_init(void)
diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h
index 3a789db..465b2e7 100644
--- a/arch/arm/mach-spear6xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear6xx/include/mach/gpio.h
@@ -16,4 +16,31 @@
 
 #include <plat/gpio.h>
 
+#define CPU_GPIO_0		0
+#define CPU_GPIO_1		1
+#define CPU_GPIO_2		2
+#define CPU_GPIO_3		3
+#define CPU_GPIO_4		4
+#define CPU_GPIO_5		5
+#define CPU_GPIO_6		6
+#define CPU_GPIO_7		7
+
+#define BASIC_GPIO_0		8
+#define BASIC_GPIO_1		9
+#define BASIC_GPIO_2		10
+#define BASIC_GPIO_3		11
+#define BASIC_GPIO_4		12
+#define BASIC_GPIO_5		13
+#define BASIC_GPIO_6		14
+#define BASIC_GPIO_7		15
+
+#define APPL_GPIO_0		16
+#define APPL_GPIO_1		17
+#define APPL_GPIO_2		18
+#define APPL_GPIO_3		19
+#define APPL_GPIO_4		20
+#define APPL_GPIO_5		21
+#define APPL_GPIO_6		22
+#define APPL_GPIO_7		23
+
 #endif /* __MACH_GPIO_H */
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 03f9acc..f462c8f 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -7,3 +7,5 @@ obj-y	:= clock.o time.o
 
 obj-$(CONFIG_ARCH_SPEAR13XX)	+= padmux.o
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
+obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
+obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
diff --git a/arch/arm/plat-spear/include/plat/gpio.h b/arch/arm/plat-spear/include/plat/gpio.h
index b857c91..450671e 100644
--- a/arch/arm/plat-spear/include/plat/gpio.h
+++ b/arch/arm/plat-spear/include/plat/gpio.h
@@ -21,4 +21,39 @@
 #define gpio_cansleep	__gpio_cansleep
 #define gpio_to_irq	__gpio_to_irq
 
+/* plgpio driver declarations */
+/*
+ * plgpio pins in all machines are not one to one mapped, bitwise with
+ * registers bits. These set of macros define register masks for which below
+ * functions (pin_to_offset and offset_to_pin) are required to be called.
+ */
+#define PTO_ENB_REG		0x001
+#define PTO_WDATA_REG		0x002
+#define PTO_DIR_REG		0x004
+#define PTO_IE_REG		0x008
+#define PTO_RDATA_REG		0x010
+#define PTO_MIS_REG		0x020
+
+/* functions for converting pin to correct offset in register and vice versa */
+/**
+ * struct plgpio_platform_data: plgpio driver platform data
+ *
+ * gpio_base: gpio start number of plgpios
+ * irq_base: irq number of plgpio0
+ * gpio_count: total count of plgpios
+ * p2o: function ptr for pin to offset conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * o2p: function ptr for offset to pin conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * p2o_regs: mask of registers for which p2o and o2p are applicable
+ */
+struct plgpio_platform_data {
+	u32 gpio_base;
+	u32 irq_base;
+	u32 gpio_count;
+	int (*p2o)(int pin);		/* pin_to_offset */
+	int (*o2p)(int offset);		/* offset_to_pin */
+	u32 p2o_regs;
+};
+
 #endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-spear/plgpio.c b/arch/arm/plat-spear/plgpio.c
new file mode 100644
index 0000000..4db9a07
--- /dev/null
+++ b/arch/arm/plat-spear/plgpio.c
@@ -0,0 +1,473 @@
+/*
+ * arch/arm/plat-spear/plgpio.c
+ *
+ * SPEAr platform PLGPIO driver source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <asm/mach-types.h>
+
+#define MAX_GPIO_PER_REG		32
+#define PIN_OFFSET(pin)			(pin % MAX_GPIO_PER_REG)
+#define REG_OFFSET(base, reg, pin)	(base + reg + (pin / MAX_GPIO_PER_REG)\
+		* sizeof(int *))
+
+static unsigned int plgpio_enb, plgpio_wdata, plgpio_dir, plgpio_rdata,
+		    plgpio_ie, plgpio_mis;
+
+/*
+ * struct plgpio: plgpio driver specific structure
+ *
+ * lock: lock for guarding gpio registers
+ * base: base address of plgpio block
+ * irq_base: irq number of plgpio0
+ * chip: gpio framework specific chip information structure
+ * p2o: function ptr for pin to offset conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * o2p: function ptr for offset to pin conversion. This is required only for
+ * machines where mapping b/w pin and offset is not 1-to-1.
+ * p2o_regs: mask of registers for which p2o and o2p are applicable
+ */
+struct plgpio {
+	spinlock_t		lock;
+	void __iomem		*base;
+	unsigned		irq_base;
+	struct gpio_chip	chip;
+	int (*p2o)(int pin);		/* pin_to_offset */
+	int (*o2p)(int offset);		/* offset_to_pin */
+	u32			p2o_regs;
+};
+
+/* register manipulation inline functions */
+static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl(reg_off);
+
+	return val & (1 << offset);
+}
+
+static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl(reg_off);
+
+	writel(val | (1 << offset), reg_off);
+}
+
+static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg)
+{
+	u32 offset = PIN_OFFSET(pin);
+	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
+	u32 val = readl(reg_off);
+
+	writel(val & ~(1 << offset), reg_off);
+}
+
+/* gpio framework specific routines */
+static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return -EINVAL;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio_dir);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+	return 0;
+}
+
+static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+	unsigned dir_offset = offset, wdata_offset = offset, tmp;
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) {
+		tmp = plgpio->p2o(offset);
+		if (tmp == -1)
+			return -EINVAL;
+
+		if (plgpio->p2o_regs & PTO_DIR_REG)
+			dir_offset = tmp;
+		if (plgpio->p2o_regs & PTO_WDATA_REG)
+			wdata_offset = tmp;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_reset(plgpio->base, dir_offset, plgpio_dir);
+	if (value)
+		plgpio_reg_set(plgpio->base, wdata_offset, plgpio_wdata);
+	else
+		plgpio_reg_reset(plgpio->base, wdata_offset, plgpio_wdata);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+	return 0;
+}
+
+static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return -EINVAL;
+	}
+
+	return is_plgpio_set(plgpio->base, offset, plgpio_rdata);
+}
+
+static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (offset >= chip->ngpio)
+		return;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	if (value)
+		plgpio_reg_set(plgpio->base, offset, plgpio_wdata);
+	else
+		plgpio_reg_reset(plgpio->base, offset, plgpio_wdata);
+}
+
+static int plgpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+	int ret = 0;
+
+	if (offset >= chip->ngpio)
+		return -EINVAL;
+
+	/*
+	 * put gpio in IN mode before enabling it. This make enabling gpio safe
+	 */
+	ret = plgpio_direction_input(chip, offset);
+	if (ret)
+		return ret;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return -EINVAL;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio_enb);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+
+	return 0;
+}
+
+static void plgpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+	unsigned long flags;
+
+	if (offset >= chip->ngpio)
+		return;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_reset(plgpio->base, offset, plgpio_enb);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
+
+	if (plgpio->irq_base == (unsigned) -1)
+		return -EINVAL;
+
+	return plgpio->irq_base + offset;
+}
+
+/* PLGPIO IRQ */
+static void plgpio_irq_mask(unsigned irq)
+{
+	struct plgpio *plgpio = get_irq_chip_data(irq);
+	int offset = irq - plgpio->irq_base;
+	unsigned long flags;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_set(plgpio->base, offset, plgpio_ie);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static void plgpio_irq_unmask(unsigned irq)
+{
+	struct plgpio *plgpio = get_irq_chip_data(irq);
+	int offset = irq - plgpio->irq_base;
+	unsigned long flags;
+
+	/* get correct offset for "offset" pin */
+	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
+		offset = plgpio->p2o(offset);
+		if (offset == -1)
+			return;
+	}
+
+	spin_lock_irqsave(&plgpio->lock, flags);
+	plgpio_reg_reset(plgpio->base, offset, plgpio_ie);
+	spin_unlock_irqrestore(&plgpio->lock, flags);
+}
+
+static int plgpio_irq_type(unsigned irq, unsigned trigger)
+{
+	struct plgpio *plgpio = get_irq_chip_data(irq);
+	int offset = irq - plgpio->irq_base;
+
+	if (offset >= plgpio->chip.ngpio)
+		return -EINVAL;
+
+	if (trigger != IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+	return 0;
+}
+
+static struct irq_chip plgpio_irqchip = {
+	.name		= "PLGPIO",
+	.mask		= plgpio_irq_mask,
+	.unmask		= plgpio_irq_unmask,
+	.set_type	= plgpio_irq_type,
+};
+
+static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct plgpio *plgpio = get_irq_data(irq);
+	unsigned long pending;
+	int regs_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG),
+	    count, pin, offset, i = 0;
+
+	/* check all plgpio MIS registers for a possible interrupt */
+	for (; i < regs_count; i++) {
+		pending = readl(plgpio->base + plgpio_mis + i * sizeof(int *));
+		if (!pending)
+			continue;
+
+		/*
+		 * clear extra bits in last register having gpios < MAX/REG
+		 * ex: Suppose there are max 102 plgpios. then last register
+		 * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits
+		 * so, we must not take other 28 bits into consideration for
+		 * checking interrupt. so clear those bits.
+		 */
+		count = plgpio->chip.ngpio - i * MAX_GPIO_PER_REG;
+		if (count < MAX_GPIO_PER_REG)
+			pending &= (1 << count) - 1;
+
+		for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) {
+			/* get correct pin for "offset" */
+			if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) {
+				pin = plgpio->o2p(offset);
+				if (pin == -1)
+					continue;
+			} else
+				pin = offset;
+
+			generic_handle_irq(plgpio_to_irq(&plgpio->chip,
+						i * MAX_GPIO_PER_REG + pin));
+		}
+	}
+}
+
+static int __devinit plgpio_probe(struct platform_device *pdev)
+{
+	struct plgpio_platform_data *pdata;
+	struct plgpio *plgpio;
+	int ret, irq, i;
+	struct resource *res;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "invalid platform data\n");
+		goto fail;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EBUSY;
+		dev_dbg(&pdev->dev, "invalid IORESOURCE_MEM\n");
+		goto fail;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), "plgpio")) {
+		ret = -EBUSY;
+		dev_dbg(&pdev->dev, "request mem region fail\n");
+		goto fail;
+	}
+
+	plgpio = kzalloc(sizeof(*plgpio), GFP_KERNEL);
+	if (!plgpio) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "memory allocation fail\n");
+		goto release_region;
+	}
+
+	plgpio->base = ioremap(res->start, resource_size(res));
+	if (!plgpio->base) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "ioremap fail\n");
+		goto kfree;
+	}
+
+	spin_lock_init(&plgpio->lock);
+
+	plgpio->chip.request = plgpio_request;
+	plgpio->chip.free = plgpio_free;
+	plgpio->chip.direction_input = plgpio_direction_input;
+	plgpio->chip.direction_output = plgpio_direction_output;
+	plgpio->chip.get = plgpio_get_value;
+	plgpio->chip.set = plgpio_set_value;
+	plgpio->chip.to_irq = plgpio_to_irq;
+	plgpio->chip.base = pdata->gpio_base;
+	plgpio->chip.ngpio = pdata->gpio_count;
+	plgpio->chip.label = dev_name(&pdev->dev);
+	plgpio->chip.dev = &pdev->dev;
+	plgpio->chip.owner = THIS_MODULE;
+	plgpio->irq_base = pdata->irq_base;
+	plgpio->p2o = pdata->p2o;
+	plgpio->o2p = pdata->o2p;
+	plgpio->p2o_regs = pdata->p2o_regs;
+
+	ret = gpiochip_add(&plgpio->chip);
+	if (ret) {
+		dev_dbg(&pdev->dev, "unable to add gpio chip\n");
+		goto iounmap;
+	}
+
+	/* irq_chip support */
+	if (pdata->irq_base == (unsigned) -1) {
+		dev_info(&pdev->dev, "Initialization successful\n");
+		return 0;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "invalid irq number\n");
+		goto remove_gpiochip;
+	}
+
+	set_irq_chained_handler(irq, plgpio_irq_handler);
+	for (i = 0; i < pdata->gpio_count; i++) {
+		set_irq_chip(i+plgpio->irq_base, &plgpio_irqchip);
+		set_irq_handler(i+plgpio->irq_base, handle_simple_irq);
+		set_irq_flags(i+plgpio->irq_base, IRQF_VALID);
+		set_irq_chip_data(i+plgpio->irq_base, plgpio);
+	}
+	set_irq_data(irq, plgpio);
+	dev_info(&pdev->dev, "Initialization successful\n");
+
+	return 0;
+
+remove_gpiochip:
+	if (gpiochip_remove(&plgpio->chip))
+		dev_dbg(&pdev->dev, "unable to remove gpiochip\n");
+iounmap:
+	iounmap(plgpio->base);
+kfree:
+	kfree(plgpio);
+release_region:
+	release_mem_region(res->start, resource_size(res));
+fail:
+	dev_err(&pdev->dev, "probe fail: %d\n", ret);
+	return ret;
+}
+
+static struct platform_driver plgpio_driver = {
+	.probe		= plgpio_probe,
+	.driver		= {
+		.name	= "plgpio",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init plgpio_init(void)
+{
+	if (machine_is_spear310()) {
+		plgpio_enb = SPEAR310_PLGPIO_ENB;
+		plgpio_wdata = SPEAR310_PLGPIO_WDATA;
+		plgpio_dir = SPEAR310_PLGPIO_DIR;
+		plgpio_rdata = SPEAR310_PLGPIO_IE;
+		plgpio_ie = SPEAR310_PLGPIO_RDATA;
+		plgpio_mis = SPEAR310_PLGPIO_MIS;
+	} else if (machine_is_spear320()) {
+		plgpio_enb = SPEAR320_PLGPIO_ENB;
+		plgpio_wdata = SPEAR320_PLGPIO_WDATA;
+		plgpio_dir = SPEAR320_PLGPIO_DIR;
+		plgpio_rdata = SPEAR320_PLGPIO_IE;
+		plgpio_ie = SPEAR320_PLGPIO_RDATA;
+		plgpio_mis = SPEAR320_PLGPIO_MIS;
+	} else
+		return -EACCES;
+
+	return platform_driver_register(&plgpio_driver);
+}
+subsys_initcall(plgpio_init);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("SPEAr PLGPIO driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* [PATCH V6 04/17] ST SPEAr3xx: Adding support for ST's PWM IP
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (2 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 03/17] ST SPEAr: Adding PLGPIO driver for spear platform Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 05/17] ST SPEAr: Adding Watchdog support on spear3xx & spear6xx machines Viresh Kumar
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear3xx/spear320.c             |   16 +
 arch/arm/mach-spear3xx/spear320_evb.c         |    1 +
 arch/arm/plat-spear/Kconfig                   |    7 +
 arch/arm/plat-spear/Makefile                  |    2 +
 arch/arm/plat-spear/pwm.c                     |  484 +++++++++++++++++++++++++
 6 files changed, 511 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/pwm.c

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 31e7a03..f43d104 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -168,6 +168,7 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
 extern struct platform_device spear320_plgpio_device;
+extern struct platform_device spear320_pwm_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear320_auto_net_smii_mode;
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 06b3332..c1642c1 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -740,6 +740,22 @@ struct platform_device spear320_plgpio_device = {
 	.resource = plgpio_resources,
 };
 
+/* pwm device registeration */
+static struct resource pwm_resources[] = {
+	{
+		.start = SPEAR320_PWM_BASE,
+		.end = SPEAR320_PWM_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear320_pwm_device = {
+	.name = "pwm",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(pwm_resources),
+	.resource = pwm_resources,
+};
+
 /* spear320 routines */
 void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 4d747db..6190660 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -50,6 +50,7 @@ static struct platform_device *plat_devs[] __initdata = {
 
 	/* spear320 specific devices */
 	&spear320_plgpio_device,
+	&spear320_pwm_device,
 };
 
 static void __init spear320_evb_init(void)
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index ee5fd4a..21f31cd 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -38,4 +38,11 @@ source "arch/arm/mach-spear13xx/Kconfig"
 source "arch/arm/mach-spear3xx/Kconfig"
 source "arch/arm/mach-spear6xx/Kconfig"
 
+config SPEAR_PWM
+	tristate "SPEAr Pulse Width Modulator"
+	depends on MACH_SPEAR320
+	default y
+	help
+	  Support for ST Microelectronics Pulse Width Modulator present on SPEAr Platform.
+
 endif
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index f462c8f..636678a 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -9,3 +9,5 @@ obj-$(CONFIG_ARCH_SPEAR13XX)	+= padmux.o
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
 obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
+
+obj-$(CONFIG_SPEAR_PWM)		+= pwm.o
diff --git a/arch/arm/plat-spear/pwm.c b/arch/arm/plat-spear/pwm.c
new file mode 100644
index 0000000..307c725
--- /dev/null
+++ b/arch/arm/plat-spear/pwm.c
@@ -0,0 +1,484 @@
+/*
+ * arch/arm/plat-spear/pwm.c
+ *
+ * ST Microelectronics SPEAr Pulse Width Modulator driver
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* PWM registers and bits definitions */
+#define PWMCR			0x00
+#define PWMDCR			0x04
+#define PWMPCR			0x08
+
+#define PWM_EN_MASK		0x1
+#define MIN_PRESCALE		0x00
+#define MAX_PRESCALE		0x3FFF
+#define PRESCALE_SHIFT		2
+#define MIN_DUTY		0x0001
+#define MAX_DUTY		0xFFFF
+#define MAX_PERIOD		0xFFFF
+#define MIN_PERIOD		0x0001
+
+#define PWM_DEVICE_PER_IP	4
+#define PWM_DEVICE_OFFSET	0x10
+
+/* lock for pwm_list */
+static DEFINE_SPINLOCK(list_lock);
+/* list of all pwm ips available in system */
+static LIST_HEAD(pwm_list);
+
+/**
+ * struct pwm_device: struct representing pwm device/channel
+ *
+ * pwmd_id: id of pwm device
+ * pwm: pointer to parent pwm ip
+ * label: used for storing label passed in pwm_request
+ * offset: base address offset from parent pwm mmio_base
+ * busy: represents usage status of a pwm device
+ * lock: lock specific to a pwm device
+ * node: node for adding device to parent pwm's devices list
+ *
+ * Each pwm IP contains four independent pwm device/channels. Some or all of
+ * which may be present in our configuration.
+ */
+struct pwm_device {
+	unsigned pwmd_id;
+	struct pwm *pwm;
+	const char *label;
+	unsigned offset;
+	unsigned busy;
+	spinlock_t lock;
+	struct list_head node;
+};
+
+/**
+ * struct pwm: struct representing pwm ip
+ *
+ * id: id of pwm ip
+ * mmio_base: base address of pwm
+ * clk: pointer to clk structure of pwm ip
+ * clk_enabled: clock enable status
+ * pdev: pointer to pdev structure of pwm
+ * lock: lock specific to current pwm ip
+ * devices: list of devices/childrens of pwm ip
+ * node: node for adding pwm to global list of all pwm ips
+ */
+struct pwm {
+	unsigned id;
+	void __iomem *mmio_base;
+	struct clk *clk;
+	int clk_enabled;
+	struct platform_device *pdev;
+	spinlock_t lock;
+	struct list_head devices;
+	struct list_head node;
+};
+
+/*
+ * period_ns = 10^9 * (PRESCALE + 1) * PV / PWM_CLK_RATE
+ * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+ *
+ * PV = (PWM_CLK_RATE * period_ns)/ (10^9 * (PRESCALE + 1))
+ * DC = (PWM_CLK_RATE * duty_ns)/ (10^9 * (PRESCALE + 1))
+ */
+int pwm_config(struct pwm_device *pwmd, int duty_ns, int period_ns)
+{
+	u64 val, div, clk_rate;
+	unsigned long prescale = MIN_PRESCALE, pv, dc;
+	int ret = 0;
+
+	if (!pwmd) {
+		pr_err("pwm: config - NULL pwm device pointer\n");
+		return -EFAULT;
+	}
+
+	if (period_ns == 0 || duty_ns > period_ns) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* TODO: Need to optimize this loop */
+	while (1) {
+		div = 1000000000;
+		div *= 1 + prescale;
+		clk_rate = clk_get_rate(pwmd->pwm->clk);
+		val = clk_rate * period_ns;
+		pv = div64_u64(val, div);
+		val = clk_rate * duty_ns;
+		dc = div64_u64(val, div);
+
+		if ((pv == 0) || (dc == 0)) {
+			ret = -EINVAL;
+			goto err;
+		}
+		if ((pv > MAX_PERIOD) || (dc > MAX_DUTY)) {
+			prescale++;
+			if (prescale > MAX_PRESCALE) {
+				ret = -EINVAL;
+				goto err;
+			}
+			continue;
+		}
+		if ((pv < MIN_PERIOD) || (dc < MIN_DUTY)) {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	}
+
+	/*
+	 * NOTE: the clock to PWM has to be enabled first
+	 * before writing to the registers
+	 */
+	spin_lock(&pwmd->pwm->lock);
+	ret = clk_enable(pwmd->pwm->clk);
+	if (ret) {
+		spin_unlock(&pwmd->pwm->lock);
+		goto err;
+	}
+
+	spin_lock(&pwmd->lock);
+	writel(prescale << PRESCALE_SHIFT, pwmd->pwm->mmio_base +
+			pwmd->offset + PWMCR);
+	writel(dc, pwmd->pwm->mmio_base + pwmd->offset + PWMDCR);
+	writel(pv, pwmd->pwm->mmio_base + pwmd->offset + PWMPCR);
+	spin_unlock(&pwmd->lock);
+	clk_disable(pwmd->pwm->clk);
+	spin_unlock(&pwmd->pwm->lock);
+
+	return 0;
+err:
+	dev_err(&pwmd->pwm->pdev->dev, "pwm config fail\n");
+	return ret;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwmd)
+{
+	int ret = 0;
+	u32 val = 0;
+
+	if (!pwmd) {
+		pr_err("pwm: enable - NULL pwm device pointer\n");
+		return -EFAULT;
+	}
+
+	spin_lock(&pwmd->pwm->lock);
+	ret = clk_enable(pwmd->pwm->clk);
+	if (!ret)
+		pwmd->pwm->clk_enabled++;
+	else {
+		spin_unlock(&pwmd->pwm->lock);
+		goto err;
+	}
+
+	spin_lock(&pwmd->lock);
+	val = readl(pwmd->pwm->mmio_base + pwmd->offset + PWMCR);
+	writel(val | PWM_EN_MASK, pwmd->pwm->mmio_base + pwmd->offset + PWMCR);
+	spin_unlock(&pwmd->lock);
+	spin_unlock(&pwmd->pwm->lock);
+	return 0;
+err:
+	dev_err(&pwmd->pwm->pdev->dev, "pwm enable fail\n");
+	return ret;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwmd)
+{
+	if (!pwmd) {
+		pr_err("pwm: disable - NULL pwm device pointer\n");
+		return;
+	}
+
+	spin_lock(&pwmd->pwm->lock);
+	spin_lock(&pwmd->lock);
+	writel(0, pwmd->pwm->mmio_base + pwmd->offset + PWMCR);
+	if (pwmd->pwm->clk_enabled) {
+		clk_disable(pwmd->pwm->clk);
+		pwmd->pwm->clk_enabled--;
+	}
+	spin_unlock(&pwmd->lock);
+	spin_unlock(&pwmd->pwm->lock);
+}
+EXPORT_SYMBOL(pwm_disable);
+
+struct pwm_device *pwm_request(int pwmd_id, const char *label)
+{
+	int found = 0;
+	struct pwm *pwm;
+	struct pwm_device *pwmd = NULL;
+
+	spin_lock(&list_lock);
+	list_for_each_entry(pwm, &pwm_list, node) {
+		spin_lock(&pwm->lock);
+		list_for_each_entry(pwmd, &pwm->devices, node) {
+			if (pwmd->pwmd_id == pwmd_id) {
+				found = 1;
+				break;
+			}
+		}
+		spin_unlock(&pwm->lock);
+		if (found)
+			break;
+	}
+	spin_unlock(&list_lock);
+
+	if (found) {
+		spin_lock(&pwmd->lock);
+		if (pwmd->busy == 0) {
+			pwmd->busy++;
+			pwmd->label = label;
+		} else
+			pwmd = ERR_PTR(-EBUSY);
+		spin_unlock(&pwmd->lock);
+	} else
+		pwmd = ERR_PTR(-ENOENT);
+
+	if (IS_ERR(pwmd))
+		pr_err("pwm: request fail\n");
+
+	return pwmd;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwmd)
+{
+	if (!pwmd) {
+		pr_err("pwm: disable - NULL pwm device pointer\n");
+		return;
+	}
+
+	spin_lock(&pwmd->lock);
+	if (pwmd->busy) {
+		pwmd->busy--;
+		pwmd->label = NULL;
+	} else {
+		spin_unlock(&pwmd->lock);
+		dev_warn(&pwmd->pwm->pdev->dev, "pwm device already freed\n");
+		return;
+	}
+
+	spin_unlock(&pwmd->lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+/* creates and add pwmd device to parent pwm's devices list */
+static int add_pwm_device(unsigned int pwmd_id, struct pwm *pwm)
+{
+	struct pwm_device *pwmd;
+
+	pwmd = kzalloc(sizeof(*pwmd), GFP_KERNEL);
+	if (!pwmd)
+		return -ENOMEM;
+
+	pwmd->pwm = pwm;
+	pwmd->busy = 0;
+	pwmd->pwmd_id = pwmd_id + pwm->id * PWM_DEVICE_PER_IP;
+	pwmd->offset = pwmd_id * PWM_DEVICE_OFFSET;
+	spin_lock_init(&pwmd->lock);
+
+	spin_lock(&pwm->lock);
+	list_add_tail(&pwmd->node, &pwm->devices);
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+/* removes all pwmd devices from parent pwm's devices list */
+static void remove_pwm_devices(struct pwm *pwm)
+{
+	struct pwm_device *pwmd;
+
+	spin_lock(&pwm->lock);
+	list_for_each_entry(pwmd, &pwm->devices, node) {
+		list_del(&pwmd->node);
+		kfree(pwmd);
+	}
+	spin_unlock(&pwm->lock);
+}
+
+static int __devinit spear_pwm_probe(struct platform_device *pdev)
+{
+	struct pwm *pwm = NULL;
+	struct resource *res;
+	int ret = 0, pwmd_id = 0;
+
+	pwm = kzalloc(sizeof(*pwm), GFP_KERNEL);
+	if (!pwm) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "failed to allocate memory\n");
+		goto err;
+	}
+
+	pwm->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm->clk)) {
+		ret = PTR_ERR(pwm->clk);
+		dev_dbg(&pdev->dev, "Error getting clock\n");
+		goto err_free;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "no memory resource defined\n");
+		goto err_free_clk;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		ret = -EBUSY;
+		dev_dbg(&pdev->dev, "failed to request memory resource\n");
+		goto err_free_clk;
+	}
+
+	pwm->mmio_base = ioremap(res->start, resource_size(res));
+	if (!pwm->mmio_base) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "failed to ioremap\n");
+		goto err_free_mem;
+	}
+
+	/* initialize pwm structure */
+	pwm->clk_enabled = 0;
+	pwm->pdev = pdev;
+	/* if pdev->id is -1, only one pwm ip is present */
+	if (pdev->id == -1)
+		pwm->id = 0;
+	else
+		pwm->id = pdev->id;
+
+	spin_lock_init(&pwm->lock);
+	INIT_LIST_HEAD(&pwm->devices);
+	platform_set_drvdata(pdev, pwm);
+
+	/* add pwm to pwm list */
+	spin_lock(&list_lock);
+	list_add_tail(&pwm->node, &pwm_list);
+	spin_unlock(&list_lock);
+
+	/* add pwm devices */
+	for (pwmd_id = 0; pwmd_id < PWM_DEVICE_PER_IP; pwmd_id++) {
+		ret = add_pwm_device(pwmd_id, pwm);
+		if (!ret)
+			continue;
+		dev_err(&pdev->dev, "Add device fail for pwm device id: %d\n",
+				pwmd_id);
+	}
+
+	if (list_empty(&pwm->node))
+		goto err_remove_pwm;
+
+	dev_info(&pdev->dev, "Initialization successful\n");
+	return 0;
+
+err_remove_pwm:
+	spin_lock(&list_lock);
+	list_del(&pwm->node);
+	spin_unlock(&list_lock);
+
+	platform_set_drvdata(pdev, NULL);
+	iounmap(pwm->mmio_base);
+err_free_mem:
+	release_mem_region(res->start, resource_size(res));
+err_free_clk:
+	clk_put(pwm->clk);
+err_free:
+	kfree(pwm);
+err:
+	dev_err(&pdev->dev, "Initialization Fail. Error: %d\n", ret);
+
+	return ret;
+}
+
+static int __devexit spear_pwm_remove(struct platform_device *pdev)
+{
+	struct pwm *pwm;
+	struct resource *res;
+	int ret = 0;
+
+	pwm = platform_get_drvdata(pdev);
+	if (pwm == NULL) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "Remove: get_drvdata fail\n");
+		goto err;
+	}
+	platform_set_drvdata(pdev, NULL);
+
+	/* remove pwm devices */
+	remove_pwm_devices(pwm);
+
+	/* remove pwm from pwm_list */
+	spin_lock(&list_lock);
+	list_del(&pwm->node);
+	spin_unlock(&list_lock);
+
+	iounmap(pwm->mmio_base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "Remove: get_resource fail\n");
+		goto err;
+	}
+	release_mem_region(res->start, resource_size(res));
+
+	if (pwm->clk_enabled)
+		clk_disable(pwm->clk);
+	clk_put(pwm->clk);
+
+	kfree(pwm);
+	return 0;
+
+err:
+	dev_err(&pdev->dev, "Remove: Fail - %d\n", ret);
+	return ret;
+}
+
+static struct platform_driver spear_pwm_driver = {
+	.driver = {
+		.name = "pwm",
+		.bus = &platform_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = spear_pwm_probe,
+	.remove = __devexit_p(spear_pwm_remove)
+};
+
+static int __init spear_pwm_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&spear_pwm_driver);
+	if (ret)
+		pr_err("failed to register spear_pwm_driver\n");
+
+	return ret;
+}
+module_init(spear_pwm_init);
+
+static void __exit spear_pwm_exit(void)
+{
+	platform_driver_unregister(&spear_pwm_driver);
+}
+module_exit(spear_pwm_exit);
+
+MODULE_AUTHOR("Viresh Kumar");
+MODULE_DESCRIPTION("SPEAr PWM Driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* [PATCH V6 05/17] ST SPEAr: Adding Watchdog support on spear3xx & spear6xx machines
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (3 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 04/17] ST SPEAr3xx: Adding support for ST's PWM IP Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 06/17] ST SPEAr3xx: Adding RAS uart devices Viresh Kumar
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear3xx/spear300_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear310_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear320_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear3xx.c             |   12 ++++++++++++
 arch/arm/mach-spear6xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c         |    1 +
 arch/arm/mach-spear6xx/spear6xx.c             |   12 ++++++++++++
 8 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index f43d104..6d4db44 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -33,6 +33,7 @@
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device spear3xx_gpio_device;
 extern struct amba_device spear3xx_uart_device;
+extern struct amba_device spear3xx_wdt_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 69006f6..f4fd6db 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -36,6 +36,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
 	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear300 specific devices */
 	&spear300_gpio1_device,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index f6832c4..9c1b7ca 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -44,6 +44,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
 	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear310 specific devices */
 };
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 6190660..7b12f0c 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -41,6 +41,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
 	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear320 specific devices */
 };
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index c32a186..b07c659 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -54,6 +54,18 @@ struct amba_device spear3xx_uart_device = {
 	.irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
 };
 
+/* watchdog device registeration */
+struct amba_device spear3xx_wdt_device = {
+	.dev = {
+		.init_name = "wdt",
+	},
+	.res = {
+		.start = SPEAR3XX_ICM3_WDT_BASE,
+		.end = SPEAR3XX_ICM3_WDT_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 /* Do spear3xx familiy common initialization part here */
 void __init spear3xx_init(void)
 {
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 183f023..0d17e65 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -31,6 +31,7 @@
 /* Add spear6xx family device structure declarations here */
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
+extern struct amba_device wdt_device;
 extern struct sys_timer spear6xx_timer;
 
 /* Add spear6xx family function declarations here */
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index f19cefe..6730868 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -22,6 +22,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[2],
 	&uart_device[0],
 	&uart_device[1],
+	&wdt_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index e0f6628..3842545 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -99,6 +99,18 @@ struct amba_device gpio_device[] = {
 	}
 };
 
+/* watchdog device registeration */
+struct amba_device wdt_device = {
+	.dev = {
+		.init_name = "wdt",
+	},
+	.res = {
+		.start = SPEAR6XX_ICM3_WDT_BASE,
+		.end = SPEAR6XX_ICM3_WDT_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 /* This will add devices, and do machine specific tasks */
 void __init spear6xx_init(void)
 {
-- 
1.7.2.2

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

* [PATCH V6 06/17] ST SPEAr3xx: Adding RAS uart devices
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (4 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 05/17] ST SPEAr: Adding Watchdog support on spear3xx & spear6xx machines Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 07/17] ST SPEAr320: Adding support for CAN Viresh Kumar
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    7 +++
 arch/arm/mach-spear3xx/spear310.c             |   65 +++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear310_evb.c         |    5 ++
 arch/arm/mach-spear3xx/spear320.c             |   26 ++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c         |    2 +
 5 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 6d4db44..8925b7b 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -146,6 +146,11 @@ void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear310 declarations */
 #ifdef CONFIG_MACH_SPEAR310
 /* Add spear310 machine device structure declarations here */
+extern struct amba_device spear310_uart1_device;
+extern struct amba_device spear310_uart2_device;
+extern struct amba_device spear310_uart3_device;
+extern struct amba_device spear310_uart4_device;
+extern struct amba_device spear310_uart5_device;
 extern struct platform_device spear310_plgpio_device;
 
 /* pad mux devices */
@@ -168,6 +173,8 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear320 declarations */
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
+extern struct amba_device spear320_uart1_device;
+extern struct amba_device spear320_uart2_device;
 extern struct platform_device spear320_plgpio_device;
 extern struct platform_device spear320_pwm_device;
 
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index a4cd44c..ba21b75 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -309,6 +309,71 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* Add spear310 specific devices here */
+/* uart1 device registeration */
+struct amba_device spear310_uart1_device = {
+	.dev = {
+		.init_name = "uart1",
+	},
+	.res = {
+		.start = SPEAR310_UART1_BASE,
+		.end = SPEAR310_UART1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR310_VIRQ_UART1, NO_IRQ},
+};
+
+/* uart2 device registeration */
+struct amba_device spear310_uart2_device = {
+	.dev = {
+		.init_name = "uart2",
+	},
+	.res = {
+		.start = SPEAR310_UART2_BASE,
+		.end = SPEAR310_UART2_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR310_VIRQ_UART2, NO_IRQ},
+};
+
+/* uart3 device registeration */
+struct amba_device spear310_uart3_device = {
+	.dev = {
+		.init_name = "uart3",
+	},
+	.res = {
+		.start = SPEAR310_UART3_BASE,
+		.end = SPEAR310_UART3_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR310_VIRQ_UART3, NO_IRQ},
+};
+
+/* uart4 device registeration */
+struct amba_device spear310_uart4_device = {
+	.dev = {
+		.init_name = "uart4",
+	},
+	.res = {
+		.start = SPEAR310_UART4_BASE,
+		.end = SPEAR310_UART4_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR310_VIRQ_UART4, NO_IRQ},
+};
+
+/* uart5 device registeration */
+struct amba_device spear310_uart5_device = {
+	.dev = {
+		.init_name = "uart5",
+	},
+	.res = {
+		.start = SPEAR310_UART5_BASE,
+		.end = SPEAR310_UART5_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR310_VIRQ_UART5, NO_IRQ},
+};
+
 /* plgpio device registeration */
 /*
  * pin to offset and offset to pin converter functions
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 9c1b7ca..36fb611 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -47,6 +47,11 @@ static struct amba_device *amba_devs[] __initdata = {
 	&spear3xx_wdt_device,
 
 	/* spear310 specific devices */
+	&spear310_uart1_device,
+	&spear310_uart2_device,
+	&spear310_uart3_device,
+	&spear310_uart4_device,
+	&spear310_uart5_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index c1642c1..77089a7 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -712,6 +712,32 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* Add spear320 specific devices here */
+/* uart1 device registeration */
+struct amba_device spear320_uart1_device = {
+	.dev = {
+		.init_name = "uart1",
+	},
+	.res = {
+		.start = SPEAR320_UART1_BASE,
+		.end = SPEAR320_UART1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR320_VIRQ_UART1, NO_IRQ},
+};
+
+/* uart2 device registeration */
+struct amba_device spear320_uart2_device = {
+	.dev = {
+		.init_name = "uart2",
+	},
+	.res = {
+		.start = SPEAR320_UART2_BASE,
+		.end = SPEAR320_UART2_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR320_VIRQ_UART2, NO_IRQ},
+};
+
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 7b12f0c..ebc4bb9 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -44,6 +44,8 @@ static struct amba_device *amba_devs[] __initdata = {
 	&spear3xx_wdt_device,
 
 	/* spear320 specific devices */
+	&spear320_uart1_device,
+	&spear320_uart2_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
-- 
1.7.2.2

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

* [PATCH V6 07/17] ST SPEAr320: Adding support for CAN
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (5 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 06/17] ST SPEAr3xx: Adding RAS uart devices Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 08/17] ST SPEAr3xx: EMI (External Memory Interface) controller driver Viresh Kumar
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    2 +
 arch/arm/mach-spear3xx/spear320.c             |   37 +++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c         |    2 +
 3 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 8925b7b..e8dfbb5 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -175,6 +175,8 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device spear320_uart1_device;
 extern struct amba_device spear320_uart2_device;
+extern struct platform_device spear320_can0_device;
+extern struct platform_device spear320_can1_device;
 extern struct platform_device spear320_plgpio_device;
 extern struct platform_device spear320_pwm_device;
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 77089a7..3f058c7 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -738,6 +738,43 @@ struct amba_device spear320_uart2_device = {
 	.irq = {SPEAR320_VIRQ_UART2, NO_IRQ},
 };
 
+/* CAN device registeration */
+static struct resource can0_resources[] = {
+	{
+		.start = SPEAR320_CAN0_BASE,
+		.end = SPEAR320_CAN0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	}, {
+		.start = SPEAR320_VIRQ_CANU,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear320_can0_device = {
+	.name = "c_can_platform",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(can0_resources),
+	.resource = can0_resources,
+};
+
+static struct resource can1_resources[] = {
+	{
+		.start = SPEAR320_CAN1_BASE,
+		.end = SPEAR320_CAN1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	}, {
+		.start = SPEAR320_VIRQ_CANL,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear320_can1_device = {
+	.name = "c_can_platform",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(can1_resources),
+	.resource = can1_resources,
+};
+
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index ebc4bb9..f2c3cd3 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -52,6 +52,8 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 
 	/* spear320 specific devices */
+	&spear320_can0_device,
+	&spear320_can1_device,
 	&spear320_plgpio_device,
 	&spear320_pwm_device,
 };
-- 
1.7.2.2

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

* [PATCH V6 08/17] ST SPEAr3xx: EMI (External Memory Interface) controller driver
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (6 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 07/17] ST SPEAr320: Adding support for CAN Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:27 ` [PATCH V6 09/17] ST SPEAr: Adding machine support for rtc-spear Viresh Kumar
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vipin Kumar <vipin.kumar@st.com>

Two SPEAr platform SoCs(spear310 and spear320) support an External Memory
Interface controller. This controller is used to interface with
Parallel NOR Flash devices.

This patch adds just the platform code needed for EMI (mainly EMI
initialization). The driver being used is driver/mtd/maps/physmap.c

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/Makefile                |    4 +
 arch/arm/mach-spear3xx/emi.c                   |   98 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/emi.h      |   61 +++++++++++++++
 arch/arm/mach-spear3xx/include/mach/spear310.h |    9 ++
 arch/arm/mach-spear3xx/include/mach/spear320.h |    6 ++
 arch/arm/mach-spear3xx/spear310_evb.c          |   35 +++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   35 +++++++++
 7 files changed, 248 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-spear3xx/emi.c
 create mode 100644 arch/arm/mach-spear3xx/include/mach/emi.h

diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
index b248624..d38ae47 100644
--- a/arch/arm/mach-spear3xx/Makefile
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -24,3 +24,7 @@ obj-$(CONFIG_MACH_SPEAR320) += spear320.o
 
 # spear320 boards files
 obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o
+
+# specific files
+obj-$(CONFIG_MACH_SPEAR310) += emi.o
+obj-$(CONFIG_MACH_SPEAR320) += emi.o
diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c
new file mode 100644
index 0000000..4d01322
--- /dev/null
+++ b/arch/arm/mach-spear3xx/emi.c
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/mach-spear3xx/emi.c
+ *
+ * EMI (External Memory Interface) file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Vipin Kumar<vipin.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/mach-types.h>
+#include <mach/emi.h>
+
+int __init emi_init(unsigned long base, u32 bank, u32 width)
+{
+	void __iomem *emi_reg_base;
+	struct clk *clk;
+	int ret;
+	u32 ack_reg, max_banks;
+	/* u32 timeout_reg, irq_reg; */
+
+	/* fixing machine dependent values */
+	if (machine_is_spear310()) {
+		ack_reg = SPEAR310_ACK_REG;
+		max_banks = SPEAR310_EMI_MAX_BANKS;
+		/* timeout_reg = SPEAR310_TIMEOUT_REG; */
+		/* irq_reg = SPEAR310_IRQ_REG; */
+	} else {
+		ack_reg = SPEAR320_ACK_REG;
+		max_banks = SPEAR320_EMI_MAX_BANKS;
+		/* timeout_reg = SPEAR320_TIMEOUT_REG; */
+		/* irq_reg = SPEAR320_IRQ_REG; */
+	}
+
+	if (bank > (max_banks - 1))
+		return -EINVAL;
+
+	emi_reg_base = ioremap(base, EMI_REG_SIZE);
+	if (!emi_reg_base)
+		return -ENOMEM;
+
+	clk = clk_get(NULL, "emi");
+	if (IS_ERR(clk)) {
+		iounmap(emi_reg_base);
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_enable(clk);
+	if (ret) {
+		iounmap(emi_reg_base);
+		return ret;
+	}
+
+	/*
+	 * Note: These are relaxed NOR device timings. Nor devices on spear
+	 * eval machines are working fine with these timings. Specific board
+	 * files can optimize these timings based on devices found on board.
+	 */
+	writel(0x10, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TAP_REG);
+	writel(0x05, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TSDP_REG);
+	writel(0x0a, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDPW_REG);
+	writel(0x0a, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDPR_REG);
+	writel(0x05, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDCS_REG);
+
+	switch (width) {
+	case EMI_FLASH_WIDTH8:
+		width = EMI_CNTL_WIDTH8;
+		break;
+
+	case EMI_FLASH_WIDTH16:
+		width = EMI_CNTL_WIDTH16;
+		break;
+
+	case EMI_FLASH_WIDTH32:
+		width = EMI_CNTL_WIDTH32;
+		break;
+	default:
+		width = EMI_CNTL_WIDTH8;
+		break;
+	}
+	/* set the data width */
+	writel(width | EMI_CNTL_ENBBYTERW,
+		emi_reg_base + (EMI_BANK_REG_SIZE * bank) + CTRL_REG);
+
+	/* disable all the acks */
+	writel(0x3f, emi_reg_base + ack_reg);
+
+	iounmap(emi_reg_base);
+
+	return 0;
+}
diff --git a/arch/arm/mach-spear3xx/include/mach/emi.h b/arch/arm/mach-spear3xx/include/mach/emi.h
new file mode 100644
index 0000000..c15b12e
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/emi.h
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/emi.h
+ *
+ * EMI macros for SPEAr platform
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Vipin Kumar <vipin.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_EMI_H
+#define __MACH_EMI_H
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#define EMI_FLASH_WIDTH8	1
+#define EMI_FLASH_WIDTH16	2
+#define EMI_FLASH_WIDTH32	4
+
+#define EMI_REG_SIZE		0x100
+#define EMI_BANK_REG_SIZE	0x18
+
+#define TAP_REG			(0x0)
+#define TSDP_REG		(0x4)
+#define TDPW_REG		(0x8)
+#define TDPR_REG		(0xC)
+#define TDCS_REG		(0x10)
+#define CTRL_REG		(0x14)
+
+#if defined(CONFIG_MACH_SPEAR310)
+#define SPEAR310_TIMEOUT_REG	(0x90)
+#define SPEAR310_ACK_REG	(0x94)
+#define SPEAR310_IRQ_REG	(0x98)
+
+#define SPEAR310_EMI_MAX_BANKS	6
+#endif
+
+#if defined(CONFIG_MACH_SPEAR320)
+#define SPEAR320_TIMEOUT_REG	(0x60)
+#define SPEAR320_ACK_REG	(0x64)
+#define SPEAR320_IRQ_REG	(0x68)
+
+#define SPEAR320_EMI_MAX_BANKS	4
+
+#endif
+
+/* Control register definitions */
+#define EMI_CNTL_WIDTH8		(0 << 0)
+#define EMI_CNTL_WIDTH16	(1 << 0)
+#define EMI_CNTL_WIDTH32	(2 << 0)
+#define EMI_CNTL_ENBBYTEW	(1 << 2)
+#define EMI_CNTL_ENBBYTER	(1 << 3)
+#define EMI_CNTL_ENBBYTERW	(EMI_CNTL_ENBBYTER | EMI_CNTL_ENBBYTEW)
+
+extern int __init emi_init(unsigned long base, u32 bank, u32 width);
+#endif
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
index 1567d0da..0780c47 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear310.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -18,6 +18,15 @@
 
 #define SPEAR310_NAND_BASE		UL(0x40000000)
 #define SPEAR310_FSMC_BASE		UL(0x44000000)
+#define SPEAR310_EMI_REG_BASE		UL(0x4F000000)
+#define SPEAR310_EMI_MEM_0_BASE		UL(0x50000000)
+#define SPEAR310_EMI_MEM_1_BASE		UL(0x60000000)
+#define SPEAR310_EMI_MEM_2_BASE		UL(0x70000000)
+#define SPEAR310_EMI_MEM_3_BASE		UL(0x80000000)
+#define SPEAR310_EMI_MEM_4_BASE		UL(0x90000000)
+#define SPEAR310_EMI_MEM_5_BASE		UL(0xA0000000)
+#define SPEAR310_EMI_MEM_SIZE		UL(0x10000000)
+
 #define SPEAR310_UART1_BASE		UL(0xB2000000)
 #define SPEAR310_UART2_BASE		UL(0xB2080000)
 #define SPEAR310_UART3_BASE		UL(0xB2100000)
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index 8cfa83f..30ea941 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -17,6 +17,12 @@
 #define __MACH_SPEAR320_H
 
 #define SPEAR320_EMI_CTRL_BASE		UL(0x40000000)
+#define SPEAR320_EMI_MEM_0_BASE		UL(0x44000000)
+#define SPEAR320_EMI_MEM_1_BASE		UL(0x45000000)
+#define SPEAR320_EMI_MEM_2_BASE		UL(0x46000000)
+#define SPEAR320_EMI_MEM_3_BASE		UL(0x47000000)
+#define SPEAR320_EMI_MEM_SIZE		UL(0x01000000)
+
 #define SPEAR320_FSMC_BASE		UL(0x4C000000)
 #define SPEAR320_NAND_BASE		UL(0x50000000)
 #define SPEAR320_I2S_BASE		UL(0x60000000)
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 36fb611..8d5becb 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -13,9 +13,40 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+#define PARTITION(n, off, sz)	{.name = n, .offset = off, .size = sz}
+static struct mtd_partition partition_info[] = {
+	PARTITION("X-loader", 0, 1 * 0x20000),
+	PARTITION("U-Boot", 0x20000, 3 * 0x20000),
+	PARTITION("Kernel", 0x80000, 24 * 0x20000),
+	PARTITION("Root File System", 0x380000, 84 * 0x20000),
+};
+
+/* emi nor flash resources registeration */
+static struct resource emi_nor_resources[] = {
+	{
+		.start	= SPEAR310_EMI_MEM_0_BASE,
+		.end	= SPEAR310_EMI_MEM_0_BASE + SPEAR310_EMI_MEM_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct physmap_flash_data emi_norflash_data = {
+	.parts = partition_info,
+	.nr_parts = ARRAY_SIZE(partition_info),
+	.width = 4,
+};
+static struct platform_device spear310_emi_nor_device = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.dev.platform_data = &emi_norflash_data,
+	.resource = emi_nor_resources,
+	.num_resources = ARRAY_SIZE(emi_nor_resources),
+};
+
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
@@ -58,6 +89,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 
 	/* spear310 specific devices */
+	&spear310_emi_nor_device,
 	&spear310_plgpio_device,
 };
 
@@ -68,6 +100,9 @@ static void __init spear310_evb_init(void)
 	/* call spear310 machine init function */
 	spear310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+	/* Initialize emi regiters */
+	emi_init(SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32);
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index f2c3cd3..8addd5f 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -13,9 +13,40 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+#define PARTITION(n, off, sz)	{.name = n, .offset = off, .size = sz}
+static struct mtd_partition partition_info[] = {
+	PARTITION("X-loader", 0, 1 * 0x20000),
+	PARTITION("U-Boot", 0x20000, 3 * 0x20000),
+	PARTITION("Kernel", 0x80000, 24 * 0x20000),
+	PARTITION("Root File System", 0x380000, 84 * 0x20000),
+};
+
+/* emi nor flash resources registeration */
+static struct resource emi_nor_resources[] = {
+	{
+		.start	= SPEAR320_EMI_MEM_0_BASE,
+		.end	= SPEAR320_EMI_MEM_0_BASE + SPEAR320_EMI_MEM_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct physmap_flash_data emi_norflash_data = {
+	.parts = partition_info,
+	.nr_parts = ARRAY_SIZE(partition_info),
+	.width = 2,
+};
+static struct platform_device spear320_emi_nor_device = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.dev.platform_data = &emi_norflash_data,
+	.resource = emi_nor_resources,
+	.num_resources = ARRAY_SIZE(emi_nor_resources),
+};
+
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
@@ -54,6 +85,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear320 specific devices */
 	&spear320_can0_device,
 	&spear320_can1_device,
+	&spear320_emi_nor_device,
 	&spear320_plgpio_device,
 	&spear320_pwm_device,
 };
@@ -66,6 +98,9 @@ static void __init spear320_evb_init(void)
 	spear320_init(&spear320_auto_net_mii_mode, pmx_devs,
 			ARRAY_SIZE(pmx_devs));
 
+	/* Initialize emi regiters */
+	emi_init(SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16);
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
-- 
1.7.2.2

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

* [PATCH V6 09/17] ST SPEAr: Adding machine support for rtc-spear
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (7 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 08/17] ST SPEAr3xx: EMI (External Memory Interface) controller driver Viresh Kumar
@ 2011-03-01 11:27 ` Viresh Kumar
  2011-03-01 11:30 ` [PATCH V6 10/17] ST SPEAr: adding support for synopsis i2c designware Viresh Kumar
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.kumar@st.com>

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear1310_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear13xx.c            |   19 +++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300_evb.c          |    1 +
 arch/arm/mach-spear3xx/spear310_evb.c          |    1 +
 arch/arm/mach-spear3xx/spear320_evb.c          |    1 +
 arch/arm/mach-spear3xx/spear3xx.c              |   19 +++++++++++++++++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    1 +
 arch/arm/mach-spear6xx/spear6xx.c              |   19 +++++++++++++++++++
 12 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index de9de17..b598236 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -223,6 +223,7 @@ extern struct pmx_dev pmx_uart1_modem;
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device spear13xx_gpio_device[];
 extern struct amba_device spear13xx_uart_device;
+extern struct platform_device spear13xx_rtc_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 4799ae1..796d04c 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -44,6 +44,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&spear13xx_rtc_device,
 };
 
 #ifdef CONFIG_PCIEPORTBUS
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 2e74879..1eea995 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -59,6 +59,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear13xx specific devices */
+	&spear13xx_rtc_device,
 
 	/* spear1310 specific devices */
 	&spear1310_can0_device,
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 6c2525a..e9ba888 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -76,6 +76,25 @@ struct amba_device spear13xx_uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+/* rtc device registration */
+static struct resource rtc_resources[] = {
+	{
+		.start = SPEAR13XX_RTC_BASE,
+		.end = SPEAR13XX_RTC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear13xx_rtc_device = {
+	.name = "rtc-spear",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(rtc_resources),
+	.resource = rtc_resources,
+};
+
 #ifdef CONFIG_PCIEPORTBUS
 /* PCIE0 clock always needs to be enabled if any of the three PCIE port
  * have to be used. So call this function from the board initilization
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index e8dfbb5..73f3f3b 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -34,6 +34,7 @@
 extern struct amba_device spear3xx_gpio_device;
 extern struct amba_device spear3xx_uart_device;
 extern struct amba_device spear3xx_wdt_device;
+extern struct platform_device spear3xx_rtc_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index f4fd6db..e4a9a4f 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -44,6 +44,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_rtc_device,
 
 	/* spear300 specific devices */
 };
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 8d5becb..97c9551 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -87,6 +87,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_rtc_device,
 
 	/* spear310 specific devices */
 	&spear310_emi_nor_device,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 8addd5f..17248f4 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -81,6 +81,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_rtc_device,
 
 	/* spear320 specific devices */
 	&spear320_can0_device,
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index b07c659..6e8bcd0 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -66,6 +66,25 @@ struct amba_device spear3xx_wdt_device = {
 	},
 };
 
+/* rtc device registration */
+static struct resource rtc_resources[] = {
+	{
+		.start = SPEAR3XX_ICM3_RTC_BASE,
+		.end = SPEAR3XX_ICM3_RTC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR3XX_IRQ_BASIC_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear3xx_rtc_device = {
+	.name = "rtc-spear",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(rtc_resources),
+	.resource = rtc_resources,
+};
+
 /* Do spear3xx familiy common initialization part here */
 void __init spear3xx_init(void)
 {
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 0d17e65..9b7a758 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -32,6 +32,7 @@
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
 extern struct amba_device wdt_device;
+extern struct platform_device rtc_device;
 extern struct sys_timer spear6xx_timer;
 
 /* Add spear6xx family function declarations here */
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index 6730868..2b8cd87 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -26,6 +26,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&rtc_device,
 };
 
 static void __init spear600_evb_init(void)
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 3842545..f976377 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -111,6 +111,25 @@ struct amba_device wdt_device = {
 	},
 };
 
+/* rtc device registration */
+static struct resource rtc_resources[] = {
+	{
+		.start = SPEAR6XX_ICM3_RTC_BASE,
+		.end = SPEAR6XX_ICM3_RTC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_BASIC_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device rtc_device = {
+	.name = "rtc-spear",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(rtc_resources),
+	.resource = rtc_resources,
+};
+
 /* This will add devices, and do machine specific tasks */
 void __init spear6xx_init(void)
 {
-- 
1.7.2.2

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

* [PATCH V6 10/17] ST SPEAr: adding support for synopsis i2c designware
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (8 preceding siblings ...)
  2011-03-01 11:27 ` [PATCH V6 09/17] ST SPEAr: Adding machine support for rtc-spear Viresh Kumar
@ 2011-03-01 11:30 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 11/17] ST SPEAr: Adding machine support for USB host Viresh Kumar
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.kumar@st.com>

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    3 ++
 arch/arm/mach-spear13xx/spear1300_evb.c        |    4 +++
 arch/arm/mach-spear13xx/spear1310.c            |   22 ++++++++++++++++++
 arch/arm/mach-spear13xx/spear1310_evb.c        |    5 ++++
 arch/arm/mach-spear13xx/spear13xx.c            |   22 ++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    3 ++
 arch/arm/mach-spear3xx/spear300_evb.c          |    4 +++
 arch/arm/mach-spear3xx/spear310_evb.c          |    4 +++
 arch/arm/mach-spear3xx/spear320.c              |   22 ++++++++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |    5 ++++
 arch/arm/mach-spear3xx/spear3xx.c              |   22 ++++++++++++++++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    2 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    4 +++
 arch/arm/mach-spear6xx/spear6xx.c              |   22 ++++++++++++++++++
 arch/arm/plat-spear/Makefile                   |    7 +++++
 arch/arm/plat-spear/i2c_eval_board.c           |   29 ++++++++++++++++++++++++
 16 files changed, 180 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/i2c_eval_board.c

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index b598236..991abda 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -223,10 +223,12 @@ extern struct pmx_dev pmx_uart1_modem;
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device spear13xx_gpio_device[];
 extern struct amba_device spear13xx_uart_device;
+extern struct platform_device spear13xx_i2c_device;
 extern struct platform_device spear13xx_rtc_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
+void __init i2c_register_default_devices(void);
 void __init spear13xx_clk_init(void);
 void __init spear_setup_timer(void);
 void __init spear13xx_map_io(void);
@@ -252,6 +254,7 @@ extern struct amba_device spear1310_uart4_device;
 extern struct amba_device spear1310_uart5_device;
 extern struct platform_device spear1310_can0_device;
 extern struct platform_device spear1310_can1_device;
+extern struct platform_device spear1310_i2c1_device;
 
 /* Add spear1310 machine function declarations here */
 void __init spear1310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 796d04c..69accb2 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -44,6 +44,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&spear13xx_i2c_device,
 	&spear13xx_rtc_device,
 };
 
@@ -84,6 +85,9 @@ static void __init spear1300_evb_init(void)
 	pcie_init(spear1300_pcie_port_is_host);
 #endif
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 21ec388..18e38c9 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -458,6 +458,28 @@ struct platform_device spear1310_can1_device = {
 	.resource = can1_resources,
 };
 
+/* i2c1 device registeration */
+static struct resource i2c1_resources[] = {
+	{
+		.start = SPEAR1310_I2C1_BASE,
+		.end = SPEAR1310_I2C1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_I2C_CNTR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear1310_i2c1_device = {
+	.name = "i2c_designware",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c1_resources),
+	.resource = i2c1_resources,
+};
+
 /* Following will create 1310 specific static virtual/physical mappings */
 struct map_desc spear1310_io_desc[] __initdata = {
 	{
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 1eea995..891018e 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -59,11 +59,13 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear13xx specific devices */
+	&spear13xx_i2c_device,
 	&spear13xx_rtc_device,
 
 	/* spear1310 specific devices */
 	&spear1310_can0_device,
 	&spear1310_can1_device,
+	&spear1310_i2c1_device,
 };
 
 #ifdef CONFIG_PCIEPORTBUS
@@ -103,6 +105,9 @@ static void __init spear1310_evb_init(void)
 	pcie_init(spear1310_pcie_port_is_host);
 #endif
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index e9ba888..1ee23e6 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -76,6 +76,28 @@ struct amba_device spear13xx_uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+/* i2c device registeration */
+static struct resource i2c_resources[] = {
+	{
+		.start = SPEAR13XX_I2C_BASE,
+		.end = SPEAR13XX_I2C_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear13xx_i2c_device = {
+	.name = "i2c_designware",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c_resources),
+	.resource = i2c_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 73f3f3b..97e9235 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -34,10 +34,12 @@
 extern struct amba_device spear3xx_gpio_device;
 extern struct amba_device spear3xx_uart_device;
 extern struct amba_device spear3xx_wdt_device;
+extern struct platform_device spear3xx_i2c_device;
 extern struct platform_device spear3xx_rtc_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
+void __init i2c_register_default_devices(void);
 void __init spear3xx_clk_init(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
@@ -178,6 +180,7 @@ extern struct amba_device spear320_uart1_device;
 extern struct amba_device spear320_uart2_device;
 extern struct platform_device spear320_can0_device;
 extern struct platform_device spear320_can1_device;
+extern struct platform_device spear320_i2c1_device;
 extern struct platform_device spear320_plgpio_device;
 extern struct platform_device spear320_pwm_device;
 
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index e4a9a4f..0d2b365 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -44,6 +44,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_i2c_device,
 	&spear3xx_rtc_device,
 
 	/* spear300 specific devices */
@@ -57,6 +58,9 @@ static void __init spear300_evb_init(void)
 	spear300_init(&spear300_photo_frame_mode, pmx_devs,
 			ARRAY_SIZE(pmx_devs));
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 97c9551..59f69d5 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -87,6 +87,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_i2c_device,
 	&spear3xx_rtc_device,
 
 	/* spear310 specific devices */
@@ -104,6 +105,9 @@ static void __init spear310_evb_init(void)
 	/* Initialize emi regiters */
 	emi_init(SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32);
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 3f058c7..047dcae 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -775,6 +775,28 @@ struct platform_device spear320_can1_device = {
 	.resource = can1_resources,
 };
 
+/* i2c1 device registeration */
+static struct resource i2c1_resources[] = {
+	{
+		.start = SPEAR320_I2C_BASE,
+		.end = SPEAR320_I2C_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR320_VIRQ_I2C1 ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear320_i2c1_device = {
+	.name = "i2c_designware",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c1_resources),
+	.resource = i2c1_resources,
+};
+
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 17248f4..40d62ae 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -81,11 +81,13 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_i2c_device,
 	&spear3xx_rtc_device,
 
 	/* spear320 specific devices */
 	&spear320_can0_device,
 	&spear320_can1_device,
+	&spear320_i2c1_device,
 	&spear320_emi_nor_device,
 	&spear320_plgpio_device,
 	&spear320_pwm_device,
@@ -102,6 +104,9 @@ static void __init spear320_evb_init(void)
 	/* Initialize emi regiters */
 	emi_init(SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16);
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 6e8bcd0..f9b5bb1 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -66,6 +66,28 @@ struct amba_device spear3xx_wdt_device = {
 	},
 };
 
+/* i2c device registeration */
+static struct resource i2c_resources[] = {
+	{
+		.start = SPEAR3XX_ICM1_I2C_BASE,
+		.end = SPEAR3XX_ICM1_I2C_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR3XX_IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear3xx_i2c_device = {
+	.name = "i2c_designware",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c_resources),
+	.resource = i2c_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 9b7a758..fee7f69 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -32,10 +32,12 @@
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
 extern struct amba_device wdt_device;
+extern struct platform_device i2c_device;
 extern struct platform_device rtc_device;
 extern struct sys_timer spear6xx_timer;
 
 /* Add spear6xx family function declarations here */
+void __init i2c_register_default_devices(void);
 void __init spear_setup_timer(void);
 void __init spear6xx_map_io(void);
 void __init spear6xx_init_irq(void);
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index 2b8cd87..d8af2bd 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -26,6 +26,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&i2c_device,
 	&rtc_device,
 };
 
@@ -36,6 +37,9 @@ static void __init spear600_evb_init(void)
 	/* call spear600 machine init function */
 	spear600_init();
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_default_devices();
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index f976377..fb0a46b 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -111,6 +111,28 @@ struct amba_device wdt_device = {
 	},
 };
 
+/* i2c device registeration */
+static struct resource i2c_resources[] = {
+	{
+		.start = SPEAR6XX_ICM1_I2C_BASE,
+		.end = SPEAR6XX_ICM1_I2C_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device i2c_device = {
+	.name = "i2c_designware",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c_resources),
+	.resource = i2c_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 636678a..44923e9 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -11,3 +11,10 @@ obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
 obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
 
 obj-$(CONFIG_SPEAR_PWM)		+= pwm.o
+
+obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= i2c_eval_board.o
+obj-$(CONFIG_BOARD_SPEAR1310_EVB)	+= i2c_eval_board.o
+obj-$(CONFIG_BOARD_SPEAR300_EVB)	+= i2c_eval_board.o
+obj-$(CONFIG_BOARD_SPEAR310_EVB)	+= i2c_eval_board.o
+obj-$(CONFIG_BOARD_SPEAR320_EVB)	+= i2c_eval_board.o
+obj-$(CONFIG_BOARD_SPEAR600_EVB)	+= i2c_eval_board.o
diff --git a/arch/arm/plat-spear/i2c_eval_board.c b/arch/arm/plat-spear/i2c_eval_board.c
new file mode 100644
index 0000000..869d9c9
--- /dev/null
+++ b/arch/arm/plat-spear/i2c_eval_board.c
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/plat-spear/i2c_eval_board.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+
+static struct i2c_board_info __initdata i2c_board_info[] = {
+	{
+		.type = "eeprom",
+		.addr = 0x50,
+	}, {
+		.type = "eeprom",
+		.addr = 0x51,
+	},
+};
+
+void __init i2c_register_default_devices(void)
+{
+	i2c_register_board_info(0, i2c_board_info,
+				ARRAY_SIZE(i2c_board_info));
+}
-- 
1.7.2.2

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

* [PATCH V6 11/17] ST SPEAr: Adding machine support for USB host
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (9 preceding siblings ...)
  2011-03-01 11:30 ` [PATCH V6 10/17] ST SPEAr: adding support for synopsis i2c designware Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 12/17] ST SPEAr: Adding machine support for keyboard Viresh Kumar
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Deepak Sikri <deepak.sikri@st.com>

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    4 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    4 +
 arch/arm/mach-spear13xx/spear1310_evb.c        |    4 +
 arch/arm/mach-spear13xx/spear13xx.c            |  106 +++++++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    3 +
 arch/arm/mach-spear3xx/spear300_evb.c          |    3 +
 arch/arm/mach-spear3xx/spear310_evb.c          |    3 +
 arch/arm/mach-spear3xx/spear320_evb.c          |    3 +
 arch/arm/mach-spear3xx/spear3xx.c              |   77 +++++++++++++++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    4 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    4 +
 arch/arm/mach-spear6xx/spear6xx.c              |  108 ++++++++++++++++++++++++
 12 files changed, 323 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 991abda..9a9b6a3 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -223,7 +223,11 @@ extern struct pmx_dev pmx_uart1_modem;
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device spear13xx_gpio_device[];
 extern struct amba_device spear13xx_uart_device;
+extern struct platform_device spear13xx_ehci0_device;
+extern struct platform_device spear13xx_ehci1_device;
 extern struct platform_device spear13xx_i2c_device;
+extern struct platform_device spear13xx_ohci0_device;
+extern struct platform_device spear13xx_ohci1_device;
 extern struct platform_device spear13xx_rtc_device;
 extern struct sys_timer spear13xx_timer;
 
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 69accb2..c0066a6 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -44,7 +44,11 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&spear13xx_ehci0_device,
+	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
+	&spear13xx_ohci0_device,
+	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
 };
 
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 891018e..d58d3ff 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -59,7 +59,11 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear13xx specific devices */
+	&spear13xx_ehci0_device,
+	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
+	&spear13xx_ohci0_device,
+	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
 
 	/* spear1310 specific devices */
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 1ee23e6..69ead0f 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -98,6 +98,112 @@ struct platform_device spear13xx_i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* usb host device registeration */
+static struct resource ehci0_resources[] = {
+	[0] = {
+		.start = SPEAR13XX_UHC0_EHCI_BASE,
+		.end = SPEAR13XX_UHC0_EHCI_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH_EHCI0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ehci1_resources[] = {
+	[0] = {
+		.start = SPEAR13XX_UHC1_EHCI_BASE,
+		.end = SPEAR13XX_UHC1_EHCI_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH_EHCI1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ohci0_resources[] = {
+	[0] = {
+		.start = SPEAR13XX_UHC0_OHCI_BASE,
+		.end = SPEAR13XX_UHC0_OHCI_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH_OHCI0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+static struct resource ohci1_resources[] = {
+	[0] = {
+		.start = SPEAR13XX_UHC1_OHCI_BASE,
+		.end = SPEAR13XX_UHC1_OHCI_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH_OHCI1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* usbh0_id defaults to 0, being static variable */
+static int usbh0_id;
+static int usbh1_id = 1;
+static u64 ehci0_dmamask = ~0;
+
+struct platform_device spear13xx_ehci0_device = {
+	.name = "spear-ehci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ehci0_dmamask,
+		.platform_data = &usbh0_id,
+	},
+	.num_resources = ARRAY_SIZE(ehci0_resources),
+	.resource = ehci0_resources,
+};
+
+static u64 ehci1_dmamask = ~0;
+
+struct platform_device spear13xx_ehci1_device = {
+	.name = "spear-ehci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ehci1_dmamask,
+		.platform_data = &usbh1_id,
+	},
+	.num_resources = ARRAY_SIZE(ehci1_resources),
+	.resource = ehci1_resources,
+};
+
+static u64 ohci0_dmamask = ~0;
+
+struct platform_device spear13xx_ohci0_device = {
+	.name = "spear-ohci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci0_dmamask,
+		.platform_data = &usbh0_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci0_resources),
+	.resource = ohci0_resources,
+};
+
+static u64 ohci1_dmamask = ~0;
+struct platform_device spear13xx_ohci1_device = {
+	.name = "spear-ohci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci1_dmamask,
+		.platform_data = &usbh1_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci1_resources),
+	.resource = ohci1_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 97e9235..ea21478 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -34,7 +34,10 @@
 extern struct amba_device spear3xx_gpio_device;
 extern struct amba_device spear3xx_uart_device;
 extern struct amba_device spear3xx_wdt_device;
+extern struct platform_device spear3xx_ehci_device;
 extern struct platform_device spear3xx_i2c_device;
+extern struct platform_device spear3xx_ohci0_device;
+extern struct platform_device spear3xx_ohci1_device;
 extern struct platform_device spear3xx_rtc_device;
 extern struct sys_timer spear3xx_timer;
 
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 0d2b365..1dd0e18 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -44,7 +44,10 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_ehci_device,
 	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
 	&spear3xx_rtc_device,
 
 	/* spear300 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 59f69d5..38f2331 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -87,7 +87,10 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_ehci_device,
 	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
 	&spear3xx_rtc_device,
 
 	/* spear310 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 40d62ae..75f1495 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -81,7 +81,10 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&spear3xx_ehci_device,
 	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
 	&spear3xx_rtc_device,
 
 	/* spear320 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index f9b5bb1..574e93a 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -88,6 +88,83 @@ struct platform_device spear3xx_i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* usb host device registeration */
+static int usbh_id = -1;
+static struct resource ehci_resources[] = {
+	[0] = {
+		.start = SPEAR3XX_ICM4_USB_EHCI0_1_BASE,
+		.end = SPEAR3XX_ICM4_USB_EHCI0_1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = SPEAR3XX_IRQ_USB_H_EHCI_0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ohci0_resources[] = {
+	[0] = {
+		.start = SPEAR3XX_ICM4_USB_OHCI0_BASE,
+		.end = SPEAR3XX_ICM4_USB_OHCI0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = SPEAR3XX_IRQ_USB_H_OHCI_0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ohci1_resources[] = {
+	[0] = {
+		.start = SPEAR3XX_ICM4_USB_OHCI1_BASE,
+		.end = SPEAR3XX_ICM4_USB_OHCI1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = SPEAR3XX_IRQ_USB_H_OHCI_1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = ~0;
+struct platform_device spear3xx_ehci_device = {
+	.name = "spear-ehci",
+	.id = -1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ehci_dmamask,
+		.platform_data = &usbh_id,
+	},
+	.num_resources = ARRAY_SIZE(ehci_resources),
+	.resource = ehci_resources,
+};
+
+static u64 ohci0_dmamask = ~0;
+struct platform_device spear3xx_ohci0_device = {
+	.name = "spear-ohci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci0_dmamask,
+		.platform_data = &usbh_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci0_resources),
+	.resource = ohci0_resources,
+};
+
+static u64 ohci1_dmamask = ~0;
+struct platform_device spear3xx_ohci1_device = {
+	.name = "spear-ohci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci1_dmamask,
+		.platform_data = &usbh_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci1_resources),
+	.resource = ohci1_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index fee7f69..62d8b09 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -32,7 +32,11 @@
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
 extern struct amba_device wdt_device;
+extern struct platform_device ehci0_device;
+extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
+extern struct platform_device ohci0_device;
+extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
 extern struct sys_timer spear6xx_timer;
 
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index d8af2bd..d8a13a1 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -26,7 +26,11 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&ehci0_device,
+	&ehci1_device,
 	&i2c_device,
+	&ohci0_device,
+	&ohci1_device,
 	&rtc_device,
 };
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index fb0a46b..fb1a804 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -133,6 +133,114 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* usb host device registeration */
+static struct resource ehci0_resources[] = {
+	[0] = {
+		.start = SPEAR6XX_ICM4_USB_EHCI0_BASE,
+		.end = SPEAR6XX_ICM4_USB_EHCI0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USB_H_EHCI_0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ehci1_resources[] = {
+	[0] = {
+		.start = SPEAR6XX_ICM4_USB_EHCI1_BASE,
+		.end = SPEAR6XX_ICM4_USB_EHCI1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USB_H_EHCI_1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ohci0_resources[] = {
+	[0] = {
+		.start = SPEAR6XX_ICM4_USB_OHCI0_BASE,
+		.end = SPEAR6XX_ICM4_USB_OHCI0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USB_H_OHCI_0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource ohci1_resources[] = {
+	[0] = {
+		.start = SPEAR6XX_ICM4_USB_OHCI1_BASE,
+		.end = SPEAR6XX_ICM4_USB_OHCI1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USB_H_OHCI_1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* usbh0_id defaults to 0, being static variable */
+static int usbh0_id;
+static int usbh1_id = 1;
+static u64 ehci0_dmamask = ~0;
+
+struct platform_device ehci0_device = {
+	.name = "spear-ehci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ehci0_dmamask,
+		.platform_data = &usbh0_id,
+	},
+	.num_resources = ARRAY_SIZE(ehci0_resources),
+	.resource = ehci0_resources,
+};
+
+static u64 ehci1_dmamask = ~0;
+
+struct platform_device ehci1_device = {
+	.name = "spear-ehci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ehci1_dmamask,
+		.platform_data = &usbh1_id,
+	},
+	.num_resources = ARRAY_SIZE(ehci1_resources),
+	.resource = ehci1_resources,
+};
+
+static u64 ohci0_dmamask = ~0;
+
+struct platform_device ohci0_device = {
+	.name = "spear-ohci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci0_dmamask,
+		.platform_data = &usbh0_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci0_resources),
+	.resource = ohci0_resources,
+};
+
+static u64 ohci1_dmamask = ~0;
+
+struct platform_device ohci1_device = {
+	.name = "spear-ohci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &ohci1_dmamask,
+		.platform_data = &usbh1_id,
+	},
+	.num_resources = ARRAY_SIZE(ohci1_resources),
+	.resource = ohci1_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
-- 
1.7.2.2

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

* [PATCH V6 12/17] ST SPEAr: Adding machine support for keyboard
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (10 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 11/17] ST SPEAr: Adding machine support for USB host Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 13/17] ST SPEAr: Adding machine support for nand Viresh Kumar
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.kumar@st.com>

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   20 ++++++++++++++++++++
 arch/arm/mach-spear13xx/spear1310_evb.c        |   20 ++++++++++++++++++++
 arch/arm/mach-spear13xx/spear13xx.c            |   19 +++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300.c              |   19 +++++++++++++++++++
 arch/arm/mach-spear3xx/spear300_evb.c          |   20 ++++++++++++++++++++
 arch/arm/plat-spear/include/plat/keyboard.h    |    7 -------
 8 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 9a9b6a3..f86f097 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -226,6 +226,7 @@ extern struct amba_device spear13xx_uart_device;
 extern struct platform_device spear13xx_ehci0_device;
 extern struct platform_device spear13xx_ehci1_device;
 extern struct platform_device spear13xx_i2c_device;
+extern struct platform_device spear13xx_kbd_device;
 extern struct platform_device spear13xx_ohci0_device;
 extern struct platform_device spear13xx_ohci1_device;
 extern struct platform_device spear13xx_rtc_device;
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index c0066a6..19be757 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/keyboard.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 #include <mach/pcie.h>
@@ -47,11 +48,24 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ehci0_device,
 	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
+	&spear13xx_kbd_device,
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
 };
 
+/* keyboard specific platform data */
+static const __initconst DECLARE_KEYMAP(keymap);
+static const struct matrix_keymap_data keymap_data __initconst = {
+	.keymap = keymap,
+	.keymap_size = ARRAY_SIZE(keymap),
+};
+
+static const struct kbd_platform_data kbd_data __initconst = {
+	.keymap = &keymap_data,
+	.rep = 1,
+};
+
 #ifdef CONFIG_PCIEPORTBUS
 /*
  * This function is needed for PCIE host and device driver. Same
@@ -83,6 +97,12 @@ static void __init spear1300_evb_init(void)
 	/* call spear1300 machine init function */
 	spear1300_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+	/* set keyboard plat data */
+	if (platform_device_add_data(&spear13xx_kbd_device, &kbd_data,
+				sizeof(kbd_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear13xx_kbd_device.name);
+
 #ifdef CONFIG_PCIEPORTBUS
 	/* Enable PCIE0 clk */
 	enable_pcie0_clk();
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index d58d3ff..e196223 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/keyboard.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 #include <mach/pcie.h>
@@ -62,6 +63,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ehci0_device,
 	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
+	&spear13xx_kbd_device,
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
@@ -72,6 +74,18 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear1310_i2c1_device,
 };
 
+/* keyboard specific platform data */
+static const __initconst DECLARE_KEYMAP(keymap);
+static const struct matrix_keymap_data keymap_data __initconst = {
+	.keymap = keymap,
+	.keymap_size = ARRAY_SIZE(keymap),
+};
+
+static const struct kbd_platform_data kbd_data __initconst = {
+	.keymap = &keymap_data,
+	.rep = 1,
+};
+
 #ifdef CONFIG_PCIEPORTBUS
 /*
  * This function is needed for PCIE host and device driver. Same
@@ -103,6 +117,12 @@ static void __init spear1310_evb_init(void)
 	/* call spear1310 machine init function */
 	spear1310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+	/* set keyboard plat data */
+	if (platform_device_add_data(&spear13xx_kbd_device, &kbd_data,
+				sizeof(kbd_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear13xx_kbd_device.name);
+
 #ifdef CONFIG_PCIEPORTBUS
 	/* Enable PCIE0 clk */
 	enable_pcie0_clk();
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 69ead0f..3856161 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -204,6 +204,25 @@ struct platform_device spear13xx_ohci1_device = {
 	.resource = ohci1_resources,
 };
 
+/* keyboard device registration */
+static struct resource kbd_resources[] = {
+	{
+		.start = SPEAR13XX_KBD_BASE,
+		.end = SPEAR13XX_KBD_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_KBD,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear13xx_kbd_device = {
+	.name = "keyboard",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(kbd_resources),
+	.resource = kbd_resources,
+};
+
 /* rtc device registration */
 static struct resource rtc_resources[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index ea21478..0307f7e 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -107,6 +107,7 @@ extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
 #ifdef CONFIG_MACH_SPEAR300
 /* Add spear300 machine device structure declarations here */
 extern struct amba_device spear300_gpio1_device;
+extern struct platform_device spear300_kbd_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear300_nand_mode;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 89999bf..6b75fe8 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -595,6 +595,25 @@ struct amba_device spear300_gpio1_device = {
 	.irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
 };
 
+/* keyboard device registration */
+static struct resource kbd_resources[] = {
+	{
+		.start = SPEAR300_KEYBOARD_BASE,
+		.end = SPEAR300_KEYBOARD_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR300_VIRQ_KEYBOARD,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device spear300_kbd_device = {
+	.name = "keyboard",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(kbd_resources),
+	.resource = kbd_resources,
+};
+
 /* spear300 routines */
 void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 1dd0e18..280bf80 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -13,6 +13,7 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/keyboard.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
@@ -51,6 +52,19 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear3xx_rtc_device,
 
 	/* spear300 specific devices */
+	&spear300_kbd_device,
+};
+
+/* keyboard specific platform data */
+static const __initconst DECLARE_KEYMAP(keymap);
+static const struct matrix_keymap_data keymap_data __initconst = {
+	.keymap = keymap,
+	.keymap_size = ARRAY_SIZE(keymap),
+};
+
+static const struct kbd_platform_data kbd_data __initconst = {
+	.keymap = &keymap_data,
+	.rep = 1,
 };
 
 static void __init spear300_evb_init(void)
@@ -61,6 +75,12 @@ static void __init spear300_evb_init(void)
 	spear300_init(&spear300_photo_frame_mode, pmx_devs,
 			ARRAY_SIZE(pmx_devs));
 
+	/* set keyboard plat data */
+	if (platform_device_add_data(&spear300_kbd_device, &kbd_data,
+				sizeof(kbd_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear300_kbd_device.name);
+
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
index 68b5394..63908cc 100644
--- a/arch/arm/plat-spear/include/plat/keyboard.h
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -131,11 +131,4 @@ struct kbd_platform_data {
 	bool rep;
 };
 
-/* This function is used to set platform data field of pdev->dev */
-static inline void
-kbd_set_plat_data(struct platform_device *pdev, struct kbd_platform_data *data)
-{
-	pdev->dev.platform_data = data;
-}
-
 #endif /* __PLAT_KEYBOARD_H */
-- 
1.7.2.2

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

* [PATCH V6 13/17] ST SPEAr: Adding machine support for nand
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (11 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 12/17] ST SPEAr: Adding machine support for keyboard Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 14/17] ST SPEAr: Adding support for SSP PL022 Viresh Kumar
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vipin Kumar <vipin.kumar@st.com>

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    3 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   17 +++++
 arch/arm/mach-spear13xx/spear1310_evb.c        |   17 +++++
 arch/arm/mach-spear13xx/spear13xx.c            |   53 +++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    6 ++
 arch/arm/mach-spear3xx/spear300.c              |   85 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear300_evb.c          |   15 ++++
 arch/arm/mach-spear3xx/spear310.c              |   22 ++++++
 arch/arm/mach-spear3xx/spear310_evb.c          |   15 ++++
 arch/arm/mach-spear3xx/spear320.c              |   22 ++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   15 ++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |   15 ++++
 arch/arm/mach-spear6xx/spear6xx.c              |   22 ++++++
 14 files changed, 308 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index f86f097..f332f96 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -227,6 +227,7 @@ extern struct platform_device spear13xx_ehci0_device;
 extern struct platform_device spear13xx_ehci1_device;
 extern struct platform_device spear13xx_i2c_device;
 extern struct platform_device spear13xx_kbd_device;
+extern struct platform_device spear13xx_nand_device;
 extern struct platform_device spear13xx_ohci0_device;
 extern struct platform_device spear13xx_ohci1_device;
 extern struct platform_device spear13xx_rtc_device;
@@ -239,6 +240,8 @@ void __init spear_setup_timer(void);
 void __init spear13xx_map_io(void);
 void __init spear13xx_init_irq(void);
 void __init spear13xx_init(void);
+void __init nand_mach_init(u32 busw);
+void nand_select_bank(u32 bank, u32 busw);
 void spear13xx_secondary_startup(void);
 
 /* spear1300 declarations */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 19be757..9aafa91 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -12,6 +12,8 @@
  */
 
 #include <linux/types.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
@@ -49,11 +51,19 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
 	&spear13xx_kbd_device,
+	&spear13xx_nand_device,
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
 };
 
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
+	.select_bank = nand_select_bank,
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
+};
+
 /* keyboard specific platform data */
 static const __initconst DECLARE_KEYMAP(keymap);
 static const struct matrix_keymap_data keymap_data __initconst = {
@@ -97,6 +107,13 @@ static void __init spear1300_evb_init(void)
 	/* call spear1300 machine init function */
 	spear1300_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+	/* set nand device's plat data */
+	nand_mach_init(FSMC_NAND_BW8);
+	if (platform_device_add_data(&spear13xx_nand_device, &nand_plat_data,
+				sizeof(nand_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear13xx_nand_device.name);
+
 	/* set keyboard plat data */
 	if (platform_device_add_data(&spear13xx_kbd_device, &kbd_data,
 				sizeof(kbd_data)))
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index e196223..d4ef083 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -12,6 +12,8 @@
  */
 
 #include <linux/types.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
@@ -64,6 +66,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ehci1_device,
 	&spear13xx_i2c_device,
 	&spear13xx_kbd_device,
+	&spear13xx_nand_device,
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
@@ -74,6 +77,13 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear1310_i2c1_device,
 };
 
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
+	.select_bank = nand_select_bank,
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
+};
+
 /* keyboard specific platform data */
 static const __initconst DECLARE_KEYMAP(keymap);
 static const struct matrix_keymap_data keymap_data __initconst = {
@@ -117,6 +127,13 @@ static void __init spear1310_evb_init(void)
 	/* call spear1310 machine init function */
 	spear1310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
+	/* set nand device's plat data */
+	nand_mach_init(FSMC_NAND_BW8);
+	if (platform_device_add_data(&spear13xx_nand_device, &nand_plat_data,
+				sizeof(nand_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear13xx_nand_device.name);
+
 	/* set keyboard plat data */
 	if (platform_device_add_data(&spear13xx_kbd_device, &kbd_data,
 				sizeof(kbd_data)))
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 3856161..4e8cd35 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -15,6 +15,7 @@
 #include <linux/amba/pl061.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/hardware/gic.h>
 #include <asm/irq.h>
 #include <asm/localtimer.h>
@@ -24,6 +25,7 @@
 #include <mach/generic.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
+#include <mach/misc_regs.h>
 
 /* Add spear13xx machines common devices here */
 /* gpio device registeration */
@@ -98,6 +100,57 @@ struct platform_device spear13xx_i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* nand device registeration */
+void __init nand_mach_init(u32 busw)
+{
+	u32 fsmc_cfg = readl(FSMC_CFG);
+	fsmc_cfg &= ~(FSMC_MEMSEL_MASK << FSMC_MEMSEL_SHIFT);
+	fsmc_cfg |= (FSMC_MEM_NAND << FSMC_MEMSEL_SHIFT);
+
+	if (busw == FSMC_NAND_BW16)
+		fsmc_cfg |= 1 << NAND_DEV_WIDTH16;
+	else
+		fsmc_cfg &= ~(1 << NAND_DEV_WIDTH16);
+
+	writel(fsmc_cfg, FSMC_CFG);
+}
+
+void nand_select_bank(u32 bank, u32 busw)
+{
+	u32 fsmc_cfg = readl(FSMC_CFG);
+
+	fsmc_cfg &= ~(NAND_BANK_MASK << NAND_BANK_SHIFT);
+	fsmc_cfg |= (bank << NAND_BANK_SHIFT);
+
+	if (busw)
+		fsmc_cfg |= 1 << NAND_DEV_WIDTH16;
+	else
+		fsmc_cfg &= ~(1 << NAND_DEV_WIDTH16);
+
+	writel(fsmc_cfg, FSMC_CFG);
+}
+
+static struct resource nand_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR13XX_FSMC_MEM_BASE,
+		.end = SPEAR13XX_FSMC_MEM_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR13XX_FSMC_BASE,
+		.end = SPEAR13XX_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear13xx_nand_device = {
+	.name = "fsmc-nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 0307f7e..189aed4 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -108,6 +108,10 @@ extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
 /* Add spear300 machine device structure declarations here */
 extern struct amba_device spear300_gpio1_device;
 extern struct platform_device spear300_kbd_device;
+extern struct platform_device spear300_nand0_device;
+extern struct platform_device spear300_nand1_device;
+extern struct platform_device spear300_nand2_device;
+extern struct platform_device spear300_nand3_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear300_nand_mode;
@@ -158,6 +162,7 @@ extern struct amba_device spear310_uart2_device;
 extern struct amba_device spear310_uart3_device;
 extern struct amba_device spear310_uart4_device;
 extern struct amba_device spear310_uart5_device;
+extern struct platform_device spear310_nand_device;
 extern struct platform_device spear310_plgpio_device;
 
 /* pad mux devices */
@@ -185,6 +190,7 @@ extern struct amba_device spear320_uart2_device;
 extern struct platform_device spear320_can0_device;
 extern struct platform_device spear320_can1_device;
 extern struct platform_device spear320_i2c1_device;
+extern struct platform_device spear320_nand_device;
 extern struct platform_device spear320_plgpio_device;
 extern struct platform_device spear320_pwm_device;
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 6b75fe8..3a46551 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -614,6 +614,91 @@ struct platform_device spear300_kbd_device = {
 	.resource = kbd_resources,
 };
 
+/* nand device registeration */
+static struct resource nand0_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR300_NAND_0_BASE,
+		.end = SPEAR300_NAND_0_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR300_FSMC_BASE,
+		.end = SPEAR300_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear300_nand0_device = {
+	.name = "fsmc-nand",
+	.id = 0,
+	.resource = nand0_resources,
+	.num_resources = ARRAY_SIZE(nand0_resources),
+};
+
+static struct resource nand1_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR300_NAND_1_BASE,
+		.end = SPEAR300_NAND_1_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR300_FSMC_BASE,
+		.end = SPEAR300_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear300_nand1_device = {
+	.name = "fsmc-nand",
+	.id = 1,
+	.resource = nand1_resources,
+	.num_resources = ARRAY_SIZE(nand1_resources),
+};
+
+static struct resource nand2_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR300_NAND_2_BASE,
+		.end = SPEAR300_NAND_2_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR300_FSMC_BASE,
+		.end = SPEAR300_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear300_nand2_device = {
+	.name = "fsmc-nand",
+	.id = 2,
+	.resource = nand2_resources,
+	.num_resources = ARRAY_SIZE(nand2_resources),
+};
+
+static struct resource nand3_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR300_NAND_3_BASE,
+		.end = SPEAR300_NAND_3_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR300_FSMC_BASE,
+		.end = SPEAR300_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear300_nand3_device = {
+	.name = "fsmc-nand",
+	.id = 3,
+	.resource = nand3_resources,
+	.num_resources = ARRAY_SIZE(nand3_resources),
+};
+
 /* spear300 routines */
 void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 280bf80..92f9346 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -11,6 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
@@ -53,6 +55,13 @@ static struct platform_device *plat_devs[] __initdata = {
 
 	/* spear300 specific devices */
 	&spear300_kbd_device,
+	&spear300_nand0_device,
+};
+
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand0_plat_data __initconst = {
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
 };
 
 /* keyboard specific platform data */
@@ -75,6 +84,12 @@ static void __init spear300_evb_init(void)
 	spear300_init(&spear300_photo_frame_mode, pmx_devs,
 			ARRAY_SIZE(pmx_devs));
 
+	/* set nand0 device's plat data */
+	if (platform_device_add_data(&spear300_nand0_device, &nand0_plat_data,
+				sizeof(nand0_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear300_nand0_device.name);
+
 	/* set keyboard plat data */
 	if (platform_device_add_data(&spear300_kbd_device, &kbd_data,
 				sizeof(kbd_data)))
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index ba21b75..9a1bea7 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -374,6 +374,28 @@ struct amba_device spear310_uart5_device = {
 	.irq = {SPEAR310_VIRQ_UART5, NO_IRQ},
 };
 
+/* nand device registeration */
+static struct resource nand_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR310_NAND_BASE,
+		.end = SPEAR310_NAND_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR310_FSMC_BASE,
+		.end = SPEAR310_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear310_nand_device = {
+	.name = "fsmc-nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+};
+
 /* plgpio device registeration */
 /*
  * pin to offset and offset to pin converter functions
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 38f2331..9c5c9b1 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -11,6 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/emi.h>
@@ -95,9 +97,16 @@ static struct platform_device *plat_devs[] __initdata = {
 
 	/* spear310 specific devices */
 	&spear310_emi_nor_device,
+	&spear310_nand_device,
 	&spear310_plgpio_device,
 };
 
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
+};
+
 static void __init spear310_evb_init(void)
 {
 	unsigned int i;
@@ -108,6 +117,12 @@ static void __init spear310_evb_init(void)
 	/* Initialize emi regiters */
 	emi_init(SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32);
 
+	/* set nand device's plat data */
+	if (platform_device_add_data(&spear310_nand_device, &nand_plat_data,
+				sizeof(nand_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear310_nand_device.name);
+
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 047dcae..4a5041f 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -797,6 +797,28 @@ struct platform_device spear320_i2c1_device = {
 	.resource = i2c1_resources,
 };
 
+/* nand device registeration */
+static struct resource nand_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR320_NAND_BASE,
+		.end = SPEAR320_NAND_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR320_FSMC_BASE,
+		.end = SPEAR320_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device spear320_nand_device = {
+	.name = "fsmc-nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+};
+
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 75f1495..bfe5d09 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -11,6 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/emi.h>
@@ -92,10 +94,17 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear320_can1_device,
 	&spear320_i2c1_device,
 	&spear320_emi_nor_device,
+	&spear320_nand_device,
 	&spear320_plgpio_device,
 	&spear320_pwm_device,
 };
 
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
+};
+
 static void __init spear320_evb_init(void)
 {
 	unsigned int i;
@@ -107,6 +116,12 @@ static void __init spear320_evb_init(void)
 	/* Initialize emi regiters */
 	emi_init(SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16);
 
+	/* set nand device's plat data */
+	if (platform_device_add_data(&spear320_nand_device, &nand_plat_data,
+				sizeof(nand_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				spear320_nand_device.name);
+
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 62d8b09..df2606f 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -35,6 +35,7 @@ extern struct amba_device wdt_device;
 extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
+extern struct platform_device nand_device;
 extern struct platform_device ohci0_device;
 extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index d8a13a1..93cc614 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -11,6 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -31,13 +33,26 @@ static struct platform_device *plat_devs[] __initdata = {
 	&i2c_device,
 	&ohci0_device,
 	&ohci1_device,
+	&nand_device,
 	&rtc_device,
 };
 
+/* fsmc platform data */
+static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
+	.options = NAND_SKIP_BBTSCAN,
+	.width = FSMC_NAND_BW8,
+};
+
 static void __init spear600_evb_init(void)
 {
 	unsigned int i;
 
+	/* set nand device's plat data */
+	if (platform_device_add_data(&nand_device, &nand_plat_data,
+				sizeof(nand_plat_data)))
+		printk(KERN_WARNING "%s: couldn't add plat_data",
+				nand_device.name);
+
 	/* call spear600 machine init function */
 	spear600_init();
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index fb1a804..927812d 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -133,6 +133,28 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* nand device registeration */
+static struct resource nand_resources[] = {
+	{
+		.name = "nand_data",
+		.start = SPEAR6XX_ICM1_NAND_BASE,
+		.end = SPEAR6XX_ICM1_NAND_BASE + SZ_16 - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "fsmc_regs",
+		.start = SPEAR6XX_ICM1_FSMC_BASE,
+		.end = SPEAR6XX_ICM1_FSMC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device nand_device = {
+	.name = "fsmc-nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
-- 
1.7.2.2

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

* [PATCH V6 14/17] ST SPEAr: Adding support for SSP PL022
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (12 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 13/17] ST SPEAr: Adding machine support for nand Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 15/17] ST SPEAr: Adding support for SDHCI (SDIO) Viresh Kumar
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   10 +++
 arch/arm/mach-spear13xx/spear1310_evb.c        |   10 +++
 arch/arm/mach-spear13xx/spear13xx.c            |   31 ++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    2 +
 arch/arm/mach-spear3xx/spear300_evb.c          |   25 ++++++++
 arch/arm/mach-spear3xx/spear310_evb.c          |   37 ++++++++++++
 arch/arm/mach-spear3xx/spear320.c              |   42 +++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   13 ++++
 arch/arm/mach-spear3xx/spear3xx.c              |   31 ++++++++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |   12 ++++
 arch/arm/mach-spear6xx/spear6xx.c              |   68 ++++++++++++++++++++++
 arch/arm/plat-spear/include/plat/spi.h         |   74 ++++++++++++++++++++++++
 14 files changed, 357 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/spi.h

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index f332f96..15f5e03 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -222,6 +222,7 @@ extern struct pmx_dev pmx_uart1_modem;
 
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device spear13xx_gpio_device[];
+extern struct amba_device spear13xx_ssp_device;
 extern struct amba_device spear13xx_uart_device;
 extern struct platform_device spear13xx_ehci0_device;
 extern struct platform_device spear13xx_ehci1_device;
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 9aafa91..8500e10 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -12,11 +12,15 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
+#include <plat/spi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 #include <mach/pcie.h>
@@ -43,6 +47,7 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	&spear13xx_gpio_device[0],
 	&spear13xx_gpio_device[1],
+	&spear13xx_ssp_device,
 	&spear13xx_uart_device,
 };
 
@@ -76,6 +81,9 @@ static const struct kbd_platform_data kbd_data __initconst = {
 	.rep = 1,
 };
 
+static struct spi_board_info __initdata spi_board_info[] = {
+};
+
 #ifdef CONFIG_PCIEPORTBUS
 /*
  * This function is needed for PCIE host and device driver. Same
@@ -129,6 +137,8 @@ static void __init spear1300_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index d4ef083..ec3d617 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -12,11 +12,15 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <linux/mtd/fsmc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
+#include <plat/spi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 #include <mach/pcie.h>
@@ -50,6 +54,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
 	&spear13xx_gpio_device[0],
 	&spear13xx_gpio_device[1],
+	&spear13xx_ssp_device,
 	&spear13xx_uart_device,
 
 	/* spear1310 specific devices */
@@ -96,6 +101,9 @@ static const struct kbd_platform_data kbd_data __initconst = {
 	.rep = 1,
 };
 
+static struct spi_board_info __initdata spi_board_info[] = {
+};
+
 #ifdef CONFIG_PCIEPORTBUS
 /*
  * This function is needed for PCIE host and device driver. Same
@@ -152,6 +160,8 @@ static void __init spear1310_evb_init(void)
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 4e8cd35..47f45d5 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/amba/pl022.h>
 #include <linux/amba/pl061.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
@@ -65,6 +66,36 @@ struct amba_device spear13xx_gpio_device[] = {
 	}
 };
 
+/* ssp device registeration */
+static struct pl022_ssp_controller ssp_platform_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	/*
+	 * This is number of spi devices that can be connected to spi. There are
+	 * two type of chipselects on which slave devices can work. One is chip
+	 * select provided by spi masters other is controlled through external
+	 * gpio's. We can't use chipselect provided from spi master (because as
+	 * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+	 * this number now depends on number of gpios available for spi. each
+	 * slave on each master requires a separate gpio pin.
+	 */
+	.num_chipselect = 2,
+};
+
+struct amba_device spear13xx_ssp_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "ssp-pl022",
+		.platform_data = &ssp_platform_data,
+	},
+	.res = {
+		.start = SPEAR13XX_SSP_BASE,
+		.end = SPEAR13XX_SSP_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_SSP, NO_IRQ},
+};
+
 /* uart device registeration */
 struct amba_device spear13xx_uart_device = {
 	.dev = {
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 189aed4..39cc43f 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -32,6 +32,7 @@
 
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device spear3xx_gpio_device;
+extern struct amba_device spear3xx_ssp0_device;
 extern struct amba_device spear3xx_uart_device;
 extern struct amba_device spear3xx_wdt_device;
 extern struct platform_device spear3xx_ehci_device;
@@ -185,6 +186,7 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear320 declarations */
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
+extern struct amba_device spear320_ssp_device[];
 extern struct amba_device spear320_uart1_device;
 extern struct amba_device spear320_uart2_device;
 extern struct platform_device spear320_can0_device;
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 92f9346..7ab29d4 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -11,11 +11,15 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <plat/keyboard.h>
+#include <plat/spi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
@@ -38,6 +42,7 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
+	&spear3xx_ssp0_device,
 	&spear3xx_uart_device,
 	&spear3xx_wdt_device,
 
@@ -76,6 +81,24 @@ static const struct kbd_platform_data kbd_data __initconst = {
 	.rep = 1,
 };
 
+/* spi board information */
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, RAS_GPIO_3);
+/* spi0 flash Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, flash, spi0_flash_cs_control);
+
+static struct spi_board_info __initdata spi_board_info[] = {
+	/* spi0 board info */
+	{
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 25000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = SPI_MODE_1,
+	}
+};
+
 static void __init spear300_evb_init(void)
 {
 	unsigned int i;
@@ -99,6 +122,8 @@ static void __init spear300_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 9c5c9b1..45abb1c 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -11,10 +11,14 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/spi.h>
 #include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
@@ -76,6 +80,7 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
+	&spear3xx_ssp0_device,
 	&spear3xx_uart_device,
 	&spear3xx_wdt_device,
 
@@ -107,6 +112,36 @@ static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
 	.width = FSMC_NAND_BW8,
 };
 
+/* spi board information */
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, BASIC_GPIO_3);
+/* spi0 flash Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, flash, spi0_flash_cs_control);
+
+/* spi0 spidev Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, dev, BASIC_GPIO_4);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+
+static struct spi_board_info __initdata spi_board_info[] = {
+	/* spi0 board info */
+	{
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 25000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = SPI_MODE_1,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 25000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = SPI_MODE_1,
+	}
+};
+
 static void __init spear310_evb_init(void)
 {
 	unsigned int i;
@@ -126,6 +161,8 @@ static void __init spear310_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 4a5041f..ac5dfb4 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/amba/pl022.h>
 #include <linux/ptrace.h>
 #include <asm/irq.h>
 #include <plat/gpio.h>
@@ -712,6 +713,47 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* Add spear320 specific devices here */
+/* ssp device registeration */
+static struct pl022_ssp_controller ssp_platform_data[] = {
+	{
+		.bus_id = 1,
+		.enable_dma = 0,
+		.num_chipselect = 2,
+	}, {
+		.bus_id = 2,
+		.enable_dma = 0,
+		.num_chipselect = 2,
+	}
+};
+
+struct amba_device spear320_ssp_device[] = {
+	{
+		.dev = {
+			.coherent_dma_mask = ~0,
+			.init_name = "ssp-pl022.1",
+			.platform_data = &ssp_platform_data[0],
+		},
+		.res = {
+			.start = SPEAR320_SSP0_BASE,
+			.end = SPEAR320_SSP0_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {SPEAR320_VIRQ_SSP1, NO_IRQ},
+	}, {
+		.dev = {
+			.coherent_dma_mask = ~0,
+			.init_name = "ssp-pl022.2",
+			.platform_data = &ssp_platform_data[1],
+		},
+		.res = {
+			.start = SPEAR320_SSP1_BASE,
+			.end = SPEAR320_SSP1_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {SPEAR320_VIRQ_SSP2, NO_IRQ},
+	}
+};
+
 /* uart1 device registeration */
 struct amba_device spear320_uart1_device = {
 	.dev = {
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index bfe5d09..a1a76f2 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -11,10 +11,14 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/spi.h>
 #include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
@@ -73,10 +77,13 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&spear3xx_gpio_device,
+	&spear3xx_ssp0_device,
 	&spear3xx_uart_device,
 	&spear3xx_wdt_device,
 
 	/* spear320 specific devices */
+	&spear320_ssp_device[0],
+	&spear320_ssp_device[1],
 	&spear320_uart1_device,
 	&spear320_uart2_device,
 };
@@ -105,6 +112,10 @@ static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
 	.width = FSMC_NAND_BW8,
 };
 
+/* spi board information */
+static struct spi_board_info __initdata spi_board_info[] = {
+};
+
 static void __init spear320_evb_init(void)
 {
 	unsigned int i;
@@ -125,6 +136,8 @@ static void __init spear320_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 574e93a..16ca683 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/amba/pl022.h>
 #include <linux/amba/pl061.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
@@ -41,6 +42,36 @@ struct amba_device spear3xx_gpio_device = {
 	.irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
 };
 
+/* ssp device registration */
+static struct pl022_ssp_controller ssp_platform_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	/*
+	 * This is number of spi devices that can be connected to spi. There are
+	 * two type of chipselects on which slave devices can work. One is chip
+	 * select provided by spi masters other is controlled through external
+	 * gpio's. We can't use chipselect provided from spi master (because as
+	 * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+	 * this number now depends on number of gpios available for spi. each
+	 * slave on each master requires a separate gpio pin.
+	 */
+	.num_chipselect = 2,
+};
+
+struct amba_device spear3xx_ssp0_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "ssp-pl022.0",
+		.platform_data = &ssp_platform_data,
+	},
+	.res = {
+		.start = SPEAR3XX_ICM1_SSP_BASE,
+		.end = SPEAR3XX_ICM1_SSP_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {SPEAR3XX_IRQ_SSP, NO_IRQ},
+};
+
 /* uart device registration */
 struct amba_device spear3xx_uart_device = {
 	.dev = {
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index df2606f..c802cb3 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -30,6 +30,7 @@
 
 /* Add spear6xx family device structure declarations here */
 extern struct amba_device gpio_device[];
+extern struct amba_device ssp_device[];
 extern struct amba_device uart_device[];
 extern struct amba_device wdt_device;
 extern struct platform_device ehci0_device;
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index 93cc614..dbfab1d 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -11,10 +11,14 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <plat/spi.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
@@ -22,6 +26,9 @@ static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[0],
 	&gpio_device[1],
 	&gpio_device[2],
+	&ssp_device[0],
+	&ssp_device[1],
+	&ssp_device[2],
 	&uart_device[0],
 	&uart_device[1],
 	&wdt_device,
@@ -43,6 +50,9 @@ static const struct fsmc_nand_platform_data nand_plat_data __initconst = {
 	.width = FSMC_NAND_BW8,
 };
 
+static struct spi_board_info __initdata spi_board_info[] = {
+};
+
 static void __init spear600_evb_init(void)
 {
 	unsigned int i;
@@ -59,6 +69,8 @@ static void __init spear600_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 927812d..00336e9 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/amba/pl022.h>
 #include <linux/amba/pl061.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
@@ -23,6 +24,73 @@
 #include <mach/irqs.h>
 
 /* Add spear6xx machines common devices here */
+/* ssp device registration */
+static struct pl022_ssp_controller ssp_platform_data[] = {
+	{
+		.bus_id = 0,
+		.enable_dma = 0,
+		/*
+		 * This is number of spi devices that can be connected to spi.
+		 * There are two type of chipselects on which slave devices can
+		 * work. One is chip select provided by spi masters other is
+		 * controlled through external gpio's. We can't use chipselect
+		 * provided from spi master (because as soon as FIFO becomes
+		 * empty, CS is disabled and transfer ends). So this number now
+		 * depends on number of gpios available for spi. each slave on
+		 * each master requires a separate gpio pin.
+		 */
+		.num_chipselect = 2,
+	}, {
+		.bus_id = 1,
+		.enable_dma = 0,
+		.num_chipselect = 2,
+	}, {
+		.bus_id = 2,
+		.enable_dma = 0,
+		.num_chipselect = 2,
+	}
+};
+
+struct amba_device ssp_device[] = {
+	{
+		.dev = {
+			.coherent_dma_mask = ~0,
+			.init_name = "ssp-pl022.0",
+			.platform_data = &ssp_platform_data[0],
+		},
+		.res = {
+			.start = SPEAR6XX_ICM1_SSP0_BASE,
+			.end = SPEAR6XX_ICM1_SSP0_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_SSP_1, NO_IRQ},
+	}, {
+		.dev = {
+			.coherent_dma_mask = ~0,
+			.init_name = "ssp-pl022.1",
+			.platform_data = &ssp_platform_data[1],
+		},
+		.res = {
+			.start = SPEAR6XX_ICM1_SSP1_BASE,
+			.end = SPEAR6XX_ICM1_SSP1_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_SSP_2, NO_IRQ},
+	}, {
+		.dev = {
+			.coherent_dma_mask = ~0,
+			.init_name = "ssp-pl022.2",
+			.platform_data = &ssp_platform_data[2],
+		},
+		.res = {
+			.start = SPEAR6XX_ICM2_SSP2_BASE,
+			.end = SPEAR6XX_ICM2_SSP2_BASE + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_APPL_SSP, NO_IRQ},
+	}
+};
+
 /* uart device registration */
 struct amba_device uart_device[] = {
 	{
diff --git a/arch/arm/plat-spear/include/plat/spi.h b/arch/arm/plat-spear/include/plat/spi.h
new file mode 100644
index 0000000..24d57e1
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/spi.h
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/plat-spear/include/plat/spi.h
+ *
+ * SPI board specific definitions common to multiple boards on multiple
+ * machines.
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_SPI_H
+#define __PLAT_SPI_H
+
+#include <linux/amba/pl022.h>
+#include <linux/gpio.h>
+
+/* spi board information */
+static inline int spi_cs_gpio_request(u32 gpio_pin)
+{
+	int ret;
+
+	ret = gpio_request(gpio_pin, "SPI_CS");
+	if (ret < 0) {
+		printk(KERN_ERR "SPI: gpio:%d request fail\n", gpio_pin);
+		return ret;
+	} else {
+		ret = gpio_direction_output(gpio_pin, 1);
+		if (ret) {
+			printk(KERN_ERR "SPI: gpio:%d direction set fail\n",
+					gpio_pin);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+/* This will define cs_control function for a specific spi slave */
+#define DECLARE_SPI_CS_CONTROL(id, type, gpio)		\
+static void spi##id##_##type##_cs_control(u32 control)	\
+{							\
+	static int count, ret;				\
+							\
+	if (unlikely(!count)) {				\
+		count++;				\
+		ret = spi_cs_gpio_request(gpio);	\
+	}						\
+							\
+	if (!ret)					\
+		gpio_set_value(gpio, control);		\
+}
+
+/* This will define CHIP_INFO structure for a specific spi slave */
+#define DECLARE_SPI_CHIP_INFO(id, type, chip_select_control)	\
+static struct pl022_config_chip spi##id##_##type##_chip_info = {\
+	.iface = SSP_INTERFACE_MOTOROLA_SPI,		\
+	.hierarchy = SSP_MASTER,			\
+	.slave_tx_disable = 0,				\
+	.com_mode = INTERRUPT_TRANSFER,			\
+	.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,		\
+	.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,	\
+	.ctrl_len = SSP_BITS_12,			\
+	.wait_state = SSP_MWIRE_WAIT_ZERO,		\
+	.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,	\
+	.cs_control = chip_select_control,		\
+};
+
+#define DECLARE_SPI_CHIP_INFO_NULL_ID(chip_select_control)	\
+DECLARE_SPI_CHIP_INFO(, chip_select_control)
+
+#endif /* __PLAT_SPI_H */
-- 
1.7.2.2

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

* [PATCH V6 15/17] ST SPEAr: Adding support for SDHCI (SDIO)
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (13 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 14/17] ST SPEAr: Adding support for SSP PL022 Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 16/17] ST SPEAr Power Management: Added the support for Standby mode Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 17/17] ST SPEAr: Updating defconfigs Viresh Kumar
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear1310_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear13xx.c            |   34 +++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    6 +++
 arch/arm/mach-spear3xx/spear300.c              |   42 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear300_evb.c          |   16 +++++++++
 arch/arm/mach-spear3xx/spear320.c              |   23 +++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   13 +++++++
 9 files changed, 137 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 15f5e03..d918368 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -232,6 +232,7 @@ extern struct platform_device spear13xx_nand_device;
 extern struct platform_device spear13xx_ohci0_device;
 extern struct platform_device spear13xx_ohci1_device;
 extern struct platform_device spear13xx_rtc_device;
+extern struct platform_device spear13xx_sdhci_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 8500e10..3b619e5 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -60,6 +60,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
+	&spear13xx_sdhci_device,
 };
 
 /* fsmc platform data */
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index ec3d617..11aafd8 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -75,6 +75,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear13xx_ohci0_device,
 	&spear13xx_ohci1_device,
 	&spear13xx_rtc_device,
+	&spear13xx_sdhci_device,
 
 	/* spear1310 specific devices */
 	&spear1310_can0_device,
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 47f45d5..5370b5b 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -326,6 +326,38 @@ struct platform_device spear13xx_rtc_device = {
 	.resource = rtc_resources,
 };
 
+/* sdhci (sdio) device declaration */
+static struct resource sdhci_resources[] = {
+	{
+		.start	= SPEAR13XX_MCIF_SDHCI_BASE,
+		.end	= SPEAR13XX_MCIF_SDHCI_BASE + SZ_256 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_SDHCI,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device spear13xx_sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
+
+static void sdhci_enable(void)
+{
+	unsigned val = readl(PERIP_CFG);
+
+	/* This function enables SD/MMC interface out of SD/MMC, CF, XD */
+	val &= ~(MCIF_SEL_MASK << MCIF_SEL_SHIFT);
+	val |= SD_MMC_ACTIVE << MCIF_SEL_SHIFT;
+	writel(val, PERIP_CFG);
+}
+
 #ifdef CONFIG_PCIEPORTBUS
 /* PCIE0 clock always needs to be enabled if any of the three PCIE port
  * have to be used. So call this function from the board initilization
@@ -367,6 +399,8 @@ void __init spear13xx_init(void)
 	 */
 	l2x0_init(__io_address(SPEAR13XX_L2CC_BASE), 0x00260249, 0xfe00ffff);
 #endif
+
+	sdhci_enable();
 }
 
 /* This will initialize vic */
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 39cc43f..54540e2 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -113,6 +113,7 @@ extern struct platform_device spear300_nand0_device;
 extern struct platform_device spear300_nand1_device;
 extern struct platform_device spear300_nand2_device;
 extern struct platform_device spear300_nand3_device;
+extern struct platform_device spear300_sdhci_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear300_nand_mode;
@@ -152,6 +153,10 @@ extern struct pmx_dev spear300_pmx_gpio1;
 /* Add spear300 machine function declarations here */
 void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count);
+#define SDHCI_MEM_ENB		0x1
+#define I2S_MEM_ENB		0x2
+#define SDHCI_MEM_SELECT	0x20000000
+void sdhci_i2s_mem_enable(u8 mask);
 
 #endif /* CONFIG_MACH_SPEAR300 */
 
@@ -195,6 +200,7 @@ extern struct platform_device spear320_i2c1_device;
 extern struct platform_device spear320_nand_device;
 extern struct platform_device spear320_plgpio_device;
 extern struct platform_device spear320_pwm_device;
+extern struct platform_device spear320_sdhci_device;
 
 /* pad mux modes */
 extern struct pmx_mode spear320_auto_net_smii_mode;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 3a46551..3643b79 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -699,6 +699,48 @@ struct platform_device spear300_nand3_device = {
 	.num_resources = ARRAY_SIZE(nand3_resources),
 };
 
+/* sdhci (sdio) device declaration */
+static struct resource sdhci_resources[] = {
+	{
+		.start	= SPEAR300_SDHCI_BASE,
+		.end	= SPEAR300_SDHCI_BASE + SZ_256 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= SPEAR300_IRQ_SDHCI,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device spear300_sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
+
+/* Function handling sdhci and i2s memory sharing */
+void sdhci_i2s_mem_enable(u8 mask)
+{
+	u32 val;
+	void __iomem *config = ioremap(SPEAR300_MODE_CONFIG_REG, SZ_16);
+	if (!config) {
+		pr_debug("sdhci_i2s_enb: ioremap fail\n");
+		return;
+	}
+
+	val = readl(config);
+	if (mask == SDHCI_MEM_ENB)
+		val |= SDHCI_MEM_SELECT;
+	else
+		val &= ~SDHCI_MEM_SELECT;
+	writel(val, config);
+
+	iounmap(config);
+}
+
 /* spear300 routines */
 void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 7ab29d4..30b5a1c 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
 #include <linux/spi/flash.h>
@@ -61,6 +62,15 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear300 specific devices */
 	&spear300_kbd_device,
 	&spear300_nand0_device,
+	&spear300_sdhci_device,
+};
+
+/* sdhci board specific information */
+static struct sdhci_plat_data sdhci_plat_data = {
+	.card_power_gpio = RAS_GPIO_2,
+	.power_active_high = 0,
+	.power_always_enb = 0,
+	.card_int_gpio = RAS_GPIO_0,
 };
 
 /* fsmc platform data */
@@ -122,6 +132,12 @@ static void __init spear300_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
+	/* set sdhci device platform data */
+	sdhci_set_plat_data(&spear300_sdhci_device, &sdhci_plat_data);
+
+	/* Enable sdhci memory */
+	sdhci_i2s_mem_enable(SDHCI_MEM_ENB);
+
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 
 	/* Add Platform Devices */
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index ac5dfb4..34e66cf 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -13,6 +13,7 @@
 
 #include <linux/amba/pl022.h>
 #include <linux/ptrace.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <asm/irq.h>
 #include <plat/gpio.h>
 #include <plat/shirq.h>
@@ -905,6 +906,28 @@ struct platform_device spear320_pwm_device = {
 	.resource = pwm_resources,
 };
 
+/* sdhci (sdio) device registeration */
+static struct resource sdhci_resources[] = {
+	{
+		.start	= SPEAR320_SDHCI_BASE,
+		.end	= SPEAR320_SDHCI_BASE + SZ_256 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= SPEAR320_IRQ_SDHCI,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device spear320_sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
+
 /* spear320 routines */
 void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index a1a76f2..2b27383 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -15,6 +15,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
 #include <linux/spi/flash.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
@@ -104,6 +105,15 @@ static struct platform_device *plat_devs[] __initdata = {
 	&spear320_nand_device,
 	&spear320_plgpio_device,
 	&spear320_pwm_device,
+	&spear320_sdhci_device,
+};
+
+/* sdhci board specific information */
+static struct sdhci_plat_data sdhci_plat_data = {
+	.card_power_gpio = PLGPIO_61,
+	.power_active_high = 0,
+	.power_always_enb = 1,
+	.card_int_gpio = -1,
 };
 
 /* fsmc platform data */
@@ -133,6 +143,9 @@ static void __init spear320_evb_init(void)
 		printk(KERN_WARNING "%s: couldn't add plat_data",
 				spear320_nand_device.name);
 
+	/* set sdhci device platform data */
+	sdhci_set_plat_data(&spear320_sdhci_device, &sdhci_plat_data);
+
 	/* Register slave devices on the I2C buses */
 	i2c_register_default_devices();
 
-- 
1.7.2.2

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

* [PATCH V6 16/17] ST SPEAr Power Management: Added the support for Standby mode.
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (14 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 15/17] ST SPEAr: Adding support for SDHCI (SDIO) Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  2011-03-01 11:31 ` [PATCH V6 17/17] ST SPEAr: Updating defconfigs Viresh Kumar
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Deepak Sikri <deepak.sikri@st.com>

Open Points:
	-> Suspend to RAM support needs to be added.
	-> SPEAr13xx: The power domains need to be added.
	-> For SPEAr13xx: PLL-4 has not been switch off while moving
	   into sleep. There is some problem in getting the pll back to on.

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/Makefile               |    1 +
 arch/arm/mach-spear13xx/include/mach/suspend.h |   47 +++
 arch/arm/mach-spear13xx/pm.c                   |  107 ++++++
 arch/arm/mach-spear13xx/sleep.S                |  435 ++++++++++++++++++++++++
 arch/arm/mach-spear13xx/spear13xx.c            |    5 +
 arch/arm/mach-spear3xx/include/mach/suspend.h  |   44 +++
 arch/arm/mach-spear3xx/spear3xx.c              |    7 +-
 arch/arm/mach-spear6xx/include/mach/suspend.h  |   44 +++
 arch/arm/mach-spear6xx/spear6xx.c              |    9 +-
 arch/arm/plat-spear/Makefile                   |    6 +
 arch/arm/plat-spear/pm.c                       |  104 ++++++
 arch/arm/plat-spear/sleep.S                    |  288 ++++++++++++++++
 12 files changed, 1095 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/include/mach/suspend.h
 create mode 100644 arch/arm/mach-spear13xx/pm.c
 create mode 100644 arch/arm/mach-spear13xx/sleep.S
 create mode 100644 arch/arm/mach-spear3xx/include/mach/suspend.h
 create mode 100644 arch/arm/mach-spear6xx/include/mach/suspend.h
 create mode 100644 arch/arm/plat-spear/pm.c
 create mode 100644 arch/arm/plat-spear/sleep.S

diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
index 2a113b0..42d378e 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 obj-$(CONFIG_PCIEPORTBUS)		+= pcie.o
+obj-$(CONFIG_PM)			+= pm.o sleep.o
 
 # spear1300 specific files
 obj-$(CONFIG_MACH_SPEAR1300)		+= spear1300.o
diff --git a/arch/arm/mach-spear13xx/include/mach/suspend.h b/arch/arm/mach-spear13xx/include/mach/suspend.h
new file mode 100644
index 0000000..98d7db9
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/suspend.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/suspend.h
+ *
+ * Sleep mode defines for SPEAr13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * AUTHOR : Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SUSPEND_H
+#define __MACH_SUSPEND_H
+
+#include <mach/hardware.h>
+
+#ifndef __ASSEMBLER__
+extern void spear_sleep_mode(suspend_state_t state);
+extern unsigned int spear_sleep_mode_sz;
+extern void spear_wakeup(void);
+extern unsigned int spear_wakeup_sz;
+#endif
+
+/* SRAM related defines*/
+#define SRAM_STACK_STRT_OFF	0x500
+#define SRAM_STACK_SCR_OFFS	0xF00
+#define SPEAR_START_SRAM	SPEAR13XX_SYSRAM1_BASE
+#define SPEAR_LIMIT_SRAM	(SPEAR_START_SRAM + SZ_4K - 1)
+#define SPEAR_SRAM_STACK_PA	(SPEAR_START_SRAM + SRAM_STACK_STRT_OFF)
+#define SPEAR_SRAM_SCR_REG	(SPEAR_START_SRAM + SRAM_STACK_SCR_OFFS)
+/* SPEAr subsystem physical addresses */
+#define MPMC_BASE_PA		SPEAR13XX_MPMC_BASE
+#define MISC_BASE_PA		SPEAR13XX_MISC_BASE
+
+/* ARM Modes of Operation */
+#define MODE_USR_32		0x10
+#define MODE_FIQ_32		0x11
+#define MODE_IRQ_32		0x12
+#define MODE_SVC_32		0x13
+#define MODE_ABT_32		0x17
+#define MODE_UND_32		0x1B
+#define MODE_SYS_32		0x1F
+#define MODE_BITS		0x1F
+
+#endif /* __MACH_SUSPEND_H */
diff --git a/arch/arm/mach-spear13xx/pm.c b/arch/arm/mach-spear13xx/pm.c
new file mode 100644
index 0000000..6df799d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/pm.c
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/mach-spear13xx/pm.c
+ *
+ * SPEAr13xx Power Management source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/suspend.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/suspend.h>
+
+static int spear_pm_sleep(suspend_state_t state)
+{
+	void (*spear_sram_sleep)(suspend_state_t state) = NULL;
+	void (*spear_sram_wake)(void) = NULL;
+	void *sram_dest = (void *)IO_ADDRESS(SPEAR_START_SRAM);
+
+	if (state == PM_SUSPEND_MEM) {
+		spear_sram_wake = memcpy(sram_dest, (void *)spear_wakeup,
+				spear_wakeup_sz);
+		/* Increment destination pointer by the size copied*/
+		sram_dest += roundup(spear_wakeup_sz, 4);
+	}
+
+	/* Copy the Sleep code on to the SRAM*/
+	spear_sram_sleep = memcpy(sram_dest, (void *)spear_sleep_mode,
+			spear_sleep_mode_sz);
+	flush_cache_all();
+	/* Jump to the suspend routines in sram */
+	spear_sram_sleep(state);
+	return 0;
+}
+
+/*
+ *	spear_pm_prepare - Do preliminary suspend work.
+ *
+ */
+static int spear_pm_prepare(void)
+{
+	/* We cannot sleep in idle until we have resumed */
+	disable_hlt();
+	return 0;
+}
+
+/*
+ *	spear_pm_enter - Actually enter a sleep state.
+ *	@state:		State we're entering.
+ *
+ */
+static int spear_pm_enter(suspend_state_t state)
+{
+	int ret;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		ret = spear_pm_sleep(state);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/*
+ *	spear_pm_finish - Finish up suspend sequence.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed).
+ */
+static void spear_pm_finish(void)
+{
+	enable_hlt();
+}
+
+static struct platform_suspend_ops spear_pm_ops = {
+	.prepare	= spear_pm_prepare,
+	.enter		= spear_pm_enter,
+	.finish		= spear_pm_finish,
+	.valid		= suspend_valid_only_mem,
+};
+
+static int __init spear_pm_init(void)
+{
+	void * sram_limit_va = (void *)IO_ADDRESS(SPEAR_LIMIT_SRAM);
+	void * sram_st_va = (void *)IO_ADDRESS(SPEAR_START_SRAM);
+
+	/* In case the suspend code size is more than sram size return */
+	if (spear_sleep_mode_sz > (sram_limit_va - sram_st_va))
+		return	-ENOMEM;
+
+	suspend_set_ops(&spear_pm_ops);
+
+	return 0;
+}
+arch_initcall(spear_pm_init);
diff --git a/arch/arm/mach-spear13xx/sleep.S b/arch/arm/mach-spear13xx/sleep.S
new file mode 100644
index 0000000..9c7f12b
--- /dev/null
+++ b/arch/arm/mach-spear13xx/sleep.S
@@ -0,0 +1,435 @@
+/*
+ * linux/arch/arm/mach-spear13xx/sleep.S
+ *
+ * SPEAR13xx specific functions that will run in internal SRAM.
+ * The functions are used in power management.
+ *
+ * Copyright (C) 2010 ST MicroElectronics
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/suspend.h>
+
+/* #define DDR_PLL_SREFRESH */
+/* #define TEST_PWRDOMAINS */
+.text
+ENTRY(spear_wakeup)
+
+spear_wakeup:
+	b	spear_wakeup
+	adr	r0, spear_sleep_restore
+	bx	r0
+
+ENTRY(spear_wakeup_sz)
+	.word	. - spear_wakeup
+/*
+ * spear_sleep_mode()
+ * Forces SPEAr into sleep
+ */
+ENTRY(spear_sleep_mode)
+	stmfd	sp!, {r0-r12, lr}		@ save registers on stack
+	/* Store Stack address in r8 */
+	ldr	r8, SRAM_STACK_VA
+
+	/* Store sp and spsr to SDRAM */
+	mov	r4, sp
+	mrs	r5, spsr
+	mov	r6, lr
+	stmia	r8!, {r4-r6}
+
+	/* Save all ARM registers */
+	/* Coprocessor access control register */
+	mrc	p15, 0, r6, c1, c0, 2
+	stmia	r8!, {r6}
+	/* TTBR0, TTBR1 and Translation table base control */
+	mrc	p15, 0, r4, c2, c0, 0
+	mrc	p15, 0, r5, c2, c0, 1
+	mrc	p15, 0, r6, c2, c0, 2
+	stmia	r8!, {r4-r6}
+	/*
+	 * Domain access control register, data fault status register,
+	 * and instruction fault status register
+	 */
+	mrc	p15, 0, r4, c3, c0, 0
+	mrc	p15, 0, r5, c5, c0, 0
+	mrc	p15, 0, r6, c5, c0, 1
+	stmia	r8!, {r4-r6}
+	/*
+	 * Data aux fault status register, instruction aux fault status,
+	 * data fault address register and instruction fault address register
+	 */
+	mrc	p15, 0, r4, c5, c1, 0
+	mrc	p15, 0, r5, c5, c1, 1
+	mrc	p15, 0, r6, c6, c0, 0
+	mrc	p15, 0, r7, c6, c0, 2
+	stmia	r8!, {r4-r7}
+	/*
+	 * user r/w thread and process ID, user r/o thread and process ID,
+	 * priv only thread and process ID, cache size selection
+	 */
+	mrc	p15, 0, r4, c13, c0, 2
+	mrc	p15, 0, r5, c13, c0, 3
+	mrc	p15, 0, r6, c13, c0, 4
+	mrc	p15, 2, r7, c0, c0, 0
+	stmia	r8!, {r4-r7}
+	/* Data TLB lockdown, instruction TLB lockdown registers */
+	mrc	p15, 0, r5, c10, c0, 0
+	mrc	p15, 0, r6, c10, c0, 1
+	stmia	r8!, {r5-r6}
+	/* Secure or non secure vector base address, FCSE PID, Context PID*/
+	mrc	p15, 0, r4, c12, c0, 0
+	mrc	p15, 0, r5, c13, c0, 0
+	mrc	p15, 0, r6, c13, c0, 1
+	stmia	r8!, {r4-r6}
+	/* Primary remap, normal remap registers */
+	mrc	p15, 0, r4, c10, c2, 0
+	mrc	p15, 0, r5, c10, c2, 1
+	stmia	r8!, {r4-r5}
+	/* Store current cpsr*/
+	mrs	r2, cpsr
+	stmia	r8!, {r2}
+	mrc	p15, 0, r4, c1, c0, 0
+	/* save control register */
+	stmia	r8!, {r4}
+	/* Data memory barrier and Data sync barrier */
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c10, 4
+	mcr	p15, 0, r1, c7, c10, 5
+	dsb
+	isb
+	/* Extract the physical address to jump to */
+	adr	r0, mmu_off
+	mov	r1, #0xcfffffff
+	and	r0, r0, r1
+	ldr	r1, =0x20000000
+	orr	r0, r0, r1
+	mov	r2, r0
+
+	/* Disable MMU */
+	mrc	p15, 0, r0, c1, c0, 0
+	ldr	r1, DISABLE_I_C_M_V
+	bic	r0, r0, r1
+	mcr	p15, 0, r0, c1, c0, 0
+	/* Move the Physical address into PC */
+	bx	r2
+	nop
+mmu_off:
+	/* Put the DDR in self refresh mode */
+	ldr	r6, MISC_BASE_P
+	/* Program MPMC Control Status register in Misc Space */
+	ldr	r0, [r6, #0x334]
+	/* Set srefresh_enter bit(2) */
+	orr	r0, r0, #0x4
+	str	r0, [r6, #0x334]
+wait_till_srefresh_on:
+	ldr	r0, [r6, #0x334]
+	/* check for cke_status bit(13) */
+	tst	r0, #0x2000
+	beq	wait_till_srefresh_on
+
+	/* Put the system in slow mode */
+	ldr	r0, [r6, #0x200]
+	bic	r0, r0, #0x4
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	orr	r0, r0, #0x2
+	str	r0, [r6, #0x200]	/* System is now in slow mode */
+wait_till_slow_mode:
+	ldr	r0, [r6, #0x200]
+	/* Wait for the mode to be updated */
+	and	r0, r0, #0xF0000
+	/* Poll the SCCTRL register status bits (6:3) */
+	cmp	r0, #0xA0000
+	bne wait_till_slow_mode
+
+	/*
+	 * Put the all the system pll's to off state
+	 * The loop of count 3 is provided below to
+	 * switch off the pll-1/2/3.
+	 * r1 contains the offset for the pll control
+	 * registers in the misc space.
+	 * DDR pll-4 requires different processing.
+	 */
+	ldr	r1, MISC_PLL_OFFS
+	ldr	r2, =0x0	/* PLL Counter 1, 2, 3, 4 */
+swoff_pll:
+	ldr	r0, [r6, r1]
+	/* Clear pll_enable bit(1) of PLL1_CTR register in Misc registers */
+	bic	r0, r0, #0x02
+	str	r0, [r6, r1]
+	add	r1, #0xc
+	add	r2, #0x1
+	cmp	r2, #0x3	/* Switch off pll-1/2/3 */
+	bne	swoff_pll
+
+#ifdef DDR_PLL_SREFRESH
+	/* Switch off pll-4 */
+	ldr	r0, [r6, r1]
+	/* Clear pll_enable bit(2) of PLL1_CTR register in Misc registers */
+	bic	r0, r0, #0x04
+	str	r0, [r6, r1]
+#endif
+
+#ifdef TEST_PWRDOMAINS
+	/* Switch off the undesired PLL's */
+	nop
+	ldr	r6, MISC_BASE_P
+	ldr	r0, [r6, #0x200]
+	bic	r0, r0, #0x7
+	orr	r0, r0, #0x2
+	str	r0, [r6, #0x200	]
+wait_ack0:
+	ldr	r0, [r6, #0x200]
+	and	r0, r0, #0xF0000
+	cmp	r0, #0xA0000
+	bne	wait_ack0
+	ldr	r6, MISC_BASE_P
+	ldr	r0, [r6, #0x100]
+
+	/*
+	 * Switch off the power domains.
+	 * Clear the ack bit
+	 */
+	bic	r0, r0, #0xc000
+	str	r0, [r6, #0x100]
+
+	bic	r0, r0, #0x1000
+	str	r0, [r6, #0x100]
+
+wait_ack1:
+	ldr	r0, [r6, #0x100]
+	tst	r0, #0x4000
+	beq	wait_ack1
+
+	/* Clear the ack bit */
+	bic	r0, r0, #0xc000
+	str	r0, [r6, #0x100]
+
+	bic	r0, r0, #0x0800
+	str	r0, [r6, #0x100]
+wait_ack2:
+	ldr	r0, [r6, #0x100]
+	tst	r0, #0x4000
+	beq	wait_ack2
+
+	/* Clear the ack bit */
+	bic	r0, r0, #0xc000
+	str	r0, [r6, #0x100]
+
+	bic	r0, r0, #0x2400
+	str	r0, [r6, #0x100]
+wait_ack3:
+	ldr	r0, [r6, #0x100]
+	tst	r0, #0x4000
+	beq	wait_ack3
+#endif
+	wfi				@ wait for interrupt
+	nop
+spear_sleep_restore:
+	/*
+	 * Reenable the switched off pll's. The Pll's are
+	 * enabled using loop count of 4 to activalte all the
+	 * pll-1/2/3/4.
+	 * The strobing is done for pll-4 only.
+	 */
+
+	ldr	r6, MISC_BASE_P
+	ldr	r1, MISC_PLL_OFFS
+	ldr	r2, =0x0	/* PLL Counter 1, 2, 3, 4 */
+swon_pll_1_3:
+	/* Switch on Pll-1/2/3 */
+	ldr	r0, [r6, r1]
+	orr	r0, r0, #0x2
+	str	r0, [r6, r1]
+pll_lock_1_3:
+	/* Set the pll_lock bit(0) in PLLX_CTR register in misc space*/
+	ldr	r5, [r6, r1]
+	and	r5, r5, #0x1
+	/* Wait for pll lock status */
+	cmp	r5, #0x1
+	bne	pll_lock_1_3
+
+	/* Loop for all the pll's */
+	add	r1, #0xc
+	add	r2, #0x1
+	cmp	r2, #0x3	/* Switch on till pll-3 */
+	bne	swon_pll_1_3
+
+#ifdef DDR_PLL_SREFRESH
+	/* Switch on PLL-4, strobe the pll also */
+	ldr	r0, [r6, r1]
+	ldr	r0, PLL_VAL1
+	str	r0, [r6, r1]
+	ldr	r0, PLL_VAL2
+	str	r0, [r6, r1]
+	ldr	r0, PLL_VAL3
+	str	r0, [r6, r1]
+	ldr	r0, PLL_VAL2
+	str	r0, [r6, r1]
+pll_lock_4:
+	/* Set the pll_lock bit(0) in PLLX_CTR register in misc space*/
+	ldr	r5, [r6, r1]
+	and	r5, r5, #0x1
+	/* Wait for pll lock status */
+	cmp	r5, #0x1
+	bne	pll_lock_4
+#endif
+
+	/* Put the system in normal mode */
+	ldr	r0, [r6, #0x200]
+	bic	r0, r0, #0x7
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	orr	r0, r0, #0x4
+	str	r0, [r6, #0x200]	/* System is now in slow mode */
+wait_till_normal_mode:
+	ldr	r0, [r6, #0x200]
+	/* Wait for the mode to be updated */
+	and	r0, r0, #0xF0000
+	/* Poll the SCCTRL register status bits (6:3) */
+	cmp	r0, #0xf0000
+	bne wait_till_normal_mode
+
+	/*
+	 * Invalidate all instruction caches to PoU
+	 * and flush branch target cache
+	 */
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0
+
+	ldr	r3, SRAM_STACK_PA
+	ldmia	r3!, {r4-r6}
+	mov	sp, r4
+	msr	spsr_cxsf, r5
+	mov	lr, r6
+
+	ldmia	r3!, {r4-r9}
+	/* Coprocessor access Control Register */
+	mcr	p15, 0, r4, c1, c0, 2
+
+	/* TTBR0 */
+	mcr	p15, 0, r5, c2, c0, 0
+	/* TTBR1 */
+	mcr	p15, 0, r6, c2, c0, 1
+	/* Translation table base control register */
+	mcr	p15, 0, r7, c2, c0, 2
+	/*domain access Control Register */
+	mcr	p15, 0, r8, c3, c0, 0
+	/* data fault status Register */
+	mcr	p15, 0, r9, c5, c0, 0
+
+	ldmia	r3!, {r4-r8}
+	/* instruction fault status Register */
+	mcr	p15, 0, r4, c5, c0, 1
+	/*Data Auxiliary Fault Status Register */
+	mcr	p15, 0, r5, c5, c1, 0
+	/*Instruction Auxiliary Fault Status Register*/
+	mcr	p15, 0, r6, c5, c1, 1
+	/*Data Fault Address Register */
+	mcr	p15, 0, r7, c6, c0, 0
+	/*Instruction Fault Address Register*/
+	mcr	p15, 0, r8, c6, c0, 2
+	ldmia	r3!, {r4-r7}
+
+	/* user r/w thread and process ID */
+	mcr	p15, 0, r4, c13, c0, 2
+	/* user ro thread and process ID */
+	mcr	p15, 0, r5, c13, c0, 3
+	/*Privileged only thread and process ID */
+	mcr	p15, 0, r6, c13, c0, 4
+	/* cache size selection */
+	mcr	p15, 2, r7, c0, c0, 0
+	ldmia	r3!, {r4-r8}
+	/* Data TLB lockdown registers */
+	mcr	p15, 0, r4, c10, c0, 0
+	/* Instruction TLB lockdown registers */
+	mcr	p15, 0, r5, c10, c0, 1
+	/* Secure or Nonsecure Vector Base Address */
+	mcr	p15, 0, r6, c12, c0, 0
+	/* FCSE PID */
+	mcr	p15, 0, r7, c13, c0, 0
+	/* Context PID */
+	mcr	p15, 0, r8, c13, c0, 1
+
+	ldmia	r3!, {r4-r5}
+	/* primary memory remap register */
+	mcr	p15, 0, r4, c10, c2, 0
+	/*normal memory remap register */
+	mcr	p15, 0, r5, c10, c2, 1
+
+	/* Restore cpsr */
+	ldmfd	r3!, {r4}	/*load CPSR from SDRAM*/
+	msr	cpsr, r4	/*store cpsr */
+	dsb
+	isb
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 4	@ Flush prefetch buffer
+	mcr	p15, 0, r0, c7, c5, 6	@ Invalidate branch predictor array
+	mcr	p15, 0, r0, c8, c5, 0	@ Invalidate instruction TLB
+	mcr	p15, 0, r0, c8, c6, 0	@ Invalidate data TLB
+
+	adr	r5, mmu_on
+	mov	r1, #0xcfffffff
+	and	r5, r5, r1
+	ldr	r1, =0x30000000
+	orr	r5, r5, r1
+	mov	r4, r5
+
+	/* Move the DDR out of self refresh mode */
+	ldr	r6, MISC_BASE_P
+	ldr	r7, MPMC_BASE_P
+	/* Program MPMC Control Status register in Misc Space */
+	ldr	r0, [r6, #0x334]
+	/* Clear srefresh_enter bit(2) */
+	bic	r0, r0, #0x4
+	str	r0, [r6, #0x334]
+	/* Additional clearance is required in the mpmc space */
+	ldr	r0, [r7, #0x2c]
+	/*
+	 * Clear bit srefresh bit (2) of MPMC_11 register
+	 * The misc wrapper does not works fine by itself till
+	 * this bit is also cleared.
+	 */
+	bic	r0, r0, #0x10000
+	str	r0, [r7, #0x2c]
+wait_for_refresh_exit:
+	ldr	r0, [r6, #0x334]
+	tst	r0, #0x2000
+	bne	wait_for_refresh_exit
+
+	ldmfd	r3!, {r2}
+	/* restore the MMU control register from stack to enable mmu */
+	mcr	p15, 0, r2, c1, c0, 0
+	bx	r4
+
+mmu_on:
+	ldmfd	sp!, {r0-r12, pc}		@ restore regs and return
+	nop
+
+MPMC_BASE_P :
+	.word MPMC_BASE_PA
+MISC_BASE_P :
+	.word MISC_BASE_PA
+SRAM_STACK_VA :
+	.word IO_ADDRESS(SPEAR_SRAM_STACK_PA)
+SRAM_STACK_PA :
+	.word SPEAR_SRAM_STACK_PA
+DISABLE_I_C_M_V:
+	.word 0x1805
+MISC_PLL_OFFS:
+	.word 0x214
+#ifdef DDR_PLL_SREFRESH
+PLL_VAL1:
+	.word 0x060a
+PLL_VAL2:
+	.word 0x060e
+PLL_VAL3:
+	.word 0x0606
+#endif
+ENTRY(spear_sleep_mode_sz)
+	.word	. - spear_sleep_mode
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 5370b5b..515b8c9 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -439,6 +439,11 @@ struct map_desc spear13xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM0_BASE),
 		.length		= SZ_32K,
 		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR13XX_SYSRAM1_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM1_BASE),
+		.length		= SZ_1M,
+		.type		= MT_MEMORY_NONCACHED
 	},
 };
 
diff --git a/arch/arm/mach-spear3xx/include/mach/suspend.h b/arch/arm/mach-spear3xx/include/mach/suspend.h
new file mode 100644
index 0000000..2435886
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/suspend.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/suspend.h
+ *
+ * Sleep mode defines for SPEAr3xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * AUTHOR : Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SUSPEND_H
+#define __MACH_SUSPEND_H
+
+#include <mach/hardware.h>
+
+#ifndef __ASSEMBLER__
+extern void spear_sleep_mode(suspend_state_t state);
+extern unsigned int spear_sleep_mode_sz;
+#endif
+
+/* SRAM related defines*/
+#define SRAM_STACK_SCR_OFFS	0xF00
+#define SPEAR_START_SRAM	SPEAR3XX_ICM1_SRAM_BASE
+#define SPEAR_SRAM_SIZE		SZ_4K
+#define SPEAR_SRAM_SCR_REG	(SPEAR_START_SRAM + SRAM_STACK_SCR_OFFS)
+/* SPEAr subsystem physical addresses */
+#define SYS_CTRL_BASE_PA	SPEAR3XX_ICM3_SYS_CTRL_BASE
+#define MPMC_BASE_PA		SPEAR3XX_ICM3_SDRAM_CTRL_BASE
+#define MISC_BASE_PA		SPEAR3XX_ICM3_MISC_REG_BASE
+
+/* ARM Modes of Operation */
+#define MODE_USR_32		0x10
+#define MODE_FIQ_32		0x11
+#define MODE_IRQ_32		0x12
+#define MODE_SVC_32		0x13
+#define MODE_ABT_32		0x17
+#define MODE_UND_32		0x1B
+#define MODE_SYS_32		0x1F
+#define MODE_BITS		0x1F
+
+#endif /* __MACH_SUSPEND_H */
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 16ca683..2278c08 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -22,6 +22,10 @@
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+#define SPEAR3XX_WKUP_SRCS	(1 << SPEAR3XX_IRQ_MAC_1 | 1 << \
+		SPEAR3XX_IRQ_USB_DEV | 1 << SPEAR3XX_IRQ_BASIC_RTC | 1 << \
+		SPEAR3XX_IRQ_BASIC_GPIO)
+
 /* Add spear3xx machines common devices here */
 /* gpio device registration */
 static struct pl061_platform_data gpio_plat_data = {
@@ -224,7 +228,8 @@ void __init spear3xx_init(void)
 /* This will initialize vic */
 void __init spear3xx_init_irq(void)
 {
-	vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0);
+	vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0,
+			SPEAR3XX_WKUP_SRCS);
 }
 
 /* Following will create static virtual/physical mappings */
diff --git a/arch/arm/mach-spear6xx/include/mach/suspend.h b/arch/arm/mach-spear6xx/include/mach/suspend.h
new file mode 100644
index 0000000..bf870fc
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/suspend.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/suspend.h
+ *
+ * Sleep mode defines for SPEAr6xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * AUTHOR : Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SUSPEND_H
+#define __MACH_SUSPEND_H
+
+#include <mach/hardware.h>
+
+#ifndef __ASSEMBLER__
+extern void spear_sleep_mode(suspend_state_t state);
+extern unsigned int spear_sleep_mode_sz;
+#endif
+
+/* SRAM related defines*/
+#define SRAM_STACK_SCR_OFFS	0xF00
+#define SPEAR_START_SRAM	SPEAR6XX_ICM1_SRAM_BASE
+#define SPEAR_SRAM_SIZE		SZ_4K
+#define SPEAR_SRAM_SCR_REG	(SPEAR_START_SRAM + SRAM_STACK_SCR_OFFS)
+/* SPEAr subsystem physical addresses */
+#define SYS_CTRL_BASE_PA	SPEAR6XX_ICM3_SYS_CTRL_BASE
+#define MPMC_BASE_PA		SPEAR6XX_ICM3_SDRAM_CTRL_BASE
+#define MISC_BASE_PA		SPEAR6XX_ICM3_MISC_REG_BASE
+
+/* ARM Modes of Operation */
+#define MODE_USR_32		0x10
+#define MODE_FIQ_32		0x11
+#define MODE_IRQ_32		0x12
+#define MODE_SVC_32		0x13
+#define MODE_ABT_32		0x17
+#define MODE_UND_32		0x1B
+#define MODE_SYS_32		0x1F
+#define MODE_BITS		0x1F
+
+#endif /* __MACH_SUSPEND_H */
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 00336e9..b38bf2b 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -23,6 +23,12 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+/* The wake sources are routed through vic-2 */
+#define SPEAR6XX_WKUP_SRCS_VIC2		(1 << (IRQ_GMAC_1 - 32) | \
+					1 << (IRQ_USB_DEV - 32) | \
+					1 << (IRQ_BASIC_RTC - 32) |\
+					1 << (IRQ_BASIC_GPIO - 32))
+
 /* Add spear6xx machines common devices here */
 /* ssp device registration */
 static struct pl022_ssp_controller ssp_platform_data[] = {
@@ -360,7 +366,8 @@ void __init spear6xx_init(void)
 void __init spear6xx_init_irq(void)
 {
 	vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0);
-	vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0);
+	vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0,
+			SPEAR6XX_WKUP_SRCS_VIC2);
 }
 
 /* Following will create static virtual/physical mappings */
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 44923e9..0c979af 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -7,6 +7,7 @@ obj-y	:= clock.o time.o
 
 obj-$(CONFIG_ARCH_SPEAR13XX)	+= padmux.o
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
+
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
 obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
 
@@ -18,3 +19,8 @@ obj-$(CONFIG_BOARD_SPEAR300_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR310_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR320_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR600_EVB)	+= i2c_eval_board.o
+
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= pm.o sleep.o
+obj-$(CONFIG_ARCH_SPEAR6XX)	+= pm.o sleep.o
+endif
diff --git a/arch/arm/plat-spear/pm.c b/arch/arm/plat-spear/pm.c
new file mode 100644
index 0000000..0cb2d0c
--- /dev/null
+++ b/arch/arm/plat-spear/pm.c
@@ -0,0 +1,104 @@
+/*
+ * arch/arm/plat-spear/pm.c
+ *
+ * SPEAr3xx & SPEAr6xx Power Management source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/suspend.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <mach/irqs.h>
+#include <mach/suspend.h>
+
+static void (*saved_idle)(void);
+static void __iomem *spear_sram_base;
+
+static int spear_pm_sleep(suspend_state_t state)
+{
+	void (*spear_sram_sleep)(suspend_state_t state) = NULL;
+
+	/* Copy the Sleep code on to the SRAM*/
+	spear_sram_sleep = memcpy((void *)spear_sram_base,
+			(void *)spear_sleep_mode, spear_sleep_mode_sz);
+	flush_cache_all();
+	/* Jump to the suspend routines in sram */
+	spear_sram_sleep(state);
+	return 0;
+}
+
+/*
+ *	spear_pm_prepare - Do preliminary suspend work.
+ *
+ */
+static int spear_pm_prepare(void)
+{
+	/* We cannot sleep in idle until we have resumed */
+	saved_idle = pm_idle;
+	pm_idle = NULL;
+	return 0;
+}
+
+/*
+ *	spear_pm_enter - Actually enter a sleep state.
+ *	@state:		State we're entering.
+ *
+ */
+static int spear_pm_enter(suspend_state_t state)
+{
+	int ret;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		ret = spear_pm_sleep(state);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/*
+ *	spear_pm_finish - Finish up suspend sequence.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed).
+ */
+static void spear_pm_finish(void)
+{
+	pm_idle = saved_idle;
+}
+
+static struct platform_suspend_ops spear_pm_ops = {
+	.prepare	= spear_pm_prepare,
+	.enter		= spear_pm_enter,
+	.finish		= spear_pm_finish,
+	.valid		= suspend_valid_only_mem,
+};
+
+static int __init spear_pm_init(void)
+{
+
+	spear_sram_base = ioremap(SPEAR_START_SRAM, SPEAR_SRAM_SIZE);
+
+	if (!spear_sram_base)
+		return -ENOMEM;
+
+	/* In case the suspend code size is more than sram size return */
+	if (spear_sleep_mode_sz > (SPEAR_SRAM_SIZE))
+		return	-ENOMEM;
+
+	suspend_set_ops(&spear_pm_ops);
+	return 0;
+}
+arch_initcall(spear_pm_init);
diff --git a/arch/arm/plat-spear/sleep.S b/arch/arm/plat-spear/sleep.S
new file mode 100644
index 0000000..5347789
--- /dev/null
+++ b/arch/arm/plat-spear/sleep.S
@@ -0,0 +1,288 @@
+/*
+ * arch/arm/plat-spear/sleep.S
+ *
+ * SPEAR3xx and SPEAR6xx specific functions that will run in
+ * internal SRAM. The functions are used in power management.
+ *
+ * Copyright (ST) 2010 Deepak Sikri <deepak.sikri@.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/suspend.h>
+
+.text
+ENTRY(spear_sleep_mode)
+	stmfd	sp!, {r0-r12, lr}
+
+	/* Latch some of MMU registers on to stack */
+	mrc	p15, 0, r0, c5, c0, 0 /* FSR--Domain Fault */
+	mrc	p15, 0, r1, c5, c0, 1 /* FSR--Instruction Fault */
+	mrc	p15, 0, r2, c6, c0, 0 /* FAR */
+	mrc	p15, 0, r3, c9, c0, 0 /* Read Dcache Lockdown */
+	mrc	p15, 0, r4, c9, c0, 1 /* Read ICache Lockdown */
+	mrc	p15, 0, r5, c9, c1, 0 /* Read Data TLB */
+	mrc	p15, 0, r6, c9, c1, 1 /* Read Instr TCM region register */
+
+	mrc	p15, 0, r7, c10, c0, 0 /* Data TLBLock Down operation */
+	mrc	p15, 0, r8, c13, c0, 0 /* FCSE--PID */
+	mrc	p15, 0, r9, c13, c0, 1 /* Context-ID */
+
+	/* Save all these registers onto the stack */
+	stmfd	sp!, {r0-r9}
+	/* Save the stack pointer */
+	mov	r3, sp
+	/* Store the two mode registers */
+	stmfd	r3!, {sp, lr}
+	/* Save the current mode with irq disabled */
+	mrs	r0, cpsr
+	stmfd	r3!, {r0}
+	/*
+	 * Save the MMU registers on the SRAM Stack
+	 * Domain Register on Back-up RAM structure
+	 */
+	mrc	p15, 0, r2, c3, c0, 0
+	/* TTB Register */
+	mrc	p15, 0, r1, c2, c0, 0
+	/* MMU Enable Register */
+	mrc	p15, 0, r0, c1, c0, 0
+	stmfd	r3!, {r0, r1, r2}
+	/*
+	 * Capture the Physical Address.
+	 * This will be used once MMU is Off
+	 */
+	adr	r0, mmu_off
+	adr	r1, spear_sleep_mode
+	/* Store the virtual address on to DDR */
+	stmfd	r3!, {r1}
+	sub	r1, r0, r1
+	ldr	r0, SRAM_START_P
+	add	r2, r1, r0
+
+	/* Disable MMU */
+	mrc	p15, 0, r0, c1, c0, 0
+	ldr	r1, DISABLE_I_C_M_V
+	bic	r0, r0, r1
+	mcr	p15, 0, r0, c1, c0, 0
+	/* Move the Physical address into PC */
+	bx	r2
+
+	/*
+	 * This portion of code is executed from SRAM
+	 * post MMU has been turned off
+	 */
+mmu_off:
+	/* Store the DDR stack address onto scratch pad location */
+	ldr	r0, SCRATCH_PAD
+	str	r3, [r0]
+
+	ldr	r6, MISC_BASE_P
+	ldr	r7, MPMC_BASE_P
+	ldr	r8, SYS_CTRL_BASE_P
+
+	/*
+	 * Put SDRAM in self-refresh mode
+	 * Clear START bit(24) of MEMCTL_GP_03 register in MPMC
+	 */
+	ldr	r0, [r7, #0x1c]
+	ldr	r4, =0x1000000
+	/* Begin the command processing in controller */
+	bic	r0, r0, r4
+	str	r0, [r7, #0x1c]
+	ldr	r0, [r7, #0x1c]
+	/* set the SREFRESH bit(16) */
+	ldr	r4, =0x10000
+	orr	r0, r0, r4
+	str	r0, [r7, #0x1c]
+
+	/* Put the DDR into low power mode */
+	ldr	r0, [r6, #0xf0]
+	ldr	r4, =0x00000001
+	/* Clear DDR_LOW_POWER_DDR2_MODE bit(1) of DDR_PAD register */
+	bic	r0, r0, r4
+	str	r0, [r6, #0xf0]
+
+	/* Put the system in slow mode, use system controller */
+	ldr	r0, [r8]
+	bic	r0, r0, #0x4
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	orr	r0, r0, #0x2
+	str	r0, [r8]	/* System is now in slow mode */
+
+wait_till_slow_mode:
+	ldr	r0, [r8]
+	and	r0, r0, #0x78	/* Wait for the mode to be updated */
+	cmp	r0, #0x10	/* Poll the SCCTRL register status bits (6:3) */
+	bne wait_till_slow_mode
+
+	/* Put the Pll-1 to off. */
+	ldr	r0, [r6, #0x08]
+	/* Clear pll_enable bit(2) of PLL1_CTR register in Misc registers */
+	bic	r0, r0, #0x04
+	str	r0, [r6, #0x08]
+
+	/* Put the Pll-2 to off */
+	ldr	r0, [r6, #0x14]
+	/* Clear pll_enable bit(2) of PLL2_CTR register in Misc registers */
+	bic	r0, r0, #0x04
+	str	r0, [r6, #0x14]
+	mov	r2, #0
+	/* Put the system in sleep */
+	ldr	r0, [r8]
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	bic	r0, r0, #0x7
+#ifdef TEST_SLOW
+	orr	r0, r0, #0x2 /* Slow Mode */
+#endif
+	str	r0, [r8]
+	/* Put system in WFI */
+	mcr	p15, 0, r2, c7, c0, 4
+wakeup_addr:
+	ldr	r6, MISC_BASE_P
+	ldr	r7, MPMC_BASE_P
+	ldr	r8, SYS_CTRL_BASE_P
+	/* Reenable pll1 and pll2 */
+	ldr	r0, PLL_VAL1
+	str	r0, [r6, #0x08]
+	str	r0, [r6, #0x14]
+	ldr	r0, PLL_VAL2
+	str	r0, [r6, #0x08]
+	str	r0, [r6, #0x14]
+	/* Strobe */
+	ldr	r2, PLL_VAL3
+	str	r2, [r6, #0x08]
+	str	r2, [r6, #0x14]
+	ldr	r2, PLL_VAL2
+	str	r2, [r6, #0x08]
+	str	r2, [r6, #0x14]
+pll1_lock_1:
+	/* Set the pll_lock bit(0) in PLL1_CTR register in misc space*/
+	ldr	r2, [r6, #0x08]
+	and	r2, r2, #0x1
+	/* Wait for pll-1 lock status */
+	cmp	r2, #0x1
+	bne	pll1_lock_1
+
+pll2_lock_2:
+	/* Set the pll_lock bit(0) in PLL2_CTR register in misc space*/
+	ldr	r2, [r6, #0x14]
+	and	r2, r2, #0x1
+	/* Wait for pll-2 lock status */
+	cmp	r2, #0x1
+	bne	pll2_lock_2
+
+	/* Move the system in Normal mode, use system controller */
+	ldr	r3, [r8]
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	bic	r3, r3, #0x7
+	orr	r3, r3, #0x4
+	str	r3, [r8]
+
+wait_till_norm_mode:
+	ldr	r3, [r8]
+	and	r3, r3, #0x78
+	cmp	r3, #0x20	/* Poll the SCCTRL register status bits (6:3) */
+	bne	wait_till_norm_mode
+
+	/* Resume the DDR from Low power mode. */
+	ldr	r0, [r6, #0xf0]
+	/* Set DDR_LOW_POWER_DDR2_MODE bit(1) of DDR_PAD register */
+	orr	r0, r0, #0x01
+	str	r0, [r6, #0xf0]
+
+	/* Exit DDR-SDRAM from self-refresh mode */
+	ldr	r1, [r7, #0x1c]
+	/* clear the SREFRESH bit(16) */
+	ldr	r4, =0x10000
+	bic	r1, r1, r4
+	str	r1, [r7, #0x1c]
+
+	/* Begin the command processing in controller */
+	ldr	r4, =0x1000000
+	/* Set START bit(24) of MEMCTL_GP_03 register in MPMC*/
+	orr	r1, r1, r4
+	str	r1, [r7, #0x1c]
+
+	mov	r0, r0
+	/* Start the Restore Processing */
+	ldr	r0, SCRATCH_PAD
+	ldr	r6, [r0]
+
+	/* Restore the Virtual Address to be used */
+	/* Once MMU is made on */
+	ldr	r0, SRAM_START_P
+	adr	r1, mmu_on
+	sub	r0, r1, r0
+	/* Get the physical Address */
+	mov	r3, #0xc0000000
+	sub	r6, r6, r3
+	/* Fetch the sram virtual address */
+	ldmfd	r6!, {r1}
+	add	r4, r1, r0
+
+	/* Fetch the MMU Related information latched on SDRAM */
+	ldmfd	r6!, {r0, r1, r2}
+	/* Enable the MMU */
+	mcr	p15, 0, r2, c3, c0, 0
+	mcr	p15, 0, r1, c2, c0, 0
+	mcr	p15, 0, r0, c1, c0, 0
+	bx	r4
+mmu_on:
+	add	r6, r6, r3
+	/* Store the value of cpsr in R0 */
+	mrs	r0, cpsr
+	bic	r0, r0, #MODE_BITS
+
+	/* Here we will restore our cpsr IRQ/FIQ Disabled */
+	ldr	r0, [r6]
+	msr	cpsr_cxsf, r0
+	add	r6, r6, #4
+
+	/* Now only two user-mode registers are left */
+	ldmfd	r6!, {sp, lr}
+	mov	r0, r0
+
+	/* Restore stack pointer for the current mode */
+	mov	sp, r6
+
+	ldmfd	sp!, {r0-r9}
+	mcr	p15, 0, r0, c5, c0, 0 /* FSR--Domain Fault */
+	mcr	p15, 0, r1, c5, c0, 1 /* FSR--Instruction Fault */
+	mcr	p15, 0, r2, c6, c0, 0 /* FAR */
+	mcr	p15, 0, r3, c9, c0, 0 /* Read Dcache Lockdown */
+	mcr	p15, 0, r4, c9, c0, 1 /* Read ICache Lockdown */
+	mcr 	p15, 0, r5, c9, c1, 0 /* Read Data TLB */
+	mcr	p15, 0, r6, c9, c1, 1 /* Read Instruction Lockdown */
+
+	mcr	p15, 0, r7, c10, c0, 0 /* Data TLB LockDown operation */
+	mcr	p15, 0, r8, c13, c0, 0 /* FCSE--PID */
+	mcr	p15, 0, r9, c13, c0, 1 /* Context-ID */
+
+	mov	r0, #0
+	ldmfd	sp!, {r0-r12, pc}
+
+SYS_CTRL_BASE_P :
+	.word SYS_CTRL_BASE_PA
+MPMC_BASE_P :
+	.word MPMC_BASE_PA
+MISC_BASE_P :
+	.word MISC_BASE_PA
+SRAM_START_P:
+	.word SPEAR_START_SRAM
+SCRATCH_PAD:
+	.word SPEAR_SRAM_SCR_REG
+DISABLE_I_C_M_V:
+	.word 0x1005
+PLL_VAL1:
+	.word 0x1c0a
+PLL_VAL2:
+	.word 0x1c0e
+PLL_VAL3:
+	.word 0x1c06
+ENTRY(spear_sleep_mode_sz)
+	.word . - spear_sleep_mode
-- 
1.7.2.2

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

* [PATCH V6 17/17] ST SPEAr: Updating defconfigs
  2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
                   ` (15 preceding siblings ...)
  2011-03-01 11:31 ` [PATCH V6 16/17] ST SPEAr Power Management: Added the support for Standby mode Viresh Kumar
@ 2011-03-01 11:31 ` Viresh Kumar
  16 siblings, 0 replies; 22+ messages in thread
From: Viresh Kumar @ 2011-03-01 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/configs/spear13xx_defconfig |   78 ++++++++++++++++++++++++++++++---
 arch/arm/configs/spear3xx_defconfig  |   80 +++++++++++++++++++++++++++++++---
 arch/arm/configs/spear6xx_defconfig  |   72 ++++++++++++++++++++++++++++---
 3 files changed, 211 insertions(+), 19 deletions(-)

diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index 9f3baf8..d764fee 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -10,31 +10,94 @@ CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR13XX=y
 CONFIG_BOARD_SPEAR1300_EVB=y
 CONFIG_BOARD_SPEAR1310_EVB=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCIEAER is not set
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_AEABI=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
 CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_ARPD=y
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_NETDEVICES=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_TEST=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -42,16 +105,18 @@ CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
+CONFIG_NLS_ASCII=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
@@ -59,3 +124,4 @@ CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
+# CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
index fea7e1f..5a210ce 100644
--- a/arch/arm/configs/spear3xx_defconfig
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -10,13 +10,54 @@ CONFIG_PLAT_SPEAR=y
 CONFIG_BOARD_SPEAR300_EVB=y
 CONFIG_BOARD_SPEAR310_EVB=y
 CONFIG_BOARD_SPEAR320_EVB=y
+CONFIG_AEABI=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_ARPD=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_NETDEVICES=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
@@ -24,30 +65,55 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_ARMCLCD_SAMSUNG_LMS700=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_TEST=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
+CONFIG_NLS_ASCII=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
+# CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
index cef2e83..5217396 100644
--- a/arch/arm/configs/spear6xx_defconfig
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -9,10 +9,48 @@ CONFIG_MODVERSIONS=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR6XX=y
 CONFIG_BOARD_SPEAR600_EVB=y
+CONFIG_AEABI=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_ARPD=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_NETDEVICES=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_SERIAL_AMBA_PL011=y
@@ -20,30 +58,52 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_ARMCLCD_SAMSUNG_LMS700=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_TEST=y
+CONFIG_RTC_CLASS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
+CONFIG_NLS_ASCII=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
+# CONFIG_ARM_UNWIND is not set
-- 
1.7.2.2

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

* [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support.
  2011-03-01 11:27 ` [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support Viresh Kumar
@ 2011-03-01 15:10   ` Arnd Bergmann
  2011-03-10 12:45     ` shiraz hashim
  2011-03-10 12:56     ` pratyush
  0 siblings, 2 replies; 22+ messages in thread
From: Arnd Bergmann @ 2011-03-01 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 01 March 2011, Viresh Kumar wrote:
> From: Pratyush Anand <pratyush.anand@st.com>

Hi Viresh and Pratyush,

The code looks really nice, I have just a few comments, mostly
about pointer type conversion.
 
> SPEAr13xx family contains Synopsys designware PCIe version 3.30a. This
> patch adds support for this PCIe module for spear platform.

If this is a standard PCIe controller, why add it to the platform
code instead of a common place like arch/arch/common or arch/arm/kernel ?

> diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
> index fd8c2dc..c3fb454 100644
> --- a/arch/arm/mach-spear13xx/include/mach/hardware.h
> +++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
> @@ -28,4 +28,11 @@
>  /* typesafe io address */
>  #define __io_address(n)		__io(IO_ADDRESS(n))

I could not find the definition for __io() here, but I suspect this is
wrong. If __io_address() is what you use for accessing the direct-mapped
MMIO registers, it cannot also be what you use to access the PCIe PIO
ports, so most likely one of the two is broken. Can you explain?

> +#if defined(CONFIG_PCI)
> +#define PCIBIOS_MIN_IO		0
> +#define PCIBIOS_MIN_MEM		0
> +#define pcibios_assign_all_busses()	0
> +#endif
> +

No need for the #ifdef here, if you have no PCI, there won't be a conflict.

Better make PCIBIOS_MIN_IO 0x1000, in order to avoid stepping over
ISA port ranges.

> +static u32 spr_pcie_base[NUM_PCIE_PORTS] = {
> +	SPEAR13XX_PCIE0_BASE,
> +	SPEAR13XX_PCIE1_BASE,
> +	SPEAR13XX_PCIE2_BASE,
> +};
> +static u32 spr_pcie_app_base[NUM_PCIE_PORTS] = {
> +	SPEAR13XX_PCIE0_APP_BASE,
> +	SPEAR13XX_PCIE1_APP_BASE,
> +	SPEAR13XX_PCIE2_APP_BASE,
> +};

I think these should be __iomem pointers, not u32 tokens, since you
are listing virtual addresses. If you unroll the loop in
spear13xx_pcie_init() that uses these, you can actually get rid
of the two arrays, and simplify the code used there at the
same time.

> +#ifdef CONFIG_PCI_MSI
> +static DECLARE_BITMAP(msi_irq_in_use[NUM_PCIE_PORTS], SPEAR_NUM_MSI_IRQS);
> +static unsigned int spear_msi_data[NUM_PCIE_PORTS];
> +
> +static void spear13xx_msi_init(struct pcie_port *pp);
> +#endif
> +
> +static void spear_pcie_int_handler(unsigned int irq, struct irq_desc *desc);

It would be nice if you could avoid the forward declarations by reordering
the functions if possible.

> +static int __init spear13xx_pcie_setup(int nr, struct pci_sys_data *sys)
> +{
> +	struct pcie_port *pp;
> +	u32 val = 0;
> +
> +	if (nr >= NUM_PCIE_PORTS)
> +		return 0;
> +
> +	if ((*pcie_port_is_host)(nr) != 1)
> +		return 0;
> +
> +	pp = &pcie_port[nr];
> +	if (!spear13xx_pcie_link_up((void __iomem *)pp->va_app_base))
> +		return 0;

No need for the cast, va_app_base is already (void __iomem *).

> +static void __init add_pcie_port(int port, u32 base, u32 app_base)
> +{
> +	struct pcie_port *pp = &pcie_port[port];
> +	struct pcie_app_reg *app_reg;
> +
> +	pp->port = port;
> +	pp->root_bus_nr = -1;
> +	pp->base = (void __iomem *)base;
> +	pp->app_base = (void __iomem *)app_base;
> +	pp->va_app_base = (void __iomem *) ioremap(app_base, 0x200);
> +	if (!pp->va_app_base) {
> +		pr_err("error with ioremap in function %s\n", __func__);
> +		return;
> +	}
> +	pp->va_dbi_base = (void __iomem *) ioremap(base, 0x2000);
> +	if (!pp->va_dbi_base) {
> +		pr_err("error with ioremap in function %s\n", __func__);
> +		return;
> +	}

Please remove all these casts. Some are unneeded, some can go away
after the things I mention above.

> +	spin_lock_init(&pp->conf_lock);
> +	memset(pp->res, 0, sizeof(pp->res));
> +	pr_info("spear13xx PCIe port %d\n", port);
> +	if (spear13xx_pcie_link_up((void __iomem *)pp->va_app_base)) {
> +		pr_info("link up in bios\n");
> +	} else {
> +		pr_info("link down in bios\n");
> +		spear13xx_pcie_host_init(pp);
> +		spear13xx_int_init(pp);
> +		app_reg = (struct pcie_app_reg *)pp->va_app_base;

This cast looks invalid, you cast from __iomem to a regular pointer,

> +		pp->va_cfg0_base = (void __iomem *)
> +			ioremap(app_reg->in_cfg0_addr_start, IN_CFG0_SIZE);

which breaks here when you pass the value to ioremap without doing a readl.

> +#ifdef CONFIG_PCI_MSI
> +/* MSI int handler
> + */
> +static void handle_msi(struct pcie_port *pp)
> +{
> +	unsigned long val;
> +	int i, pos;
> +
> +	for (i = 0; i < 8; i++) {
> +		spear_dbi_read_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4,
> +				(u32 *)&val);
> +		if (val) {
> +			pos = 0;
> +			while ((pos = find_next_bit(&val, 32, pos)) != 32) {
> +				generic_handle_irq(SPEAR_MSI0_INT_BASE
> +					+ pp->port * SPEAR_NUM_MSI_IRQS
> +					+ (i * 32) + pos);
> +				pos++;
> +			}
> +		}
> +		spear_dbi_write_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, val);
> +	}
> +}
> +#else
> +static void handle_msi(struct pcie_port *pp)
> +{
> +}
> +#endif

The MSI code is not big, but I'd still recommend moving it to a separate
file, which gets compiled only when CONFIG_PCI_MSI is set. You can have
the #ifdef and inline NOP alternative in a header for this.

	Arnd

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

* [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support.
  2011-03-01 15:10   ` Arnd Bergmann
@ 2011-03-10 12:45     ` shiraz hashim
  2011-03-10 14:38       ` Arnd Bergmann
  2011-03-10 12:56     ` pratyush
  1 sibling, 1 reply; 22+ messages in thread
From: shiraz hashim @ 2011-03-10 12:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Arnd,

On Tue, Mar 1, 2011 at 8:40 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 01 March 2011, Viresh Kumar wrote:
>> From: Pratyush Anand <pratyush.anand@st.com>

[...]

>> diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
>> index fd8c2dc..c3fb454 100644
>> --- a/arch/arm/mach-spear13xx/include/mach/hardware.h
>> +++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
>> @@ -28,4 +28,11 @@
>> ?/* typesafe io address */
>> ?#define __io_address(n) ? ? ? ? ? ? ?__io(IO_ADDRESS(n))
>
> I could not find the definition for __io() here, but I suspect this is
> wrong. If __io_address() is what you use for accessing the direct-mapped
> MMIO registers, it cannot also be what you use to access the PCIe PIO
> ports, so most likely one of the two is broken. Can you explain?

This is not used in PCIe and infact is not part of this PCIe patch.
This is used at few places in the architecture code.

-- 
regards
Shiraz Hashim

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

* [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support.
  2011-03-01 15:10   ` Arnd Bergmann
  2011-03-10 12:45     ` shiraz hashim
@ 2011-03-10 12:56     ` pratyush
  1 sibling, 0 replies; 22+ messages in thread
From: pratyush @ 2011-03-10 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Arnd,

On 3/1/2011 8:40 PM, Arnd Bergmann wrote:
> On Tuesday 01 March 2011, Viresh Kumar wrote:
>> From: Pratyush Anand <pratyush.anand@st.com>
> 
> Hi Viresh and Pratyush,
> 
> The code looks really nice, I have just a few comments, mostly
> about pointer type conversion.
>  
>> SPEAr13xx family contains Synopsys designware PCIe version 3.30a. This
>> patch adds support for this PCIe module for spear platform.
> 
> If this is a standard PCIe controller, why add it to the platform
> code instead of a common place like arch/arch/common or arch/arm/kernel ?
> 

Yes, It is for Synopsys IP , but there are ST specific changes for accessing
HW resources.

>> diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
>> index fd8c2dc..c3fb454 100644
>> --- a/arch/arm/mach-spear13xx/include/mach/hardware.h
>> +++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
>> @@ -28,4 +28,11 @@
>>  /* typesafe io address */
>>  #define __io_address(n)		__io(IO_ADDRESS(n))
> 
> I could not find the definition for __io() here, but I suspect this is
> wrong. If __io_address() is what you use for accessing the direct-mapped
> MMIO registers, it cannot also be what you use to access the PCIe PIO
> ports, so most likely one of the two is broken. Can you explain?
> 
>> +#if defined(CONFIG_PCI)
>> +#define PCIBIOS_MIN_IO		0
>> +#define PCIBIOS_MIN_MEM		0
>> +#define pcibios_assign_all_busses()	0
>> +#endif
>> +
> 
> No need for the #ifdef here, if you have no PCI, there won't be a conflict.
> 
> Better make PCIBIOS_MIN_IO 0x1000, in order to avoid stepping over
> ISA port ranges.
> 

In fact , I do not need these defines. I will remove them.

>> +static u32 spr_pcie_base[NUM_PCIE_PORTS] = {
>> +	SPEAR13XX_PCIE0_BASE,
>> +	SPEAR13XX_PCIE1_BASE,
>> +	SPEAR13XX_PCIE2_BASE,
>> +};
>> +static u32 spr_pcie_app_base[NUM_PCIE_PORTS] = {
>> +	SPEAR13XX_PCIE0_APP_BASE,
>> +	SPEAR13XX_PCIE1_APP_BASE,
>> +	SPEAR13XX_PCIE2_APP_BASE,
>> +};
> 
> I think these should be __iomem pointers, not u32 tokens, since you
> are listing virtual addresses. If you unroll the loop in
> spear13xx_pcie_init() that uses these, you can actually get rid
> of the two arrays, and simplify the code used there at the
> same time.
> 

will do it.

>> +#ifdef CONFIG_PCI_MSI
>> +static DECLARE_BITMAP(msi_irq_in_use[NUM_PCIE_PORTS], SPEAR_NUM_MSI_IRQS);
>> +static unsigned int spear_msi_data[NUM_PCIE_PORTS];
>> +
>> +static void spear13xx_msi_init(struct pcie_port *pp);
>> +#endif
>> +
>> +static void spear_pcie_int_handler(unsigned int irq, struct irq_desc *desc);
> 
> It would be nice if you could avoid the forward declarations by reordering
> the functions if possible.
> 

will do it.

>> +static int __init spear13xx_pcie_setup(int nr, struct pci_sys_data *sys)
>> +{
>> +	struct pcie_port *pp;
>> +	u32 val = 0;
>> +
>> +	if (nr >= NUM_PCIE_PORTS)
>> +		return 0;
>> +
>> +	if ((*pcie_port_is_host)(nr) != 1)
>> +		return 0;
>> +
>> +	pp = &pcie_port[nr];
>> +	if (!spear13xx_pcie_link_up((void __iomem *)pp->va_app_base))
>> +		return 0;
> 
> No need for the cast, va_app_base is already (void __iomem *).
> 

ok.

>> +static void __init add_pcie_port(int port, u32 base, u32 app_base)
>> +{
>> +	struct pcie_port *pp = &pcie_port[port];
>> +	struct pcie_app_reg *app_reg;
>> +
>> +	pp->port = port;
>> +	pp->root_bus_nr = -1;
>> +	pp->base = (void __iomem *)base;
>> +	pp->app_base = (void __iomem *)app_base;
>> +	pp->va_app_base = (void __iomem *) ioremap(app_base, 0x200);
>> +	if (!pp->va_app_base) {
>> +		pr_err("error with ioremap in function %s\n", __func__);
>> +		return;
>> +	}
>> +	pp->va_dbi_base = (void __iomem *) ioremap(base, 0x2000);
>> +	if (!pp->va_dbi_base) {
>> +		pr_err("error with ioremap in function %s\n", __func__);
>> +		return;
>> +	}
> 
> Please remove all these casts. Some are unneeded, some can go away
> after the things I mention above.
> 

ok.

>> +	spin_lock_init(&pp->conf_lock);
>> +	memset(pp->res, 0, sizeof(pp->res));
>> +	pr_info("spear13xx PCIe port %d\n", port);
>> +	if (spear13xx_pcie_link_up((void __iomem *)pp->va_app_base)) {
>> +		pr_info("link up in bios\n");
>> +	} else {
>> +		pr_info("link down in bios\n");
>> +		spear13xx_pcie_host_init(pp);
>> +		spear13xx_int_init(pp);
>> +		app_reg = (struct pcie_app_reg *)pp->va_app_base;
> 
> This cast looks invalid, you cast from __iomem to a regular pointer,
> 

will typecast it with (struct pcie_app_reg __iomem*)

>> +		pp->va_cfg0_base = (void __iomem *)
>> +			ioremap(app_reg->in_cfg0_addr_start, IN_CFG0_SIZE);
> 
> which breaks here when you pass the value to ioremap without doing a readl.
> 

will modify.

>> +#ifdef CONFIG_PCI_MSI
>> +/* MSI int handler
>> + */
>> +static void handle_msi(struct pcie_port *pp)
>> +{
>> +	unsigned long val;
>> +	int i, pos;
>> +
>> +	for (i = 0; i < 8; i++) {
>> +		spear_dbi_read_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4,
>> +				(u32 *)&val);
>> +		if (val) {
>> +			pos = 0;
>> +			while ((pos = find_next_bit(&val, 32, pos)) != 32) {
>> +				generic_handle_irq(SPEAR_MSI0_INT_BASE
>> +					+ pp->port * SPEAR_NUM_MSI_IRQS
>> +					+ (i * 32) + pos);
>> +				pos++;
>> +			}
>> +		}
>> +		spear_dbi_write_reg(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, val);
>> +	}
>> +}
>> +#else
>> +static void handle_msi(struct pcie_port *pp)
>> +{
>> +}
>> +#endif
> 
> The MSI code is not big, but I'd still recommend moving it to a separate
> file, which gets compiled only when CONFIG_PCI_MSI is set. You can have
> the #ifdef and inline NOP alternative in a header for this.
> 

will put it in a separate file.

Regards
Pratyush


> 	Arnd
> .
> 

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

* [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support.
  2011-03-10 12:45     ` shiraz hashim
@ 2011-03-10 14:38       ` Arnd Bergmann
  0 siblings, 0 replies; 22+ messages in thread
From: Arnd Bergmann @ 2011-03-10 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 10 March 2011, shiraz hashim wrote:
> >> diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
> >> index fd8c2dc..c3fb454 100644
> >> --- a/arch/arm/mach-spear13xx/include/mach/hardware.h
> >> +++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
> >> @@ -28,4 +28,11 @@
> >>  /* typesafe io address */
> >>  #define __io_address(n)              __io(IO_ADDRESS(n))
> >
> > I could not find the definition for __io() here, but I suspect this is
> > wrong. If __io_address() is what you use for accessing the direct-mapped
> > MMIO registers, it cannot also be what you use to access the PCIe PIO
> > ports, so most likely one of the two is broken. Can you explain?
> 
> This is not used in PCIe and infact is not part of this PCIe patch.
> This is used at few places in the architecture code.

Let me rephrase my point:

The __io() macro is used for accessing PIO registers in PCIe drivers,
it needs to be defined to convert I/O port numbers between PCIBIOS_MIN_IO
and IO_SPACE_LIMIT to the virtual address that is mapped to the I/O
space registers on your PCIe bus.

__io_address() is used in spear13xx to map from physical addresses
in the SOC to virtual addresses that are part of the linear mapping
set up through iotable_init().

These two are not the same, so I believe that either __io_address()
or __io() is broken.

	Arnd

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

end of thread, other threads:[~2011-03-10 14:38 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-01 11:27 [PATCH V6 00/17] Adding devices support for all spear machines Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 01/17] ST SPEAr13xx: Added ARM PL061 GPIO Support Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 02/17] ST SPEAr13xx: Added PCIe host controller base driver support Viresh Kumar
2011-03-01 15:10   ` Arnd Bergmann
2011-03-10 12:45     ` shiraz hashim
2011-03-10 14:38       ` Arnd Bergmann
2011-03-10 12:56     ` pratyush
2011-03-01 11:27 ` [PATCH V6 03/17] ST SPEAr: Adding PLGPIO driver for spear platform Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 04/17] ST SPEAr3xx: Adding support for ST's PWM IP Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 05/17] ST SPEAr: Adding Watchdog support on spear3xx & spear6xx machines Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 06/17] ST SPEAr3xx: Adding RAS uart devices Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 07/17] ST SPEAr320: Adding support for CAN Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 08/17] ST SPEAr3xx: EMI (External Memory Interface) controller driver Viresh Kumar
2011-03-01 11:27 ` [PATCH V6 09/17] ST SPEAr: Adding machine support for rtc-spear Viresh Kumar
2011-03-01 11:30 ` [PATCH V6 10/17] ST SPEAr: adding support for synopsis i2c designware Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 11/17] ST SPEAr: Adding machine support for USB host Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 12/17] ST SPEAr: Adding machine support for keyboard Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 13/17] ST SPEAr: Adding machine support for nand Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 14/17] ST SPEAr: Adding support for SSP PL022 Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 15/17] ST SPEAr: Adding support for SDHCI (SDIO) Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 16/17] ST SPEAr Power Management: Added the support for Standby mode Viresh Kumar
2011-03-01 11:31 ` [PATCH V6 17/17] ST SPEAr: Updating defconfigs Viresh Kumar

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