All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/74] Updating SPEAr Support
@ 2010-08-30 10:38 Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 01/74] ST SPEAr: Padmux code Updated Viresh KUMAR
                   ` (74 more replies)
  0 siblings, 75 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Following set of patches:
- updates SPEAr3xx, 6xx support
- Adds support for SPEAr13xx
- Removes Multiple defconfigs per machine family

Bhupesh Sharma (2):
  ST SPEAr 13xx : Adding support for SPEAr1310
  ST SPEAr : Adding CAN platform support for SPEAr320 and SPEAr1310

Deepak Sikri (7):
  ST SPEAr: Adding USB Host support
  SPEAr Clock Framework: Adding support for PLL frequency change
  SPEAr Power Management: Added the support for Standby mode.
  GIC: Added dummy handlers for Power Management Suspend Resume
  SPEAr CPU freq: Adding support for CPU Freq framework
  ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms
  SPEAr13xx: Adding and Updating Clock definitions

Pratyush Anand (2):
  ST SPEAr: Added PCIE host controller base driver support.
  ST SPEAr: PCIE gadget suppport

Rajeev Kumar (3):
  ST SPEAr: adding support for rtc
  ST SPEAr: adding support for synopsis i2c designware
  ST SPEAr : Added keyboard support

Ryan Mallon (5):
  SPEAr3xx: Make local structres static
  SPEAR3xx: Rename register/irq defines to remove naming conflicts
  SPEAr3xx: Rework pmx_dev code to remove conflicts
  SPEAr3xx: Rework KConfig to allow all boards to be compiled in
  SPEAr3xx: Replace defconfigs with single unfied defconfig

Shiraz Hashim (16):
  ST SPEAr: Formalized timer support
  ST SPEAr13XX: Adding machine specific header files
  ST SPEAr13XX: Adding machine specific src files
  ST SPEAr: Adding support for SPEAr13xx SoC in spear generic plat/
  ST SPEAr13XX: Added compilation support in arch/arm/
  ST SPEAr1300: Adding default config file
  ST SPEAr: Adding information in Documentation/ and MAINTAINERS
  ST SPEAr: Update clock framework and definitions
  ST SPEAr: enhanced spear clock framework
  ST SPEAr: Adding Debugfs support on clock framework
  ST SPEAr: Add smi driver for serial NOR flash
  ST SPEAr: Adding support for serial nor flash in all spear platforms
  ST SPEAr: Replacing SIZE macro's with actual required size
  SPEAr: removing size based macros except those necessary
  ST SPEAr13xx: add l2 cache support
  ST SPEAr13xx: Modified static mappings

Vipin Kumar (10):
  ST SPEAr : NAND interface driver for spear platforms
  Incrementing the ecc_pos array to contain 128 char
  Newly erased page read workaround
  ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface
    driver
  SPEAr : SEV Send event to secondary CPUs
  ST SPEAr1310: Adding fsmc nor support
  SPEAr : Pad multiplexing handling modified
  SPEAr13xx : Fixed part devices in SPEAr13xx addded to the generic
    implementation
  SPEAr : Adding SPEAr1310 pad multiplexing devices

Vipul-kumar Samar (1):
  ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx

Viresh Kumar (28):
  ST SPEAr: Padmux code Updated
  ST SPEAr: Making clock functions more generic
  ST SPEAr: Adding support for divisor per parent clock
  ST SPEAr: Correcting SOC Config base address for spear320
  ST SPEAr: Adding PLGPIO driver for spear platform
  Clock Framework: Adding ENABLED_ON_INIT feature in clk
  ST SPEAr: Added ARM PL061 GPIO Support on SPEAr13xx and modified
    resource size
  ST SPEAr: Adding support for ST's PWM IP
  ST SPEAr: Adding Watchdog support
  ST SPEAr: Adding support for SSP PL022
  ST SPEAr: Adding clk_set_rate support
  ST SPEAr: Adding support for SDHCI (SDIO)
  ST SPEAr: Changing resource size of amba devices to SZ_4K
  ST SPEAr: Enabling clocks before amba device registeration
  ST SPEAr3xx: Rearranging declarations in clock.c file
  ST SPEAr: Adding miscellaneous devices and clocks
  ST SPEAr: Adding support for DDR in clock framework
  ST SPEAr: SDHCI- selecting SD_MMC from misc and fixing sdhci_synth
    rate to 48 MHz
  ST SPEAr3xx: Passing pmx devices address from machine *.c files
  ST SPEAr: Appending spear3** with global structures
  ST SPEAr3xx: Updating plgpio and emi source to make it compliant with
    single image strategy
  SPEAr6xx: Rework Kconfig for single image solution
  ST SPEAR6xx: renaming spear600_defconfig as spear6xx_defconfig
  SPEAr13XX: Update register/macros/devices/routine names and pmx dev
    registration to implement single image for multiple boards.
  SPEAr13xx: Rework KConfig to allow all boards to be compiled in
  SPEAr13xx: Replace defconfigs with single unfied defconfig
  ST SPEAr: Updating defconfigs
  ST SPEAr: Enabling devices in various evb.c files

 Documentation/arm/SPEAr/overview.txt               |   33 +-
 MAINTAINERS                                        |    6 +
 arch/arm/Kconfig                                   |   19 +-
 arch/arm/Makefile                                  |    2 +
 arch/arm/common/gic.c                              |   13 +
 arch/arm/configs/spear13xx_defconfig               | 1769 ++++++++++++++++++++
 arch/arm/configs/spear300_defconfig                |   51 -
 arch/arm/configs/spear310_defconfig                |   52 -
 arch/arm/configs/spear320_defconfig                |   52 -
 arch/arm/configs/spear3xx_defconfig                | 1615 ++++++++++++++++++
 arch/arm/configs/spear600_defconfig                |   49 -
 arch/arm/configs/spear6xx_defconfig                | 1606 ++++++++++++++++++
 arch/arm/mach-spear13xx/Kconfig                    |   32 +
 arch/arm/mach-spear13xx/Makefile                   |   21 +
 arch/arm/mach-spear13xx/Makefile.boot              |    3 +
 arch/arm/mach-spear13xx/clock.c                    | 1140 +++++++++++++
 arch/arm/mach-spear13xx/fsmc-nor.c                 |   81 +
 arch/arm/mach-spear13xx/headsmp.S                  |   95 ++
 arch/arm/mach-spear13xx/hotplug.c                  |  146 ++
 arch/arm/mach-spear13xx/include/mach/clkdev.h      |   19 +
 arch/arm/mach-spear13xx/include/mach/debug-macro.S |   14 +
 arch/arm/mach-spear13xx/include/mach/entry-macro.S |   88 +
 arch/arm/mach-spear13xx/include/mach/generic.h     |  275 +++
 arch/arm/mach-spear13xx/include/mach/gpio.h        |   37 +
 arch/arm/mach-spear13xx/include/mach/hardware.h    |   37 +
 arch/arm/mach-spear13xx/include/mach/io.h          |   19 +
 arch/arm/mach-spear13xx/include/mach/irqs.h        |  152 ++
 arch/arm/mach-spear13xx/include/mach/memory.h      |   19 +
 arch/arm/mach-spear13xx/include/mach/misc_regs.h   |  386 +++++
 arch/arm/mach-spear13xx/include/mach/pcie.h        |  169 ++
 arch/arm/mach-spear13xx/include/mach/smp.h         |   39 +
 arch/arm/mach-spear13xx/include/mach/spear.h       |   95 ++
 arch/arm/mach-spear13xx/include/mach/spear1300.h   |   21 +
 arch/arm/mach-spear13xx/include/mach/spear1310.h   |   46 +
 arch/arm/mach-spear13xx/include/mach/suspend.h     |   47 +
 arch/arm/mach-spear13xx/include/mach/system.h      |   43 +
 arch/arm/mach-spear13xx/include/mach/timex.h       |   19 +
 arch/arm/mach-spear13xx/include/mach/uncompress.h  |   19 +
 arch/arm/mach-spear13xx/include/mach/vmalloc.h     |   18 +
 arch/arm/mach-spear13xx/localtimer.c               |   25 +
 arch/arm/mach-spear13xx/pcie.c                     |  881 ++++++++++
 arch/arm/mach-spear13xx/platsmp.c                  |  220 +++
 arch/arm/mach-spear13xx/pm.c                       |  107 ++
 arch/arm/mach-spear13xx/sleep.S                    |  435 +++++
 arch/arm/mach-spear13xx/spear1300.c                |   38 +
 arch/arm/mach-spear13xx/spear1300_evb.c            |  212 +++
 arch/arm/mach-spear13xx/spear1310.c                |  468 ++++++
 arch/arm/mach-spear13xx/spear1310_evb.c            |  217 +++
 arch/arm/mach-spear13xx/spear13xx.c                | 1163 +++++++++++++
 arch/arm/mach-spear3xx/Kconfig                     |   30 +-
 arch/arm/mach-spear3xx/Kconfig300                  |   17 -
 arch/arm/mach-spear3xx/Kconfig310                  |   17 -
 arch/arm/mach-spear3xx/Kconfig320                  |   17 -
 arch/arm/mach-spear3xx/Makefile                    |    4 +
 arch/arm/mach-spear3xx/clock.c                     |  563 ++++++-
 arch/arm/mach-spear3xx/emi.c                       |  102 ++
 arch/arm/mach-spear3xx/include/mach/emi.h          |   80 +
 arch/arm/mach-spear3xx/include/mach/generic.h      |  282 ++--
 arch/arm/mach-spear3xx/include/mach/gpio.h         |  143 ++
 arch/arm/mach-spear3xx/include/mach/irqs.h         |  206 ++--
 arch/arm/mach-spear3xx/include/mach/misc_regs.h    |   12 +-
 arch/arm/mach-spear3xx/include/mach/spear.h        |  134 +--
 arch/arm/mach-spear3xx/include/mach/spear300.h     |   86 +-
 arch/arm/mach-spear3xx/include/mach/spear310.h     |   85 +-
 arch/arm/mach-spear3xx/include/mach/spear320.h     |  121 +-
 arch/arm/mach-spear3xx/include/mach/suspend.h      |   44 +
 arch/arm/mach-spear3xx/spear300.c                  |  640 ++++++--
 arch/arm/mach-spear3xx/spear300_evb.c              |  138 ++-
 arch/arm/mach-spear3xx/spear310.c                  |  434 ++++--
 arch/arm/mach-spear3xx/spear310_evb.c              |  137 ++-
 arch/arm/mach-spear3xx/spear320.c                  |  855 ++++++++---
 arch/arm/mach-spear3xx/spear320_evb.c              |  154 ++-
 arch/arm/mach-spear3xx/spear3xx.c                  |  742 +++++++--
 arch/arm/mach-spear6xx/Kconfig                     |   15 +-
 arch/arm/mach-spear6xx/Kconfig600                  |   17 -
 arch/arm/mach-spear6xx/clock.c                     |  438 ++++-
 arch/arm/mach-spear6xx/include/mach/generic.h      |   21 +-
 arch/arm/mach-spear6xx/include/mach/gpio.h         |   27 +
 arch/arm/mach-spear6xx/include/mach/misc_regs.h    |   12 +-
 arch/arm/mach-spear6xx/include/mach/spear.h        |  174 +--
 arch/arm/mach-spear6xx/include/mach/suspend.h      |   44 +
 arch/arm/mach-spear6xx/spear600_evb.c              |   80 +-
 arch/arm/mach-spear6xx/spear6xx.c                  |  341 ++++-
 arch/arm/mm/Kconfig                                |    2 +-
 arch/arm/plat-spear/Kconfig                        |   16 +
 arch/arm/plat-spear/Makefile                       |   21 +-
 arch/arm/plat-spear/clcd.c                         |  126 ++
 arch/arm/plat-spear/clock.c                        |  911 +++++++++--
 arch/arm/plat-spear/cpufreq.c                      |  160 ++
 arch/arm/plat-spear/i2c_eval_board.c               |   29 +
 arch/arm/plat-spear/include/plat/clock.h           |  187 ++-
 arch/arm/plat-spear/include/plat/device.h          |   37 +
 arch/arm/plat-spear/include/plat/fsmc.h            |  158 ++
 arch/arm/plat-spear/include/plat/gpio.h            |   35 +
 arch/arm/plat-spear/include/plat/keyboard.h        |  154 ++
 arch/arm/plat-spear/include/plat/nand.h            |   76 +
 arch/arm/plat-spear/include/plat/padmux.h          |   34 +-
 arch/arm/plat-spear/include/plat/smi.h             |   71 +
 arch/arm/plat-spear/include/plat/spi.h             |   77 +
 arch/arm/plat-spear/padmux.c                       |   54 +-
 arch/arm/plat-spear/plgpio.c                       |  475 ++++++
 arch/arm/plat-spear/pll_clk.S                      |  187 ++
 arch/arm/plat-spear/pm.c                           |  104 ++
 arch/arm/plat-spear/pwm.c                          |  484 ++++++
 arch/arm/plat-spear/sleep.S                        |  288 ++++
 arch/arm/plat-spear/smi.c                          |   63 +
 arch/arm/plat-spear/time.c                         |   34 +-
 drivers/input/keyboard/Kconfig                     |    8 +
 drivers/input/keyboard/Makefile                    |    1 +
 drivers/input/keyboard/spear-keyboard.c            |  335 ++++
 drivers/misc/Kconfig                               |   10 +
 drivers/misc/Makefile                              |    1 +
 drivers/misc/spear13xx_pcie_gadget.c               |  888 ++++++++++
 drivers/mtd/devices/Kconfig                        |    7 +
 drivers/mtd/devices/Makefile                       |    1 +
 drivers/mtd/devices/spear_smi.c                    | 1122 +++++++++++++
 drivers/mtd/nand/Kconfig                           |    6 +
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/spear_nand.c                      |  876 ++++++++++
 drivers/rtc/Kconfig                                |    7 +
 drivers/rtc/Makefile                               |    1 +
 drivers/rtc/rtc-spear.c                            |  598 +++++++
 drivers/usb/Kconfig                                |    2 +
 drivers/usb/host/ehci-hcd.c                        |    5 +
 drivers/usb/host/ehci-spear.c                      |  210 +++
 drivers/usb/host/ohci-hcd.c                        |    5 +
 drivers/usb/host/ohci-spear.c                      |  240 +++
 drivers/video/Kconfig                              |   14 +-
 include/mtd/mtd-abi.h                              |    2 +-
 129 files changed, 24444 insertions(+), 2004 deletions(-)
 create mode 100644 arch/arm/configs/spear13xx_defconfig
 delete mode 100644 arch/arm/configs/spear300_defconfig
 delete mode 100644 arch/arm/configs/spear310_defconfig
 delete mode 100644 arch/arm/configs/spear320_defconfig
 create mode 100644 arch/arm/configs/spear3xx_defconfig
 delete mode 100644 arch/arm/configs/spear600_defconfig
 create mode 100644 arch/arm/configs/spear6xx_defconfig
 create mode 100644 arch/arm/mach-spear13xx/Kconfig
 create mode 100644 arch/arm/mach-spear13xx/Makefile
 create mode 100644 arch/arm/mach-spear13xx/Makefile.boot
 create mode 100644 arch/arm/mach-spear13xx/clock.c
 create mode 100644 arch/arm/mach-spear13xx/fsmc-nor.c
 create mode 100644 arch/arm/mach-spear13xx/headsmp.S
 create mode 100644 arch/arm/mach-spear13xx/hotplug.c
 create mode 100644 arch/arm/mach-spear13xx/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-spear13xx/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-spear13xx/include/mach/generic.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/gpio.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/hardware.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/io.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/irqs.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/memory.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/misc_regs.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/pcie.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/smp.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear1300.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear1310.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/suspend.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/system.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/timex.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-spear13xx/localtimer.c
 create mode 100644 arch/arm/mach-spear13xx/pcie.c
 create mode 100644 arch/arm/mach-spear13xx/platsmp.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-spear13xx/spear1300.c
 create mode 100644 arch/arm/mach-spear13xx/spear1300_evb.c
 create mode 100644 arch/arm/mach-spear13xx/spear1310.c
 create mode 100644 arch/arm/mach-spear13xx/spear1310_evb.c
 create mode 100644 arch/arm/mach-spear13xx/spear13xx.c
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig300
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig310
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig320
 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
 delete mode 100644 arch/arm/mach-spear6xx/Kconfig600
 create mode 100644 arch/arm/mach-spear6xx/include/mach/suspend.h
 create mode 100644 arch/arm/plat-spear/clcd.c
 create mode 100644 arch/arm/plat-spear/cpufreq.c
 create mode 100644 arch/arm/plat-spear/i2c_eval_board.c
 create mode 100644 arch/arm/plat-spear/include/plat/device.h
 create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
 create mode 100644 arch/arm/plat-spear/include/plat/keyboard.h
 create mode 100644 arch/arm/plat-spear/include/plat/nand.h
 create mode 100644 arch/arm/plat-spear/include/plat/smi.h
 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/pll_clk.S
 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
 create mode 100644 arch/arm/plat-spear/smi.c
 create mode 100644 drivers/input/keyboard/spear-keyboard.c
 create mode 100644 drivers/misc/spear13xx_pcie_gadget.c
 create mode 100644 drivers/mtd/devices/spear_smi.c
 create mode 100644 drivers/mtd/nand/spear_nand.c
 create mode 100644 drivers/rtc/rtc-spear.c
 create mode 100644 drivers/usb/host/ehci-spear.c
 create mode 100644 drivers/usb/host/ohci-spear.c

-- 
1.7.2.2

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

* [PATCH 01/74] ST SPEAr: Padmux code Updated
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-06 22:49   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
                   ` (73 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

- compiling padmux only for spear3xx
- padmux initialization code rearranged in evaluation board and machine files.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    7 -------
 arch/arm/mach-spear3xx/spear300.c             |   13 +++++++++----
 arch/arm/mach-spear3xx/spear300_evb.c         |    9 ++++-----
 arch/arm/mach-spear3xx/spear310.c             |   11 ++++++-----
 arch/arm/mach-spear3xx/spear310_evb.c         |    9 ++++-----
 arch/arm/mach-spear3xx/spear320.c             |   11 ++++++-----
 arch/arm/mach-spear3xx/spear320_evb.c         |    9 ++++-----
 arch/arm/mach-spear3xx/spear3xx.c             |   21 ---------------------
 arch/arm/plat-spear/Makefile                  |    4 ++--
 9 files changed, 35 insertions(+), 59 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index af7e02c..c16d2f8 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -40,7 +40,6 @@ void __init clk_init(void);
 void __init spear3xx_map_io(void);
 void __init spear3xx_init_irq(void);
 void __init spear3xx_init(void);
-void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size);
 
 /* pad mux declarations */
 #define PMX_FIRDA_MASK		(1 << 14)
@@ -133,8 +132,6 @@ extern struct pmx_dev pmx_telecom_sdio_4bit;
 extern struct pmx_dev pmx_telecom_sdio_8bit;
 extern struct pmx_dev pmx_gpio1;
 
-void spear300_pmx_init(void);
-
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
 
@@ -154,8 +151,6 @@ extern struct pmx_dev pmx_fsmc;
 extern struct pmx_dev pmx_rs485_0_1;
 extern struct pmx_dev pmx_tdm0;
 
-void spear310_pmx_init(void);
-
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
 
@@ -195,8 +190,6 @@ extern struct pmx_dev pmx_smii0;
 extern struct pmx_dev pmx_smii1;
 extern struct pmx_dev pmx_i2c1;
 
-void spear320_pmx_init(void);
-
 /* Add spear320 machine function declarations here */
 void __init spear320_init(void);
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 3560f8c..7e0ca5d 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -459,10 +459,15 @@ void __init spear300_init(void)
 		if (ret)
 			printk(KERN_ERR "Error registering Shared IRQ\n");
 	}
-}
 
-void spear300_pmx_init(void)
-{
-	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
+	/* pmx initialization */
+	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
 			SPEAR300_SOC_CONFIG_SIZE);
+	if (pmx_driver.base) {
+		ret = pmx_register(&pmx_driver);
+		if (ret)
+			printk(KERN_ERR "padmux: registeration failed. err no"
+					": %d\n", ret);
+		iounmap(pmx_driver.base);
+	}
 }
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index bb21db1..2c90663 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -51,14 +51,13 @@ static void __init spear300_evb_init(void)
 {
 	unsigned int i;
 
-	/* call spear300 machine init function */
-	spear300_init();
-
-	/* padmux initialization */
+	/* padmux initialization, must be done before spear300_init */
 	pmx_driver.mode = &photo_frame_mode;
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-	spear300_pmx_init();
+
+	/* call spear300 machine init function */
+	spear300_init();
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 96a1ab8..576bc57 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -293,10 +293,11 @@ void __init spear310_init(void)
 		if (ret)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
-}
 
-void spear310_pmx_init(void)
-{
-	spear_pmx_init(&pmx_driver, SPEAR310_SOC_CONFIG_BASE,
-			SPEAR310_SOC_CONFIG_SIZE);
+	/* pmx initialization */
+	pmx_driver.base = base;
+	ret = pmx_register(&pmx_driver);
+	if (ret)
+		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+				ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 7facf66..4e55e55 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -58,14 +58,13 @@ static void __init spear310_evb_init(void)
 {
 	unsigned int i;
 
-	/* call spear310 machine init function */
-	spear310_init();
-
-	/* padmux initialization */
+	/* padmux initialization, must be done before spear310_init */
 	pmx_driver.mode = NULL;
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-	spear310_pmx_init();
+
+	/* call spear310 machine init function */
+	spear310_init();
 
 	/* 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 6a12195..2886bb2 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -540,10 +540,11 @@ void __init spear320_init(void)
 		if (ret)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
-}
 
-void spear320_pmx_init(void)
-{
-	spear_pmx_init(&pmx_driver, SPEAR320_SOC_CONFIG_BASE,
-			SPEAR320_SOC_CONFIG_SIZE);
+	/* pmx initialization */
+	pmx_driver.base = base;
+	ret = pmx_register(&pmx_driver);
+	if (ret)
+		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+				ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 62ac685..7083a06 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -55,14 +55,13 @@ static void __init spear320_evb_init(void)
 {
 	unsigned int i;
 
-	/* call spear320 machine init function */
-	spear320_init();
-
-	/* padmux initialization */
+	/* padmux initialization, must be done before spear320_init */
 	pmx_driver.mode = &auto_net_mii_mode;
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-	spear320_pmx_init();
+
+	/* call spear320 machine init function */
+	spear320_init();
 
 	/* 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 e87313a..efd2e17 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -525,24 +525,3 @@ struct pmx_dev pmx_plgpio_45_46_49_50 = {
 };
 
 #endif
-
-/* spear padmux initialization function */
-void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size)
-{
-	int ret = 0;
-
-	/* pad mux initialization */
-	pmx_driver->base = ioremap(base, size);
-	if (!pmx_driver->base) {
-		ret = -ENOMEM;
-		goto pmx_fail;
-	}
-
-	ret = pmx_register(pmx_driver);
-	iounmap(pmx_driver->base);
-
-pmx_fail:
-	if (ret)
-		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
-				ret);
-}
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index eb89540..b4f340b 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,6 @@
 #
 
 # Common support
-obj-y	:= clock.o padmux.o time.o
+obj-y	:= clock.o time.o
 
-obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
-- 
1.7.2.2

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

* [PATCH 02/74] ST SPEAr: Making clock functions more generic
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 01/74] ST SPEAr: Padmux code Updated Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 03/74] ST SPEAr: Formalized timer support Viresh KUMAR
                   ` (72 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Modifications include:
 - Adding dummy clk_set_rate function. Required for compilation of few drivers
 - Making function present in plat-spear/clock.c more generic over all platforms
 - Added div_factor filed in struct clk for clks with .recalc = follow_parent

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear3xx/clock.c           |   66 ++++++++++++++++++++++++++----
 arch/arm/mach-spear6xx/clock.c           |   67 ++++++++++++++++++++++++++----
 arch/arm/plat-spear/clock.c              |   59 ++++++++++++++++++--------
 arch/arm/plat-spear/include/plat/clock.h |   64 ++++++++++++++++++++++++----
 4 files changed, 212 insertions(+), 44 deletions(-)

diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 18febf9..7ea8749 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -39,10 +39,25 @@ static struct clk rtc_clk = {
 };
 
 /* clock derived from 24 MHz osc clk */
+/* pll masks structure */
+static struct pll_clk_masks pll1_masks = {
+	.mode_mask = PLL_MODE_MASK,
+	.mode_shift = PLL_MODE_SHIFT,
+	.norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
+	.norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
+	.dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
+	.dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
+	.div_p_mask = PLL_DIV_P_MASK,
+	.div_p_shift = PLL_DIV_P_SHIFT,
+	.div_n_mask = PLL_DIV_N_MASK,
+	.div_n_shift = PLL_DIV_N_SHIFT,
+};
+
 /* pll1 configuration structure */
 static struct pll_clk_config pll1_config = {
 	.mode_reg = PLL1_CTR,
 	.cfg_reg = PLL1_FRQ,
+	.masks = &pll1_masks,
 };
 
 /* PLL1 clock */
@@ -50,7 +65,7 @@ static struct clk pll1_clk = {
 	.pclk = &osc_24m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
-	.recalc = &pll1_clk_recalc,
+	.recalc = &pll_clk_recalc,
 	.private_data = &pll1_config,
 };
 
@@ -76,11 +91,16 @@ static struct clk cpu_clk = {
 	.recalc = &follow_parent,
 };
 
+/* ahb masks structure */
+static struct bus_clk_masks ahb_masks = {
+	.mask = PLL_HCLK_RATIO_MASK,
+	.shift = PLL_HCLK_RATIO_SHIFT,
+};
+
 /* ahb configuration structure */
 static struct bus_clk_config ahb_config = {
 	.reg = CORE_CLK_CFG,
-	.mask = PLL_HCLK_RATIO_MASK,
-	.shift = PLL_HCLK_RATIO_SHIFT,
+	.masks = &ahb_masks,
 };
 
 /* ahb clock */
@@ -91,9 +111,22 @@ static struct clk ahb_clk = {
 	.private_data = &ahb_config,
 };
 
+/* auxiliary synthesizers masks */
+static struct aux_clk_masks aux_masks = {
+	.eq_sel_mask = AUX_EQ_SEL_MASK,
+	.eq_sel_shift = AUX_EQ_SEL_SHIFT,
+	.eq1_mask = AUX_EQ1_SEL,
+	.eq2_mask = AUX_EQ2_SEL,
+	.xscale_sel_mask = AUX_XSCALE_MASK,
+	.xscale_sel_shift = AUX_XSCALE_SHIFT,
+	.yscale_sel_mask = AUX_YSCALE_MASK,
+	.yscale_sel_shift = AUX_YSCALE_SHIFT,
+};
+
 /* uart configurations */
 static struct aux_clk_config uart_config = {
 	.synth_reg = UART_CLK_SYNT,
+	.masks = &aux_masks,
 };
 
 /* uart parents */
@@ -130,6 +163,7 @@ static struct clk uart_clk = {
 /* firda configurations */
 static struct aux_clk_config firda_config = {
 	.synth_reg = FIRDA_CLK_SYNT,
+	.masks = &aux_masks,
 };
 
 /* firda parents */
@@ -184,9 +218,18 @@ static struct pclk_sel gpt_pclk_sel = {
 	.pclk_sel_mask = GPT_CLK_MASK,
 };
 
+/* gpt synthesizer masks */
+static struct gpt_clk_masks gpt_masks = {
+	.mscale_sel_mask = GPT_MSCALE_MASK,
+	.mscale_sel_shift = GPT_MSCALE_SHIFT,
+	.nscale_sel_mask = GPT_NSCALE_MASK,
+	.nscale_sel_shift = GPT_NSCALE_SHIFT,
+};
+
 /* gpt0 configurations */
-static struct aux_clk_config gpt0_config = {
+static struct gpt_clk_config gpt0_config = {
 	.synth_reg = PRSC1_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt0 timer clock */
@@ -199,8 +242,9 @@ static struct clk gpt0_clk = {
 };
 
 /* gpt1 configurations */
-static struct aux_clk_config gpt1_config = {
+static struct gpt_clk_config gpt1_config = {
 	.synth_reg = PRSC2_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt1 timer clock */
@@ -214,8 +258,9 @@ static struct clk gpt1_clk = {
 };
 
 /* gpt2 configurations */
-static struct aux_clk_config gpt2_config = {
+static struct gpt_clk_config gpt2_config = {
 	.synth_reg = PRSC3_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt2 timer clock */
@@ -253,11 +298,16 @@ static struct clk clcd_clk = {
 };
 
 /* clock derived from ahb clk */
+/* apb masks structure */
+static struct bus_clk_masks apb_masks = {
+	.mask = HCLK_PCLK_RATIO_MASK,
+	.shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
 /* apb configuration structure */
 static struct bus_clk_config apb_config = {
 	.reg = CORE_CLK_CFG,
-	.mask = HCLK_PCLK_RATIO_MASK,
-	.shift = HCLK_PCLK_RATIO_SHIFT,
+	.masks = &apb_masks,
 };
 
 /* apb clock */
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 36ff056..ef88922 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -39,10 +39,25 @@ static struct clk rtc_clk = {
 };
 
 /* clock derived from 30 MHz osc clk */
+/* pll masks structure */
+static struct pll_clk_masks pll1_masks = {
+	.mode_mask = PLL_MODE_MASK,
+	.mode_shift = PLL_MODE_SHIFT,
+	.norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
+	.norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
+	.dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
+	.dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
+	.div_p_mask = PLL_DIV_P_MASK,
+	.div_p_shift = PLL_DIV_P_SHIFT,
+	.div_n_mask = PLL_DIV_N_MASK,
+	.div_n_shift = PLL_DIV_N_SHIFT,
+};
+
 /* pll1 configuration structure */
 static struct pll_clk_config pll1_config = {
 	.mode_reg = PLL1_CTR,
 	.cfg_reg = PLL1_FRQ,
+	.masks = &pll1_masks,
 };
 
 /* PLL1 clock */
@@ -50,7 +65,7 @@ static struct clk pll1_clk = {
 	.pclk = &osc_30m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
-	.recalc = &pll1_clk_recalc,
+	.recalc = &pll_clk_recalc,
 	.private_data = &pll1_config,
 };
 
@@ -76,11 +91,16 @@ static struct clk cpu_clk = {
 	.recalc = &follow_parent,
 };
 
+/* ahb masks structure */
+static struct bus_clk_masks ahb_masks = {
+	.mask = PLL_HCLK_RATIO_MASK,
+	.shift = PLL_HCLK_RATIO_SHIFT,
+};
+
 /* ahb configuration structure */
 static struct bus_clk_config ahb_config = {
 	.reg = CORE_CLK_CFG,
-	.mask = PLL_HCLK_RATIO_MASK,
-	.shift = PLL_HCLK_RATIO_SHIFT,
+	.masks = &ahb_masks,
 };
 
 /* ahb clock */
@@ -112,9 +132,22 @@ static struct pclk_sel uart_pclk_sel = {
 	.pclk_sel_mask = UART_CLK_MASK,
 };
 
+/* auxiliary synthesizers masks */
+static struct aux_clk_masks aux_masks = {
+	.eq_sel_mask = AUX_EQ_SEL_MASK,
+	.eq_sel_shift = AUX_EQ_SEL_SHIFT,
+	.eq1_mask = AUX_EQ1_SEL,
+	.eq2_mask = AUX_EQ2_SEL,
+	.xscale_sel_mask = AUX_XSCALE_MASK,
+	.xscale_sel_shift = AUX_XSCALE_SHIFT,
+	.yscale_sel_mask = AUX_YSCALE_MASK,
+	.yscale_sel_shift = AUX_YSCALE_SHIFT,
+};
+
 /* uart configurations */
 static struct aux_clk_config uart_config = {
 	.synth_reg = UART_CLK_SYNT,
+	.masks = &aux_masks,
 };
 
 /* uart0 clock */
@@ -140,6 +173,7 @@ static struct clk uart1_clk = {
 /* firda configurations */
 static struct aux_clk_config firda_config = {
 	.synth_reg = FIRDA_CLK_SYNT,
+	.masks = &aux_masks,
 };
 
 /* firda parents */
@@ -176,6 +210,7 @@ static struct clk firda_clk = {
 /* clcd configurations */
 static struct aux_clk_config clcd_config = {
 	.synth_reg = CLCD_CLK_SYNT,
+	.masks = &aux_masks,
 };
 
 /* clcd parents */
@@ -230,9 +265,18 @@ static struct pclk_sel gpt_pclk_sel = {
 	.pclk_sel_mask = GPT_CLK_MASK,
 };
 
+/* gpt synthesizer masks */
+static struct gpt_clk_masks gpt_masks = {
+	.mscale_sel_mask = GPT_MSCALE_MASK,
+	.mscale_sel_shift = GPT_MSCALE_SHIFT,
+	.nscale_sel_mask = GPT_NSCALE_MASK,
+	.nscale_sel_shift = GPT_NSCALE_SHIFT,
+};
+
 /* gpt0_1 configurations */
-static struct aux_clk_config gpt0_1_config = {
+static struct gpt_clk_config gpt0_1_config = {
 	.synth_reg = PRSC1_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt0 ARM1 subsystem timer clock */
@@ -254,8 +298,9 @@ static struct clk gpt1_clk = {
 };
 
 /* gpt2 configurations */
-static struct aux_clk_config gpt2_config = {
+static struct gpt_clk_config gpt2_config = {
 	.synth_reg = PRSC2_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt2 timer clock */
@@ -269,8 +314,9 @@ static struct clk gpt2_clk = {
 };
 
 /* gpt3 configurations */
-static struct aux_clk_config gpt3_config = {
+static struct gpt_clk_config gpt3_config = {
 	.synth_reg = PRSC3_CLK_CFG,
+	.masks = &gpt_masks,
 };
 
 /* gpt3 timer clock */
@@ -309,11 +355,16 @@ static struct clk usbd_clk = {
 };
 
 /* clock derived from ahb clk */
+/* apb masks structure */
+static struct bus_clk_masks apb_masks = {
+	.mask = HCLK_PCLK_RATIO_MASK,
+	.shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
 /* apb configuration structure */
 static struct bus_clk_config apb_config = {
 	.reg = CORE_CLK_CFG,
-	.mask = HCLK_PCLK_RATIO_MASK,
-	.shift = HCLK_PCLK_RATIO_SHIFT,
+	.masks = &apb_masks,
 };
 
 /* apb clock */
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index ee4f90e..f1cf832 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -17,7 +17,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <mach/misc_regs.h>
 #include <plat/clock.h>
 
 static DEFINE_SPINLOCK(clocks_lock);
@@ -187,6 +186,20 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 }
 EXPORT_SYMBOL(clk_set_parent);
 
+/**
+ * clk_set_rate - set the clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	/* TODO */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
 /* registers clock in platform clock framework */
 void clk_register(struct clk_lookup *cl)
 {
@@ -212,6 +225,7 @@ void clk_register(struct clk_lookup *cl)
 		list_add(&clk->sibling, &clk->pclk->children);
 	} else {
 		/* add clocks with > 1 parent to 1st parent's children list */
+		clk->pclk = clk->pclk_sel->pclk_info[0].pclk;
 		list_add(&clk->sibling,
 			 &clk->pclk_sel->pclk_info[0].pclk->children);
 	}
@@ -283,29 +297,31 @@ static void change_parent(struct clk *cclk, struct clk *pclk)
  * In Dithered mode
  * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
  */
-void pll1_clk_recalc(struct clk *clk)
+void pll_clk_recalc(struct clk *clk)
 {
 	struct pll_clk_config *config = clk->private_data;
 	unsigned int num = 2, den = 0, val, mode = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) &
-		PLL_MODE_MASK;
+	mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
+		config->masks->mode_mask;
 
 	val = readl(config->cfg_reg);
 	/* calculate denominator */
-	den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
+	den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
 	den = 1 << den;
-	den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
+	den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
 
 	/* calculate numerator & denominator */
 	if (!mode) {
 		/* Normal mode */
-		num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
+		num *= (val >> config->masks->norm_fdbk_m_shift) &
+			config->masks->norm_fdbk_m_mask;
 	} else {
 		/* Dithered mode */
-		num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
+		num *= (val >> config->masks->dith_fdbk_m_shift) &
+			config->masks->dith_fdbk_m_mask;
 		den *= 256;
 	}
 
@@ -321,7 +337,8 @@ void bus_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	div = ((readl(config->reg) >> config->shift) & config->mask) + 1;
+	div = ((readl(config->reg) >> config->masks->shift) &
+			config->masks->mask) + 1;
 	clk->rate = (unsigned long)clk->pclk->rate / div;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
@@ -359,15 +376,18 @@ void aux_clk_recalc(struct clk *clk)
 	if (pclk_info->scalable) {
 		val = readl(config->synth_reg);
 
-		eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK;
-		if (eqn == AUX_EQ1_SEL)
+		eqn = (val >> config->masks->eq_sel_shift) &
+			config->masks->eq_sel_mask;
+		if (eqn == config->masks->eq1_mask)
 			den *= 2;
 
 		/* calculate numerator */
-		num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK;
+		num = (val >> config->masks->xscale_sel_shift) &
+			config->masks->xscale_sel_mask;
 
 		/* calculate denominator */
-		den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK;
+		den *= (val >> config->masks->yscale_sel_shift) &
+			config->masks->yscale_sel_mask;
 		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
 	} else
 		val = clk->pclk->rate;
@@ -383,7 +403,7 @@ void aux_clk_recalc(struct clk *clk)
  */
 void gpt_clk_recalc(struct clk *clk)
 {
-	struct aux_clk_config *config = clk->private_data;
+	struct gpt_clk_config *config = clk->private_data;
 	struct pclk_info *pclk_info = NULL;
 	unsigned int div = 1, val;
 	unsigned long flags;
@@ -402,8 +422,10 @@ void gpt_clk_recalc(struct clk *clk)
 	spin_lock_irqsave(&clocks_lock, flags);
 	if (pclk_info->scalable) {
 		val = readl(config->synth_reg);
-		div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK;
-		div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
+		div += (val >> config->masks->mscale_sel_shift) &
+			config->masks->mscale_sel_mask;
+		div *= 1 << (((val >> config->masks->nscale_sel_shift) &
+					config->masks->nscale_sel_mask) + 1);
 	}
 
 	clk->rate = (unsigned long)clk->pclk->rate / div;
@@ -411,15 +433,16 @@ void gpt_clk_recalc(struct clk *clk)
 }
 
 /*
- * Used for clocks that always have same value as the parent clock divided by a
+ * Used for clocks that always have value as the parent clock divided by a
  * fixed divisor
  */
 void follow_parent(struct clk *clk)
 {
 	unsigned long flags;
+	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	clk->rate = clk->pclk->rate;
+	clk->rate = clk->pclk->rate/div_factor;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 298bafc..e08b58c 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -67,6 +67,7 @@ struct pclk_sel {
  * @en_reg_bit: clk enable/disable bit
  * @ops: clk enable/disable ops - generic_clkops selected if NULL
  * @recalc: pointer to clock rate recalculate function
+ * @div_factor: division factor to parent clock. Only for recalc = follow_parent
  * @pclk: current parent clk
  * @pclk_sel: pointer to parent selection structure
  * @pclk_sel_shift: register shift for selecting parent of this clock
@@ -82,6 +83,7 @@ struct clk {
 	u8 en_reg_bit;
 	const struct clkops *ops;
 	void (*recalc) (struct clk *);
+	unsigned int div_factor;
 
 	struct clk *pclk;
 	struct pclk_sel *pclk_sel;
@@ -93,23 +95,65 @@ struct clk {
 };
 
 /* pll configuration structure */
+struct pll_clk_masks {
+	u32 mode_mask;
+	u32 mode_shift;
+
+	u32 norm_fdbk_m_mask;
+	u32 norm_fdbk_m_shift;
+	u32 dith_fdbk_m_mask;
+	u32 dith_fdbk_m_shift;
+	u32 div_p_mask;
+	u32 div_p_shift;
+	u32 div_n_mask;
+	u32 div_n_shift;
+};
+
 struct pll_clk_config {
-	unsigned int *mode_reg;
-	unsigned int *cfg_reg;
+	u32 *mode_reg;
+	u32 *cfg_reg;
+	struct pll_clk_masks *masks;
 };
 
 /* ahb and apb bus configuration structure */
+struct bus_clk_masks {
+	u32 mask;
+	u32 shift;
+};
+
 struct bus_clk_config {
-	unsigned int *reg;
-	unsigned int mask;
-	unsigned int shift;
+	u32 *reg;
+	struct bus_clk_masks *masks;
+};
+
+/* Aux clk configuration structure: applicable to UART and FIRDA */
+struct aux_clk_masks {
+	u32 eq_sel_mask;
+	u32 eq_sel_shift;
+	u32 eq1_mask;
+	u32 eq2_mask;
+	u32 xscale_sel_mask;
+	u32 xscale_sel_shift;
+	u32 yscale_sel_mask;
+	u32 yscale_sel_shift;
 };
 
-/*
- * Aux clk configuration structure: applicable to GPT, UART and FIRDA
- */
 struct aux_clk_config {
-	unsigned int *synth_reg;
+	u32 *synth_reg;
+	struct aux_clk_masks *masks;
+};
+
+/* GPT clk configuration structure */
+struct gpt_clk_masks {
+	u32 mscale_sel_mask;
+	u32 mscale_sel_shift;
+	u32 nscale_sel_mask;
+	u32 nscale_sel_shift;
+};
+
+struct gpt_clk_config {
+	u32 *synth_reg;
+	struct gpt_clk_masks *masks;
 };
 
 /* platform specific clock functions */
@@ -118,7 +162,7 @@ void recalc_root_clocks(void);
 
 /* clock recalc functions */
 void follow_parent(struct clk *clk);
-void pll1_clk_recalc(struct clk *clk);
+void pll_clk_recalc(struct clk *clk);
 void bus_clk_recalc(struct clk *clk);
 void gpt_clk_recalc(struct clk *clk);
 void aux_clk_recalc(struct clk *clk);
-- 
1.7.2.2

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 01/74] ST SPEAr: Padmux code Updated Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-06 22:55   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files Viresh KUMAR
                   ` (71 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    3 +-
 arch/arm/mach-spear3xx/spear300_evb.c         |    2 +-
 arch/arm/mach-spear3xx/spear310_evb.c         |    2 +-
 arch/arm/mach-spear3xx/spear320_evb.c         |    2 +-
 arch/arm/mach-spear3xx/spear3xx.c             |   10 ++++++-
 arch/arm/mach-spear6xx/include/mach/generic.h |    3 +-
 arch/arm/mach-spear6xx/spear600_evb.c         |    3 +-
 arch/arm/mach-spear6xx/spear6xx.c             |    9 ++++++
 arch/arm/plat-spear/time.c                    |   34 +++++++++++++++++-------
 9 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index c16d2f8..e7d2de8 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -33,10 +33,11 @@
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device gpio_device;
 extern struct amba_device uart_device;
-extern struct sys_timer spear_sys_timer;
+extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
 void __init clk_init(void);
+void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
 void __init spear3xx_init_irq(void);
 void __init spear3xx_init(void);
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 2c90663..cd23c98 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -71,6 +71,6 @@ MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
-	.timer		=	&spear_sys_timer,
+	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear300_evb_init,
 MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 4e55e55..3855431 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -78,6 +78,6 @@ MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
-	.timer		=	&spear_sys_timer,
+	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear310_evb_init,
 MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 7083a06..4a7ce35 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -75,6 +75,6 @@ MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear3xx_map_io,
 	.init_irq	=	spear3xx_init_irq,
-	.timer		=	&spear_sys_timer,
+	.timer		=	&spear3xx_timer,
 	.init_machine	=	spear320_evb_init,
 MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index efd2e17..89cf8ea 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -523,5 +523,13 @@ struct pmx_dev pmx_plgpio_45_46_49_50 = {
 	.mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
 	.enb_on_reset = 1,
 };
+#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
 
-#endif
+static void __init spear3xx_timer_init(void)
+{
+	spear_setup_timer();
+}
+
+struct sys_timer spear3xx_timer = {
+	.init = spear3xx_timer_init,
+};
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 16205a5..e5967ed 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -31,9 +31,10 @@
 /* Add spear6xx family device structure declarations here */
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
-extern struct sys_timer spear_sys_timer;
+extern struct sys_timer spear6xx_timer;
 
 /* Add spear6xx family function declarations here */
+void __init spear_setup_timer(void);
 void __init spear6xx_map_io(void);
 void __init spear6xx_init_irq(void);
 void __init spear6xx_init(void);
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index daff8d0..bdd5b76 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -42,10 +42,11 @@ static void __init spear600_evb_init(void)
 		amba_device_register(amba_devs[i], &iomem_resource);
 }
 
+
 MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
 	.boot_params	=	0x00000100,
 	.map_io		=	spear6xx_map_io,
 	.init_irq	=	spear6xx_init_irq,
-	.timer		=	&spear_sys_timer,
+	.timer		=	&spear6xx_timer,
 	.init_machine	=	spear600_evb_init,
 MACHINE_END
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index baf6bcc..88a82ca 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -155,3 +155,12 @@ void __init spear6xx_map_io(void)
 	/* This will initialize clock framework */
 	clk_init();
 }
+
+static void __init spear6xx_timer_init(void)
+{
+	spear_setup_timer();
+}
+
+struct sys_timer spear6xx_timer = {
+	.init = spear6xx_timer_init,
+};
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index ab21165..850d0cf 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -66,6 +66,13 @@
 static __iomem void *gpt_base;
 static struct clk *gpt_clk;
 
+/* following defines the parent clock to be used */
+#ifdef CONFIG_ARCH_SPEAR13XX
+static char pclk_name[] = "osc1_24m_clk";
+#else
+static char pclk_name[] = "pll3_48m_clk";
+#endif
+
 static void clockevent_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *clk_event_dev);
 static int clockevent_next_event(unsigned long evt,
@@ -215,7 +222,8 @@ static void __init spear_clockevent_init(void)
 
 void __init spear_setup_timer(void)
 {
-	struct clk *pll3_clk;
+	struct clk *clk;
+	int ret;
 
 	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
 		pr_err("%s:cannot get IO addr\n", __func__);
@@ -234,26 +242,32 @@ void __init spear_setup_timer(void)
 		goto err_iomap;
 	}
 
-	pll3_clk = clk_get(NULL, "pll3_48m_clk");
-	if (!pll3_clk) {
-		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
+	/* get the parent clock */
+	clk = clk_get(NULL, pclk_name);
+
+	if (!clk) {
+		pr_err("%s:couldn't get %s as parent for gpt\n",
+				__func__, pclk_name);
 		goto err_iomap;
 	}
 
-	clk_set_parent(gpt_clk, pll3_clk);
+	clk_set_parent(gpt_clk, clk);
+
+	ret = clk_enable(gpt_clk);
+	if (ret < 0) {
+		pr_err("%s:couldn't enable gpt clock\n", __func__);
+		goto err_clk;
+	}
 
 	spear_clockevent_init();
 	spear_clocksource_init();
 
 	return;
 
+err_clk:
+	clk_put(gpt_clk);
 err_iomap:
 	iounmap(gpt_base);
-
 err_mem:
 	release_mem_region(SPEAR_GPT0_BASE, SZ_1K);
 }
-
-struct sys_timer spear_sys_timer = {
-	.init = spear_setup_timer,
-};
-- 
1.7.2.2

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

* [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (2 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 03/74] ST SPEAr: Formalized timer support Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  8:56   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files Viresh KUMAR
                   ` (70 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@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/clkdev.h      |   19 ++
 arch/arm/mach-spear13xx/include/mach/debug-macro.S |   14 +
 arch/arm/mach-spear13xx/include/mach/entry-macro.S |   88 ++++++
 arch/arm/mach-spear13xx/include/mach/generic.h     |   46 +++
 arch/arm/mach-spear13xx/include/mach/gpio.h        |   19 ++
 arch/arm/mach-spear13xx/include/mach/hardware.h    |   25 ++
 arch/arm/mach-spear13xx/include/mach/io.h          |   19 ++
 arch/arm/mach-spear13xx/include/mach/irqs.h        |   91 ++++++
 arch/arm/mach-spear13xx/include/mach/memory.h      |   19 ++
 arch/arm/mach-spear13xx/include/mach/misc_regs.h   |  301 ++++++++++++++++++++
 arch/arm/mach-spear13xx/include/mach/smp.h         |   33 +++
 arch/arm/mach-spear13xx/include/mach/spear.h       |   93 ++++++
 arch/arm/mach-spear13xx/include/mach/spear1300.h   |   21 ++
 arch/arm/mach-spear13xx/include/mach/system.h      |   43 +++
 arch/arm/mach-spear13xx/include/mach/timex.h       |   19 ++
 arch/arm/mach-spear13xx/include/mach/uncompress.h  |   19 ++
 arch/arm/mach-spear13xx/include/mach/vmalloc.h     |   18 ++
 17 files changed, 887 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-spear13xx/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-spear13xx/include/mach/generic.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/gpio.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/hardware.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/io.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/irqs.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/memory.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/misc_regs.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/smp.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear1300.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/system.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/timex.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-spear13xx/include/mach/vmalloc.h

diff --git a/arch/arm/mach-spear13xx/include/mach/clkdev.h b/arch/arm/mach-spear13xx/include/mach/clkdev.h
new file mode 100644
index 0000000..effdb81
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/debug-macro.S b/arch/arm/mach-spear13xx/include/mach/debug-macro.S
new file mode 100644
index 0000000..3933edc
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header spear13xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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 <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear13xx/include/mach/entry-macro.S b/arch/arm/mach-spear13xx/include/mach/entry-macro.S
new file mode 100644
index 0000000..62e1785
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/entry-macro.S
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * Copy of RealView platform implementation
+ *
+ * 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 <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_preamble, base, tmp
+		ldr	\base, =IO_ADDRESS(SPEAR13XX_GIC_CPU_BASE)
+		.endm
+
+		.macro	arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		/*
+		 * The interrupt numbering scheme is defined in the
+		 * interrupt controller spec. To wit:
+		 *
+		 * Interrupts 0-15 are IPI
+		 * 16-28 are reserved
+		 * 29-31 are local. We allow 30 to be used for the watchdog.
+		 * 32-1020 are global
+		 * 1021-1022 are reserved
+		 * 1023 is "spurious" (no interrupt)
+		 *
+		 * For now, we ignore all local interrupts so only return an
+		 * interrupt if it's between 30 and 1020. The test_for_ipi
+		 * routine below will pick up on IPIs.
+		 *
+		 * A simple read from the controller will tell us the number
+		 * of the highest priority enabled interrupt. We then just
+		 * need to check whether it is in the valid range for an
+		 * IRQ (30-1020 inclusive).
+		 */
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		/* bits 12-10 = src CPU, 9-0 = int # */
+		ldr	\irqstat, [\base, #GIC_CPU_INTACK]
+
+		ldr	\tmp, =1021
+
+		bic	\irqnr, \irqstat, #0x1c00
+
+		cmp	\irqnr, #29
+		cmpcc	\irqnr, \irqnr
+		cmpne	\irqnr, \tmp
+		cmpcs	\irqnr, \irqnr
+
+		.endm
+
+		/*
+		 * We assume that irqstat (the raw value of the IRQ acknowledge
+		 * register) is preserved from the macro above.
+		 * If there is an IPI, we immediately signal end of interrupt
+		 * on the controller, since this requires the original irqstat
+		 * value which we won't easily be able to recreate later.
+		 */
+
+		.macro test_for_ipi, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		cmp	\irqnr, #16
+		strcc	\irqstat, [\base, #GIC_CPU_EOI]
+		cmpcs	\irqnr, \irqnr
+		.endm
+
+		/* this assumes that irqstat and base are preserved.. */
+
+		.macro test_for_ltirq, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		mov 	\tmp, #0
+		cmp	\irqnr, #29
+		moveq	\tmp, #1
+		streq	\irqstat, [\base, #GIC_CPU_EOI]
+		cmp	\tmp, #0
+		.endm
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
new file mode 100644
index 0000000..41c1a53
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/generic.h
+ *
+ * spear13xx machine family generic header file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE		SPEAR13XX_GPT0_BASE
+#define SPEAR_GPT0_CHAN0_IRQ	IRQ_GPT0_TMR0
+#define SPEAR_GPT0_CHAN1_IRQ	IRQ_GPT0_TMR1
+
+/* Add spear13xx family device structure declarations here */
+extern struct amba_device uart_device;
+extern struct sys_timer spear13xx_timer;
+
+/* Add spear1300 machine device structure declarations here */
+
+/* Add spear13xx family function declarations here */
+void __init clk_init(void);
+void __init spear_setup_timer(void);
+void __init spear1300_init(void);
+void __init spear13xx_map_io(void);
+void __init spear13xx_init_irq(void);
+void __init spear13xx_init(void);
+void spear13xx_secondary_startup(void);
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/gpio.h b/arch/arm/mach-spear13xx/include/mach/gpio.h
new file mode 100644
index 0000000..43fa541
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/gpio.h
+ *
+ * GPIO macros for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
new file mode 100644
index 0000000..0047d75
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/hardware.h
+ *
+ * Hardware definitions for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <mach/spear.h>
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)		(x | 0xF0000000)
+
+/* typesafe io address */
+#define __io_address(n)		__io(IO_ADDRESS(n))
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/io.h b/arch/arm/mach-spear13xx/include/mach/io.h
new file mode 100644
index 0000000..2fe3503
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/io.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/io.h
+ *
+ * IO definitions for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
new file mode 100644
index 0000000..fd90236
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_IRQS_H
+#define __MACH_IRQS_H
+
+/* IRQ definitions */
+/*
+ * SGI : ID0 - ID15
+ * PPI : ID16 - ID31
+ * SHPI : ID32 - ID224
+ */
+
+#define IRQ_LOCALTIMER		29
+#define IRQ_LOCALWDOG		30
+
+/* Shared Peripheral Interrupt (SHPI) */
+#define IRQ_SHPI_START		32
+
+#define IRQ_PLAY_I2S2		(IRQ_SHPI_START + 10)
+#define IRQ_REC_I2S2		(IRQ_SHPI_START + 11)
+#define IRQ_ADC			(IRQ_SHPI_START + 12)
+#define IRQ_CLCD		(IRQ_SHPI_START + 13)
+#define IRQ_DMAC0_FLAG_0	(IRQ_SHPI_START + 14)
+#define IRQ_DMAC0_FLAG_1	(IRQ_SHPI_START + 15)
+#define IRQ_DMAC0_FLAG_2	(IRQ_SHPI_START + 16)
+#define IRQ_DMAC0_FLAG_3	(IRQ_SHPI_START + 17)
+#define IRQ_DMAC0_FLAG_4	(IRQ_SHPI_START + 18)
+#define IRQ_DMAC0_COMBINED	(IRQ_SHPI_START + 19)
+#define IRQ_FSMC0		(IRQ_SHPI_START + 20)
+#define IRQ_FSMC1		(IRQ_SHPI_START + 21)
+#define IRQ_FSMC2		(IRQ_SHPI_START + 22)
+#define IRQ_FSMC3		(IRQ_SHPI_START + 23)
+#define IRQ_GPIO0		(IRQ_SHPI_START + 24)
+#define IRQ_GPIO1		(IRQ_SHPI_START + 25)
+#define IRQ_PLAY_I2S1		(IRQ_SHPI_START + 26)
+#define IRQ_JPEG		(IRQ_SHPI_START + 27)
+#define IRQ_MMC			(IRQ_SHPI_START + 28)
+#define IRQ_CF			(IRQ_SHPI_START + 29)
+#define IRQ_SMI			(IRQ_SHPI_START + 30)
+#define IRQ_SSP			(IRQ_SHPI_START + 31)
+#define IRQ_C3			(IRQ_SHPI_START + 32)
+#define IRQ_GMAC_1		(IRQ_SHPI_START + 33)
+#define IRQ_GMAC_2		(IRQ_SHPI_START + 34)
+#define IRQ_UART		(IRQ_SHPI_START + 35)
+#define IRQ_RTC			(IRQ_SHPI_START + 36)
+#define IRQ_GPT0_TMR0		(IRQ_SHPI_START + 37)
+#define IRQ_GPT0_TMR1		(IRQ_SHPI_START + 38)
+#define IRQ_GPT1_TMR0		(IRQ_SHPI_START + 39)
+#define IRQ_GPT1_TMR1		(IRQ_SHPI_START + 40)
+#define IRQ_I2C			(IRQ_SHPI_START + 41)
+#define IRQ_GPT2_TMR0		(IRQ_SHPI_START + 42)
+#define IRQ_GPT2_TMR1		(IRQ_SHPI_START + 43)
+#define IRQ_GPT3_TMR0		(IRQ_SHPI_START + 44)
+#define IRQ_GPT3_TMR1		(IRQ_SHPI_START + 45)
+
+#define IRQ_JPEG_RME		(IRQ_SHPI_START + 52)
+#define IRQ_KBD			(IRQ_SHPI_START + 52)
+#define IRQ_REC_I2S1		(IRQ_SHPI_START + 53)
+#define IRQ_DMAC1_FLAG_0	(IRQ_SHPI_START + 54)
+#define IRQ_DMAC1_FLAG_1	(IRQ_SHPI_START + 55)
+#define IRQ_DMAC1_FLAG_2	(IRQ_SHPI_START + 56)
+#define IRQ_DMAC1_FLAG_3	(IRQ_SHPI_START + 57)
+#define IRQ_DMAC1_FLAG_4	(IRQ_SHPI_START + 58)
+#define IRQ_DMAC1_COMBINED	(IRQ_SHPI_START + 59)
+
+#define IRQ_UDC			(IRQ_SHPI_START + 62)
+#define IRQ_UPD			(IRQ_SHPI_START + 63)
+#define IRQ_USBH_EHCI0		(IRQ_SHPI_START + 64)
+#define IRQ_USBH_OHCI0		(IRQ_SHPI_START + 65)
+#define IRQ_USBH_EHCI1		(IRQ_SHPI_START + 66)
+#define IRQ_USBH_OHCI1		(IRQ_SHPI_START + 67)
+#define IRQ_PCIE1		(IRQ_SHPI_START + 68)
+#define IRQ_PCIE2		(IRQ_SHPI_START + 69)
+#define IRQ_PCIE3		(IRQ_SHPI_START + 70)
+
+#define IRQ_GIC_END		(IRQ_SHPI_START + 128)
+
+#define NR_IRQS			IRQ_GIC_END
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/memory.h b/arch/arm/mach-spear13xx/include/mach/memory.h
new file mode 100644
index 0000000..200257c
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/memory.h
+ *
+ * Memory map for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
new file mode 100644
index 0000000..2e87a07
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -0,0 +1,301 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/hardware.h>
+
+#define MISC_BASE		VA_SPEAR13XX_MISC_BASE
+
+/* General Configuration */
+#define SOC_CFG			((unsigned int *)(MISC_BASE + 0x000))
+#define BOOTSTRAP_CFG		((unsigned int *)(MISC_BASE + 0x004))
+
+/* Power Management Registers */
+#define PCM_CFG			((unsigned int *)(MISC_BASE + 0x100))
+#define PCM_WKUP_CFG		((unsigned int *)(MISC_BASE + 0x104))
+#define SWITCH_CTR		((unsigned int *)(MISC_BASE + 0x108))
+#define SYS_CLK_CTRL		((unsigned int *)(MISC_BASE + 0x200))
+#define SYS_SW_RES		((unsigned int *)(MISC_BASE + 0x204))
+
+/* Clock Configuration Registers */
+#define SYS_CLK_PLLTIMER	((unsigned int *)(MISC_BASE + 0x208))
+#define SYS_CLK_OSCITIMER	((unsigned int *)(MISC_BASE + 0x20c))
+
+/* PLL related registers and bit values */
+#define PLL_CFG			((unsigned int *)(MISC_BASE + 0x210))
+	/* PLL_CFG bit values */
+	#define OSC_24M_MASK	0
+	#define OSC_25M_MASK	1
+	#define PLL_CLK_MASK	3
+	#define PLL1_CLK_SHIFT	20
+	#define PLL2_CLK_SHIFT	22
+	#define PLL3_CLK_SHIFT	24
+
+#define PLL1_CTR		((unsigned int *)(MISC_BASE + 0x214))
+#define PLL1_FRQ		((unsigned int *)(MISC_BASE + 0x218))
+#define PLL1_MOD		((unsigned int *)(MISC_BASE + 0x21c))
+#define PLL2_CTR		((unsigned int *)(MISC_BASE + 0x220))
+#define PLL2_FRQ		((unsigned int *)(MISC_BASE + 0x224))
+#define PLL2_MOD		((unsigned int *)(MISC_BASE + 0x228))
+#define PLL3_CTR		((unsigned int *)(MISC_BASE + 0x22c))
+#define PLL3_FRQ		((unsigned int *)(MISC_BASE + 0x230))
+#define PLL3_MOD		((unsigned int *)(MISC_BASE + 0x234))
+#define PLL4_CTR		((unsigned int *)(MISC_BASE + 0x238))
+	/* PLL_CTR register masks */
+	#define PLL_ENABLE		2
+	#define PLL_MODE_SHIFT		4
+	#define PLL_MODE_MASK		3
+	#define PLL_MODE_NORMAL		0
+	#define PLL_MODE_FRACTION	1
+	#define PLL_MODE_DITH_DSB	2
+	#define PLL_MODE_DITH_SSB	3
+
+#define PLL4_FRQ		((unsigned int *)(MISC_BASE + 0x23c))
+	/* PLL FRQ register masks */
+	#define PLL_DIV_N_SHIFT		0
+	#define PLL_DIV_N_MASK		0xFF
+	#define PLL_DIV_P_SHIFT		8
+	#define PLL_DIV_P_MASK		0x7
+	#define PLL_NORM_FDBK_M_SHIFT	24
+	#define PLL_NORM_FDBK_M_MASK	0xFF
+	#define PLL_DITH_FDBK_M_SHIFT	16
+	#define PLL_DITH_FDBK_M_MASK	0xFFFF
+
+#define PLL4_MOD		((unsigned int *)(MISC_BASE + 0x240))
+
+#define PERIP_CLK_CFG		((unsigned int *)(MISC_BASE + 0x244))
+	/* PERIP_CLK_CFG bit values */
+	#define GPT_OSC24_MASK	0
+	#define GPT_APB_MASK	1
+	#define GPT_CLK_MASK	1
+	#define GPT0_CLK_SHIFT	8
+	#define GPT1_CLK_SHIFT	9
+	#define GPT2_CLK_SHIFT	12
+	#define GPT3_CLK_SHIFT	13
+	#define AUX_CLK_PLL1_MASK	1
+	#define AUX_CLK_PLL5_MASK	0
+	#define UART_CLK_MASK		1
+	#define UART_CLK_SHIFT		4
+
+#define GMAC_CLK_CFG		((unsigned int *)(MISC_BASE + 0x248))
+#define C3_CLK_SYNTH		((unsigned int *)(MISC_BASE + 0x24c))
+#define CLCD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x250))
+#define UART_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x254))
+#define GMAC_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x258))
+#define MCIF_SD_CLK_SYNT	((unsigned int *)(MISC_BASE + 0x25c))
+#define MCIF_CFXD_CLK_SYNT	((unsigned int *)(MISC_BASE + 0x260))
+#define RAS_CLK_SYNT0		((unsigned int *)(MISC_BASE + 0x264))
+#define RAS_CLK_SYNT1		((unsigned int *)(MISC_BASE + 0x268))
+#define RAS_CLK_SYNT2		((unsigned int *)(MISC_BASE + 0x26c))
+#define RAS_CLK_SYNT3		((unsigned int *)(MISC_BASE + 0x270))
+	/* aux clk synthesizer register masks */
+	#define AUX_EQ_SEL_SHIFT	30
+	#define AUX_EQ_SEL_MASK		1
+	#define AUX_EQ1_SEL		0
+	#define AUX_EQ2_SEL		1
+	#define AUX_XSCALE_SHIFT	16
+	#define AUX_XSCALE_MASK		0xFFF
+	#define AUX_YSCALE_SHIFT	0
+	#define AUX_YSCALE_MASK		0xFFF
+
+#define PERIP1_CLK_ENB		((unsigned int *)(MISC_BASE + 0x274))
+	/* PERIP1_CLK_ENB register masks */
+	#define BUS_CLK_ENB		0
+	#define SYSROM_CLK_ENB		1
+	#define AORAM_CLK_ENB		2
+	#define SYSRAM_CLK_ENB		3
+	#define FSMC_CLK_ENB		4
+	#define SMI_CLK_ENB		5
+	#define SD_CLK_ENB		6
+	#define CF_XD_CLK_ENB		7
+	#define GETH_CLK_ENB		8
+	#define UHC0_CLK_ENB		9
+	#define UHC1_CLK_ENB		10
+	#define UDC_UPD_CLK_ENB		11
+	#define PCI0_CLK_ENB		12
+	#define PCI1_CLK_ENB		13
+	#define PCI2_CLK_ENB		14
+	#define UART_CLK_ENB		15
+	#define SSP_CLK_ENB		17
+	#define I2C_CLK_ENB		18
+	#define I2S_SLV_CLK_ENB		19
+	#define I2S_MST_CLK_ENB		20
+	#define GPT0_CLK_ENB		21
+	#define GPT1_CLK_ENB		22
+	#define GPIOA_CLK_ENB		23
+	#define GPIOB_CLK_ENB		24
+	#define DMA0_CLK_ENB		25
+	#define DMA1_CLK_ENB		26
+	#define CLCD_CLK_ENB		27
+	#define JPEGC_CLK_ENB		28
+	#define C3_CLK_ENB		29
+	#define ADC_CLK_ENB		30
+	#define RTC_CLK_ENB		31
+
+#define PERIP2_CLK_ENB		((unsigned int *)(MISC_BASE + 0x278))
+	/* PERIP2_CLK_ENB register masks */
+	#define DDR_CTRL_CLK_ENB	0
+	#define DDR_CORE_CLK_ENB	1
+	#define CPU_DBG_CLK_ENB		2
+	#define KBD_CLK_ENB		3
+	#define GPT2_CLK_ENB		4
+	#define GPT3_CLK_ENB		5
+	#define ACP_CLK_ENB		6
+	#define I2S_REFOUT_CLK_ENB	7
+	#define THSENS_CLK_ENB		8
+
+#define PERIP1_SW_RST		((unsigned int *)(MISC_BASE + 0x27c))
+	#define JPEG_SOF_RST		28
+#define PERIP2_SW_RST		((unsigned int *)(MISC_BASE + 0x280))
+#define RAS_CLK_ENB		((unsigned int *)(MISC_BASE + 0x284))
+#define RAS_SW_RST		((unsigned int *)(MISC_BASE + 0x288))
+#define PLL1_SYNT		((unsigned int *)(MISC_BASE + 0x28c))
+#define I2S_CLK_CFG		((unsigned int *)(MISC_BASE + 0x290))
+
+/* Peripheral Configuration Registers */
+#define DMAC_HS_SEL		((unsigned int *)(MISC_BASE + 0x300))
+#define DMAC_SEL		((unsigned int *)(MISC_BASE + 0x304))
+#define DMAC_FLOW_SEL		((unsigned int *)(MISC_BASE + 0x308))
+#define DMAC_DIR_SEL		((unsigned int *)(MISC_BASE + 0x30c))
+#define DMAC_CFG		((unsigned int *)(MISC_BASE + 0x310))
+#define USBPHY_GEN_CFG		((unsigned int *)(MISC_BASE + 0x314))
+#define USBPHY_P1_CFG		((unsigned int *)(MISC_BASE + 0x318))
+#define USBPHY_P2_CFG		((unsigned int *)(MISC_BASE + 0x31c))
+#define USBPHY_P3_CFG		((unsigned int *)(MISC_BASE + 0x320))
+#define PCIE_CFG		((unsigned int *)(MISC_BASE + 0x324))
+#define PCIE_MIPHY_CFG		((unsigned int *)(MISC_BASE + 0x328))
+#define PERIP_CFG		((unsigned int *)(MISC_BASE + 0x32c))
+#define FSMC_CFG		((unsigned int *)(MISC_BASE + 0x330))
+#define MPMC_CTR_STS		((unsigned int *)(MISC_BASE + 0x334))
+
+/* Inter-Processor Communication Registers */
+#define PRC1_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x500))
+#define PRC2_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x504))
+#define PRC1_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x508))
+#define PRC2_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x51C))
+
+/* Pad Configuration Registers */
+#define PAD_PU_CFG_1		((unsigned int *)(MISC_BASE + 0x600))
+#define PAD_PU_CFG_2		((unsigned int *)(MISC_BASE + 0x604))
+#define PAD_PU_CFG_3		((unsigned int *)(MISC_BASE + 0x608))
+#define PAD_PU_CFG_4		((unsigned int *)(MISC_BASE + 0x60c))
+#define PAD_PU_CFG_5		((unsigned int *)(MISC_BASE + 0x610))
+#define PAD_PU_CFG_6		((unsigned int *)(MISC_BASE + 0x614))
+#define PAD_PU_CFG_7		((unsigned int *)(MISC_BASE + 0x618))
+#define PAD_PU_CFG_8		((unsigned int *)(MISC_BASE + 0x61c))
+#define PAD_PD_CFG_1		((unsigned int *)(MISC_BASE + 0x620))
+#define PAD_PD_CFG_2		((unsigned int *)(MISC_BASE + 0x624))
+#define PAD_PD_CFG_3		((unsigned int *)(MISC_BASE + 0x628))
+#define PAD_PD_CFG_4		((unsigned int *)(MISC_BASE + 0x62c))
+#define PAD_PD_CFG_5		((unsigned int *)(MISC_BASE + 0x630))
+#define PAD_PD_CFG_6		((unsigned int *)(MISC_BASE + 0x634))
+#define PAD_PD_CFG_7		((unsigned int *)(MISC_BASE + 0x638))
+#define PAD_PD_CFG_8		((unsigned int *)(MISC_BASE + 0x63c))
+#define PAD_SLEEP_CFG		((unsigned int *)(MISC_BASE + 0x640))
+#define PAD_HYST_CFG		((unsigned int *)(MISC_BASE + 0x644))
+#define PAD_DRV_CFG		((unsigned int *)(MISC_BASE + 0x648))
+#define PAD_SLEW_CFG		((unsigned int *)(MISC_BASE + 0x64c))
+#define PAD_FUNCTION_EN_1	((unsigned int *)(MISC_BASE + 0x650))
+#define PAD_FUNCTION_EN_2	((unsigned int *)(MISC_BASE + 0x654))
+#define PAD_FUNCTION_EN_3	((unsigned int *)(MISC_BASE + 0x658))
+#define DDR_PAD_CFG		((unsigned int *)(MISC_BASE + 0x65c))
+#define THSENS_CFG		((unsigned int *)(MISC_BASE + 0x6c4))
+
+/* Compensation Configuration Registers */
+#define COMP_1V8_2V5_3V3__1_CFG		((unsigned int *)(MISC_BASE + 0x700))
+#define COMP_1V8_2V5_3V3__2_CFG		((unsigned int *)(MISC_BASE + 0x704))
+#define COMP_3V3_1_CFG			((unsigned int *)(MISC_BASE + 0x708))
+#define COMP_3V3_2_CFG			((unsigned int *)(MISC_BASE + 0x70c))
+#define COMP_DDR_CFG			((unsigned int *)(MISC_BASE + 0x710))
+
+/* OTP Programming Registers */
+#define OTP_PROG_CTR		((unsigned int *)(MISC_BASE + 0x800))
+#define OTP_WDATA1_1		((unsigned int *)(MISC_BASE + 0x804))
+#define OTP_WDATA1_2		((unsigned int *)(MISC_BASE + 0x808))
+#define OTP_WDATA1_3		((unsigned int *)(MISC_BASE + 0x80c))
+#define OTP_WDATA1_4		((unsigned int *)(MISC_BASE + 0x810))
+#define OTP_WDATA1_5		((unsigned int *)(MISC_BASE + 0x814))
+#define OTP_WDATA1_6		((unsigned int *)(MISC_BASE + 0x818))
+#define OTP_WDATA1_7		((unsigned int *)(MISC_BASE + 0x81c))
+#define OTP_WDATA1_8		((unsigned int *)(MISC_BASE + 0x820))
+#define OTP_WDATA2_1		((unsigned int *)(MISC_BASE + 0x824))
+#define OTP_WDATA2_2		((unsigned int *)(MISC_BASE + 0x828))
+#define OTP_WDATA2_3		((unsigned int *)(MISC_BASE + 0x82c))
+#define OTP_WDATA2_4		((unsigned int *)(MISC_BASE + 0x830))
+#define OTP_WDATA2_5		((unsigned int *)(MISC_BASE + 0x834))
+#define OTP_WDATA2_6		((unsigned int *)(MISC_BASE + 0x838))
+#define OTP_WDATA2_7		((unsigned int *)(MISC_BASE + 0x83c))
+#define OTP_WDATA2_8		((unsigned int *)(MISC_BASE + 0x840))
+#define OTP_MASK_1		((unsigned int *)(MISC_BASE + 0x844))
+#define OTP_MASK_2		((unsigned int *)(MISC_BASE + 0x848))
+#define OTP_MASK_3		((unsigned int *)(MISC_BASE + 0x84c))
+#define OTP_MASK_4		((unsigned int *)(MISC_BASE + 0x850))
+#define OTP_MASK_5		((unsigned int *)(MISC_BASE + 0x854))
+#define OTP_MASK_6		((unsigned int *)(MISC_BASE + 0x858))
+#define OTP_MASK_7		((unsigned int *)(MISC_BASE + 0x85c))
+#define OTP_MASK_8		((unsigned int *)(MISC_BASE + 0x860))
+#define OTP_RDATA1_1		((unsigned int *)(MISC_BASE + 0x864))
+#define OTP_RDATA1_2		((unsigned int *)(MISC_BASE + 0x868))
+#define OTP_RDATA1_3		((unsigned int *)(MISC_BASE + 0x86c))
+#define OTP_RDATA1_4		((unsigned int *)(MISC_BASE + 0x870))
+#define OTP_RDATA1_5		((unsigned int *)(MISC_BASE + 0x874))
+#define OTP_RDATA1_6		((unsigned int *)(MISC_BASE + 0x878))
+#define OTP_RDATA1_7		((unsigned int *)(MISC_BASE + 0x87c))
+#define OTP_RDATA1_8		((unsigned int *)(MISC_BASE + 0x880))
+#define OTP_RDATA2_1		((unsigned int *)(MISC_BASE + 0x884))
+#define OTP_RDATA2_2		((unsigned int *)(MISC_BASE + 0x888))
+#define OTP_RDATA2_3		((unsigned int *)(MISC_BASE + 0x88c))
+#define OTP_RDATA2_4		((unsigned int *)(MISC_BASE + 0x890))
+#define OTP_RDATA2_5		((unsigned int *)(MISC_BASE + 0x894))
+#define OTP_RDATA2_6		((unsigned int *)(MISC_BASE + 0x898))
+#define OTP_RDATA2_7		((unsigned int *)(MISC_BASE + 0x89c))
+#define OTP_RDATA2_8		((unsigned int *)(MISC_BASE + 0x8a0))
+#define OTP_RDATAM_1		((unsigned int *)(MISC_BASE + 0x8a4))
+#define OTP_RDATAM_2		((unsigned int *)(MISC_BASE + 0x8a8))
+#define OTP_RDATAM_3		((unsigned int *)(MISC_BASE + 0x8ac))
+#define OTP_RDATAM_4		((unsigned int *)(MISC_BASE + 0x8b0))
+#define OTP_RDATAM_5		((unsigned int *)(MISC_BASE + 0x8b4))
+#define OTP_RDATAM_6		((unsigned int *)(MISC_BASE + 0x8b8))
+#define OTP_RDATAM_7		((unsigned int *)(MISC_BASE + 0x8bc))
+#define OTP_RDATAM_8		((unsigned int *)(MISC_BASE + 0x8c0))
+
+/* A9SM Registers */
+#define A9SM_CLUSTERID		((unsigned int *)(MISC_BASE + 0x900))
+#define A9SM_STATUS		((unsigned int *)(MISC_BASE + 0x904))
+#define A9SM_DEBUG		((unsigned int *)(MISC_BASE + 0x908))
+#define A9SM_FILTER		((unsigned int *)(MISC_BASE + 0x90c))
+#define A9SM_PARITY_CFG		((unsigned int *)(MISC_BASE + 0x910))
+#define A9SM_PARITY_ERR		((unsigned int *)(MISC_BASE + 0x914))
+
+/* SOC ID Registers */
+#define DIE_ID_1		((unsigned int *)(MISC_BASE + 0xa00))
+#define DIE_ID_2		((unsigned int *)(MISC_BASE + 0xa04))
+#define DIE_ID_3		((unsigned int *)(MISC_BASE + 0xa08))
+#define DIE_ID_4		((unsigned int *)(MISC_BASE + 0xa0c))
+#define DIE_ID_VALID		((unsigned int *)(MISC_BASE + 0xa10))
+
+/* SOC TEST & DEBUG Registers */
+#define MIPHY_TEST		((unsigned int *)(MISC_BASE + 0x1000))
+#define PCIE_MSTR_P0		((unsigned int *)(MISC_BASE + 0x1004))
+#define PCIE_AWMISC_P0		((unsigned int *)(MISC_BASE + 0x1008))
+#define PCIE_ARMISC_P0		((unsigned int *)(MISC_BASE + 0x100c))
+#define PCIE_MSTR_P1		((unsigned int *)(MISC_BASE + 0x1010))
+#define PCIE_AWMISC_P1		((unsigned int *)(MISC_BASE + 0x1014))
+#define PCIE_ARMISC_P1		((unsigned int *)(MISC_BASE + 0x1018))
+#define PCIE_MSTR_P2		((unsigned int *)(MISC_BASE + 0x101c))
+#define PCIE_AWMISC_P2		((unsigned int *)(MISC_BASE + 0x1020))
+#define PCIE_ARMISC_P2		((unsigned int *)(MISC_BASE + 0x1024))
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h b/arch/arm/mach-spear13xx/include/mach/smp.h
new file mode 100644
index 0000000..6e028a1
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/smp.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/smp.h
+ *
+ * Few SMP related definitions for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_SMP_H
+#define __MACH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id()			\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+/* We use IRQ1 as the IPI */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+	gic_raise_softirq(mask, 1);
+}
+
+#endif
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
new file mode 100644
index 0000000..0dcd131
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/spear.h
+ *
+ * spear13xx Machine family specific definition
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_SPEAR13XX_H
+#define __MACH_SPEAR13XX_H
+
+#include <mach/spear1300.h>
+
+#define SPEAR13XX_L2CC_BASE		0xED000000
+
+/* ARM9SMP peripheral base address */
+#define SPEAR13XX_A9SM_PERIP_BASE	0xEC800000
+#define VA_SPEAR13XX_A9SM_PERIP_BASE	IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE)
+/* A9SM peripheral offsets */
+#define SPEAR13XX_SCU_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x00)
+#define SPEAR13XX_GIC_CPU_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x100)
+#define SPEAR13XX_GLOBAL_TMR_BASE	(SPEAR13XX_A9SM_PERIP_BASE + 0x200)
+#define SPEAR13XX_LOCAL_TMR_BASE	(SPEAR13XX_A9SM_PERIP_BASE + 0x600)
+#define SPEAR13XX_WDT_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x620)
+#define SPEAR13XX_GIC_DIST_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x1000)
+
+#define SPEAR13XX_UART_BASE		0xE0000000
+#define VA_SPEAR13XX_UART_BASE		IO_ADDRESS(SPEAR13XX_UART_BASE)
+
+#define SPEAR13XX_ADC_BASE		0xE0080000
+#define SPEAR13XX_SSP_BASE		0xE0100000
+#define SPEAR13XX_I2S0_BASE		0xE0180000
+#define SPEAR13XX_I2S1_BASE		0xE0200000
+#define SPEAR13XX_I2C_BASE		0xE0280000
+#define SPEAR13XX_KBD_BASE		0xE0300000
+#define SPEAR13XX_GPT0_BASE		0xE0380000
+#define SPEAR13XX_GPT1_BASE		0xE0400000
+#define SPEAR13XX_GPT2_BASE		0xE0480000
+#define SPEAR13XX_GPT3_BASE		0xE0500000
+#define SPEAR13XX_RTC_BASE		0xE0580000
+#define SPEAR13XX_GPIOA_BASE		0xE0600000
+#define SPEAR13XX_GPIOB_BASE		0xE0680000
+#define SPEAR13XX_MISC_BASE		0xE0700000
+#define VA_SPEAR13XX_MISC_BASE		IO_ADDRESS(SPEAR13XX_MISC_BASE)
+
+#define SPEAR13XX_SYSRAM0_BASE		0xB3800000
+#define SPEAR13XX_SYSRAM0_SIZE		0x00800000
+
+/*
+ * The system location which is polled by secondary cpus to find the
+ * jump address
+ */
+#define SPEAR13XX_SYS_LOCATION		(SPEAR13XX_SYSRAM0_BASE + 0x600)
+
+#define SPEAR13XX_SYSRAM1_BASE		0xE0800000
+#define SPEAR13XX_SYSRAM1_SIZE		0x00800000
+#define SPEAR13XX_CLCD_BASE		0xE1000000
+#define SPEAR13XX_C3_BASE		0xE1800000
+#define SPEAR13XX_GETH_BASE		0xE2000000
+#define SPEAR13XX_UPD_BASE		0xE2800000
+#define SPEAR13XX_UDC_BASE		0xE3800000
+#define SPEAR13XX_UHC0_OHCI_BASE	0xE4000000
+#define SPEAR13XX_UHC0_EHCI_BASE	0xE4800000
+#define SPEAR13XX_UHC1_OHCI_BASE	0xE5000000
+#define SPEAR13XX_UHC1_EHCI_BASE	0xE5800000
+#define SPEAR13XX_SMI_MEM_BASE		0xE6000000
+#define SPEAR13XX_SMI_CTRL_BASE		0xEA000000
+#define SPEAR13XX_DMAC0_BASE		0xEA800000
+#define SPEAR13XX_DMAC1_BASE		0xEB000000
+#define SPEAR13XX_MII_PHY_BASE		0xEB800000
+#define SPEAR13XX_MPMC_BASE		0xEC000000
+#define SPEAR13XX_PCIE0_BASE		0x80000000
+#define SPEAR13XX_PCIE1_BASE		0x90000000
+#define SPEAR13XX_PCIE2_BASE		0xC0000000
+#define SPEAR13XX_PCIE0_APP_BASE	0xB1000000
+#define SPEAR13XX_PCIE1_APP_BASE	0xB1800000
+#define SPEAR13XX_PCIE2_APP_BASE	0xB4000000
+#define SPEAR13XX_FSMC_MEM_BASE		0xA0000000
+#define SPEAR13XX_FSMC_BASE		0xB0000000
+#define SPEAR13XX_JPEG_BASE		0xB2000000
+#define SPEAR13XX_MCIF_CF_BASE		0xB2800000
+#define SPEAR13XX_MCIF_MMC_BASE		0xB3000000
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE		SPEAR13XX_UART_BASE
+#define VA_SPEAR_DBG_UART_BASE		VA_SPEAR13XX_UART_BASE
+
+#endif /* __MACH_SPEAR13XX_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1300.h b/arch/arm/mach-spear13xx/include/mach/spear1300.h
new file mode 100644
index 0000000..b3ba267
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear1300.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/spear1300.h
+ *
+ * SPEAr1300 Machine specific definition
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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.
+ */
+
+#ifdef	CONFIG_MACH_SPEAR1300
+
+#ifndef __MACH_SPEAR1300_H
+#define __MACH_SPEAR1300_H
+
+#endif /* __MACH_SPEAR1300_H */
+
+#endif /* CONFIG_MACH_SPEAR1300 */
diff --git a/arch/arm/mach-spear13xx/include/mach/system.h b/arch/arm/mach-spear13xx/include/mach/system.h
new file mode 100644
index 0000000..6ce0819
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/system.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/system.h
+ *
+ * spear13xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/misc_regs.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	pr_info("Going to reboot...\n");
+
+	/* let above information be printed */
+	msleep(1000);
+
+	writel(0x01, SYS_SW_RES);
+	/* wait for system to rest */
+	while (1)
+		;
+}
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/timex.h b/arch/arm/mach-spear13xx/include/mach/timex.h
new file mode 100644
index 0000000..0a81490
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/timex.h
+ *
+ * spear13xx machine family specific timex definitions
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_TIMEX_H
+#define __MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE			24000000
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/uncompress.h b/arch/arm/mach-spear13xx/include/mach/uncompress.h
new file mode 100644
index 0000000..3c27f25
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/vmalloc.h b/arch/arm/mach-spear13xx/include/mach/vmalloc.h
new file mode 100644
index 0000000..85ad57e
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/vmalloc.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for spear13xx machine family
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ *
+ * 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_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
-- 
1.7.2.2

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

* [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (3 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  9:04   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 06/74] ST SPEAr: Adding support for SPEAr13xx SoC in spear generic plat/ Viresh KUMAR
                   ` (69 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/Kconfig         |   21 ++
 arch/arm/mach-spear13xx/Kconfig1300     |   17 ++
 arch/arm/mach-spear13xx/Makefile        |   14 ++
 arch/arm/mach-spear13xx/Makefile.boot   |    3 +
 arch/arm/mach-spear13xx/clock.c         |  352 +++++++++++++++++++++++++++++++
 arch/arm/mach-spear13xx/headsmp.S       |   95 +++++++++
 arch/arm/mach-spear13xx/localtimer.c    |   25 +++
 arch/arm/mach-spear13xx/platsmp.c       |  203 ++++++++++++++++++
 arch/arm/mach-spear13xx/spear1300.c     |   23 ++
 arch/arm/mach-spear13xx/spear1300_evb.c |   48 +++++
 arch/arm/mach-spear13xx/spear13xx.c     |   98 +++++++++
 11 files changed, 899 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/Kconfig
 create mode 100644 arch/arm/mach-spear13xx/Kconfig1300
 create mode 100644 arch/arm/mach-spear13xx/Makefile
 create mode 100644 arch/arm/mach-spear13xx/Makefile.boot
 create mode 100644 arch/arm/mach-spear13xx/clock.c
 create mode 100644 arch/arm/mach-spear13xx/headsmp.S
 create mode 100644 arch/arm/mach-spear13xx/localtimer.c
 create mode 100644 arch/arm/mach-spear13xx/platsmp.c
 create mode 100644 arch/arm/mach-spear13xx/spear1300.c
 create mode 100644 arch/arm/mach-spear13xx/spear1300_evb.c
 create mode 100644 arch/arm/mach-spear13xx/spear13xx.c

diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
new file mode 100644
index 0000000..e285d87
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -0,0 +1,21 @@
+#
+# SPEAr13XX Machine configuration file
+#
+
+if ARCH_SPEAR13XX
+
+choice
+	prompt "SPEAr13XX Family"
+	default MACH_SPEAR1300
+
+config MACH_SPEAR1300
+	bool "SPEAr1300"
+	help
+	  Supports ST SPEAr1300 Machine
+
+endchoice
+
+# Adding SPEAr13XX machine specific configuration files
+source "arch/arm/mach-spear13xx/Kconfig1300"
+
+endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Kconfig1300 b/arch/arm/mach-spear13xx/Kconfig1300
new file mode 100644
index 0000000..5d6feb1
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig1300
@@ -0,0 +1,17 @@
+#
+# SPEAr1300 machine configuration file
+#
+
+if MACH_SPEAR1300
+
+choice
+	prompt "SPEAr1300 Boards"
+	default BOARD_SPEAR1300_EVB
+
+config BOARD_SPEAR1300_EVB
+	bool "SPEAr1300 Evaluation Board"
+	help
+	  Supports ST SPEAr1300 Evaluation Board
+endchoice
+
+endif #MACH_SPEAR1300
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
new file mode 100644
index 0000000..cb5ae9e
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for SPEAr13XX machine series
+#
+
+# common files
+obj-y					+= spear13xx.o clock.o
+obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
+
+# spear1300 specific files
+obj-$(CONFIG_MACH_SPEAR1300)		+= spear1300.o
+
+# spear1300 boards files
+obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= spear1300_evb.o
diff --git a/arch/arm/mach-spear13xx/Makefile.boot b/arch/arm/mach-spear13xx/Makefile.boot
new file mode 100644
index 0000000..7a1f3c0
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
new file mode 100644
index 0000000..280eb5b
--- /dev/null
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -0,0 +1,352 @@
+/*
+ * arch/arm/mach-spear13xx/clock.c
+ *
+ * SPEAr13xx machines clock framework source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * shiraz hashim<shiraz.hashim@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/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <mach/hardware.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+/* root clks */
+/* 24 MHz oscillator clock */
+static struct clk osc1_24m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 24000000,
+};
+
+/* 32 KHz oscillator clock */
+static struct clk osc2_32k_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 32000,
+};
+
+/* 25 MHz MIPHY oscillator clock */
+static struct clk osc3_25m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 25000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+	.pclk = &osc2_32k_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = RTC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from osc1 or osc3 */
+/* pll[1-3] parents */
+static struct pclk_info pll_pclk_info[] = {
+	{
+		.pclk = &osc1_24m_clk,
+		.pclk_mask = OSC_24M_MASK,
+	}, {
+		.pclk = &osc3_25m_clk,
+		.pclk_mask = OSC_25M_MASK,
+	},
+};
+
+/* pll[1-3] parent select structure */
+static struct pclk_sel pll_pclk_sel = {
+	.pclk_info = pll_pclk_info,
+	.pclk_count = ARRAY_SIZE(pll_pclk_info),
+	.pclk_sel_reg = PLL_CFG,
+	.pclk_sel_mask = PLL_CLK_MASK,
+};
+
+/* pll masks structure */
+static struct pll_clk_masks pll_masks = {
+	.mode_mask = PLL_MODE_MASK,
+	.mode_shift = PLL_MODE_SHIFT,
+	.norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
+	.norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
+	.dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
+	.dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
+	.div_p_mask = PLL_DIV_P_MASK,
+	.div_p_shift = PLL_DIV_P_SHIFT,
+	.div_n_mask = PLL_DIV_N_MASK,
+	.div_n_shift = PLL_DIV_N_SHIFT,
+};
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+	.mode_reg = PLL1_CTR,
+	.cfg_reg = PLL1_FRQ,
+	.masks = &pll_masks,
+};
+
+/* pll1 clock */
+static struct clk pll1_clk = {
+	.pclk_sel = &pll_pclk_sel,
+	.pclk_sel_shift = PLL1_CLK_SHIFT,
+	.en_reg = PLL1_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll_clk_recalc,
+	.private_data = &pll1_config,
+};
+
+/* pll2 configuration structure */
+static struct pll_clk_config pll2_config = {
+	.mode_reg = PLL2_CTR,
+	.cfg_reg = PLL2_FRQ,
+	.masks = &pll_masks,
+};
+
+/* pll2 clock */
+static struct clk pll2_clk = {
+	.pclk_sel = &pll_pclk_sel,
+	.pclk_sel_shift = PLL2_CLK_SHIFT,
+	.en_reg = PLL2_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll_clk_recalc,
+	.private_data = &pll2_config,
+};
+
+/* pll3 configuration structure */
+static struct pll_clk_config pll3_config = {
+	.mode_reg = PLL3_CTR,
+	.cfg_reg = PLL3_FRQ,
+	.masks = &pll_masks,
+};
+
+/* pll3 clock */
+static struct clk pll3_clk = {
+	.pclk_sel = &pll_pclk_sel,
+	.pclk_sel_shift = PLL3_CLK_SHIFT,
+	.en_reg = PLL3_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll_clk_recalc,
+	.private_data = &pll3_config,
+};
+
+/* pll4 (DDR) configuration structure */
+static struct pll_clk_config pll4_config = {
+	.mode_reg = PLL4_CTR,
+	.cfg_reg = PLL4_FRQ,
+	.masks = &pll_masks,
+};
+
+/* pll4 (DDR) clock */
+static struct clk pll4_clk = {
+	.pclk = &osc1_24m_clk,
+	.en_reg = PLL4_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll_clk_recalc,
+	.private_data = &pll4_config,
+};
+
+/* pll5 USB 48 MHz clock */
+static struct clk pll5_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc1_24m_clk,
+	.rate = 48000000,
+};
+
+/* pll6 (MIPHY) clock */
+static struct clk pll6_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc3_25m_clk,
+	.rate = 25000000,
+};
+
+/* clocks derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.div_factor = 2,
+	.recalc = &follow_parent,
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.div_factor = 6,
+	.recalc = &follow_parent,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.div_factor = 12,
+	.recalc = &follow_parent,
+};
+
+/* clocks derived from osc1, ahb or apb */
+/* gpt[0-3] parents */
+static struct pclk_info gpt_pclk_info[] = {
+	{
+		.pclk = &osc1_24m_clk,
+		.pclk_mask = GPT_OSC24_MASK,
+	}, {
+		.pclk = &apb_clk,
+		.pclk_mask = GPT_APB_MASK,
+	},
+};
+
+/* gpt[0-3] parent select structure */
+static struct pclk_sel gpt_pclk_sel = {
+	.pclk_info = gpt_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0 timer clock */
+static struct clk gpt0_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT0_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT0_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT1_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT1_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+	.en_reg = PERIP2_CLK_ENB,
+	.en_reg_bit = GPT2_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT2_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* gpt3 timer clock */
+static struct clk gpt3_clk = {
+	.en_reg = PERIP2_CLK_ENB,
+	.en_reg_bit = GPT3_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT3_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SMI_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* auxiliary synthesizers masks */
+static struct aux_clk_masks aux_masks = {
+	.eq_sel_mask = AUX_EQ_SEL_MASK,
+	.eq_sel_shift = AUX_EQ_SEL_SHIFT,
+	.eq1_mask = AUX_EQ1_SEL,
+	.eq2_mask = AUX_EQ2_SEL,
+	.xscale_sel_mask = AUX_XSCALE_MASK,
+	.xscale_sel_shift = AUX_XSCALE_SHIFT,
+	.yscale_sel_mask = AUX_YSCALE_MASK,
+	.yscale_sel_shift = AUX_YSCALE_SHIFT,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_config = {
+	.synth_reg = UART_CLK_SYNT,
+	.masks = &aux_masks,
+};
+
+/* clocks derived from pll1 or pll5 */
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+	{
+		.pclk = &pll5_clk,
+		.pclk_mask = AUX_CLK_PLL5_MASK,
+	}, {
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	},
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+	.pclk_info = uart_pclk_info,
+	.pclk_count = ARRAY_SIZE(uart_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart clock */
+static struct clk uart_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UART_CLK_ENB,
+	.pclk_sel = &uart_pclk_sel,
+	.pclk_sel_shift = UART_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_config,
+};
+
+/* array of all spear 13xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+	/* root clks */
+	{.con_id = "osc1_24m_clk",	.clk = &osc1_24m_clk},
+	{.con_id = "osc2_32k_clk",	.clk = &osc2_32k_clk},
+	{.con_id = "osc3_25m_clk",	.clk = &osc3_25m_clk},
+
+	/* clock derived from 32 KHz osc clk */
+	{.dev_id = "rtc",		.clk = &rtc_clk},
+
+	/* clock derived from 24/25 MHz osc1/osc3 clk */
+	{.con_id = "pll1_clk",		.clk = &pll1_clk},
+	{.con_id = "pll2_clk",		.clk = &pll2_clk},
+	{.con_id = "pll3_clk",		.clk = &pll3_clk},
+	{.con_id = "pll4_clk",		.clk = &pll4_clk},
+	{.con_id = "pll5_clk",		.clk = &pll5_clk},
+	{.con_id = "pll6_clk",		.clk = &pll6_clk},
+
+	/* clock derived from pll1 clk */
+	{.con_id = "cpu_clk",		.clk = &cpu_clk},
+	{.con_id = "ahb_clk",		.clk = &ahb_clk},
+	{ .con_id = "apb_clk",		.clk = &apb_clk},
+
+	/* clocks having multiple parent source from above clocks */
+	{.dev_id = "uart",		.clk = &uart_clk},
+	{.dev_id = "gpt0",		.clk = &gpt0_clk},
+	{.dev_id = "gpt1",		.clk = &gpt1_clk},
+	{.dev_id = "gpt2",		.clk = &gpt2_clk},
+	{.dev_id = "gpt3",		.clk = &gpt3_clk},
+
+	/* clock derived from ahb/apb clk */
+	{ .dev_id = "smi",		.clk = &smi_clk},
+	{ .dev_id = "wdt",		.clk = &wdt_clk},
+};
+
+void __init clk_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+		clk_register(&spear_clk_lookups[i]);
+
+	recalc_root_clocks();
+}
diff --git a/arch/arm/mach-spear13xx/headsmp.S b/arch/arm/mach-spear13xx/headsmp.S
new file mode 100644
index 0000000..bbe73f3
--- /dev/null
+++ b/arch/arm/mach-spear13xx/headsmp.S
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/mach-spear13XX/headsmp.S
+ *
+ * Picked from realview
+ * Copyright (c) 2010 ST Microelectronics Limited
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * This one is picked from Tegra :-
+ *
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the ain
+ * processor. We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ */
+ENTRY(v7_invalidate_l1)
+	mov	r0, #0
+	mcr	p15, 2, r0, c0, c0, 0
+	mrc	p15, 1, r0, c0, c0, 0
+
+	ldr	r1, =0x7fff
+	and	r2, r1, r0, lsr #13
+
+	ldr	r1, =0x3ff
+
+	and	r3, r1, r0, lsr #3	@ NumWays - 1
+	add	r2, r2, #1	@ NumSets
+
+	and	r0, r0, #0x7
+	add	r0, r0, #4	@ SetShift
+
+	clz	r1, r3		@ WayShift
+	add	r4, r3, #1	@ NumWays
+1:	sub	r2, r2, #1	@ NumSets--
+	mov	r3, r4		@ Temp = NumWays
+2:	subs	r3, r3, #1	@ Temp--
+	mov	r5, r3, lsl r1
+	mov	r6, r2, lsl r0
+	orr	r5, r5, r6	@ Reg = Temp<<WayShift)|(NumSets<<SetShift)
+	mcr	p15, 0, r5, c7, c6, 2
+	bgt	2b
+	cmp	r2, #0
+	bgt	1b
+	dsb
+	isb
+	mov	pc, lr
+ENDPROC(v7_invalidate_l1)
+
+/*
+ * spear13xx specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(spear13xx_secondary_startup)
+	/* If we don't do this then we have a crash */
+
+	/*
+	 * Since now this is being called from xloader so removing it
+	 * here
+	 */
+#if 0
+	bl v7_invalidate_l1
+#endif
+
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-spear13xx/localtimer.c b/arch/arm/mach-spear13xx/localtimer.c
new file mode 100644
index 0000000..816b08c
--- /dev/null
+++ b/arch/arm/mach-spear13xx/localtimer.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear13xx/localtimer.c
+ * Directly picked from realview
+ *
+ * Copyright (C) 2010 ST Microelectronics Ltd.
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/irq.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+
+/* Setup the local clock events for a CPU. */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = IRQ_LOCALTIMER;
+	twd_timer_setup(evt);
+}
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
new file mode 100644
index 0000000..8b75d1b
--- /dev/null
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -0,0 +1,203 @@
+/*
+ * arch/arm/mach-spear13xx/platsmp.c
+ *
+ * based upon linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2010 ST Microelectronics Ltd.
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/localtimer.h>
+#include <asm/mach-types.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __iomem *scu_base_addr(void)
+{
+	return __io_address(SPEAR13XX_SCU_BASE);
+}
+
+static inline unsigned int get_core_count(void)
+{
+	void __iomem *scu_base = scu_base_addr();
+
+	if (scu_base)
+		return scu_get_core_count(scu_base);
+	return 1;
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	pen_release = -1;
+	smp_wmb();
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+
+	/*
+	 * Note: Following is important otherwise cpu2 doesn't come up
+	 * as secondary_data must be flushed before pen_release also
+	 */
+
+	flush_cache_all();
+	pen_release = cpu;
+	flush_cache_all();
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init poke_milo(void)
+{
+	/* nobody is to be released from the pen yet */
+	pen_release = -1;
+
+	/*
+	 * Write the address of secondary startup into the system-wide
+	 * location (presently it is in SRAM). The BootMonitor waits
+	 * for this register to become non-zero.
+	 */
+	__raw_writel(BSYM(virt_to_phys(spear13xx_secondary_startup)),
+			__io_address(SPEAR13XX_SYS_LOCATION));
+
+	mb();
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	unsigned int i, ncores = get_core_count();
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	unsigned int ncores = get_core_count();
+	unsigned int cpu = smp_processor_id();
+	int i;
+
+	/* sanity check */
+	if (ncores == 0) {
+		pr_err("Realview: strange CM count of 0? Default to 1\n");
+
+		ncores = 1;
+	}
+
+	if (ncores > num_possible_cpus()) {
+		ncores = num_possible_cpus();
+		pr_err(
+		       "spear13xx: no. of cores (%d) greater than configured "
+		       "maximum of %d - clipping\n",
+		       ncores, ncores);
+	}
+
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * are we trying to boot more cores than exist?
+	 */
+	if (max_cpus > ncores)
+		max_cpus = ncores;
+
+	/*
+	 * Initialise the present map, which describes the set of CPUs
+	 * actually populated at the present time.
+	 */
+	for (i = 0; i < max_cpus; i++)
+		set_cpu_present(i, true);
+
+	/*
+	 * Initialise the SCU if there are more than one CPU and let
+	 * them know where to start. Note that, on modern versions of
+	 * MILO, the "poke" doesn't actually do anything until each
+	 * individual core is sent a soft interrupt to get it out of
+	 * WFI
+	 */
+	if (max_cpus > 1) {
+		/*
+		 * Enable the local timer or broadcast device for the
+		 * boot CPU, but only if we have more than one CPU.
+		 */
+		percpu_timer_setup();
+
+		scu_enable(scu_base_addr());
+		poke_milo();
+	}
+}
diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
new file mode 100644
index 0000000..c1b82f1
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1300.c
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-spear13xx/spear1300.c
+ *
+ * SPEAr1300 machine source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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 <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear1300 specific devices here */
+
+void __init spear1300_init(void)
+{
+	/* call spear13xx family common init function */
+	spear13xx_init();
+}
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
new file mode 100644
index 0000000..d72c8a8
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-spear13xx/spear1300_evb.c
+ *
+ * SPEAr1300 evaluation board source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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/types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+static struct amba_device *amba_devs[] __initdata = {
+	&uart_device,
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+};
+
+static void __init spear1300_evb_init(void)
+{
+	unsigned int i;
+
+	/* call spear1300 machine init function */
+	spear1300_init();
+
+	/* Add Platform Devices */
+	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+	/* Add Amba Devices */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR1300, "ST-SPEAR1300-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear13xx_map_io,
+	.init_irq	=	spear13xx_init_irq,
+	.timer		=	&spear13xx_timer,
+	.init_machine	=	spear1300_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
new file mode 100644
index 0000000..d11e300
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/mach-spear13xx/spear13xx.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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/types.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/gic.h>
+#include <asm/irq.h>
+#include <asm/localtimer.h>
+#include <asm/mach/arch.h>
+#include <asm/smp_twd.h>
+#include <mach/irqs.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* Add spear13xx machines common devices here */
+/* uart device registeration */
+struct amba_device uart_device = {
+	.dev = {
+		.init_name = "uart",
+	},
+	.res = {
+		.start = SPEAR13XX_UART_BASE,
+		.end = SPEAR13XX_UART_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART, NO_IRQ},
+};
+
+/* Do spear13xx familiy common initialization part here */
+void __init spear13xx_init(void)
+{
+	/* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear13xx_init_irq(void)
+{
+	gic_dist_init(0, __io_address(SPEAR13XX_GIC_DIST_BASE), 29);
+	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
+}
+
+/* Following will create static virtual/physical mappings */
+struct map_desc spear13xx_io_desc[] __initdata = {
+	{
+		.virtual	= IO_ADDRESS(SPEAR13XX_UART_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_UART_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_A9SM_PERIP_BASE),
+		.length		= SZ_8K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR13XX_MISC_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_MISC_BASE),
+		.length		= SZ_8K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR13XX_SYSRAM0_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM0_BASE),
+		.length		= SZ_32K,
+		.type		= MT_DEVICE
+	},
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear13xx_map_io(void)
+{
+	iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
+
+	/* This will initialize clock framework */
+	clk_init();
+}
+
+static void __init spear13xx_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+	/* Setup the local timer base */
+	twd_base = __io_address(SPEAR13XX_LOCAL_TMR_BASE);
+#endif
+	spear_setup_timer();
+}
+
+struct sys_timer spear13xx_timer = {
+	.init = spear13xx_timer_init,
+};
-- 
1.7.2.2

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

* [PATCH 06/74] ST SPEAr: Adding support for SPEAr13xx SoC in spear generic plat/
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (4 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/ Viresh KUMAR
                   ` (68 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/Kconfig |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 1bb3dbc..29a25d2 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -8,6 +8,13 @@ choice
 	prompt "ST SPEAr Family"
 	default ARCH_SPEAR3XX
 
+config ARCH_SPEAR13XX
+	bool "SPEAr13XX"
+	select ARM_GIC
+	select CPU_V7
+	help
+	  Supports for ARM's SPEAR13XX family
+
 config ARCH_SPEAR3XX
 	bool "SPEAr3XX"
 	select ARM_VIC
@@ -25,6 +32,7 @@ config ARCH_SPEAR6XX
 endchoice
 
 # Adding SPEAr machine specific configuration files
+source "arch/arm/mach-spear13xx/Kconfig"
 source "arch/arm/mach-spear3xx/Kconfig"
 source "arch/arm/mach-spear6xx/Kconfig"
 
-- 
1.7.2.2

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

* [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (5 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 06/74] ST SPEAr: Adding support for SPEAr13xx SoC in spear generic plat/ Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02 16:27   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 08/74] ST SPEAr1300: Adding default config file Viresh KUMAR
                   ` (67 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/Kconfig  |   12 ++++++++----
 arch/arm/Makefile |    1 +
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9295110..950c045 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1144,11 +1144,13 @@ config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
 		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
-		 ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
+		 ARCH_VEXPRESS_CA9X4)
 	depends on GENERIC_CLOCKEVENTS
 	select USE_GENERIC_SMP_HELPERS
 	select HAVE_ARM_SCU if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 ||\
-		 ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+		 ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
+		 ARCH_VEXPRESS_CA9X4
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -1218,10 +1220,11 @@ config LOCAL_TIMERS
 	bool "Use local timer interrupts"
 	depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
 		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
-		ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+		ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
+		ARCH_VEXPRESS_CA9X4)
 	default y
 	select HAVE_ARM_TWD if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 || \
-		ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS
+		ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
@@ -1599,6 +1602,7 @@ config ZRELADDR
 		ARCH_NUC93X ||\
 		ARCH_NS9XXX ||\
 		ARCH_ORION5X ||\
+		ARCH_SPEAR13XX ||\
 		ARCH_SPEAR3XX ||\
 		ARCH_SPEAR6XX ||\
 		ARCH_U8500 ||\
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 59c1ce8..d5177d7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -191,6 +191,7 @@ machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
 machine-$(CONFIG_ARCH_W90X900)		:= w90x900
 machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
+machine-$(CONFIG_MACH_SPEAR1300)	:= spear13xx
 machine-$(CONFIG_MACH_SPEAR300)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
-- 
1.7.2.2

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

* [PATCH 08/74] ST SPEAr1300: Adding default config file
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (6 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/ Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  8:51   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 09/74] ST SPEAr: Adding information in Documentation/ and MAINTAINERS Viresh KUMAR
                   ` (66 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/configs/spear1300-smp_defconfig |  875 ++++++++++++++++++++++++++++++
 1 files changed, 875 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/spear1300-smp_defconfig

diff --git a/arch/arm/configs/spear1300-smp_defconfig b/arch/arm/configs/spear1300-smp_defconfig
new file mode 100644
index 0000000..98502da
--- /dev/null
+++ b/arch/arm/configs/spear1300-smp_defconfig
@@ -0,0 +1,875 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Mon Apr 19 15:37:56 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR3XX is not set
+# CONFIG_ARCH_SPEAR6XX is not set
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1300=y
+CONFIG_BOARD_SPEAR1300_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_LOCAL_TIMERS=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
-- 
1.7.2.2

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

* [PATCH 09/74] ST SPEAr: Adding information in Documentation/ and MAINTAINERS
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (7 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 08/74] ST SPEAr1300: Adding default config file Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx Viresh KUMAR
                   ` (65 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 Documentation/arm/SPEAr/overview.txt |   33 +++++++++++++++++++++++----------
 MAINTAINERS                          |    6 ++++++
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt
index 253a35c..0e91cbf 100644
--- a/Documentation/arm/SPEAr/overview.txt
+++ b/Documentation/arm/SPEAr/overview.txt
@@ -9,8 +9,9 @@ Introduction
 
   The ST Microelectronics SPEAr range of ARM9/CortexA9 System-on-Chip CPUs are
   supported by the 'spear' platform of ARM Linux. Currently SPEAr300,
-  SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Support for the SPEAr13XX
-  series is in progress.
+  SPEAr310, SPEAr320, SPEAr600 and SPEAr1300 SOCs are supported.
+  SPEAr3XX and SPEAr6XX are based on ARM9 whereas SPEAr13XX is based on latest
+  ARM Cortex A9 CPUs.
 
   Hierarchy in SPEAr is as follows:
 
@@ -27,16 +28,26 @@ Introduction
 			- SPEAr600_EVB (Evaluation Board)
 	- SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
 		- SPEAr1300 (SOC)
+			- SPEAr1300_EVB (Evaluation Board)
 
   Configuration
   -------------
 
   A generic configuration is provided for each machine, and can be used as the
   default by
-	make spear600_defconfig
-	make spear300_defconfig
-	make spear310_defconfig
-	make spear320_defconfig
+	#make ARCH=arm spear600_defconfig
+	#make ARCH=arm spear300_defconfig
+	#make ARCH=arm spear310_defconfig
+	#make ARCH=arm spear320_defconfig
+	#make ARCH=arm spear1300_defconfig
+	#make ARCH=arm spear1300-smp_defconfig (for SMP based configuration)
+
+  Compilation
+  -----------
+
+  After applying default configuration, Linux kernel for SPEAr architecture
+  can be compiled as
+	#make ARCH=arm CROSS_COMPILE=arm-linux- uImage
 
   Layout
   ------
@@ -48,13 +59,15 @@ Introduction
   Each machine series have a directory with name arch/arm/mach-spear followed by
   series name. Like mach-spear3xx, mach-spear6xx and mach-spear13xx.
 
-  Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for
-  spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine
+  Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c, for
+  spear6xx is mach-spear6xx/spear6xx.c and similarly for spear13xx is
+  mach-spear13xx/spear13xx.c. mach-spear* also contain soc/machine
   specific files, like spear300.c, spear310.c, spear320.c and spear600.c.
-  mach-spear* also contains board specific files for each machine type.
+  Board specific files for each machine type is also contained in mach-spear*
+  folder.
 
 
   Document Author
   ---------------
 
-  Viresh Kumar, (c) 2010 ST Microelectronics
+  Viresh Kumar, Shiraz Hashim (c) 2010 ST Microelectronics
diff --git a/MAINTAINERS b/MAINTAINERS
index a1df54b..257e396 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5434,6 +5434,12 @@ W:	http://www.st.com/spear
 S:	Maintained
 F:	arch/arm/plat-spear/
 
+SPEAR13XX MACHINE SUPPORT
+M:	Shiraz Hashim <shiraz.hashim@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/mach-spear13xx/
+
 SPEAR3XX MACHINE SUPPORT
 M:	Viresh Kumar <viresh.kumar@st.com>
 W:	http://www.st.com/spear
-- 
1.7.2.2

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

* [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (8 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 09/74] ST SPEAr: Adding information in Documentation/ and MAINTAINERS Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  9:08   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 11/74] ST SPEAr: Adding support for divisor per parent clock Viresh KUMAR
                   ` (64 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vipul-kumar Samar <vipulkumar.samar@st.com>

Signed-off-by: vipul kumar samar <vipulkumar.samar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    6 +
 arch/arm/mach-spear3xx/spear300.c             |   17 ++++
 arch/arm/mach-spear3xx/spear300_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear320.c             |   16 +++
 arch/arm/mach-spear3xx/spear320_evb.c         |    1 +
 arch/arm/mach-spear6xx/include/mach/generic.h |    4 +
 arch/arm/mach-spear6xx/spear600_evb.c         |    1 +
 arch/arm/mach-spear6xx/spear6xx.c             |   17 ++++
 arch/arm/plat-spear/Makefile                  |    2 +-
 arch/arm/plat-spear/clcd.c                    |  126 +++++++++++++++++++++++++
 drivers/video/Kconfig                         |   14 +++-
 11 files changed, 203 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/plat-spear/clcd.c

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index e7d2de8..1c8f9f1 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -100,6 +100,7 @@ extern struct pmx_driver pmx_driver;
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
 /* Add spear300 machine device structure declarations here */
+extern struct amba_device clcd_device;
 extern struct amba_device gpio1_device;
 
 /* pad mux modes */
@@ -136,6 +137,8 @@ extern struct pmx_dev pmx_gpio1;
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
 
+/* Add misc structure declarations here */
+extern struct clcd_board clcd_plat_data;
 #endif /* CONFIG_MACH_SPEAR300 */
 
 /* spear310 declarations */
@@ -160,6 +163,7 @@ void __init spear310_init(void);
 /* spear320 declarations */
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
+extern struct amba_device clcd_device;
 
 /* pad mux modes */
 extern struct pmx_mode auto_net_smii_mode;
@@ -194,6 +198,8 @@ extern struct pmx_dev pmx_i2c1;
 /* Add spear320 machine function declarations here */
 void __init spear320_init(void);
 
+/* Add misc structure declarations here */
+extern struct clcd_board clcd_plat_data;
 #endif /* CONFIG_MACH_SPEAR320 */
 
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 7e0ca5d..5d8df00 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -371,6 +371,23 @@ struct pmx_driver pmx_driver = {
 };
 
 /* Add spear300 specific devices here */
+
+/* CLCD device registration */
+struct amba_device clcd_device = {
+	.dev = {
+		.init_name = "clcd",
+		.coherent_dma_mask = ~0,
+		.platform_data = &clcd_plat_data,
+	},
+	.res = {
+		.start = SPEAR300_CLCD_BASE,
+		.end = SPEAR300_CLCD_BASE + SPEAR300_CLCD_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.dma_mask = ~0,
+	.irq = {IRQ_CLCD, NO_IRQ},
+};
+
 /* arm gpio1 device registeration */
 static struct pl061_platform_data gpio1_plat_data = {
 	.gpio_base	= 8,
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index cd23c98..3bb7fbc 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -38,6 +38,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	&uart_device,
 
 	/* spear300 specific devices */
+	&clcd_device,
 	&gpio1_device,
 };
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 2886bb2..e5baa00 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -386,6 +386,22 @@ struct pmx_driver pmx_driver = {
 
 /* Add spear320 specific devices here */
 
+/* CLCD device registration */
+struct amba_device clcd_device = {
+	.dev = {
+		.init_name = "clcd",
+		.coherent_dma_mask = ~0,
+		.platform_data = &clcd_plat_data,
+	},
+	.res = {
+		.start = SPEAR320_CLCD_BASE,
+		.end = SPEAR320_CLCD_BASE + SPEAR320_CLCD_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.dma_mask = ~0,
+	.irq = {VIRQ_CLCD, NO_IRQ},
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 4a7ce35..821e806 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -43,6 +43,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	&uart_device,
 
 	/* spear320 specific devices */
+	&clcd_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index e5967ed..d6a04f2 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -29,6 +29,7 @@
 #define SPEAR_GPT0_CHAN1_IRQ	IRQ_CPU_GPT1_2
 
 /* Add spear6xx family device structure declarations here */
+extern struct amba_device clcd_device;
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_device[];
 extern struct sys_timer spear6xx_timer;
@@ -43,4 +44,7 @@ void __init clk_init(void);
 
 /* Add spear600 machine device structure declarations here */
 
+/* Add misc structure declarations here */
+extern struct clcd_board clcd_plat_data;
+
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index bdd5b76..88e69f4 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -17,6 +17,7 @@
 #include <mach/spear.h>
 
 static struct amba_device *amba_devs[] __initdata = {
+	&clcd_device,
 	&gpio_device[0],
 	&gpio_device[1],
 	&gpio_device[2],
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 88a82ca..d0f6b9d 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -23,6 +23,23 @@
 #include <mach/spear.h>
 
 /* Add spear6xx machines common devices here */
+
+/* CLCD device registration */
+struct amba_device clcd_device = {
+	.dev = {
+		.init_name = "clcd",
+		.coherent_dma_mask = ~0,
+		.platform_data = &clcd_plat_data,
+	},
+	.res = {
+		.start = SPEAR6XX_ICM3_CLCD_BASE,
+		.end = SPEAR6XX_ICM3_CLCD_BASE + SPEAR6XX_ICM3_CLCD_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.dma_mask = ~0,
+	.irq = {IRQ_BASIC_CLCD, NO_IRQ},
+};
+
 /* uart device registeration */
 struct amba_device uart_device[] = {
 	{
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index b4f340b..01a4a91 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,6 @@
 #
 
 # Common support
-obj-y	:= clock.o time.o
+obj-y	:= clcd.o clock.o time.o
 
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
diff --git a/arch/arm/plat-spear/clcd.c b/arch/arm/plat-spear/clcd.c
new file mode 100644
index 0000000..0ad4d0b
--- /dev/null
+++ b/arch/arm/plat-spear/clcd.c
@@ -0,0 +1,126 @@
+/*
+* arch/arm/plat-spear/clcd.c
+*
+* Copyright (C) 2009 ST Microelectronics
+* Shiraz Hashim<shiraz.hashim@st.com>
+* Ashish Priyadarshi<ashish.priyadarshi@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/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+/* This is enough for the size of 800x480 (1.5 MB) */
+#define FRAMESIZE 0x00180000
+
+#ifdef CONFIG_FB_ARMCLCD_SHARP_LQ043T1DG01
+static struct clcd_panel sharp_LQ043T1DG01_in = {
+	.mode = {
+		.name = "Sharp LQ043T1DG01",
+		.refresh = 0,
+		.xres = 480,
+		.yres = 272,
+		.pixclock = 48000,
+		.left_margin = 2,
+		.right_margin = 2,
+		.upper_margin = 2,
+		.lower_margin = 2,
+		.hsync_len = 41,
+		.vsync_len = 11,
+		.sync = 0,/* FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT */
+		.vmode = FB_VMODE_NONINTERLACED,
+	},
+	.width = -1,
+	.height = -1,
+	.tim2 = TIM2_IOE | TIM2_CLKSEL | 3,
+	.cntl = CNTL_LCDTFT | CNTL_BGR,
+	.bpp = 32,
+};
+#endif
+
+#ifdef CONFIG_FB_ARMCLCD_SAMSUNG_LMS700
+static struct clcd_panel samsung_LMS700_in = {
+	.mode = {
+		.name = "Samsung LMS700",
+		.refresh = 0,
+		.xres = 800,
+		.yres = 480,
+		.pixclock = 48000,
+		.left_margin = 16,
+		.right_margin = 8,
+		.upper_margin = 6,
+		.lower_margin = 5,
+		.hsync_len = 3,
+		.vsync_len = 2,
+		.sync = 0,
+		.vmode = FB_VMODE_NONINTERLACED,
+	},
+	.width = -1,
+	.height = -1,
+	.tim2 = TIM2_CLKSEL,
+	.cntl = CNTL_LCDTFT | CNTL_BGR,
+	.bpp = 32,
+};
+#endif
+
+static int clcd_setup(struct clcd_fb *fb)
+{
+	dma_addr_t dma;
+
+	/* Detect which LCD panel is connected */
+#ifdef CONFIG_FB_ARMCLCD_SHARP_LQ043T1DG01
+	fb->panel = &sharp_LQ043T1DG01_in;
+#endif
+#ifdef CONFIG_FB_ARMCLCD_SAMSUNG_LMS700
+	fb->panel = &samsung_LMS700_in;
+#endif
+	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, FRAMESIZE,
+			&dma, GFP_KERNEL);
+	if (!fb->fb.screen_base) {
+		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+		return -ENOMEM;
+	}
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = FRAMESIZE;
+
+	return 0;
+}
+
+static int clcd_check(struct clcd_fb *fb, struct fb_var_screeninfo
+		*var)
+{
+	var->xres_virtual = var->xres = (var->xres + 15) & ~15;
+	var->yres_virtual = var->yres = (var->yres + 1) & ~1;
+
+	var->nonstd = 0;
+	var->accel_flags = 0;
+
+	return 0;
+}
+
+static void clcd_remove(struct clcd_fb *fb)
+{
+	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+			fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static int clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+			fb->fb.screen_base,
+			fb->fb.fix.smem_start,
+			fb->fb.fix.smem_len);
+}
+
+struct clcd_board clcd_plat_data = {
+	.name = "spear-clcd",
+	.check = clcd_check,
+	.decode = clcdfb_decode,
+	.setup = clcd_setup,
+	.mmap = clcd_mmap,
+	.remove = clcd_remove,
+};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 8b31fdf..24c919e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -307,10 +307,22 @@ config FB_ARMCLCD
 
 choice
 
-	depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X)
+	depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X || ARCH_SPEAR6XX || MACH_SPEAR300 || MACH_SPEAR320)
 	prompt "LCD Panel"
 	default FB_ARMCLCD_SHARP_LQ035Q7DB02
 
+config FB_ARMCLCD_SHARP_LQ043T1DG01
+	bool "SHARP LQ043T1DG01 CLCD 4.2\" TFT(480x272)"
+	help
+	  This is an implementation of the Sharp LQ043T1DG01, a 4.2"
+	  color TFT panel. The native resolution is 480x272.
+
+config FB_ARMCLCD_SAMSUNG_LMS700
+	bool "SAMSUNG CLCD 7\" TFT(800x480)"
+	help
+	  This is an implementation of the Samsung LMS700, a 7"
+	  color TFT panel. The native resolution is 800x480.
+
 config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
 	bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
 	help
-- 
1.7.2.2

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

* [PATCH 11/74] ST SPEAr: Adding support for divisor per parent clock
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (9 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320 Viresh KUMAR
                   ` (63 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch was intended to provide support for clocks with multiple parents,
where clock derived from any parent can be divided by a fixed number or can be
passed to synthesizer. For this clock framework is reorganized to make behaviour
of functions more closer to their name.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/clock.c              |  249 +++++++++++++++++++-----------
 arch/arm/plat-spear/include/plat/clock.h |    6 +-
 2 files changed, 162 insertions(+), 93 deletions(-)

diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index f1cf832..ab29353 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -64,6 +64,40 @@ static struct clkops generic_clkops = {
 	.disable = generic_clk_disable,
 };
 
+/* returns current programmed clocks clock info structure */
+static struct pclk_info *pclk_info_get(struct clk *clk)
+{
+	unsigned int mask, i;
+	struct pclk_info *info = NULL;
+
+	mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
+		& clk->pclk_sel->pclk_sel_mask;
+
+	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+		if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
+			info = &clk->pclk_sel->pclk_info[i];
+	}
+
+	return info;
+}
+
+/*
+ * Set Update pclk, and pclk_info of clk and add clock sibling node to current
+ * parents children list
+ */
+static void update_clk_tree(struct clk *clk, struct pclk_info *pclk_info)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	list_del(&clk->sibling);
+	list_add(&clk->sibling, &pclk_info->pclk->children);
+
+	clk->pclk = pclk_info->pclk;
+	clk->pclk_info = pclk_info;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
 /*
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
@@ -161,6 +195,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	if (clk->pclk == parent)
 		return 0;
 
+	/* check if requested parent is in clk parent list */
 	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
 		if (clk->pclk_sel->pclk_info[i].pclk == parent) {
 			found = 1;
@@ -180,8 +215,11 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
 	/* reflect parent change in software */
+	update_clk_tree(clk, &clk->pclk_sel->pclk_info[i]);
+
 	clk->recalc(clk);
 	propagate_rate(&clk->children);
+
 	return 0;
 }
 EXPORT_SYMBOL(clk_set_parent);
@@ -220,14 +258,23 @@ void clk_register(struct clk_lookup *cl)
 	/* root clock don't have any parents */
 	if (!clk->pclk && !clk->pclk_sel) {
 		list_add(&clk->sibling, &root_clks);
-		/* add clocks with only one parent to parent's children list */
 	} else if (clk->pclk && !clk->pclk_sel) {
+		/* add clocks with only one parent to parent's children list */
 		list_add(&clk->sibling, &clk->pclk->children);
 	} else {
-		/* add clocks with > 1 parent to 1st parent's children list */
-		clk->pclk = clk->pclk_sel->pclk_info[0].pclk;
-		list_add(&clk->sibling,
-			 &clk->pclk_sel->pclk_info[0].pclk->children);
+		/* clocks with more than one parent */
+		struct pclk_info *pclk_info;
+
+		pclk_info = pclk_info_get(clk);
+		if (!pclk_info) {
+			printk(KERN_ERR "CLKDEV: invalid pclk info of clk with"
+					" %s dev_id and %s con_id\n",
+					cl->dev_id, cl->con_id);
+		} else {
+			clk->pclk = pclk_info->pclk;
+			clk->pclk_info = pclk_info;
+			list_add(&clk->sibling, &pclk_info->pclk->children);
+		}
 	}
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
@@ -252,42 +299,6 @@ static void propagate_rate(struct list_head *lhead)
 	}
 }
 
-/* returns current programmed clocks clock info structure */
-static struct pclk_info *pclk_info_get(struct clk *clk)
-{
-	unsigned int mask, i;
-	unsigned long flags;
-	struct pclk_info *info = NULL;
-
-	spin_lock_irqsave(&clocks_lock, flags);
-	mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
-			& clk->pclk_sel->pclk_sel_mask;
-
-	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
-		if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
-			info = &clk->pclk_sel->pclk_info[i];
-	}
-	spin_unlock_irqrestore(&clocks_lock, flags);
-
-	return info;
-}
-
-/*
- * Set pclk as cclk's parent and add clock sibling node to current parents
- * children list
- */
-static void change_parent(struct clk *cclk, struct clk *pclk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clocks_lock, flags);
-	list_del(&cclk->sibling);
-	list_add(&cclk->sibling, &pclk->children);
-
-	cclk->pclk = pclk;
-	spin_unlock_irqrestore(&clocks_lock, flags);
-}
-
 /*
  * calculates current programmed rate of pll1
  *
@@ -304,28 +315,53 @@ void pll_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
-		config->masks->mode_mask;
-
-	val = readl(config->cfg_reg);
-	/* calculate denominator */
-	den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
-	den = 1 << den;
-	den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
-
-	/* calculate numerator & denominator */
-	if (!mode) {
-		/* Normal mode */
-		num *= (val >> config->masks->norm_fdbk_m_shift) &
-			config->masks->norm_fdbk_m_mask;
+
+	/*
+	 * read divisor from hardware, only in two cases:
+	 * - There is only parent to clk and it requires *_clk_recalc
+	 * - There are two parents of a clock and current pclk requires
+	 *   *_clk_recalc
+	 */
+	if (!clk->pclk_info || clk->pclk_info->scalable) {
+		mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
+			config->masks->mode_mask;
+
+		val = readl(config->cfg_reg);
+		spin_unlock_irqrestore(&clocks_lock, flags);
+
+		/* calculate denominator */
+		den = (val >> config->masks->div_p_shift) &
+			config->masks->div_p_mask;
+		den = 1 << den;
+		den *= (val >> config->masks->div_n_shift) &
+			config->masks->div_n_mask;
+
+		/* calculate numerator & denominator */
+		if (!mode) {
+			/* Normal mode */
+			num *= (val >> config->masks->norm_fdbk_m_shift) &
+				config->masks->norm_fdbk_m_mask;
+		} else {
+			/* Dithered mode */
+			num *= (val >> config->masks->dith_fdbk_m_shift) &
+				config->masks->dith_fdbk_m_mask;
+			den *= 256;
+		}
+
+		spin_lock_irqsave(&clocks_lock, flags);
+		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
 	} else {
-		/* Dithered mode */
-		num *= (val >> config->masks->dith_fdbk_m_shift) &
-			config->masks->dith_fdbk_m_mask;
-		den *= 256;
+		int div = 0;
+		/*
+		 * only if there are two parents and current parent requires
+		 * simple division
+		 */
+		div = (clk->pclk_info->div_factor < 1) ? 1 :
+			clk->pclk_info->div_factor;
+		val = clk->pclk->rate/div;
 	}
 
-	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	clk->rate = val;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
@@ -337,8 +373,23 @@ void bus_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	div = ((readl(config->reg) >> config->masks->shift) &
-			config->masks->mask) + 1;
+	/*
+	 * read divisor from hardware, only in two cases:
+	 * - There is only parent to clk and it requires *_clk_recalc
+	 * - There are two parents of a clock and current pclk requires
+	 *   *_clk_recalc
+	 */
+	if (!clk->pclk_info || clk->pclk_info->scalable) {
+		div = ((readl(config->reg) >> config->masks->shift) &
+				config->masks->mask) + 1;
+	} else {
+		/*
+		 * only if there are two parents and current parent requires
+		 * simple division
+		 */
+		div = (clk->pclk_info->div_factor < 1) ? 1 :
+			clk->pclk_info->div_factor;
+	}
 	clk->rate = (unsigned long)clk->pclk->rate / div;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
@@ -356,25 +407,19 @@ void bus_clk_recalc(struct clk *clk)
 void aux_clk_recalc(struct clk *clk)
 {
 	struct aux_clk_config *config = clk->private_data;
-	struct pclk_info *pclk_info = NULL;
 	unsigned int num = 1, den = 1, val, eqn;
 	unsigned long flags;
 
-	/* get current programmed parent */
-	pclk_info = pclk_info_get(clk);
-	if (!pclk_info) {
-		spin_lock_irqsave(&clocks_lock, flags);
-		clk->pclk = NULL;
-		clk->rate = 0;
-		spin_unlock_irqrestore(&clocks_lock, flags);
-		return;
-	}
-
-	change_parent(clk, pclk_info->pclk);
-
 	spin_lock_irqsave(&clocks_lock, flags);
-	if (pclk_info->scalable) {
+	/*
+	 * read divisor from hardware, only in two cases:
+	 * - There is only parent to clk and it requires *_clk_recalc
+	 * - There are two parents of a clock and current pclk requires
+	 *   *_clk_recalc
+	 */
+	if (!clk->pclk_info || clk->pclk_info->scalable) {
 		val = readl(config->synth_reg);
+		spin_unlock_irqrestore(&clocks_lock, flags);
 
 		eqn = (val >> config->masks->eq_sel_shift) &
 			config->masks->eq_sel_mask;
@@ -388,9 +433,19 @@ void aux_clk_recalc(struct clk *clk)
 		/* calculate denominator */
 		den *= (val >> config->masks->yscale_sel_shift) &
 			config->masks->yscale_sel_mask;
+
+		spin_lock_irqsave(&clocks_lock, flags);
 		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
-	} else
-		val = clk->pclk->rate;
+	} else {
+		/*
+		 * only if there are two parents and current parent requires
+		 * simple division
+		 */
+		int div_factor = (clk->pclk_info->div_factor < 1) ? 1 :
+			clk->pclk_info->div_factor;
+
+		val = clk->pclk->rate/div_factor;
+	}
 
 	clk->rate = val;
 	spin_unlock_irqrestore(&clocks_lock, flags);
@@ -404,28 +459,32 @@ void aux_clk_recalc(struct clk *clk)
 void gpt_clk_recalc(struct clk *clk)
 {
 	struct gpt_clk_config *config = clk->private_data;
-	struct pclk_info *pclk_info = NULL;
 	unsigned int div = 1, val;
 	unsigned long flags;
 
-	pclk_info = pclk_info_get(clk);
-	if (!pclk_info) {
-		spin_lock_irqsave(&clocks_lock, flags);
-		clk->pclk = NULL;
-		clk->rate = 0;
-		spin_unlock_irqrestore(&clocks_lock, flags);
-		return;
-	}
-
-	change_parent(clk, pclk_info->pclk);
-
 	spin_lock_irqsave(&clocks_lock, flags);
-	if (pclk_info->scalable) {
+	/*
+	 * read divisor from hardware, only in two cases:
+	 * - There is only parent to clk and it requires *_clk_recalc
+	 * - There are two parents of a clock and current pclk requires
+	 *   *_clk_recalc
+	 */
+	if (!clk->pclk_info || clk->pclk_info->scalable) {
 		val = readl(config->synth_reg);
+		spin_unlock_irqrestore(&clocks_lock, flags);
+
 		div += (val >> config->masks->mscale_sel_shift) &
 			config->masks->mscale_sel_mask;
 		div *= 1 << (((val >> config->masks->nscale_sel_shift) &
 					config->masks->nscale_sel_mask) + 1);
+		spin_lock_irqsave(&clocks_lock, flags);
+	} else {
+		/*
+		 * only if there are two parents and current parent requires
+		 * simple division
+		 */
+		div = (clk->pclk_info->div_factor < 1) ? 1 :
+			clk->pclk_info->div_factor;
 	}
 
 	clk->rate = (unsigned long)clk->pclk->rate / div;
@@ -439,9 +498,15 @@ void gpt_clk_recalc(struct clk *clk)
 void follow_parent(struct clk *clk)
 {
 	unsigned long flags;
-	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
+	unsigned int div_factor;
 
 	spin_lock_irqsave(&clocks_lock, flags);
+	if (clk->pclk_info)
+		div_factor = clk->pclk_info->div_factor;
+	else
+		div_factor = clk->div_factor;
+	div_factor = (div_factor < 1) ? 1 : div_factor;
+
 	clk->rate = clk->pclk->rate/div_factor;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index e08b58c..d8d0856 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -37,11 +37,13 @@ struct clkops {
  * @pclk: pointer to parent clk
  * @pclk_mask: value to be written for selecting this parent
  * @scalable: Is parent scalable (1 - YES, 0 - NO)
+ * @div_factor: div factor for pclk
  */
 struct pclk_info {
 	struct clk *pclk;
 	u8 pclk_mask;
 	u8 scalable;
+	u8 div_factor;
 };
 
 /**
@@ -67,8 +69,9 @@ struct pclk_sel {
  * @en_reg_bit: clk enable/disable bit
  * @ops: clk enable/disable ops - generic_clkops selected if NULL
  * @recalc: pointer to clock rate recalculate function
- * @div_factor: division factor to parent clock. Only for recalc = follow_parent
+ * @div_factor: division factor to parent clock. Only for clks with one parent
  * @pclk: current parent clk
+ * @pclk_info: current parent clk's pclk_info
  * @pclk_sel: pointer to parent selection structure
  * @pclk_sel_shift: register shift for selecting parent of this clock
  * @children: list for childrens or this clock
@@ -86,6 +89,7 @@ struct clk {
 	unsigned int div_factor;
 
 	struct clk *pclk;
+	struct pclk_info *pclk_info;
 	struct pclk_sel *pclk_sel;
 	unsigned int pclk_sel_shift;
 
-- 
1.7.2.2

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

* [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (10 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 11/74] ST SPEAr: Adding support for divisor per parent clock Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-06 22:58   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 13/74] ST SPEAr: Update clock framework and definitions Viresh KUMAR
                   ` (62 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/spear320.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index cacf17a..53677e4 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -62,7 +62,7 @@
 #define SPEAR320_SMII1_BASE		0xAB000000
 #define SPEAR320_SMII1_SIZE		0x01000000
 
-#define SPEAR320_SOC_CONFIG_BASE	0xB4000000
+#define SPEAR320_SOC_CONFIG_BASE	0xB3000000
 #define SPEAR320_SOC_CONFIG_SIZE	0x00000070
 /* Interrupt registers offsets and masks */
 #define INT_STS_MASK_REG		0x04
-- 
1.7.2.2

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (11 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320 Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-06 23:09   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform Viresh KUMAR
                   ` (61 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

- Defined clks for synthesizers and prescalers as they were shared among IPs
- Simplified clk_recalc functions
- Keep divisor only at 1 level i.e. during clk defn
- Added missing clock definitions

Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/clock.c                  |  510 +++++++++++++++++++++-
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |   99 +++--
 arch/arm/mach-spear3xx/clock.c                   |  176 ++++++---
 arch/arm/mach-spear3xx/include/mach/misc_regs.h  |    5 +-
 arch/arm/mach-spear6xx/clock.c                   |  256 ++++++++----
 arch/arm/mach-spear6xx/include/mach/misc_regs.h  |    5 +-
 arch/arm/plat-spear/clock.c                      |  208 ++++------
 arch/arm/plat-spear/include/plat/clock.h         |   24 +-
 8 files changed, 940 insertions(+), 343 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 280eb5b..cef3b13 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -52,10 +52,10 @@ static struct clk rtc_clk = {
 static struct pclk_info pll_pclk_info[] = {
 	{
 		.pclk = &osc1_24m_clk,
-		.pclk_mask = OSC_24M_MASK,
+		.pclk_val = OSC_24M_VAL,
 	}, {
 		.pclk = &osc3_25m_clk,
-		.pclk_mask = OSC_25M_MASK,
+		.pclk_val = OSC_25M_VAL,
 	},
 };
 
@@ -97,6 +97,22 @@ static struct clk pll1_clk = {
 	.private_data = &pll1_config,
 };
 
+/* pll1div2 clock */
+static struct clk pll1div2_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.div_factor = 2,
+	.recalc = &follow_parent,
+};
+
+/* pll1div4 clock */
+static struct clk pll1div4_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.div_factor = 4,
+	.recalc = &follow_parent,
+};
+
 /* pll2 configuration structure */
 static struct pll_clk_config pll2_config = {
 	.mode_reg = PLL2_CTR,
@@ -191,10 +207,10 @@ static struct clk apb_clk = {
 static struct pclk_info gpt_pclk_info[] = {
 	{
 		.pclk = &osc1_24m_clk,
-		.pclk_mask = GPT_OSC24_MASK,
+		.pclk_val = GPT_OSC24_VAL,
 	}, {
 		.pclk = &apb_clk,
-		.pclk_mask = GPT_APB_MASK,
+		.pclk_val = GPT_APB_VAL,
 	},
 };
 
@@ -249,14 +265,6 @@ static struct clk wdt_clk = {
 	.recalc = &follow_parent,
 };
 
-/* smi clock */
-static struct clk smi_clk = {
-	.pclk = &ahb_clk,
-	.en_reg = PERIP1_CLK_ENB,
-	.en_reg_bit = SMI_CLK_ENB,
-	.recalc = &follow_parent,
-};
-
 /* auxiliary synthesizers masks */
 static struct aux_clk_masks aux_masks = {
 	.eq_sel_mask = AUX_EQ_SEL_MASK,
@@ -269,22 +277,30 @@ static struct aux_clk_masks aux_masks = {
 	.yscale_sel_shift = AUX_YSCALE_SHIFT,
 };
 
+/* clocks derived multiple parents (pll1, pll5, synthesizers or others) */
 /* uart configurations */
-static struct aux_clk_config uart_config = {
+static struct aux_clk_config uart_synth_config = {
 	.synth_reg = UART_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
-/* clocks derived from pll1 or pll5 */
+/* uart synth clock */
+static struct clk uart_synth_clk = {
+	.en_reg = UART_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1div2_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_synth_config,
+};
+
 /* uart parents */
 static struct pclk_info uart_pclk_info[] = {
 	{
 		.pclk = &pll5_clk,
-		.pclk_mask = AUX_CLK_PLL5_MASK,
+		.pclk_val = AUX_CLK_PLL5_VAL,
 	}, {
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &uart_synth_clk,
+		.pclk_val = AUX_CLK_SYNT_VAL,
 	},
 };
 
@@ -302,8 +318,414 @@ static struct clk uart_clk = {
 	.en_reg_bit = UART_CLK_ENB,
 	.pclk_sel = &uart_pclk_sel,
 	.pclk_sel_shift = UART_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* sd configurations */
+static struct aux_clk_config sd_synth_config = {
+	.synth_reg = SD_CLK_SYNT,
+	.masks = &aux_masks,
+};
+
+/* sd synth clock */
+static struct clk sd_synth_clk = {
+	.en_reg = SD_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1div2_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &sd_synth_config,
+};
+
+/* sd clock */
+static struct clk sd_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SD_CLK_ENB,
+	.pclk = &sd_synth_clk,
+	.recalc = &follow_parent,
+};
+
+/* cfxd configurations */
+static struct aux_clk_config cfxd_synth_config = {
+	.synth_reg = CFXD_CLK_SYNT,
+	.masks = &aux_masks,
+};
+
+/* cfxd synth clock */
+static struct clk cfxd_synth_clk = {
+	.en_reg = CFXD_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1div2_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &cfxd_synth_config,
+};
+
+/* cfxd clock */
+static struct clk cfxd_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = CFXD_CLK_ENB,
+	.pclk = &cfxd_synth_clk,
+	.recalc = &follow_parent,
+};
+
+/* C3 clk configurations */
+static struct aux_clk_config c3_synth_config = {
+	.synth_reg = C3_CLK_SYNT,
+	.masks = &aux_masks,
+};
+
+/* c3 synth clock */
+static struct clk c3_synth_clk = {
+	.en_reg = C3_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1div2_clk,
 	.recalc = &aux_clk_recalc,
-	.private_data = &uart_config,
+	.private_data = &c3_synth_config,
+};
+
+/* c3 parents */
+static struct pclk_info c3_pclk_info[] = {
+	{
+		.pclk = &pll5_clk,
+		.pclk_val = AUX_CLK_PLL5_VAL,
+	}, {
+		.pclk = &c3_synth_clk,
+		.pclk_val = AUX_CLK_SYNT_VAL,
+	},
+};
+
+/* c3 parent select structure */
+static struct pclk_sel c3_pclk_sel = {
+	.pclk_info = c3_pclk_info,
+	.pclk_count = ARRAY_SIZE(c3_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = C3_CLK_MASK,
+};
+
+/* c3 clock */
+static struct clk c3_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = C3_CLK_ENB,
+	.pclk_sel = &c3_pclk_sel,
+	.pclk_sel_shift = C3_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* gmac phy clk configurations */
+static struct aux_clk_config gmac_phy_synth_config = {
+	.synth_reg = GMAC_CLK_SYNT,
+	.masks = &aux_masks,
+};
+
+/* gmii external pad clock for phy operation */
+static struct clk gmii_txclk125_pad = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 125000000,
+};
+
+/* gmac phy set of input clks*/
+static struct pclk_info gmac_phy_input_pclk_info[] = {
+	{
+		.pclk = &gmii_txclk125_pad,
+		.pclk_val = GMAC_PHY_PAD_VAL,
+	}, {
+		.pclk = &pll2_clk,
+		.pclk_val = GMAC_PHY_PLL2_VAL,
+	}, {
+		.pclk = &osc3_25m_clk,
+		.pclk_val = GMAC_PHY_OSC3_VAL,
+	},
+};
+
+static struct pclk_sel gmac_phy_input_pclk_sel = {
+	.pclk_info = gmac_phy_input_pclk_info,
+	.pclk_count = ARRAY_SIZE(gmac_phy_input_pclk_info),
+	.pclk_sel_reg = GMAC_CLK_CFG,
+	.pclk_sel_mask = GMAC_PHY_INPUT_CLK_MASK,
+};
+
+static struct clk gmac_phy_input_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gmac_phy_input_pclk_sel,
+	.pclk_sel_shift = GMAC_PHY_INPUT_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+static struct clk gmac_phy_synth_clk = {
+	.en_reg = GMAC_CLK_CFG,
+	.en_reg_bit = GMAC_PHY_SYNT_ENB,
+	.pclk = &gmac_phy_input_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &gmac_phy_synth_config,
+};
+
+/* gmac phy parents */
+static struct pclk_info gmac_phy_pclk_info[] = {
+	{
+		.pclk = &gmac_phy_input_clk,
+		.pclk_val = 0,
+	}, {
+		.pclk = &gmac_phy_synth_clk,
+		.pclk_val = 1,
+	}
+};
+
+/* gmac phy parent select structure */
+static struct pclk_sel gmac_phy_pclk_sel = {
+	.pclk_info = gmac_phy_pclk_info,
+	.pclk_count = ARRAY_SIZE(gmac_phy_pclk_info),
+	.pclk_sel_reg = GMAC_CLK_CFG,
+	.pclk_sel_mask = GMAC_PHY_CLK_MASK,
+};
+
+/* gmac phy clock */
+static struct clk gmac_phy_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gmac_phy_pclk_sel,
+	.pclk_sel_shift = GMAC_PHY_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* clcd synthesizers masks */
+static struct clcd_synth_masks clcd_masks = {
+	.div_factor_mask = CLCD_SYNT_DIV_FACTOR_MASK,
+	.div_factor_shift = CLCD_SYNT_DIV_FACTOR_SHIFT,
+};
+
+static struct clcd_clk_config clcd_synth_config = {
+	.synth_reg = CLCD_CLK_SYNT,
+	.masks = &clcd_masks,
+};
+
+/* clcd synth parents */
+static struct pclk_info clcd_synth_pclk_info[] = {
+	{
+		.pclk = &pll1div4_clk,
+		.pclk_val = CLCD_SYNT_PLL1_DIV4_VAL,
+	}, {
+		.pclk = &pll2_clk,
+		.pclk_val = CLCD_SYNT_PLL2_VAL,
+	},
+};
+
+/* clcd synth parent select structure */
+static struct pclk_sel clcd_synth_pclk_sel = {
+	.pclk_info = clcd_synth_pclk_info,
+	.pclk_count = ARRAY_SIZE(clcd_synth_pclk_info),
+	.pclk_sel_reg = PLL_CFG,
+	.pclk_sel_mask = CLCD_SYNT_CLK_MASK,
+};
+
+/* clcd synth clock */
+static struct clk clcd_synth_clk = {
+	.en_reg = CLCD_CLK_SYNT,
+	.en_reg_bit = CLCD_SYNT_ENB,
+	.pclk_sel = &clcd_synth_pclk_sel,
+	.pclk_sel_shift = CLCD_SYNT_CLK_SHIFT,
+	.recalc = &clcd_clk_recalc,
+	.private_data = &clcd_synth_config,
+};
+
+/* clcd clock parents */
+static struct pclk_info clcd_pclk_info[] = {
+	{
+		.pclk = &pll5_clk,
+		.pclk_val = AUX_CLK_PLL5_VAL,
+	}, {
+		.pclk = &clcd_synth_clk,
+		.pclk_val = AUX_CLK_SYNT_VAL,
+	},
+};
+
+/* clcd parent select structure */
+static struct pclk_sel clcd_pclk_sel = {
+	.pclk_info = clcd_pclk_info,
+	.pclk_count = ARRAY_SIZE(clcd_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = CLCD_CLK_MASK,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = CLCD_CLK_ENB,
+	.pclk_sel = &clcd_pclk_sel,
+	.pclk_sel_shift = CLCD_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+
+/* i2c clock */
+static struct clk i2c_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = I2C_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma0_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = DMA0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+static struct clk dma1_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = DMA1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = JPEG_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GMAC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* fsmc clock */
+static struct clk fsmc_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SMI_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SMI_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* uhc0 clock */
+static struct clk uhci0_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UHC0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* uhc1 clock */
+static struct clk uhci1_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UHC1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBD_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* pci clocks */
+static struct clk pcie0_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = PCIE0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+static struct clk pcie1_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = PCIE1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+static struct clk pcie2_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = PCIE2_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* sysram clocks */
+static struct clk sysram0_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SYSRAM0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+static struct clk sysram1_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SYSRAM1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = ADC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ssp clock */
+static struct clk ssp_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SSP_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gpio clock */
+static struct clk gpio0_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPIO0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gpio clock */
+static struct clk gpio1_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPIO1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* i2s0 clock */
+static struct clk i2s0_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = I2S0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* i2s1 clock */
+static struct clk i2s1_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = I2S1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* keyboard clock */
+static struct clk kbd_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP2_CLK_ENB,
+	.en_reg_bit = KBD_CLK_ENB,
+	.recalc = &follow_parent,
 };
 
 /* array of all spear 13xx clock lookups */
@@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
 	/* clock derived from pll1 clk */
 	{.con_id = "cpu_clk",		.clk = &cpu_clk},
 	{.con_id = "ahb_clk",		.clk = &ahb_clk},
-	{ .con_id = "apb_clk",		.clk = &apb_clk},
+	{.con_id = "apb_clk",		.clk = &apb_clk},
+
+	/* synthesizers/prescaled clocks */
+	{.con_id = "pll1div2_clk",		.clk = &pll1div2_clk},
+	{.con_id = "pll1div4_clk",		.clk = &pll1div4_clk},
+	{.con_id = "c3_synth_clk",		.clk = &c3_synth_clk},
+	{.con_id = "gmii_txclk123_pad_clk",	.clk = &gmii_txclk125_pad},
+	{.con_id = "clcd_synth_clk",		.clk = &clcd_synth_clk},
+	{.con_id = "uart_synth_clk",		.clk = &uart_synth_clk},
+	{.con_id = "sd_synth_clk",		.clk = &sd_synth_clk},
+	{.con_id = "cfxd_synth_clk",		.clk = &cfxd_synth_clk},
+	{.con_id = "gmac_phy_input_clk",	.clk = &gmac_phy_input_clk},
+	{.con_id = "gmac_phy_synth_clk",	.clk = &gmac_phy_synth_clk},
+	{.con_id = "gmac_phy_clk",		.clk = &gmac_phy_clk},
 
 	/* clocks having multiple parent source from above clocks */
-	{.dev_id = "uart",		.clk = &uart_clk},
+	{.dev_id = "clcd",		.clk = &clcd_clk},
 	{.dev_id = "gpt0",		.clk = &gpt0_clk},
 	{.dev_id = "gpt1",		.clk = &gpt1_clk},
 	{.dev_id = "gpt2",		.clk = &gpt2_clk},
 	{.dev_id = "gpt3",		.clk = &gpt3_clk},
+	{.dev_id = "uart",		.clk = &uart_clk},
 
-	/* clock derived from ahb/apb clk */
-	{ .dev_id = "smi",		.clk = &smi_clk},
-	{ .dev_id = "wdt",		.clk = &wdt_clk},
+	/* clock derived from ahb clk */
+	{.dev_id = "smi",		.clk = &smi_clk},
+	{.dev_id = "uhci0",		.clk = &uhci0_clk},
+	{.dev_id = "uhci1",		.clk = &uhci1_clk},
+	{.dev_id = "usbd",		.clk = &usbd_clk},
+	{.dev_id = "i2c",		.clk = &i2c_clk},
+	{.dev_id = "dma0",		.clk = &dma0_clk},
+	{.dev_id = "dma1",		.clk = &dma1_clk},
+	{.dev_id = "jpeg",		.clk = &jpeg_clk},
+	{.dev_id = "gmac",		.clk = &gmac_clk},
+	{.dev_id = "c3",		.clk = &c3_clk},
+	{.dev_id = "pcie0",		.clk = &pcie0_clk},
+	{.dev_id = "pcie1",		.clk = &pcie1_clk},
+	{.dev_id = "pcie2",		.clk = &pcie2_clk},
+	{.dev_id = "cfxd",		.clk = &cfxd_clk},
+	{.dev_id = "sd",		.clk = &sd_clk},
+	{.dev_id = "fsmc",		.clk = &fsmc_clk},
+	{.dev_id = "sysram0",		.clk = &sysram0_clk},
+	{.dev_id = "sysram1",		.clk = &sysram1_clk},
+
+	/* clock derived from apb clk */
+	{.dev_id = "i2s0",		.clk = &i2s0_clk},
+	{.dev_id = "i2s1",		.clk = &i2s1_clk},
+	{.dev_id = "adc",		.clk = &adc_clk},
+	{.dev_id = "ssp",		.clk = &ssp_clk},
+	{.dev_id = "gpio0",		.clk = &gpio0_clk},
+	{.dev_id = "gpio1",		.clk = &gpio1_clk},
+	{.dev_id = "kbd",		.clk = &kbd_clk},
+	{.dev_id = "wdt",		.clk = &wdt_clk},
 };
 
 void __init clk_init(void)
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index 2e87a07..c4dcab2 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -36,12 +36,16 @@
 /* PLL related registers and bit values */
 #define PLL_CFG			((unsigned int *)(MISC_BASE + 0x210))
 	/* PLL_CFG bit values */
-	#define OSC_24M_MASK	0
-	#define OSC_25M_MASK	1
-	#define PLL_CLK_MASK	3
-	#define PLL1_CLK_SHIFT	20
-	#define PLL2_CLK_SHIFT	22
-	#define PLL3_CLK_SHIFT	24
+	#define OSC_24M_VAL			0
+	#define OSC_25M_VAL			1
+	#define PLL_CLK_MASK			3
+	#define PLL1_CLK_SHIFT			20
+	#define PLL2_CLK_SHIFT			22
+	#define PLL3_CLK_SHIFT			24
+	#define CLCD_SYNT_PLL1_DIV4_VAL		0
+	#define CLCD_SYNT_PLL2_VAL		1
+	#define CLCD_SYNT_CLK_MASK		1
+	#define CLCD_SYNT_CLK_SHIFT		31
 
 #define PLL1_CTR		((unsigned int *)(MISC_BASE + 0x214))
 #define PLL1_FRQ		((unsigned int *)(MISC_BASE + 0x218))
@@ -77,30 +81,53 @@
 
 #define PERIP_CLK_CFG		((unsigned int *)(MISC_BASE + 0x244))
 	/* PERIP_CLK_CFG bit values */
-	#define GPT_OSC24_MASK	0
-	#define GPT_APB_MASK	1
-	#define GPT_CLK_MASK	1
-	#define GPT0_CLK_SHIFT	8
-	#define GPT1_CLK_SHIFT	9
-	#define GPT2_CLK_SHIFT	12
-	#define GPT3_CLK_SHIFT	13
-	#define AUX_CLK_PLL1_MASK	1
-	#define AUX_CLK_PLL5_MASK	0
+	#define GPT_OSC24_VAL		0
+	#define GPT_APB_VAL		1
+	#define GPT_CLK_MASK		1
+	#define GPT0_CLK_SHIFT		8
+	#define GPT1_CLK_SHIFT		9
+	#define GPT2_CLK_SHIFT		12
+	#define GPT3_CLK_SHIFT		13
+	#define AUX_CLK_PLL5_VAL	0
+	#define AUX_CLK_SYNT_VAL	1
 	#define UART_CLK_MASK		1
 	#define UART_CLK_SHIFT		4
+	#define CLCD_PLL5_VAL		0
+	#define CLCD_SYNT_MASK		1
+	#define CLCD_CLK_MASK		3
+	#define CLCD_CLK_SHIFT		2
+	#define C3_CLK_MASK		1
+	#define C3_CLK_SHIFT		1
 
 #define GMAC_CLK_CFG		((unsigned int *)(MISC_BASE + 0x248))
-#define C3_CLK_SYNTH		((unsigned int *)(MISC_BASE + 0x24c))
+
+	#define GMAC_PHY_PAD_VAL		0
+	#define GMAC_PHY_PLL2_VAL		1
+	#define GMAC_PHY_OSC3_VAL		2
+	#define GMAC_PHY_INPUT_CLK_MASK		3
+	#define GMAC_PHY_INPUT_CLK_SHIFT	1
+	#define GMAC_PHY_SYNT_ENB		3
+	#define GMAC_PHY_CLK_MASK		1
+	#define GMAC_PHY_CLK_SHIFT		3
+	#define GMAC_PHY_SYNT_ENB_VAL		4
+
+#define C3_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x24c))
 #define CLCD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x250))
+	/* CLCD synth reg masks */
+	#define CLCD_SYNT_ENB			31
+	#define CLCD_SYNT_DIV_FACTOR_MASK	0x1ffff
+	#define CLCD_SYNT_DIV_FACTOR_SHIFT	0
+
 #define UART_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x254))
 #define GMAC_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x258))
-#define MCIF_SD_CLK_SYNT	((unsigned int *)(MISC_BASE + 0x25c))
-#define MCIF_CFXD_CLK_SYNT	((unsigned int *)(MISC_BASE + 0x260))
+#define SD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x25c))
+#define CFXD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x260))
 #define RAS_CLK_SYNT0		((unsigned int *)(MISC_BASE + 0x264))
 #define RAS_CLK_SYNT1		((unsigned int *)(MISC_BASE + 0x268))
 #define RAS_CLK_SYNT2		((unsigned int *)(MISC_BASE + 0x26c))
 #define RAS_CLK_SYNT3		((unsigned int *)(MISC_BASE + 0x270))
 	/* aux clk synthesizer register masks */
+	#define AUX_SYNT_ENB		31
 	#define AUX_EQ_SEL_SHIFT	30
 	#define AUX_EQ_SEL_MASK		1
 	#define AUX_EQ1_SEL		0
@@ -114,32 +141,32 @@
 	/* PERIP1_CLK_ENB register masks */
 	#define BUS_CLK_ENB		0
 	#define SYSROM_CLK_ENB		1
-	#define AORAM_CLK_ENB		2
-	#define SYSRAM_CLK_ENB		3
+	#define SYSRAM1_CLK_ENB		2
+	#define SYSRAM0_CLK_ENB		3
 	#define FSMC_CLK_ENB		4
 	#define SMI_CLK_ENB		5
 	#define SD_CLK_ENB		6
-	#define CF_XD_CLK_ENB		7
-	#define GETH_CLK_ENB		8
+	#define CFXD_CLK_ENB		7
+	#define GMAC_CLK_ENB		8
 	#define UHC0_CLK_ENB		9
 	#define UHC1_CLK_ENB		10
-	#define UDC_UPD_CLK_ENB		11
-	#define PCI0_CLK_ENB		12
-	#define PCI1_CLK_ENB		13
-	#define PCI2_CLK_ENB		14
+	#define USBD_CLK_ENB		11
+	#define PCIE0_CLK_ENB		12
+	#define PCIE1_CLK_ENB		13
+	#define PCIE2_CLK_ENB		14
 	#define UART_CLK_ENB		15
 	#define SSP_CLK_ENB		17
 	#define I2C_CLK_ENB		18
-	#define I2S_SLV_CLK_ENB		19
-	#define I2S_MST_CLK_ENB		20
+	#define I2S0_CLK_ENB		19
+	#define I2S1_CLK_ENB		20
 	#define GPT0_CLK_ENB		21
 	#define GPT1_CLK_ENB		22
-	#define GPIOA_CLK_ENB		23
-	#define GPIOB_CLK_ENB		24
+	#define GPIO0_CLK_ENB		23
+	#define GPIO1_CLK_ENB		24
 	#define DMA0_CLK_ENB		25
 	#define DMA1_CLK_ENB		26
 	#define CLCD_CLK_ENB		27
-	#define JPEGC_CLK_ENB		28
+	#define JPEG_CLK_ENB		28
 	#define C3_CLK_ENB		29
 	#define ADC_CLK_ENB		30
 	#define RTC_CLK_ENB		31
@@ -214,11 +241,11 @@
 #define THSENS_CFG		((unsigned int *)(MISC_BASE + 0x6c4))
 
 /* Compensation Configuration Registers */
-#define COMP_1V8_2V5_3V3__1_CFG		((unsigned int *)(MISC_BASE + 0x700))
-#define COMP_1V8_2V5_3V3__2_CFG		((unsigned int *)(MISC_BASE + 0x704))
-#define COMP_3V3_1_CFG			((unsigned int *)(MISC_BASE + 0x708))
-#define COMP_3V3_2_CFG			((unsigned int *)(MISC_BASE + 0x70c))
-#define COMP_DDR_CFG			((unsigned int *)(MISC_BASE + 0x710))
+#define COMP_1V8_2V5_3V3__1_CFG	((unsigned int *)(MISC_BASE + 0x700))
+#define COMP_1V8_2V5_3V3__2_CFG	((unsigned int *)(MISC_BASE + 0x704))
+#define COMP_3V3_1_CFG		((unsigned int *)(MISC_BASE + 0x708))
+#define COMP_3V3_2_CFG		((unsigned int *)(MISC_BASE + 0x70c))
+#define COMP_DDR_CFG		((unsigned int *)(MISC_BASE + 0x710))
 
 /* OTP Programming Registers */
 #define OTP_PROG_CTR		((unsigned int *)(MISC_BASE + 0x800))
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 7ea8749..dc19666 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -123,22 +123,29 @@ static struct aux_clk_masks aux_masks = {
 	.yscale_sel_shift = AUX_YSCALE_SHIFT,
 };
 
-/* uart configurations */
-static struct aux_clk_config uart_config = {
+/* uart synth configurations */
+static struct aux_clk_config uart_synth_config = {
 	.synth_reg = UART_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
+/* uart synth clock */
+static struct clk uart_synth_clk = {
+	.en_reg = UART_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_synth_config,
+};
+
 /* uart parents */
 static struct pclk_info uart_pclk_info[] = {
 	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &uart_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
 	}, {
 		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
+		.pclk_val = AUX_CLK_PLL3_VAL,
 	},
 };
 
@@ -156,26 +163,32 @@ static struct clk uart_clk = {
 	.en_reg_bit = UART_CLK_ENB,
 	.pclk_sel = &uart_pclk_sel,
 	.pclk_sel_shift = UART_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &uart_config,
+	.recalc = &follow_parent,
 };
 
 /* firda configurations */
-static struct aux_clk_config firda_config = {
+static struct aux_clk_config firda_synth_config = {
 	.synth_reg = FIRDA_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
+/* firda synth clock */
+static struct clk firda_synth_clk = {
+	.en_reg = FIRDA_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &firda_synth_config,
+};
+
 /* firda parents */
 static struct pclk_info firda_pclk_info[] = {
 	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &firda_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
 	}, {
 		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
+		.pclk_val = AUX_CLK_PLL3_VAL,
 	},
 };
 
@@ -193,84 +206,138 @@ static struct clk firda_clk = {
 	.en_reg_bit = FIRDA_CLK_ENB,
 	.pclk_sel = &firda_pclk_sel,
 	.pclk_sel_shift = FIRDA_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &firda_config,
+	.recalc = &follow_parent,
+};
+
+/* gpt synthesizer masks */
+static struct gpt_clk_masks gpt_masks = {
+	.mscale_sel_mask = GPT_MSCALE_MASK,
+	.mscale_sel_shift = GPT_MSCALE_SHIFT,
+	.nscale_sel_mask = GPT_NSCALE_MASK,
+	.nscale_sel_shift = GPT_NSCALE_SHIFT,
+};
+
+/* gpt0 synth clk config*/
+static struct gpt_clk_config gpt0_synth_config = {
+	.synth_reg = PRSC1_CLK_CFG,
+	.masks = &gpt_masks,
+};
+
+/* gpt synth clock */
+static struct clk gpt0_synth_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt0_synth_config,
 };
 
 /* gpt parents */
-static struct pclk_info gpt_pclk_info[] = {
+static struct pclk_info gpt0_pclk_info[] = {
 	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &gpt0_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
 	}, {
 		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
+		.pclk_val = AUX_CLK_PLL3_VAL,
 	},
 };
 
 /* gpt parent select structure */
-static struct pclk_sel gpt_pclk_sel = {
-	.pclk_info = gpt_pclk_info,
-	.pclk_count = ARRAY_SIZE(gpt_pclk_info),
+static struct pclk_sel gpt0_pclk_sel = {
+	.pclk_info = gpt0_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt0_pclk_info),
 	.pclk_sel_reg = PERIP_CLK_CFG,
 	.pclk_sel_mask = GPT_CLK_MASK,
 };
 
-/* gpt synthesizer masks */
-static struct gpt_clk_masks gpt_masks = {
-	.mscale_sel_mask = GPT_MSCALE_MASK,
-	.mscale_sel_shift = GPT_MSCALE_SHIFT,
-	.nscale_sel_mask = GPT_NSCALE_MASK,
-	.nscale_sel_shift = GPT_NSCALE_SHIFT,
+/* gpt0 timer clock */
+static struct clk gpt0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt0_pclk_sel,
+	.pclk_sel_shift = GPT0_CLK_SHIFT,
+	.recalc = &follow_parent,
 };
 
-/* gpt0 configurations */
-static struct gpt_clk_config gpt0_config = {
-	.synth_reg = PRSC1_CLK_CFG,
+/* gpt1 synth clk configurations */
+static struct gpt_clk_config gpt1_synth_config = {
+	.synth_reg = PRSC2_CLK_CFG,
 	.masks = &gpt_masks,
 };
 
-/* gpt0 timer clock */
-static struct clk gpt0_clk = {
+/* gpt1 synth clock */
+static struct clk gpt1_synth_clk = {
 	.flags = ALWAYS_ENABLED,
-	.pclk_sel = &gpt_pclk_sel,
-	.pclk_sel_shift = GPT0_CLK_SHIFT,
+	.pclk = &pll1_clk,
 	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt0_config,
+	.private_data = &gpt1_synth_config,
 };
 
-/* gpt1 configurations */
-static struct gpt_clk_config gpt1_config = {
-	.synth_reg = PRSC2_CLK_CFG,
-	.masks = &gpt_masks,
+static struct pclk_info gpt1_pclk_info[] = {
+	{
+		.pclk = &gpt1_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt1_pclk_sel = {
+	.pclk_info = gpt1_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt1_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
 };
 
 /* gpt1 timer clock */
 static struct clk gpt1_clk = {
 	.en_reg = PERIP1_CLK_ENB,
 	.en_reg_bit = GPT1_CLK_ENB,
-	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel = &gpt1_pclk_sel,
 	.pclk_sel_shift = GPT1_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt1_config,
+	.recalc = &follow_parent,
 };
 
-/* gpt2 configurations */
-static struct gpt_clk_config gpt2_config = {
+/* gpt2 synth clk configurations */
+static struct gpt_clk_config gpt2_synth_config = {
 	.synth_reg = PRSC3_CLK_CFG,
 	.masks = &gpt_masks,
 };
 
+/* gpt1 synth clock */
+static struct clk gpt2_synth_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt2_synth_config,
+};
+
+static struct pclk_info gpt2_pclk_info[] = {
+	{
+		.pclk = &gpt2_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt2_pclk_sel = {
+	.pclk_info = gpt2_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt2_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
 /* gpt2 timer clock */
 static struct clk gpt2_clk = {
 	.en_reg = PERIP1_CLK_ENB,
 	.en_reg_bit = GPT2_CLK_ENB,
-	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel = &gpt2_pclk_sel,
 	.pclk_sel_shift = GPT2_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt2_config,
+	.recalc = &follow_parent,
 };
 
 /* clock derived from pll3 clk */
@@ -408,6 +475,11 @@ static struct clk_lookup spear_clk_lookups[] = {
 	/* clock derived from pll1 clk */
 	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
 	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
+	{ .con_id = "uart_synth_clk",	.clk = &uart_synth_clk},
+	{ .con_id = "firda_synth_clk",	.clk = &firda_synth_clk},
+	{ .con_id = "gpt0_synth_clk",	.clk = &gpt0_synth_clk},
+	{ .con_id = "gpt1_synth_clk",	.clk = &gpt1_synth_clk},
+	{ .con_id = "gpt2_synth_clk",	.clk = &gpt2_synth_clk},
 	{ .dev_id = "uart",		.clk = &uart_clk},
 	{ .dev_id = "firda",		.clk = &firda_clk},
 	{ .dev_id = "gpt0",		.clk = &gpt0_clk},
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
index 38d767a..6cb4f3c 100644
--- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
@@ -63,8 +63,8 @@
 #define GPT1_CLK_SHIFT		11
 #define GPT2_CLK_SHIFT		12
 #define GPT_CLK_MASK		0x1
-#define AUX_CLK_PLL3_MASK	0
-#define AUX_CLK_PLL1_MASK	1
+#define AUX_CLK_PLL3_VAL	0
+#define AUX_CLK_PLL1_VAL	1
 
 #define PERIP1_CLK_ENB		((unsigned int *)(MISC_BASE + 0x02C))
 /* PERIP1_CLK_ENB register masks */
@@ -113,6 +113,7 @@
 #define RAS3_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x074))
 #define RAS4_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x078))
 /* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_SYNT_ENB		31
 #define AUX_EQ_SEL_SHIFT	30
 #define AUX_EQ_SEL_MASK		1
 #define AUX_EQ1_SEL		0
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index ef88922..4a91991 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -111,27 +111,6 @@ static struct clk ahb_clk = {
 	.private_data = &ahb_config,
 };
 
-/* uart parents */
-static struct pclk_info uart_pclk_info[] = {
-	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
-	}, {
-		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
-	},
-};
-
-/* uart parent select structure */
-static struct pclk_sel uart_pclk_sel = {
-	.pclk_info = uart_pclk_info,
-	.pclk_count = ARRAY_SIZE(uart_pclk_info),
-	.pclk_sel_reg = PERIP_CLK_CFG,
-	.pclk_sel_mask = UART_CLK_MASK,
-};
-
 /* auxiliary synthesizers masks */
 static struct aux_clk_masks aux_masks = {
 	.eq_sel_mask = AUX_EQ_SEL_MASK,
@@ -145,19 +124,46 @@ static struct aux_clk_masks aux_masks = {
 };
 
 /* uart configurations */
-static struct aux_clk_config uart_config = {
+static struct aux_clk_config uart_synth_config = {
 	.synth_reg = UART_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
+/* uart synth clock */
+static struct clk uart_synth_clk = {
+	.en_reg = UART_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_synth_config,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+	{
+		.pclk = &uart_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+	.pclk_info = uart_pclk_info,
+	.pclk_count = ARRAY_SIZE(uart_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = UART_CLK_MASK,
+};
+
 /* uart0 clock */
 static struct clk uart0_clk = {
 	.en_reg = PERIP1_CLK_ENB,
 	.en_reg_bit = UART0_CLK_ENB,
 	.pclk_sel = &uart_pclk_sel,
 	.pclk_sel_shift = UART_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &uart_config,
+	.recalc = &follow_parent,
 };
 
 /* uart1 clock */
@@ -166,26 +172,32 @@ static struct clk uart1_clk = {
 	.en_reg_bit = UART1_CLK_ENB,
 	.pclk_sel = &uart_pclk_sel,
 	.pclk_sel_shift = UART_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &uart_config,
+	.recalc = &follow_parent,
 };
 
 /* firda configurations */
-static struct aux_clk_config firda_config = {
+static struct aux_clk_config firda_synth_config = {
 	.synth_reg = FIRDA_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
+/* firda synth clock */
+static struct clk firda_synth_clk = {
+	.en_reg = FIRDA_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &firda_synth_config,
+};
+
 /* firda parents */
 static struct pclk_info firda_pclk_info[] = {
 	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &firda_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
 	}, {
 		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
+		.pclk_val = AUX_CLK_PLL3_VAL,
 	},
 };
 
@@ -203,26 +215,32 @@ static struct clk firda_clk = {
 	.en_reg_bit = FIRDA_CLK_ENB,
 	.pclk_sel = &firda_pclk_sel,
 	.pclk_sel_shift = FIRDA_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &firda_config,
+	.recalc = &follow_parent,
 };
 
 /* clcd configurations */
-static struct aux_clk_config clcd_config = {
+static struct aux_clk_config clcd_synth_config = {
 	.synth_reg = CLCD_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
+/* firda synth clock */
+static struct clk clcd_synth_clk = {
+	.en_reg = CLCD_CLK_SYNT,
+	.en_reg_bit = AUX_SYNT_ENB,
+	.pclk = &pll1_clk,
+	.recalc = &aux_clk_recalc,
+	.private_data = &clcd_synth_config,
+};
+
 /* clcd parents */
 static struct pclk_info clcd_pclk_info[] = {
 	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
+		.pclk = &clcd_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
 	}, {
 		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
+		.pclk_val = AUX_CLK_PLL3_VAL,
 	},
 };
 
@@ -240,29 +258,7 @@ static struct clk clcd_clk = {
 	.en_reg_bit = CLCD_CLK_ENB,
 	.pclk_sel = &clcd_pclk_sel,
 	.pclk_sel_shift = CLCD_CLK_SHIFT,
-	.recalc = &aux_clk_recalc,
-	.private_data = &clcd_config,
-};
-
-/* gpt parents */
-static struct pclk_info gpt_pclk_info[] = {
-	{
-		.pclk = &pll1_clk,
-		.pclk_mask = AUX_CLK_PLL1_MASK,
-		.scalable = 1,
-	}, {
-		.pclk = &pll3_48m_clk,
-		.pclk_mask = AUX_CLK_PLL3_MASK,
-		.scalable = 0,
-	},
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt_pclk_sel = {
-	.pclk_info = gpt_pclk_info,
-	.pclk_count = ARRAY_SIZE(gpt_pclk_info),
-	.pclk_sel_reg = PERIP_CLK_CFG,
-	.pclk_sel_mask = GPT_CLK_MASK,
+	.recalc = &follow_parent,
 };
 
 /* gpt synthesizer masks */
@@ -273,60 +269,145 @@ static struct gpt_clk_masks gpt_masks = {
 	.nscale_sel_shift = GPT_NSCALE_SHIFT,
 };
 
-/* gpt0_1 configurations */
-static struct gpt_clk_config gpt0_1_config = {
+/* gpt0 synth clk config*/
+static struct gpt_clk_config gpt0_synth_config = {
 	.synth_reg = PRSC1_CLK_CFG,
 	.masks = &gpt_masks,
 };
 
+/* gpt synth clock */
+static struct clk gpt0_synth_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt0_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt0_pclk_info[] = {
+	{
+		.pclk = &gpt0_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt0_pclk_sel = {
+	.pclk_info = gpt0_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt0_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
 /* gpt0 ARM1 subsystem timer clock */
 static struct clk gpt0_clk = {
 	.flags = ALWAYS_ENABLED,
-	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel = &gpt0_pclk_sel,
 	.pclk_sel_shift = GPT0_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt0_1_config,
+	.recalc = &follow_parent,
+};
+
+
+/* Note: gpt0 and gpt1 share same parent clocks */
+/* gpt parent select structure */
+static struct pclk_sel gpt1_pclk_sel = {
+	.pclk_info = gpt0_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt0_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
 };
 
 /* gpt1 timer clock */
 static struct clk gpt1_clk = {
 	.flags = ALWAYS_ENABLED,
-	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel = &gpt1_pclk_sel,
 	.pclk_sel_shift = GPT1_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt0_1_config,
+	.recalc = &follow_parent,
 };
 
-/* gpt2 configurations */
-static struct gpt_clk_config gpt2_config = {
+/* gpt2 synth clk config*/
+static struct gpt_clk_config gpt2_synth_config = {
 	.synth_reg = PRSC2_CLK_CFG,
 	.masks = &gpt_masks,
 };
 
+/* gpt synth clock */
+static struct clk gpt2_synth_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt2_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt2_pclk_info[] = {
+	{
+		.pclk = &gpt2_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt2_pclk_sel = {
+	.pclk_info = gpt2_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt2_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
 /* gpt2 timer clock */
 static struct clk gpt2_clk = {
-	.en_reg = PERIP1_CLK_ENB,
-	.en_reg_bit = GPT2_CLK_ENB,
-	.pclk_sel = &gpt_pclk_sel,
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt2_pclk_sel,
 	.pclk_sel_shift = GPT2_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt2_config,
+	.recalc = &follow_parent,
 };
 
-/* gpt3 configurations */
-static struct gpt_clk_config gpt3_config = {
+/* gpt3 synth clk config*/
+static struct gpt_clk_config gpt3_synth_config = {
 	.synth_reg = PRSC3_CLK_CFG,
 	.masks = &gpt_masks,
 };
 
+/* gpt synth clock */
+static struct clk gpt3_synth_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt3_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt3_pclk_info[] = {
+	{
+		.pclk = &gpt3_synth_clk,
+		.pclk_val = AUX_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_val = AUX_CLK_PLL3_VAL,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt3_pclk_sel = {
+	.pclk_info = gpt3_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt3_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
 /* gpt3 timer clock */
 static struct clk gpt3_clk = {
-	.en_reg = PERIP1_CLK_ENB,
-	.en_reg_bit = GPT3_CLK_ENB,
-	.pclk_sel = &gpt_pclk_sel,
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt3_pclk_sel,
 	.pclk_sel_shift = GPT3_CLK_SHIFT,
-	.recalc = &gpt_clk_recalc,
-	.private_data = &gpt3_config,
+	.recalc = &follow_parent,
 };
 
 /* clock derived from pll3 clk */
@@ -496,6 +577,11 @@ static struct clk_lookup spear_clk_lookups[] = {
 	/* clock derived from pll1 clk */
 	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
 	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
+	{ .con_id = "uart_synth_clk",	.clk = &uart_synth_clk},
+	{ .con_id = "firda_synth_clk",	.clk = &firda_synth_clk},
+	{ .con_id = "gpt0_synth_clk",	.clk = &gpt0_synth_clk},
+	{ .con_id = "gpt2_synth_clk",	.clk = &gpt2_synth_clk},
+	{ .con_id = "gpt3_synth_clk",	.clk = &gpt3_synth_clk},
 	{ .dev_id = "uart0",		.clk = &uart0_clk},
 	{ .dev_id = "uart1",		.clk = &uart1_clk},
 	{ .dev_id = "firda",		.clk = &firda_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
index 0390803..bd71e72 100644
--- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
@@ -66,8 +66,8 @@
 #define GPT2_CLK_SHIFT		11
 #define GPT3_CLK_SHIFT		12
 #define GPT_CLK_MASK		0x1
-#define AUX_CLK_PLL3_MASK	0
-#define AUX_CLK_PLL1_MASK	1
+#define AUX_CLK_PLL3_VAL	0
+#define AUX_CLK_PLL1_VAL	1
 
 #define PERIP1_CLK_ENB		((unsigned int *)(MISC_BASE + 0x02C))
 /* PERIP1_CLK_ENB register masks */
@@ -123,6 +123,7 @@
 #define RAS3_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x074))
 #define RAS4_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x078))
 /* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_SYNT_ENB		31
 #define AUX_EQ_SEL_SHIFT	30
 #define AUX_EQ_SEL_MASK		1
 #define AUX_EQ1_SEL		0
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index ab29353..89a0434 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -67,14 +67,14 @@ static struct clkops generic_clkops = {
 /* returns current programmed clocks clock info structure */
 static struct pclk_info *pclk_info_get(struct clk *clk)
 {
-	unsigned int mask, i;
+	unsigned int val, i;
 	struct pclk_info *info = NULL;
 
-	mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
+	val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
 		& clk->pclk_sel->pclk_sel_mask;
 
 	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
-		if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
+		if (clk->pclk_sel->pclk_info[i].pclk_val == val)
 			info = &clk->pclk_sel->pclk_info[i];
 	}
 
@@ -94,7 +94,6 @@ static void update_clk_tree(struct clk *clk, struct pclk_info *pclk_info)
 	list_add(&clk->sibling, &pclk_info->pclk->children);
 
 	clk->pclk = pclk_info->pclk;
-	clk->pclk_info = pclk_info;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
@@ -210,7 +209,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	/* reflect parent change in hardware */
 	val = readl(clk->pclk_sel->pclk_sel_reg);
 	val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
-	val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift;
+	val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
 	writel(val, clk->pclk_sel->pclk_sel_reg);
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
@@ -219,7 +218,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 
 	clk->recalc(clk);
 	propagate_rate(&clk->children);
-
 	return 0;
 }
 EXPORT_SYMBOL(clk_set_parent);
@@ -272,7 +270,6 @@ void clk_register(struct clk_lookup *cl)
 					cl->dev_id, cl->con_id);
 		} else {
 			clk->pclk = pclk_info->pclk;
-			clk->pclk_info = pclk_info;
 			list_add(&clk->sibling, &pclk_info->pclk->children);
 		}
 	}
@@ -315,53 +312,28 @@ void pll_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-
-	/*
-	 * read divisor from hardware, only in two cases:
-	 * - There is only parent to clk and it requires *_clk_recalc
-	 * - There are two parents of a clock and current pclk requires
-	 *   *_clk_recalc
-	 */
-	if (!clk->pclk_info || clk->pclk_info->scalable) {
-		mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
-			config->masks->mode_mask;
-
-		val = readl(config->cfg_reg);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-
-		/* calculate denominator */
-		den = (val >> config->masks->div_p_shift) &
-			config->masks->div_p_mask;
-		den = 1 << den;
-		den *= (val >> config->masks->div_n_shift) &
-			config->masks->div_n_mask;
-
-		/* calculate numerator & denominator */
-		if (!mode) {
-			/* Normal mode */
-			num *= (val >> config->masks->norm_fdbk_m_shift) &
-				config->masks->norm_fdbk_m_mask;
-		} else {
-			/* Dithered mode */
-			num *= (val >> config->masks->dith_fdbk_m_shift) &
-				config->masks->dith_fdbk_m_mask;
-			den *= 256;
-		}
-
-		spin_lock_irqsave(&clocks_lock, flags);
-		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
+		config->masks->mode_mask;
+
+	val = readl(config->cfg_reg);
+	/* calculate denominator */
+	den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
+	den = 1 << den;
+	den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
+
+	/* calculate numerator & denominator */
+	if (!mode) {
+		/* Normal mode */
+		num *= (val >> config->masks->norm_fdbk_m_shift) &
+			config->masks->norm_fdbk_m_mask;
 	} else {
-		int div = 0;
-		/*
-		 * only if there are two parents and current parent requires
-		 * simple division
-		 */
-		div = (clk->pclk_info->div_factor < 1) ? 1 :
-			clk->pclk_info->div_factor;
-		val = clk->pclk->rate/div;
+		/* Dithered mode */
+		num *= (val >> config->masks->dith_fdbk_m_shift) &
+			config->masks->dith_fdbk_m_mask;
+		den *= 256;
 	}
 
-	clk->rate = val;
+	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
@@ -373,23 +345,8 @@ void bus_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	/*
-	 * read divisor from hardware, only in two cases:
-	 * - There is only parent to clk and it requires *_clk_recalc
-	 * - There are two parents of a clock and current pclk requires
-	 *   *_clk_recalc
-	 */
-	if (!clk->pclk_info || clk->pclk_info->scalable) {
-		div = ((readl(config->reg) >> config->masks->shift) &
-				config->masks->mask) + 1;
-	} else {
-		/*
-		 * only if there are two parents and current parent requires
-		 * simple division
-		 */
-		div = (clk->pclk_info->div_factor < 1) ? 1 :
-			clk->pclk_info->div_factor;
-	}
+	div = ((readl(config->reg) >> config->masks->shift) &
+			config->masks->mask) + 1;
 	clk->rate = (unsigned long)clk->pclk->rate / div;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
@@ -411,41 +368,21 @@ void aux_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	/*
-	 * read divisor from hardware, only in two cases:
-	 * - There is only parent to clk and it requires *_clk_recalc
-	 * - There are two parents of a clock and current pclk requires
-	 *   *_clk_recalc
-	 */
-	if (!clk->pclk_info || clk->pclk_info->scalable) {
-		val = readl(config->synth_reg);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-
-		eqn = (val >> config->masks->eq_sel_shift) &
-			config->masks->eq_sel_mask;
-		if (eqn == config->masks->eq1_mask)
-			den *= 2;
-
-		/* calculate numerator */
-		num = (val >> config->masks->xscale_sel_shift) &
-			config->masks->xscale_sel_mask;
-
-		/* calculate denominator */
-		den *= (val >> config->masks->yscale_sel_shift) &
-			config->masks->yscale_sel_mask;
-
-		spin_lock_irqsave(&clocks_lock, flags);
-		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
-	} else {
-		/*
-		 * only if there are two parents and current parent requires
-		 * simple division
-		 */
-		int div_factor = (clk->pclk_info->div_factor < 1) ? 1 :
-			clk->pclk_info->div_factor;
-
-		val = clk->pclk->rate/div_factor;
-	}
+	val = readl(config->synth_reg);
+
+	eqn = (val >> config->masks->eq_sel_shift) &
+		config->masks->eq_sel_mask;
+	if (eqn == config->masks->eq1_mask)
+		den *= 2;
+
+	/* calculate numerator */
+	num = (val >> config->masks->xscale_sel_shift) &
+		config->masks->xscale_sel_mask;
+
+	/* calculate denominator */
+	den *= (val >> config->masks->yscale_sel_shift) &
+		config->masks->yscale_sel_mask;
+	val = (((clk->pclk->rate/10000) * num) / den) * 10000;
 
 	clk->rate = val;
 	spin_unlock_irqrestore(&clocks_lock, flags);
@@ -463,50 +400,55 @@ void gpt_clk_recalc(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	/*
-	 * read divisor from hardware, only in two cases:
-	 * - There is only parent to clk and it requires *_clk_recalc
-	 * - There are two parents of a clock and current pclk requires
-	 *   *_clk_recalc
-	 */
-	if (!clk->pclk_info || clk->pclk_info->scalable) {
-		val = readl(config->synth_reg);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-
-		div += (val >> config->masks->mscale_sel_shift) &
-			config->masks->mscale_sel_mask;
-		div *= 1 << (((val >> config->masks->nscale_sel_shift) &
-					config->masks->nscale_sel_mask) + 1);
-		spin_lock_irqsave(&clocks_lock, flags);
-	} else {
-		/*
-		 * only if there are two parents and current parent requires
-		 * simple division
-		 */
-		div = (clk->pclk_info->div_factor < 1) ? 1 :
-			clk->pclk_info->div_factor;
-	}
+	val = readl(config->synth_reg);
+	div += (val >> config->masks->mscale_sel_shift) &
+		config->masks->mscale_sel_mask;
+	div *= 1 << (((val >> config->masks->nscale_sel_shift) &
+				config->masks->nscale_sel_mask) + 1);
 
 	clk->rate = (unsigned long)clk->pclk->rate / div;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /*
+ * calculates current programmed rate of clcd synthesizer
+ * Fout from synthesizer can be given from below equation:
+ * Fout= Fin/2*div (division factor)
+ * div is 17 bits:-
+ *	0-13 (fractional part)
+ *	14-16 (integer part)
+ * To calculate Fout we left shift val by 14 bits and divide Fin by
+ * complete div (including fractional part) and then right shift the
+ * result by 14 places.
+ */
+void clcd_clk_recalc(struct clk *clk)
+{
+	struct clcd_clk_config *config = clk->private_data;
+	unsigned int div = 1;
+	unsigned long flags, prate;
+	unsigned int val;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	val = readl(config->synth_reg);
+	div = (val >> config->masks->div_factor_shift) &
+		config->masks->div_factor_mask;
+
+	prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
+	clk->rate = ((unsigned long)prate << 14 / 2 * div) >> 14;
+	clk->rate *= 1000;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
  * Used for clocks that always have value as the parent clock divided by a
  * fixed divisor
  */
 void follow_parent(struct clk *clk)
 {
 	unsigned long flags;
-	unsigned int div_factor;
+	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
 
 	spin_lock_irqsave(&clocks_lock, flags);
-	if (clk->pclk_info)
-		div_factor = clk->pclk_info->div_factor;
-	else
-		div_factor = clk->div_factor;
-	div_factor = (div_factor < 1) ? 1 : div_factor;
-
 	clk->rate = clk->pclk->rate/div_factor;
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index d8d0856..019d308 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -35,15 +35,11 @@ struct clkops {
 /**
  * struct pclk_info - parents info
  * @pclk: pointer to parent clk
- * @pclk_mask: value to be written for selecting this parent
- * @scalable: Is parent scalable (1 - YES, 0 - NO)
- * @div_factor: div factor for pclk
+ * @pclk_val: value to be written for selecting this parent
  */
 struct pclk_info {
 	struct clk *pclk;
-	u8 pclk_mask;
-	u8 scalable;
-	u8 div_factor;
+	u8 pclk_val;
 };
 
 /**
@@ -69,9 +65,8 @@ struct pclk_sel {
  * @en_reg_bit: clk enable/disable bit
  * @ops: clk enable/disable ops - generic_clkops selected if NULL
  * @recalc: pointer to clock rate recalculate function
- * @div_factor: division factor to parent clock. Only for clks with one parent
+ * @div_factor: division factor to parent clock.
  * @pclk: current parent clk
- * @pclk_info: current parent clk's pclk_info
  * @pclk_sel: pointer to parent selection structure
  * @pclk_sel_shift: register shift for selecting parent of this clock
  * @children: list for childrens or this clock
@@ -89,7 +84,6 @@ struct clk {
 	unsigned int div_factor;
 
 	struct clk *pclk;
-	struct pclk_info *pclk_info;
 	struct pclk_sel *pclk_sel;
 	unsigned int pclk_sel_shift;
 
@@ -160,6 +154,17 @@ struct gpt_clk_config {
 	struct gpt_clk_masks *masks;
 };
 
+/* clcd clk configuration structure */
+struct clcd_synth_masks {
+	u32 div_factor_mask;
+	u32 div_factor_shift;
+};
+
+struct clcd_clk_config {
+	u32 *synth_reg;
+	struct clcd_synth_masks *masks;
+};
+
 /* platform specific clock functions */
 void clk_register(struct clk_lookup *cl);
 void recalc_root_clocks(void);
@@ -170,5 +175,6 @@ void pll_clk_recalc(struct clk *clk);
 void bus_clk_recalc(struct clk *clk);
 void gpt_clk_recalc(struct clk *clk);
 void aux_clk_recalc(struct clk *clk);
+void clcd_clk_recalc(struct clk *clk);
 
 #endif /* __PLAT_CLOCK_H */
-- 
1.7.2.2

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

* [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (12 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 13/74] ST SPEAr: Update clock framework and definitions Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  9:13   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware Viresh KUMAR
                   ` (60 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 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.

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    |  141 ++++++++
 arch/arm/mach-spear3xx/include/mach/irqs.h    |    9 +-
 arch/arm/mach-spear3xx/spear310.c             |   69 ++++
 arch/arm/mach-spear3xx/spear310_evb.c         |    1 +
 arch/arm/mach-spear3xx/spear320.c             |   30 ++-
 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                  |  453 +++++++++++++++++++++++++
 11 files changed, 765 insertions(+), 5 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 1c8f9f1..d76ee98 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -144,6 +144,7 @@ extern struct clcd_board clcd_plat_data;
 /* spear310 declarations */
 #ifdef CONFIG_MACH_SPEAR310
 /* Add spear310 machine device structure declarations here */
+extern struct platform_device plgpio_device;
 
 /* pad mux devices */
 extern struct pmx_dev pmx_emi_cs_0_1_4_5;
@@ -164,6 +165,7 @@ void __init spear310_init(void);
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
+extern struct platform_device plgpio_device;
 
 /* pad mux modes */
 extern struct pmx_mode 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..e531f6d 100644
--- a/arch/arm/mach-spear3xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -16,4 +16,145 @@
 
 #include <plat/gpio.h>
 
+#ifdef CONFIG_MACH_SPEAR310
+#define PLGPIO_ENB		0x0010
+#define PLGPIO_WDATA		0x0020
+#define PLGPIO_DIR		0x0030
+#define PLGPIO_IE		0x0040
+#define PLGPIO_RDATA		0x0050
+#define PLGPIO_MIS		0x0060
+
+#elif defined(CONFIG_MACH_SPEAR320)
+#define PLGPIO_ENB		0x0024
+#define PLGPIO_WDATA		0x0034
+#define PLGPIO_DIR		0x0044
+#define PLGPIO_RDATA		0x0054
+#define PLGPIO_IE		0x0064
+#define PLGPIO_MIS		0x0074
+#endif
+
+#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
+
+#elif 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/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index 7f940b8..f1175b9 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -141,12 +141,13 @@
 #endif
 
 /* PLGPIO Virtual IRQs */
+#define SPEAR_PLGPIO_COUNT	102
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-#define SPEAR_PLGPIO_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END			(SPEAR_PLGPIO_INT_BASE + 102)
+#define SPEAR_PLGPIO_INT_BASE	(SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END	(SPEAR_PLGPIO_INT_BASE + SPEAR_PLGPIO_COUNT)
 #endif
 
-#define VIRQ_END				SPEAR_GPIO_INT_END
-#define NR_IRQS					VIRQ_END
+#define VIRQ_END		SPEAR_GPIO_INT_END
+#define NR_IRQS			VIRQ_END
 
 #endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 576bc57..88b55b5 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -15,6 +15,7 @@
 #include <asm/irq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/gpio.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -140,6 +141,74 @@ struct pmx_driver pmx_driver = {
 };
 
 /* 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 = SPEAR_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR_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 = VIRQ_PLGPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device plgpio_device = {
+	.name = "plgpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &plgpio_plat_data,
+	},
+	.num_resources = ARRAY_SIZE(plgpio_resources),
+	.resource = plgpio_resources,
+};
+
 
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 3855431..7dd93bd 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 */
+	&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 e5baa00..2e388dd 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -15,6 +15,7 @@
 #include <asm/irq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/gpio.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -385,7 +386,6 @@ struct pmx_driver pmx_driver = {
 };
 
 /* Add spear320 specific devices here */
-
 /* CLCD device registration */
 struct amba_device clcd_device = {
 	.dev = {
@@ -402,6 +402,34 @@ struct amba_device clcd_device = {
 	.irq = {VIRQ_CLCD, NO_IRQ},
 };
 
+/* plgpio device registeration */
+static struct plgpio_platform_data plgpio_plat_data = {
+	.gpio_base = 8,
+	.irq_base = SPEAR_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR_PLGPIO_COUNT,
+};
+
+static struct resource plgpio_resources[] = {
+	{
+		.start = SPEAR320_SOC_CONFIG_BASE,
+		.end = SPEAR320_SOC_CONFIG_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = VIRQ_PLGPIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device plgpio_device = {
+	.name = "plgpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &plgpio_plat_data,
+	},
+	.num_resources = ARRAY_SIZE(plgpio_resources),
+	.resource = plgpio_resources,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 821e806..82f4e76 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 = {
 	/* spear3xx specific devices */
 
 	/* spear320 specific devices */
+	&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 01a4a91..e66bc5f 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -6,3 +6,5 @@
 obj-y	:= clcd.o clock.o time.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..847ff9c
--- /dev/null
+++ b/arch/arm/plat-spear/plgpio.c
@@ -0,0 +1,453 @@
+/*
+ * 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 <mach/gpio.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 *))
+
+/*
+ * 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)
+{
+	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] 245+ messages in thread

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (13 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-06 23:12   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:38 ` [PATCH 18/74] ST SPEAr: enhanced spear clock framework Viresh KUMAR
                   ` (59 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    2 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    4 +++
 arch/arm/mach-spear13xx/spear13xx.c            |   23 +++++++++++++++++++
 arch/arm/mach-spear3xx/clock.c                 |   14 ++++++++++-
 arch/arm/mach-spear3xx/include/mach/generic.h  |    3 ++
 arch/arm/mach-spear3xx/include/mach/irqs.h     |    2 +-
 arch/arm/mach-spear3xx/spear300_evb.c          |    4 +++
 arch/arm/mach-spear3xx/spear310_evb.c          |    4 +++
 arch/arm/mach-spear3xx/spear320.c              |   24 +++++++++++++++++++-
 arch/arm/mach-spear3xx/spear320_evb.c          |    5 ++++
 arch/arm/mach-spear3xx/spear3xx.c              |   22 ++++++++++++++++++
 arch/arm/mach-spear6xx/clock.c                 |    2 +-
 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                   |    6 +++++
 arch/arm/plat-spear/i2c_eval_board.c           |   29 ++++++++++++++++++++++++
 18 files changed, 169 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/plat-spear/i2c_eval_board.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index cc692cc..7f7330c 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -777,7 +777,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "uhci0",		.clk = &uhci0_clk},
 	{.dev_id = "uhci1",		.clk = &uhci1_clk},
 	{.dev_id = "usbd",		.clk = &usbd_clk},
-	{.dev_id = "i2c",		.clk = &i2c_clk},
+	{.dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{.dev_id = "dma0",		.clk = &dma0_clk},
 	{.dev_id = "dma1",		.clk = &dma1_clk},
 	{.dev_id = "jpeg",		.clk = &jpeg_clk},
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index dc80421..0ba99de 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -30,6 +30,7 @@
 
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device uart_device;
+extern struct platform_device i2c_device;
 extern struct platform_device rtc_device;
 extern struct sys_timer spear13xx_timer;
 
@@ -37,6 +38,7 @@ extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
 void __init clk_init(void);
+void __init i2c_register_board_devices(void);
 void __init spear_setup_timer(void);
 void __init spear1300_init(void);
 void __init spear13xx_map_io(void);
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 60c5fee..4bf908f 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -22,6 +22,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&i2c_device,
 	&rtc_device,
 };
 
@@ -32,6 +33,9 @@ static void __init spear1300_evb_init(void)
 	/* call spear1300 machine init function */
 	spear1300_init();
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_board_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 bdca713..5abdae8 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -24,6 +24,7 @@
 #include <mach/hardware.h>
 
 /* Add spear13xx machines common devices here */
+
 /* uart device registeration */
 struct amba_device uart_device = {
 	.dev = {
@@ -37,6 +38,28 @@ struct amba_device 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 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/clock.c b/arch/arm/mach-spear3xx/clock.c
index 147d0a3..ae6c244 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -460,6 +460,15 @@ static struct clk gpio_clk = {
 
 static struct clk dummy_apb_pclk;
 
+#ifdef CONFIG_MACH_SPEAR320
+/* i2c1 clock */
+static struct clk i2c1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
@@ -491,7 +500,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "clcd",		.clk = &clcd_clk},
 	/* clock derived from ahb clk */
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
-	{ .dev_id = "i2c",		.clk = &i2c_clk},
+	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{ .dev_id = "dma",		.clk = &dma_clk},
 	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
 	{ .dev_id = "gmac",		.clk = &gmac_clk},
@@ -501,6 +510,9 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#ifdef CONFIG_MACH_SPEAR320
+	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
+#endif
 };
 
 void __init clk_init(void)
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 408bb8d..162f33b 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -33,11 +33,13 @@
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device gpio_device;
 extern struct amba_device uart_device;
+extern struct platform_device i2c_device;
 extern struct platform_device rtc_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
 void __init clk_init(void);
+void __init i2c_register_board_devices(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
 void __init spear3xx_init_irq(void);
@@ -166,6 +168,7 @@ void __init spear310_init(void);
 #ifdef CONFIG_MACH_SPEAR320
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
+extern struct platform_device i2c1_device;
 extern struct platform_device plgpio_device;
 
 /* pad mux modes */
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index f1175b9..5ad7574 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -133,7 +133,7 @@
 #define VIRQ_MII1_SMII1				(VIRQ_START + 13)
 #define VIRQ_WAKEUP_SMII0			(VIRQ_START + 14)
 #define VIRQ_WAKEUP_MII1_SMII1			(VIRQ_START + 15)
-#define VIRQ_I2C				(VIRQ_START + 16)
+#define VIRQ_I2C1				(VIRQ_START + 16)
 
 /* GPIO pins virtual irqs */
 #define SPEAR_GPIO_INT_BASE			(VIRQ_START + 17)
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 392ee4a..083f65c 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 */
+	&i2c_device,
 	&rtc_device,
 
 	/* spear300 specific devices */
@@ -61,6 +62,9 @@ static void __init spear300_evb_init(void)
 	/* call spear300 machine init function */
 	spear300_init();
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_board_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 15ca8fc..208a68ce1 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -50,6 +50,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&i2c_device,
 	&rtc_device,
 
 	/* spear310 specific devices */
@@ -68,6 +69,9 @@ static void __init spear310_evb_init(void)
 	/* call spear310 machine init function */
 	spear310_init();
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_board_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 2e388dd..bfb21ae 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -409,6 +409,28 @@ static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_count = SPEAR_PLGPIO_COUNT,
 };
 
+/* i2c1 device registeration */
+static struct resource i2c1_resources[] = {
+	{
+		.start = SPEAR320_I2C_BASE,
+		.end = SPEAR320_I2C_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = VIRQ_I2C1 ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device i2c1_device = {
+	.name = "i2c_designware",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.num_resources = ARRAY_SIZE(i2c1_resources),
+	.resource = i2c1_resources,
+};
+
 static struct resource plgpio_resources[] = {
 	{
 		.start = SPEAR320_SOC_CONFIG_BASE,
@@ -535,7 +557,7 @@ struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 		.status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
 		.clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2C,
+		.virq = VIRQ_I2C1,
 		.status_mask = I2C1_IRQ_MASK,
 		.clear_mask = I2C1_IRQ_MASK,
 	},
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 48155cc..90d685e 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -48,9 +48,11 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&i2c_device,
 	&rtc_device,
 
 	/* spear320 specific devices */
+	&i2c1_device,
 	&plgpio_device,
 };
 
@@ -66,6 +68,9 @@ static void __init spear320_evb_init(void)
 	/* call spear320 machine init function */
 	spear320_init();
 
+	/* Register slave devices on the I2C buses */
+	i2c_register_board_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 6d8791e..34d22a5 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -54,6 +54,28 @@ struct amba_device uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+/* 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 = 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/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 66fc622..0972b8f 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -596,7 +596,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
 	/* clock derived from ahb clk */
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
-	{ .dev_id = "i2c",		.clk = &i2c_clk},
+	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{ .dev_id = "dma",		.clk = &dma_clk},
 	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
 	{ .dev_id = "gmac",		.clk = &gmac_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 674b16c..44a2f99 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 clcd_device;
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_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_board_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 861e83d..6b0cf23 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_board_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 1e403cb..787de46 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -121,6 +121,28 @@ struct amba_device gpio_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 e66bc5f..c31892a 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -8,3 +8,9 @@ obj-y	:= clcd.o clock.o time.o
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
 obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
+
+obj-$(CONFIG_BOARD_SPEAR1300_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..a2473a8
--- /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_board_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] 245+ messages in thread

* [PATCH 18/74] ST SPEAr: enhanced spear clock framework
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (14 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 19/74] ST SPEAr: Adding Debugfs support on " Viresh KUMAR
                   ` (58 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Added support for
- recursive enabling of parent clock
- recursive disabling of parent clock
- recalc called only when clk is enabled in h/w

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/clock.c |  199 +++++++++++++++++++++++++++++--------------
 1 files changed, 136 insertions(+), 63 deletions(-)

diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index 89a0434..b4d8110 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/bug.h>
+#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/list.h>
@@ -22,7 +23,24 @@
 static DEFINE_SPINLOCK(clocks_lock);
 static LIST_HEAD(root_clks);
 
-static void propagate_rate(struct list_head *);
+static void propagate_rate(struct clk *);
+
+static int clk_is_enabled(struct clk *clk)
+{
+	unsigned int val;
+
+	if (clk->flags & ALWAYS_ENABLED)
+		return 1;
+
+	BUG_ON(!clk->en_reg);
+	val = readl(clk->en_reg);
+	val = val & (1 << clk->en_reg_bit);
+
+	if (unlikely(clk->flags & RESET_TO_ENABLE))
+		return !val;
+	else
+		return !!val;
+}
 
 static int generic_clk_enable(struct clk *clk)
 {
@@ -85,7 +103,7 @@ static struct pclk_info *pclk_info_get(struct clk *clk)
  * Set Update pclk, and pclk_info of clk and add clock sibling node to current
  * parents children list
  */
-static void update_clk_tree(struct clk *clk, struct pclk_info *pclk_info)
+static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
 {
 	unsigned long flags;
 
@@ -97,6 +115,64 @@ static void update_clk_tree(struct clk *clk, struct pclk_info *pclk_info)
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
+void do_clk_disable(struct clk *clk)
+{
+	if (!clk)
+		return;
+
+	if (!clk->usage_count) {
+		WARN_ON(1);
+		return;
+	}
+
+	clk->usage_count--;
+
+	if (clk->usage_count == 0) {
+		/*
+		 * Surely, there are no active childrens or direct users
+		 * of this clock
+		 */
+		if (clk->pclk)
+			do_clk_disable(clk->pclk);
+
+		if (clk->ops && clk->ops->disable)
+			clk->ops->disable(clk);
+	}
+}
+
+int do_clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (!clk)
+		return -EFAULT;
+
+	if (clk->usage_count == 0) {
+		if (clk->pclk) {
+			ret = do_clk_enable(clk->pclk);
+			if (ret)
+				goto err;
+		}
+		if (clk->ops && clk->ops->enable) {
+			ret = clk->ops->enable(clk);
+			if (ret) {
+				if (clk->pclk)
+					do_clk_disable(clk->pclk);
+				goto err;
+			}
+		}
+		/*
+		 * Since the clock is going to be used for the first
+		 * time please reclac
+		 */
+		if (clk->recalc)
+			clk->recalc(clk);
+	}
+	clk->usage_count++;
+err:
+	return ret;
+}
+
 /*
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
@@ -110,17 +186,9 @@ int clk_enable(struct clk *clk)
 	unsigned long flags;
 	int ret = 0;
 
-	if (!clk || IS_ERR(clk))
-		return -EFAULT;
-
 	spin_lock_irqsave(&clocks_lock, flags);
-	if (clk->usage_count == 0) {
-		if (clk->ops && clk->ops->enable)
-			ret = clk->ops->enable(clk);
-	}
-	clk->usage_count++;
+	ret = do_clk_enable(clk);
 	spin_unlock_irqrestore(&clocks_lock, flags);
-
 	return ret;
 }
 EXPORT_SYMBOL(clk_enable);
@@ -141,17 +209,8 @@ void clk_disable(struct clk *clk)
 {
 	unsigned long flags;
 
-	if (!clk || IS_ERR(clk))
-		return;
-
-	WARN_ON(clk->usage_count == 0);
-
 	spin_lock_irqsave(&clocks_lock, flags);
-	clk->usage_count--;
-	if (clk->usage_count == 0) {
-		if (clk->ops && clk->ops->disable)
-			clk->ops->disable(clk);
-	}
+	do_clk_disable(clk);
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
@@ -178,21 +237,22 @@ EXPORT_SYMBOL(clk_get_rate);
  * @clk: clock source
  * @parent: parent clock source
  *
- * Returns success (0) or negative errno.
+ * Returns success (0) or negative errno. clk usage_count must be zero
+ * before calling this function.
  */
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
 	int i, found = 0, val = 0;
 	unsigned long flags;
 
-	if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent))
+	if (!clk || !parent)
 		return -EFAULT;
 	if (clk->usage_count)
-		return -EBUSY;
-	if (!clk->pclk_sel)
 		return -EPERM;
 	if (clk->pclk == parent)
 		return 0;
+	if (!clk->pclk_sel)
+		return -EPERM;
 
 	/* check if requested parent is in clk parent list */
 	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
@@ -214,10 +274,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
 	/* reflect parent change in software */
-	update_clk_tree(clk, &clk->pclk_sel->pclk_info[i]);
+	clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
 
-	clk->recalc(clk);
-	propagate_rate(&clk->children);
 	return 0;
 }
 EXPORT_SYMBOL(clk_set_parent);
@@ -239,11 +297,12 @@ EXPORT_SYMBOL(clk_set_rate);
 /* registers clock in platform clock framework */
 void clk_register(struct clk_lookup *cl)
 {
-	struct clk *clk = cl->clk;
+	struct clk *clk;
 	unsigned long flags;
 
-	if (!clk || IS_ERR(clk))
+	if (!cl || !cl->clk)
 		return;
+	clk = cl->clk;
 
 	spin_lock_irqsave(&clocks_lock, flags);
 
@@ -265,7 +324,7 @@ void clk_register(struct clk_lookup *cl)
 
 		pclk_info = pclk_info_get(clk);
 		if (!pclk_info) {
-			printk(KERN_ERR "CLKDEV: invalid pclk info of clk with"
+			pr_err("CLKDEV: invalid pclk info of clk with"
 					" %s dev_id and %s con_id\n",
 					cl->dev_id, cl->con_id);
 		} else {
@@ -273,6 +332,7 @@ void clk_register(struct clk_lookup *cl)
 			list_add(&clk->sibling, &pclk_info->pclk->children);
 		}
 	}
+
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
 	/* add clock to arm clockdev framework */
@@ -280,22 +340,26 @@ void clk_register(struct clk_lookup *cl)
 }
 
 /**
- * propagate_rate - recalculate and propagate all clocks in list head
+ * propagate_rate - recalculate and propagate all clocks to children
  *
- * Recalculates all root clocks in list head, which if the clock's .recalc is
- * set correctly, should also propagate their rates.
+ * Recalculates all children clocks
  */
-static void propagate_rate(struct list_head *lhead)
+void propagate_rate(struct clk *pclk)
 {
-	struct clk *clkp, *_temp;
-
-	list_for_each_entry_safe(clkp, _temp, lhead, sibling) {
-		if (clkp->recalc)
-			clkp->recalc(clkp);
-		propagate_rate(&clkp->children);
+	struct clk *clk, *_temp;
+
+	list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
+		/* recalc and propogate only if clk is enabled */
+		if (clk_is_enabled(clk)) {
+			if (clk->recalc)
+				clk->recalc(clk);
+			propagate_rate(clk);
+		}
 	}
 }
 
+/*All recalc functions are called with lock held */
+
 /*
  * calculates current programmed rate of pll1
  *
@@ -309,9 +373,7 @@ void pll_clk_recalc(struct clk *clk)
 {
 	struct pll_clk_config *config = clk->private_data;
 	unsigned int num = 2, den = 0, val, mode = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
 		config->masks->mode_mask;
 
@@ -333,8 +395,9 @@ void pll_clk_recalc(struct clk *clk)
 		den *= 256;
 	}
 
+	BUG_ON(!den);
+
 	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
-	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /* calculates current programmed rate of ahb or apb bus */
@@ -342,13 +405,13 @@ void bus_clk_recalc(struct clk *clk)
 {
 	struct bus_clk_config *config = clk->private_data;
 	unsigned int div;
-	unsigned long flags;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	div = ((readl(config->reg) >> config->masks->shift) &
 			config->masks->mask) + 1;
+
+	BUG_ON(!div);
+
 	clk->rate = (unsigned long)clk->pclk->rate / div;
-	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /*
@@ -365,9 +428,7 @@ void aux_clk_recalc(struct clk *clk)
 {
 	struct aux_clk_config *config = clk->private_data;
 	unsigned int num = 1, den = 1, val, eqn;
-	unsigned long flags;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	val = readl(config->synth_reg);
 
 	eqn = (val >> config->masks->eq_sel_shift) &
@@ -382,10 +443,10 @@ void aux_clk_recalc(struct clk *clk)
 	/* calculate denominator */
 	den *= (val >> config->masks->yscale_sel_shift) &
 		config->masks->yscale_sel_mask;
-	val = (((clk->pclk->rate/10000) * num) / den) * 10000;
 
-	clk->rate = val;
-	spin_unlock_irqrestore(&clocks_lock, flags);
+	BUG_ON(!den);
+
+	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
 }
 
 /*
@@ -397,17 +458,16 @@ void gpt_clk_recalc(struct clk *clk)
 {
 	struct gpt_clk_config *config = clk->private_data;
 	unsigned int div = 1, val;
-	unsigned long flags;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	val = readl(config->synth_reg);
 	div += (val >> config->masks->mscale_sel_shift) &
 		config->masks->mscale_sel_mask;
 	div *= 1 << (((val >> config->masks->nscale_sel_shift) &
 				config->masks->nscale_sel_mask) + 1);
 
+	BUG_ON(!div);
+
 	clk->rate = (unsigned long)clk->pclk->rate / div;
-	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /*
@@ -425,18 +485,19 @@ void clcd_clk_recalc(struct clk *clk)
 {
 	struct clcd_clk_config *config = clk->private_data;
 	unsigned int div = 1;
-	unsigned long flags, prate;
+	unsigned long prate;
 	unsigned int val;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	val = readl(config->synth_reg);
 	div = (val >> config->masks->div_factor_shift) &
 		config->masks->div_factor_mask;
 
 	prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
-	clk->rate = ((unsigned long)prate << 14 / 2 * div) >> 14;
+
+	BUG_ON(!div);
+
+	clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
 	clk->rate *= 1000;
-	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /*
@@ -445,12 +506,9 @@ void clcd_clk_recalc(struct clk *clk)
  */
 void follow_parent(struct clk *clk)
 {
-	unsigned long flags;
 	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
 
-	spin_lock_irqsave(&clocks_lock, flags);
 	clk->rate = clk->pclk->rate/div_factor;
-	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
 /**
@@ -461,5 +519,20 @@ void follow_parent(struct clk *clk)
  */
 void recalc_root_clocks(void)
 {
-	propagate_rate(&root_clks);
+	struct clk *pclk;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	list_for_each_entry(pclk, &root_clks, sibling) {
+		/*
+		 * It doesn't make a sense to recalc and propogate rate
+		 * if clk is not enabled in hw.
+		 */
+		if (clk_is_enabled(pclk)) {
+			if (pclk->recalc)
+				pclk->recalc(pclk);
+			propagate_rate(pclk);
+		}
+	}
+	spin_unlock_irqrestore(&clocks_lock, flags);
 }
-- 
1.7.2.2

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

* [PATCH 19/74] ST SPEAr: Adding Debugfs support on clock framework
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (15 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 18/74] ST SPEAr: enhanced spear clock framework Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 20/74] Clock Framework: Adding ENABLED_ON_INIT feature in clk Viresh KUMAR
                   ` (57 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/clock.c              |  116 ++++++++++++++++++++++++++++++
 arch/arm/plat-spear/include/plat/clock.h |    8 ++
 2 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index b4d8110..75c42a3 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -13,6 +13,7 @@
 
 #include <linux/bug.h>
 #include <linux/clk.h>
+#include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/list.h>
@@ -22,8 +23,14 @@
 
 static DEFINE_SPINLOCK(clocks_lock);
 static LIST_HEAD(root_clks);
+#ifdef CONFIG_DEBUG_FS
+static LIST_HEAD(clocks);
+#endif
 
 static void propagate_rate(struct clk *);
+#ifdef CONFIG_DEBUG_FS
+static int clk_debugfs_reparent(struct clk *);
+#endif
 
 static int clk_is_enabled(struct clk *clk)
 {
@@ -113,6 +120,10 @@ static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
 
 	clk->pclk = pclk_info->pclk;
 	spin_unlock_irqrestore(&clocks_lock, flags);
+
+#ifdef CONFIG_DEBUG_FS
+	clk_debugfs_reparent(clk);
+#endif
 }
 
 void do_clk_disable(struct clk *clk)
@@ -335,6 +346,12 @@ void clk_register(struct clk_lookup *cl)
 
 	spin_unlock_irqrestore(&clocks_lock, flags);
 
+	/* debugfs specific */
+#ifdef CONFIG_DEBUG_FS
+	list_add(&clk->node, &clocks);
+	clk->cl = cl;
+#endif
+
 	/* add clock to arm clockdev framework */
 	clkdev_add(cl);
 }
@@ -536,3 +553,102 @@ void recalc_root_clocks(void)
 	}
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
+
+#ifdef CONFIG_DEBUG_FS
+/*
+ *	debugfs support to trace clock tree hierarchy and attributes
+ */
+static struct dentry *clk_debugfs_root;
+static int clk_debugfs_register_one(struct clk *c)
+{
+	int err;
+	struct dentry *d, *child;
+	struct clk *pa = c->pclk;
+	char s[255];
+	char *p = s;
+
+	if (c) {
+		if (c->cl->con_id)
+			p += sprintf(p, "%s", c->cl->con_id);
+		if (c->cl->dev_id)
+			p += sprintf(p, "%s", c->cl->dev_id);
+	}
+	d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+	if (!d)
+		return -ENOMEM;
+	c->dent = d;
+
+	d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
+			(u32 *)&c->usage_count);
+	if (!d) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+	if (!d) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+	if (!d) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	return 0;
+
+err_out:
+	d = c->dent;
+	list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
+		debugfs_remove(child);
+	debugfs_remove(c->dent);
+	return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+	int err;
+	struct clk *pa = c->pclk;
+
+	if (pa && !pa->dent) {
+		err = clk_debugfs_register(pa);
+		if (err)
+			return err;
+	}
+
+	if (!c->dent) {
+		err = clk_debugfs_register_one(c);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+	struct clk *c;
+	struct dentry *d;
+	int err;
+
+	d = debugfs_create_dir("clock", NULL);
+	if (!d)
+		return -ENOMEM;
+	clk_debugfs_root = d;
+
+	list_for_each_entry(c, &clocks, node) {
+		err = clk_debugfs_register(c);
+		if (err)
+			goto err_out;
+	}
+	return 0;
+err_out:
+	debugfs_remove_recursive(clk_debugfs_root);
+	return err;
+}
+late_initcall(clk_debugfs_init);
+
+static int clk_debugfs_reparent(struct clk *c)
+{
+	debugfs_remove(c->dent);
+	return clk_debugfs_register_one(c);
+}
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 019d308..2e55855 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -72,6 +72,9 @@ struct pclk_sel {
  * @children: list for childrens or this clock
  * @sibling: node for list of clocks having same parents
  * @private_data: clock specific private data
+ * @node: list to maintain clocks linearly
+ * @cl: clocklook up assoicated with this clock
+ * @dent: object for debugfs
  */
 struct clk {
 	unsigned int usage_count;
@@ -90,6 +93,11 @@ struct clk {
 	struct list_head children;
 	struct list_head sibling;
 	void *private_data;
+#ifdef CONFIG_DEBUG_FS
+	struct list_head node;
+	struct clk_lookup *cl;
+	struct dentry *dent;
+#endif
 };
 
 /* pll configuration structure */
-- 
1.7.2.2

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

* [PATCH 20/74] Clock Framework: Adding ENABLED_ON_INIT feature in clk
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (16 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 19/74] ST SPEAr: Adding Debugfs support on " Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 22/74] ST SPEAr: Added ARM PL061 GPIO Support on SPEAr13xx and modified resource size Viresh KUMAR
                   ` (56 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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/clock.c          |    2 ++
 arch/arm/mach-spear3xx/clock.c           |    1 +
 arch/arm/mach-spear6xx/clock.c           |    1 +
 arch/arm/plat-spear/clock.c              |    6 ++++++
 arch/arm/plat-spear/include/plat/clock.h |    1 +
 5 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 9d97c69..9252940 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -89,6 +89,7 @@ static struct pll_clk_config pll1_config = {
 
 /* pll1 clock */
 static struct clk pll1_clk = {
+	.flags = ENABLED_ON_INIT,
 	.pclk_sel = &pll_pclk_sel,
 	.pclk_sel_shift = PLL1_CLK_SHIFT,
 	.en_reg = PLL1_CTR,
@@ -156,6 +157,7 @@ static struct pll_clk_config pll4_config = {
 
 /* pll4 (DDR) clock */
 static struct clk pll4_clk = {
+	.flags = ENABLED_ON_INIT,
 	.pclk = &osc1_24m_clk,
 	.en_reg = PLL4_CTR,
 	.en_reg_bit = PLL_ENABLE,
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 5eb6ff6..79f0159 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -62,6 +62,7 @@ static struct pll_clk_config pll1_config = {
 
 /* PLL1 clock */
 static struct clk pll1_clk = {
+	.flags = ENABLED_ON_INIT,
 	.pclk = &osc_24m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 3caf91a..fb05ec8 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -62,6 +62,7 @@ static struct pll_clk_config pll1_config = {
 
 /* PLL1 clock */
 static struct clk pll1_clk = {
+	.flags = ENABLED_ON_INIT,
 	.pclk = &osc_30m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index 75c42a3..e871016 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -372,6 +372,9 @@ void propagate_rate(struct clk *pclk)
 				clk->recalc(clk);
 			propagate_rate(clk);
 		}
+		/* Enable clks enabled on init, in software view */
+		if (clk->flags & ENABLED_ON_INIT)
+			do_clk_enable(clk);
 	}
 }
 
@@ -550,6 +553,9 @@ void recalc_root_clocks(void)
 				pclk->recalc(pclk);
 			propagate_rate(pclk);
 		}
+		/* Enable clks enabled on init, in software view */
+		if (pclk->flags & ENABLED_ON_INIT)
+			do_clk_enable(pclk);
 	}
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 2e55855..91f8e3f 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -21,6 +21,7 @@
 /* clk structure flags */
 #define	ALWAYS_ENABLED		(1 << 0) /* clock always enabled */
 #define	RESET_TO_ENABLE		(1 << 1) /* reset register bit to enable clk */
+#define	ENABLED_ON_INIT		(1 << 2) /* clocks enabled@init */
 
 /**
  * struct clkops - clock operations
-- 
1.7.2.2

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

* [PATCH 22/74] ST SPEAr: Added ARM PL061 GPIO Support on SPEAr13xx and modified resource size
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (17 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 20/74] Clock Framework: Adding ENABLED_ON_INIT feature in clk Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 23/74] ST SPEAr: Adding support for ST's PWM IP Viresh KUMAR
                   ` (55 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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/include/mach/spear.h   |    4 +-
 arch/arm/mach-spear13xx/spear1300_evb.c        |    2 +
 arch/arm/mach-spear13xx/spear13xx.c            |   37 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear300.c              |    2 +-
 arch/arm/mach-spear3xx/spear3xx.c              |    2 +-
 arch/arm/mach-spear6xx/spear6xx.c              |    9 ++----
 9 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 19c5de0..5b974f4 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -29,6 +29,7 @@
 #define SPEAR_GPT0_CHAN1_IRQ	IRQ_GPT0_TMR1
 
 /* Add spear13xx family device structure declarations here */
+extern struct amba_device gpio_device[];
 extern struct amba_device uart_device;
 extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
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 fd90236..562d20f 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -86,6 +86,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/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index 0dcd131..716e215 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -43,8 +43,8 @@
 #define SPEAR13XX_GPT2_BASE		0xE0480000
 #define SPEAR13XX_GPT3_BASE		0xE0500000
 #define SPEAR13XX_RTC_BASE		0xE0580000
-#define SPEAR13XX_GPIOA_BASE		0xE0600000
-#define SPEAR13XX_GPIOB_BASE		0xE0680000
+#define SPEAR13XX_GPIO0_BASE		0xE0600000
+#define SPEAR13XX_GPIO1_BASE		0xE0680000
 #define SPEAR13XX_MISC_BASE		0xE0700000
 #define VA_SPEAR13XX_MISC_BASE		IO_ADDRESS(SPEAR13XX_MISC_BASE)
 
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 0cdad7a..a518620 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -19,6 +19,8 @@
 #include <plat/keyboard.h>
 
 static struct amba_device *amba_devs[] __initdata = {
+	&gpio_device[0],
+	&gpio_device[1],
 	&uart_device,
 };
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 342fcd9..c86e7b9 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>
@@ -24,6 +25,42 @@
 #include <mach/hardware.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 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 uart_device = {
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index fa314e9..cf010cc 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -401,7 +401,7 @@ struct amba_device gpio1_device = {
 	},
 	.res = {
 		.start = SPEAR300_GPIO_BASE,
-		.end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1,
+		.end = SPEAR300_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.irq = {VIRQ_GPIO1, NO_IRQ},
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 780d83e..eb64087 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -35,7 +35,7 @@ struct amba_device gpio_device = {
 	},
 	.res = {
 		.start = SPEAR3XX_ICM3_GPIO_BASE,
-		.end = SPEAR3XX_ICM3_GPIO_BASE + SPEAR3XX_ICM3_GPIO_SIZE - 1,
+		.end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.irq = {IRQ_BASIC_GPIO, NO_IRQ},
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 5a5195b..9a357a1 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -89,8 +89,7 @@ struct amba_device gpio_device[] = {
 		},
 		.res = {
 			.start = SPEAR6XX_CPU_GPIO_BASE,
-			.end = SPEAR6XX_CPU_GPIO_BASE +
-				SPEAR6XX_CPU_GPIO_SIZE - 1,
+			.end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
 		.irq = {IRQ_LOCAL_GPIO, NO_IRQ},
@@ -101,8 +100,7 @@ struct amba_device gpio_device[] = {
 		},
 		.res = {
 			.start = SPEAR6XX_ICM3_GPIO_BASE,
-			.end = SPEAR6XX_ICM3_GPIO_BASE +
-				SPEAR6XX_ICM3_GPIO_SIZE - 1,
+			.end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
 		.irq = {IRQ_BASIC_GPIO, NO_IRQ},
@@ -113,8 +111,7 @@ struct amba_device gpio_device[] = {
 		},
 		.res = {
 			.start = SPEAR6XX_ICM2_GPIO_BASE,
-			.end = SPEAR6XX_ICM2_GPIO_BASE +
-				SPEAR6XX_ICM2_GPIO_SIZE - 1,
+			.end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
 		.irq = {IRQ_APPL_GPIO, NO_IRQ},
-- 
1.7.2.2

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

* [PATCH 23/74] ST SPEAr: Adding support for ST's PWM IP
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (18 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 22/74] ST SPEAr: Added ARM PL061 GPIO Support on SPEAr13xx and modified resource size Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 25/74] ST SPEAr: Adding support for serial nor flash in all spear platforms Viresh KUMAR
                   ` (54 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/clock.c                |   32 ++-
 arch/arm/mach-spear3xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear3xx/spear320.c             |   17 +
 arch/arm/mach-spear3xx/spear320_evb.c         |    1 +
 arch/arm/plat-spear/Kconfig                   |    7 +
 arch/arm/plat-spear/Makefile                  |    1 +
 arch/arm/plat-spear/pwm.c                     |  484 +++++++++++++++++++++++++
 7 files changed, 539 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/plat-spear/pwm.c

diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 3a26622..39835e8 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -461,6 +461,23 @@ static struct clk gpio_clk = {
 
 static struct clk dummy_apb_pclk;
 
+/* spear300 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR300
+/* keyboard clock */
+static struct clk kbd_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+#endif
+
+/* spear310 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR310
+
+#endif
+
+/* spear320 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR320
 /* i2c1 clock */
 static struct clk i2c1_clk = {
@@ -468,11 +485,9 @@ static struct clk i2c1_clk = {
 	.pclk = &ahb_clk,
 	.recalc = &follow_parent,
 };
-#endif
 
-#ifdef CONFIG_MACH_SPEAR300
-/* keyboard clock */
-static struct clk kbd_clk = {
+/* pwm clock */
+static struct clk pwm_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &apb_clk,
 	.recalc = &follow_parent,
@@ -520,11 +535,20 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+
+	/* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
 	{ .dev_id = "keyboard",		.clk = &kbd_clk},
 #endif
+
+	/* spear310 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR310
+
+#endif
+	/* spear320 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR320
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
+	{ .dev_id = "pwm",		.clk = &pwm_clk},
 #endif
 };
 
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 70f7ee2..447de7e 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -174,6 +174,7 @@ void __init spear310_init(void);
 extern struct amba_device clcd_device;
 extern struct platform_device i2c1_device;
 extern struct platform_device plgpio_device;
+extern struct platform_device pwm_device;
 
 /* pad mux modes */
 extern struct pmx_mode auto_net_smii_mode;
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index bfb21ae..75e7890 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -452,6 +452,23 @@ struct platform_device 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 pwm_device = {
+	.name = "pwm",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(pwm_resources),
+	.resource = pwm_resources,
+};
+
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index f90a9b8..943eddc 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -57,6 +57,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear320 specific devices */
 	&i2c1_device,
 	&plgpio_device,
+	&pwm_device,
 };
 
 static void __init spear320_evb_init(void)
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 29a25d2..80f402b 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -36,4 +36,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 c31892a..0e29587 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -8,6 +8,7 @@ obj-y	:= clcd.o clock.o time.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
 
 obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR300_EVB)	+= i2c_eval_board.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] 245+ messages in thread

* [PATCH 25/74] ST SPEAr: Adding support for serial nor flash in all spear platforms
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (19 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 23/74] ST SPEAr: Adding support for ST's PWM IP Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 26/74] ST SPEAr: Adding Watchdog support Viresh KUMAR
                   ` (53 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Adding smi device support and enumerating all serial nor flashes present
in spear(spear3xx/spear6xx/spear13xx) evaluation boards.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@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        |    5 ++
 arch/arm/mach-spear13xx/spear13xx.c            |   19 +++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300_evb.c          |    5 ++
 arch/arm/mach-spear3xx/spear310_evb.c          |    5 ++
 arch/arm/mach-spear3xx/spear320_evb.c          |    5 ++
 arch/arm/mach-spear3xx/spear3xx.c              |   19 +++++++
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    5 ++
 arch/arm/mach-spear6xx/spear6xx.c              |   19 +++++++
 arch/arm/plat-spear/Makefile                   |    2 +-
 arch/arm/plat-spear/include/plat/smi.h         |    3 +
 arch/arm/plat-spear/smi.c                      |   63 ++++++++++++++++++++++++
 14 files changed, 152 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/plat-spear/smi.c

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 5b974f4..186a8be 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -38,6 +38,7 @@ extern struct platform_device kbd_device;
 extern struct platform_device ohci0_device;
 extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
+extern struct platform_device smi_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear1300 machine device structure declarations here */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index a518620..5b74f05 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -17,6 +17,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[0],
@@ -32,6 +33,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&smi_device,
 };
 
 /* keyboard specific platform data */
@@ -56,6 +58,9 @@ static void __init spear1300_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+
 	/* 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 c86e7b9..b6bddff 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -241,6 +241,25 @@ struct platform_device rtc_device = {
 	.resource = rtc_resources,
 };
 
+/* smi device registration */
+static struct resource smi_resources[] = {
+	{
+		.start = SPEAR13XX_SMI_CTRL_BASE,
+		.end = SPEAR13XX_SMI_CTRL_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_SMI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device smi_device = {
+	.name = "smi",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(smi_resources),
+	.resource = smi_resources,
+};
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 447de7e..9317af8 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -38,6 +38,7 @@ 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 platform_device smi_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 afb773e..c948289 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -16,6 +16,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/smi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -50,6 +51,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&smi_device,
 
 	/* spear300 specific devices */
 	&kbd_device,
@@ -82,6 +84,9 @@ static void __init spear300_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+
 	/* 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 d523040..2a88cd2 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/smi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -55,6 +56,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&smi_device,
 
 	/* spear310 specific devices */
 	&plgpio_device,
@@ -75,6 +77,9 @@ static void __init spear310_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+
 	/* 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 943eddc..d0cfd96 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/smi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -53,6 +54,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&smi_device,
 
 	/* spear320 specific devices */
 	&i2c1_device,
@@ -72,6 +74,9 @@ static void __init spear320_evb_init(void)
 	/* call spear320 machine init function */
 	spear320_init();
 
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index eb64087..ab78396 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -175,6 +175,25 @@ struct platform_device rtc_device = {
 	.resource = rtc_resources,
 };
 
+/* smi device registration */
+static struct resource smi_resources[] = {
+	{
+		.start = SPEAR3XX_ICM3_SMI_CTRL_BASE,
+		.end = SPEAR3XX_ICM3_SMI_CTRL_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_BASIC_SMI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device smi_device = {
+	.name = "smi",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(smi_resources),
+	.resource = smi_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 3b15289..8aee3ad 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -38,6 +38,7 @@ 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 platform_device smi_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 b4dfd25..bd4be34 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&clcd_device,
@@ -32,6 +33,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&smi_device,
 };
 
 static void __init spear600_evb_init(void)
@@ -44,6 +46,9 @@ static void __init spear600_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+
 	/* 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 9a357a1..e3313e6 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -267,6 +267,25 @@ struct platform_device rtc_device = {
 	.resource = rtc_resources,
 };
 
+/* smi device registration */
+static struct resource smi_resources[] = {
+	{
+		.start = SPEAR6XX_ICM3_SMI_CTRL_BASE,
+		.end = SPEAR6XX_ICM3_SMI_CTRL_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_BASIC_SMI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device smi_device = {
+	.name = "smi",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(smi_resources),
+	.resource = smi_resources,
+};
+
 /* This will add devices, and do machine specific tasks */
 void __init spear6xx_init(void)
 {
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 0e29587..b8a7403 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y	:= clcd.o clock.o time.o
+obj-y	:= clcd.o clock.o time.o smi.o
 
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
diff --git a/arch/arm/plat-spear/include/plat/smi.h b/arch/arm/plat-spear/include/plat/smi.h
index 4c74df7..37dbd5e 100644
--- a/arch/arm/plat-spear/include/plat/smi.h
+++ b/arch/arm/plat-spear/include/plat/smi.h
@@ -65,4 +65,7 @@ static inline void smi_set_plat_data(struct platform_device *pdev,
 	pdev->dev.platform_data = pdata;
 }
 
+/* function used to initialize default smi platform data */
+void smi_init_board_info(struct platform_device *pdev);
+
 #endif /* __PLAT_SMI_H */
diff --git a/arch/arm/plat-spear/smi.c b/arch/arm/plat-spear/smi.c
new file mode 100644
index 0000000..b109dc1
--- /dev/null
+++ b/arch/arm/plat-spear/smi.c
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/plat-spear/smi.c
+ *
+ * spear smi platform intialization
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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 <asm/mach-types.h>
+#include <mach/spear.h>
+#include <plat/smi.h>
+
+/*
+ * physical base address of flash/bank mem map base associated with smi
+ * depends on SoC
+ */
+
+#if defined(CONFIG_ARCH_SPEAR13XX)
+#define FLASH_MEM_BASE	SPEAR13XX_SMI_MEM_BASE
+
+#elif defined(CONFIG_ARCH_SPEAR3XX)
+#define FLASH_MEM_BASE	SPEAR3XX_ICM3_SMEM_BASE
+
+#elif defined(CONFIG_ARCH_SPEAR6XX)
+#define FLASH_MEM_BASE	SPEAR6XX_ICM3_SMEM_BASE
+
+#endif
+
+/* serial nor flash specific board data */
+static struct mtd_partition nor_partition_info[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x10000),
+	DEFINE_PARTS("UBoot", 0x10000, 0x40000),
+	DEFINE_PARTS("Kernel", 0x50000, 0x2C0000),
+	DEFINE_PARTS("Root File System", 0x310000, 0x4F0000),
+};
+
+static struct spear_smi_flash_info nor_flash_info[] = {
+	{
+		.name = "m25p64",
+		.fast_mode = 1,
+		.mem_base = FLASH_MEM_BASE,
+		.size = 8 * 1024 * 1024,
+		.num_parts = ARRAY_SIZE(nor_partition_info),
+		.parts = nor_partition_info,
+	},
+};
+
+/* smi specific board data */
+static struct spear_smi_plat_data smi_plat_data = {
+	.clk_rate = 50000000,	/* 50MHz */
+	.num_flashes = ARRAY_SIZE(nor_flash_info),
+	.board_flash_info = nor_flash_info,
+};
+
+void smi_init_board_info(struct platform_device *pdev)
+{
+	smi_set_plat_data(pdev, &smi_plat_data);
+}
-- 
1.7.2.2

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

* [PATCH 26/74] ST SPEAr: Adding Watchdog support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (20 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 25/74] ST SPEAr: Adding support for serial nor flash in all spear platforms Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 30/74] ST SPEAr: Added PCIE host controller base driver support Viresh KUMAR
                   ` (52 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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/clock.c               |    3 ++-
 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 ++++++++++++
 9 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index c48b779..5280657 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -263,7 +263,8 @@ static struct clk gpt3_clk = {
 /* watch dog timer clock */
 static struct clk wdt_clk = {
 	.flags = ALWAYS_ENABLED,
-	.pclk = &apb_clk,
+	.pclk = &cpu_clk,
+	.div_factor = 2,
 	.recalc = &follow_parent,
 };
 
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 9317af8..91c0c09 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 gpio_device;
 extern struct amba_device uart_device;
+extern struct amba_device wdt_device;
 extern struct platform_device ehci_device;
 extern struct platform_device i2c_device;
 extern struct platform_device ohci0_device;
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index c948289..7bd8963 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -38,6 +38,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&gpio_device,
 	&uart_device,
+	&wdt_device,
 
 	/* spear300 specific devices */
 	&clcd_device,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 2a88cd2..cd076c9 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -45,6 +45,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&gpio_device,
 	&uart_device,
+	&wdt_device,
 
 	/* spear310 specific devices */
 };
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index d0cfd96..7f7b5dd 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -42,6 +42,7 @@ static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&gpio_device,
 	&uart_device,
+	&wdt_device,
 
 	/* spear320 specific devices */
 	&clcd_device,
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index ab78396..b15fd27 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -54,6 +54,18 @@ struct amba_device uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+/* watchdog device registeration */
+struct amba_device wdt_device = {
+	.dev = {
+		.init_name = "wdt",
+	},
+	.res = {
+		.start = SPEAR3XX_ICM3_WDT_BASE,
+		.end = SPEAR3XX_ICM3_WDT_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 /* i2c device registeration */
 static struct resource i2c_resources[] = {
 	{
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 8aee3ad..f885898 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 clcd_device;
 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;
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index bd4be34..0eb5f50 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -24,6 +24,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 e3313e6..4987597 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -118,6 +118,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,
+	},
+};
+
 /* i2c device registeration */
 static struct resource i2c_resources[] = {
 	{
-- 
1.7.2.2

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

* [PATCH 30/74] ST SPEAr: Added PCIE host controller base driver support.
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (21 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 26/74] ST SPEAr: Adding Watchdog support Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 31/74] ST SPEAr: Adding support for SSP PL022 Viresh KUMAR
                   ` (51 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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

This driver is based on synopsys DWC version 3.30a.

Intr, MSI, & Hotplug and other interfaces have still
to be implemented.

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                                 |    5 +-
 arch/arm/mach-spear13xx/Makefile                 |    1 +
 arch/arm/mach-spear13xx/include/mach/hardware.h  |    7 +
 arch/arm/mach-spear13xx/include/mach/irqs.h      |   25 +-
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |   20 +
 arch/arm/mach-spear13xx/include/mach/pcie.h      |  169 +++++
 arch/arm/mach-spear13xx/pcie.c                   |  881 ++++++++++++++++++++++
 arch/arm/mach-spear13xx/spear1300_evb.c          |   31 +
 arch/arm/mach-spear13xx/spear13xx.c              |   28 +
 arch/arm/plat-spear/Kconfig                      |    1 +
 10 files changed, 1163 insertions(+), 5 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 950c045..c4d1df3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1104,7 +1104,9 @@ config ISA_DMA_API
 	bool
 
 config PCI
-	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX
+	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB ||\
+	ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX ||\
+	ARCH_SPEAR13XX
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
@@ -1131,6 +1133,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 cb5ae9e..b55f92e 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 
 # spear1300 specific files
 obj-$(CONFIG_MACH_SPEAR1300)		+= spear1300.o
+obj-$(CONFIG_PCIEPORTBUS)		+= pcie.o
 
 # spear1300 boards files
 obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= spear1300_evb.o
diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
index 0047d75..4abc2c0 100644
--- a/arch/arm/mach-spear13xx/include/mach/hardware.h
+++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
@@ -22,4 +22,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 562d20f..97d0d80 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -80,9 +80,9 @@
 #define IRQ_USBH_OHCI0		(IRQ_SHPI_START + 65)
 #define IRQ_USBH_EHCI1		(IRQ_SHPI_START + 66)
 #define IRQ_USBH_OHCI1		(IRQ_SHPI_START + 67)
-#define IRQ_PCIE1		(IRQ_SHPI_START + 68)
-#define IRQ_PCIE2		(IRQ_SHPI_START + 69)
-#define IRQ_PCIE3		(IRQ_SHPI_START + 70)
+#define IRQ_PCIE0		(IRQ_SHPI_START + 68)
+#define IRQ_PCIE1		(IRQ_SHPI_START + 69)
+#define IRQ_PCIE2		(IRQ_SHPI_START + 70)
 
 #define IRQ_GIC_END		(IRQ_SHPI_START + 128)
 
@@ -93,7 +93,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/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index 05815fa..bc785f9 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -202,6 +202,26 @@
 #define USBPHY_P2_CFG		((unsigned int *)(MISC_BASE + 0x31c))
 #define USBPHY_P3_CFG		((unsigned int *)(MISC_BASE + 0x320))
 #define PCIE_CFG		((unsigned int *)(MISC_BASE + 0x324))
+	/* PCIE CFG MASks */
+	#define PCIE2_CFG_AUX_CLK	(1 << 0)
+	#define PCIE1_CFG_AUX_CLK	(1 << 1)
+	#define PCIE0_CFG_AUX_CLK	(1 << 2)
+	#define PCIE2_CFG_CORE_CLK	(1 << 3)
+	#define PCIE1_CFG_CORE_CLK	(1 << 4)
+	#define PCIE0_CFG_CORE_CLK	(1 << 5)
+	#define PCIE2_CFG_POWERUP_RESET	(1 << 6)
+	#define PCIE1_CFG_POWERUP_RESET	(1 << 7)
+	#define PCIE0_CFG_POWERUP_RESET	(1 << 8)
+	#define PCIE2_CFG_DEVICE_PRESENT	(1 << 9)
+	#define PCIE1_CFG_DEVICE_PRESENT	(1 << 10)
+	#define PCIE0_CFG_DEVICE_PRESENT	(1 << 11)
+	#define PCIE0_CFG_VAL	(PCIE0_CFG_AUX_CLK | PCIE0_CFG_CORE_CLK \
+			| PCIE0_CFG_POWERUP_RESET | PCIE0_CFG_DEVICE_PRESENT)
+	#define PCIE1_CFG_VAL	(PCIE1_CFG_AUX_CLK | PCIE1_CFG_CORE_CLK \
+			| PCIE1_CFG_POWERUP_RESET | PCIE1_CFG_DEVICE_PRESENT)
+	#define PCIE2_CFG_VAL	(PCIE2_CFG_AUX_CLK | PCIE2_CFG_CORE_CLK \
+			| PCIE2_CFG_POWERUP_RESET | PCIE2_CFG_DEVICE_PRESENT)
+
 #define PCIE_MIPHY_CFG		((unsigned int *)(MISC_BASE + 0x328))
 #define PERIP_CFG		((unsigned int *)(MISC_BASE + 0x32c))
 #define FSMC_CFG		((unsigned int *)(MISC_BASE + 0x330))
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..3ec1e94
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/pcie.h
@@ -0,0 +1,169 @@
+/*
+ * 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;
+	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..4128897
--- /dev/null
+++ b/arch/arm/mach-spear13xx/pcie.c
@@ -0,0 +1,881 @@
+/*
+ * 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/pci.h>
+#include <asm/mach/irq.h>
+#include <mach/pcie.h>
+#include <mach/irqs.h>
+#include <mach/misc_regs.h>
+
+#define NUM_PCIE_PORTS	3
+
+#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	(12 * 1024 * 1024 - 1)
+#define IN_CFG1_SIZE	(12 * 1024 * 1024 - 1)
+#define IN_MSG_SIZE	(12 * 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);
+
+		if (!(*pcie_port_is_host)(i))
+			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))
+		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_MEMORY | PCI_COMMAND_MASTER);
+	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))
+			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 va_address;
+	u32 address = readl(&app_reg->in_cfg0_addr_start)
+			| (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);
+	va_address = (u32)ioremap(address, 4);
+	if (!va_address) {
+		pr_err("error with ioremap in function %s\n", __func__);
+		return -ENOMEM;
+	}
+
+	*val = readl(va_address);
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	iounmap((void *)va_address);
+	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 va_address;
+	u32 address = readl(&app_reg->in_cfg0_addr_start)
+			| (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);
+	va_address = (u32)ioremap(address, 4);
+	if (!va_address) {
+		pr_err("error with ioremap in function %s\n", __func__);
+		return -ENOMEM;
+	}
+
+	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));
+	else
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+
+	iounmap((void *)va_address);
+	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)) {
+		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];
+
+	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);
+
+	}
+}
+
+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 (!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 (!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))
+			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, type;
+	int i;
+
+	status = readl(&app_reg->int_sts);
+
+	desc->chip->ack(irq);
+
+	for (i = 0; i < 26; i++) {
+		type = status & (1 << i);
+		switch (type) {
+		case MSI_CTRL_INT:
+			handle_msi(pp);
+			writel(type, &app_reg->int_clr);
+			break;
+		case INTA_CTRL_INT:
+			generic_handle_irq(SPEAR_INTX0_BASE
+					+ pp->port * SPEAR_NUM_INTX_IRQS);
+			break;
+		case INTB_CTRL_INT:
+			generic_handle_irq(SPEAR_INTX0_BASE
+					+ pp->port * SPEAR_NUM_INTX_IRQS + 1);
+			break;
+		case INTC_CTRL_INT:
+			generic_handle_irq(SPEAR_INTX0_BASE
+					+ pp->port * SPEAR_NUM_INTX_IRQS + 2);
+			break;
+		case INTD_CTRL_INT:
+			generic_handle_irq(SPEAR_INTX0_BASE
+					+ pp->port * SPEAR_NUM_INTX_IRQS + 3);
+			break;
+		default:
+			writel(type, &app_reg->int_clr);
+			break;
+		}
+	}
+
+	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,
+	.enable = unmask_msi_irq,
+	.disable = mask_msi_irq,
+	.mask = mask_msi_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 4267b46..c5ac2fb 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -17,6 +17,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <mach/pcie.h>
 #include <plat/keyboard.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
@@ -48,6 +49,30 @@ static struct kbd_platform_data kbd_data = {
 	.rep = 1,
 };
 
+#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.
+ * it is the responsibility of calling function to not send port number
+ * greter than max no of controller(3)
+ */
+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;
@@ -69,6 +94,12 @@ static void __init spear1300_evb_init(void)
 	/* initialize serial nor related data in smi plat data */
 	smi_init_board_info(&smi_device);
 
+#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/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 4810652..c5a0a0c 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -318,6 +318,34 @@ struct platform_device smi_device = {
 	.resource = smi_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
+ * 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 (!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 80f402b..b8e4988 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,6 +12,7 @@ config ARCH_SPEAR13XX
 	bool "SPEAr13XX"
 	select ARM_GIC
 	select CPU_V7
+	select ARCH_SUPPORTS_MSI
 	help
 	  Supports for ARM's SPEAR13XX family
 
-- 
1.7.2.2

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

* [PATCH 31/74] ST SPEAr: Adding support for SSP PL022
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (22 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 30/74] ST SPEAr: Added PCIE host controller base driver support Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  9:57   ` Russell King - ARM Linux
  2010-09-02 19:18   ` Linus Walleij
  2010-08-30 10:38 ` [PATCH 32/74] ST SPEAr: Adding clk_set_rate support Viresh KUMAR
                   ` (50 subsequent siblings)
  74 siblings, 2 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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/clock.c                |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   47 ++++++++++++++
 arch/arm/mach-spear13xx/spear13xx.c            |   31 ++++++++++
 arch/arm/mach-spear3xx/clock.c                 |    4 +-
 arch/arm/mach-spear3xx/include/mach/generic.h  |    2 +
 arch/arm/mach-spear3xx/spear300_evb.c          |   50 +++++++++++++++
 arch/arm/mach-spear3xx/spear310_evb.c          |   42 +++++++++++++
 arch/arm/mach-spear3xx/spear320.c              |   42 +++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   46 ++++++++++++++
 arch/arm/mach-spear3xx/spear3xx.c              |   31 ++++++++++
 arch/arm/mach-spear6xx/clock.c                 |    6 +-
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/include/mach/spear.h    |    4 +-
 arch/arm/mach-spear6xx/spear600_evb.c          |   51 ++++++++++++++++
 arch/arm/mach-spear6xx/spear6xx.c              |   68 +++++++++++++++++++++
 arch/arm/plat-spear/include/plat/spi.h         |   77 ++++++++++++++++++++++++
 17 files changed, 497 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/spi.h

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 8658d48..8399c15 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -799,7 +799,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "i2s0",		.clk = &i2s0_clk},
 	{.dev_id = "i2s1",		.clk = &i2s1_clk},
 	{.dev_id = "adc",		.clk = &adc_clk},
-	{.dev_id = "ssp",		.clk = &ssp_clk},
+	{.dev_id = "ssp-pl022",		.clk = &ssp_clk},
 	{.dev_id = "gpio0",		.clk = &gpio0_clk},
 	{.dev_id = "gpio1",		.clk = &gpio1_clk},
 	{.dev_id = "keyboard",		.clk = &kbd_clk},
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index b884359..967e96e 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -30,6 +30,7 @@
 
 /* Add spear13xx 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 platform_device ehci0_device;
 extern struct platform_device ehci1_device;
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index c5ac2fb..6aaae5a 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -12,7 +12,10 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/mtd/nand.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
@@ -21,10 +24,12 @@
 #include <plat/keyboard.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
+#include <plat/spi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[0],
 	&gpio_device[1],
+	&ssp_device,
 	&uart_device,
 };
 
@@ -49,6 +54,46 @@ static struct kbd_platform_data kbd_data = {
 	.rep = 1,
 };
 
+/* Currently no gpios are free on eval board so it is kept commented */
+#if 0
+/* spi board information */
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, /* mention gpio number here */);
+/* 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, /* mention gpio number here */);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+#endif
+
+static struct spi_board_info __initdata spi_board_info[] = {
+#if 0
+	/* spi0 board info */
+	{
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 1000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+#endif
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 #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
@@ -106,6 +151,8 @@ static void __init spear1300_evb_init(void)
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_init();
 }
 
 MACHINE_START(SPEAR1300, "ST-SPEAR1300-EVB")
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index c5a0a0c..9e4a673 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>
@@ -64,6 +65,36 @@ struct amba_device 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 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 uart_device = {
 	.dev = {
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 93c5fd9..f7dedc6 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -444,7 +444,7 @@ static struct clk adc_clk = {
 };
 
 /* ssp clock */
-static struct clk ssp_clk = {
+static struct clk ssp0_clk = {
 	.pclk = &apb_clk,
 	.en_reg = PERIP1_CLK_ENB,
 	.en_reg_bit = SSP_CLK_ENB,
@@ -543,7 +543,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "c3",		.clk = &c3_clk},
 	/* clock derived from apb clk */
 	{ .dev_id = "adc",		.clk = &adc_clk},
-	{ .dev_id = "ssp",		.clk = &ssp_clk},
+	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
 #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
 	defined(CONFIG_MACH_SPEAR320)
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 6aac229..04ce870 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 gpio_device;
+extern struct amba_device ssp0_device;
 extern struct amba_device uart_device;
 extern struct amba_device wdt_device;
 extern struct platform_device ehci_device;
@@ -176,6 +177,7 @@ void __init spear310_init(void);
 #elif defined(CONFIG_MACH_SPEAR320)
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
+extern struct amba_device ssp_device[];
 extern struct platform_device i2c1_device;
 extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 895f7b7..653adec 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -14,11 +14,15 @@
 #include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <mach/generic.h>
+#include <mach/gpio.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
+#include <plat/spi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -39,6 +43,7 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&gpio_device,
+	&ssp0_device,
 	&uart_device,
 	&wdt_device,
 
@@ -70,6 +75,49 @@ static struct kbd_platform_data kbd_data = {
 	.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);
+
+/*
+ * Chip select of spidev, currently no gpio is free on eval board so it is kept
+ * commented
+ */
+#if 0
+/* spi0 spidev Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, dev, /* mention gpio number here */);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+#endif
+
+static struct spi_board_info __initdata spi_board_info[] = {
+	/* spi0 board info */
+	{
+#if 0
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+#endif
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 400000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 static void __init spear300_evb_init(void)
 {
 	unsigned int i;
@@ -101,6 +149,8 @@ static void __init spear300_evb_init(void)
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_init();
 }
 
 MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 8f17362..663e78e 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -14,10 +14,14 @@
 #include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <mach/generic.h>
+#include <mach/gpio.h>
 #include <mach/spear.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
+#include <plat/spi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -46,6 +50,7 @@ static struct pmx_dev *pmx_devs[] = {
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&gpio_device,
+	&ssp0_device,
 	&uart_device,
 	&wdt_device,
 
@@ -66,6 +71,41 @@ static struct platform_device *plat_devs[] __initdata = {
 	&plgpio_device,
 };
 
+/* 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 = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 400000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 static void __init spear310_evb_init(void)
 {
 	unsigned int i;
@@ -94,6 +134,8 @@ static void __init spear310_evb_init(void)
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_init();
 }
 
 MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 2ac838b..9c3d75f 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 <mach/generic.h>
@@ -403,6 +404,47 @@ struct amba_device clcd_device = {
 	.irq = {VIRQ_CLCD, NO_IRQ},
 };
 
+/* 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 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 = {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 = {VIRQ_SSP2, 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 d693877..99ae3ba 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -14,10 +14,14 @@
 #include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <mach/generic.h>
+#include <mach/gpio.h>
 #include <mach/spear.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
+#include <plat/spi.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -66,6 +70,46 @@ static struct platform_device *plat_devs[] __initdata = {
 	&pwm_device,
 };
 
+/* Currently no gpios are free on eval board so it is kept commented */
+#if 0
+/* spi board information */
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, /* mention gpio number here */);
+/* 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, /* mention gpio number here */);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+#endif
+
+static struct spi_board_info __initdata spi_board_info[] = {
+#if 0
+	/* spi0 board info */
+	{
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 400000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+#endif
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 static void __init spear320_evb_init(void)
 {
 	unsigned int i;
@@ -94,6 +138,8 @@ static void __init spear320_evb_init(void)
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_init();
 }
 
 MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index b15fd27..fdb4fa8 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 gpio_device = {
 	.irq = {IRQ_BASIC_GPIO, NO_IRQ},
 };
 
+/* 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 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 = {IRQ_SSP, NO_IRQ},
+};
+
 /* uart device registeration */
 struct amba_device uart_device = {
 	.dev = {
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 91f1f3f..52d5bff 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -605,9 +605,9 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 	/* clock derived from apb clk */
 	{ .dev_id = "adc",		.clk = &adc_clk},
-	{ .dev_id = "ssp0",		.clk = &ssp0_clk},
-	{ .dev_id = "ssp1",		.clk = &ssp1_clk},
-	{ .dev_id = "ssp2",		.clk = &ssp2_clk},
+	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
+	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
+	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
 	{ .dev_id = "gpio0",		.clk = &gpio0_clk},
 	{ .dev_id = "gpio1",		.clk = &gpio1_clk},
 	{ .dev_id = "gpio2",		.clk = &gpio2_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index ff90419..dd29298 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 clcd_device;
 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/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
index a835f5b..31486e5 100644
--- a/arch/arm/mach-spear6xx/include/mach/spear.h
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -68,8 +68,8 @@
 #define SPEAR6XX_ICM2_GPIO_BASE		0xD8100000
 #define SPEAR6XX_ICM2_GPIO_SIZE		0x00080000
 
-#define SPEAR6XX_ICM2_SPI2_BASE		0xD8180000
-#define SPEAR6XX_ICM2_SPI2_SIZE		0x00080000
+#define SPEAR6XX_ICM2_SSP2_BASE		0xD8180000
+#define SPEAR6XX_ICM2_SSP2_SIZE		0x00080000
 
 #define SPEAR6XX_ICM2_ADC_BASE		0xD8200000
 #define SPEAR6XX_ICM2_ADC_SIZE		0x00080000
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index cf86efc..ae1055a 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -14,16 +14,24 @@
 #include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/gpio.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
 #include <mach/generic.h>
+#include <mach/gpio.h>
 #include <mach/spear.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
+#include <plat/spi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&clcd_device,
 	&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,
@@ -40,6 +48,47 @@ static struct platform_device *plat_devs[] __initdata = {
 	&smi_device,
 };
 
+/* Currently no gpios are free on eval board so it is kept commented */
+#if 0
+/* spi board information */
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, /* mention gpio number here */);
+/* 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, /* mention gpio number here */);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+#endif
+
+static struct spi_board_info __initdata spi_board_info[] = {
+#if 0
+	/* spi0 board info */
+	{
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 400000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+#endif
+	/* Similarly can be done for other spi masters */
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
 static void __init spear600_evb_init(void)
 {
 	unsigned int i;
@@ -63,6 +112,8 @@ static void __init spear600_evb_init(void)
 	/* Add Amba Devices */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_init();
 }
 
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 2296d0f..876692e 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>
@@ -41,6 +42,73 @@ struct amba_device clcd_device = {
 	.irq = {IRQ_BASIC_CLCD, NO_IRQ},
 };
 
+/* 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,
+	}, {
+		.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 registeration */
 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..a2c53f3
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/spi.h
@@ -0,0 +1,77 @@
+/*
+ * 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)	\
+struct pl022_config_chip spi##id##_##type##_chip_info = {	\
+	.lbm = LOOPBACK_DISABLED,			\
+	.iface = SSP_INTERFACE_MOTOROLA_SPI,		\
+	.hierarchy = SSP_MASTER,			\
+	.slave_tx_disable = 0,				\
+	.endian_tx = SSP_TX_LSB,			\
+	.endian_rx = SSP_RX_LSB,			\
+	.data_size = SSP_DATA_BITS_8,			\
+	.com_mode = INTERRUPT_TRANSFER,			\
+	.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,		\
+	.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,	\
+	.clk_phase = SSP_CLK_SECOND_EDGE,		\
+	.clk_pol = SSP_CLK_POL_IDLE_LOW,		\
+	.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] 245+ messages in thread

* [PATCH 32/74] ST SPEAr: Adding clk_set_rate support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (23 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 31/74] ST SPEAr: Adding support for SSP PL022 Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02  9:21   ` Russell King - ARM Linux
  2010-08-30 10:38 ` [PATCH 33/74] ST SPEAr: Adding support for SDHCI (SDIO) Viresh KUMAR
                   ` (49 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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/clock.c          |   74 +++++-
 arch/arm/mach-spear3xx/clock.c           |   54 ++++
 arch/arm/mach-spear6xx/clock.c           |   58 ++++
 arch/arm/plat-spear/clock.c              |  423 ++++++++++++++++++++++++++----
 arch/arm/plat-spear/include/plat/clock.h |   75 +++++-
 5 files changed, 620 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 8399c15..630ab65 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -87,6 +87,15 @@ static struct pll_clk_config pll1_config = {
 	.masks = &pll_masks,
 };
 
+/* pll rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll_rtbl[] = {
+	/* PCLK 24MHz */
+	{.mode = 0, .m = 0x7D, .n = 0x03, .p = 0x2}, /* 500 MHz */
+	{.mode = 0, .m = 0xA6, .n = 0x03, .p = 0x2}, /* 664 MHz */
+	{.mode = 0, .m = 0xC8, .n = 0x03, .p = 0x2}, /* 800 MHz */
+	{.mode = 0, .m = 0xFA, .n = 0x06, .p = 0x1}, /* 1000 MHz */
+};
+
 /* pll1 clock */
 static struct clk pll1_clk = {
 	.flags = ENABLED_ON_INIT,
@@ -94,7 +103,10 @@ static struct clk pll1_clk = {
 	.pclk_sel_shift = PLL1_CLK_SHIFT,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 3},
 	.private_data = &pll1_config,
 };
 
@@ -127,7 +139,10 @@ static struct clk pll2_clk = {
 	.pclk_sel_shift = PLL2_CLK_SHIFT,
 	.en_reg = PLL2_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 3},
 	.private_data = &pll2_config,
 };
 
@@ -144,7 +159,10 @@ static struct clk pll3_clk = {
 	.pclk_sel_shift = PLL3_CLK_SHIFT,
 	.en_reg = PLL3_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 3},
 	.private_data = &pll3_config,
 };
 
@@ -155,13 +173,24 @@ static struct pll_clk_config pll4_config = {
 	.masks = &pll_masks,
 };
 
+/* pll4 rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll4_rtbl[] = {
+	{.mode = 0, .m = 0x7D, .n = 0x03, .p = 0x2}, /* 500 MHz */
+	{.mode = 0, .m = 0xA6, .n = 0x03, .p = 0x2}, /* 664 MHz */
+	{.mode = 0, .m = 0xC8, .n = 0x03, .p = 0x2}, /* 800 MHz */
+	{.mode = 0, .m = 0xFA, .n = 0x06, .p = 0x1}, /* 1000 MHz */
+};
+
 /* pll4 (DDR) clock */
 static struct clk pll4_clk = {
 	.flags = ENABLED_ON_INIT,
 	.pclk = &osc1_24m_clk,
 	.en_reg = PLL4_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll4_rtbl, ARRAY_SIZE(pll4_rtbl), 3},
 	.private_data = &pll4_config,
 };
 
@@ -287,12 +316,24 @@ static struct aux_clk_config uart_synth_config = {
 	.masks = &aux_masks,
 };
 
+/* aux rate configuration table, in ascending order of rates */
+struct aux_rate_tbl aux_rtbl[] = {
+	/* For PLL1div2 = 500 MHz */
+	{.xscale = 1, .yscale = 6, .eq = 1}, /* 83 MHz */
+	{.xscale = 1, .yscale = 4, .eq = 1}, /* 125 MHz */
+	{.xscale = 1, .yscale = 3, .eq = 1}, /* 166 MHz */
+	{.xscale = 1, .yscale = 2, .eq = 1}, /* 250 MHz */
+};
+
 /* uart synth clock */
 static struct clk uart_synth_clk = {
 	.en_reg = UART_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1div2_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
 	.private_data = &uart_synth_config,
 };
 
@@ -335,8 +376,11 @@ static struct clk sd_synth_clk = {
 	.en_reg = SD_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1div2_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
-	.private_data = &sd_synth_config,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+	.private_data = &sdhci_synth_config,
 };
 
 /* sd clock */
@@ -358,7 +402,10 @@ static struct clk cfxd_synth_clk = {
 	.en_reg = CFXD_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1div2_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
 	.private_data = &cfxd_synth_config,
 };
 
@@ -381,7 +428,10 @@ static struct clk c3_synth_clk = {
 	.en_reg = C3_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1div2_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
 	.private_data = &c3_synth_config,
 };
 
@@ -453,11 +503,23 @@ static struct clk gmac_phy_input_clk = {
 	.recalc = &follow_parent,
 };
 
+/* gmac rate configuration table, in ascending order of rates */
+struct aux_rate_tbl gmac_rtbl[] = {
+	/* For gmac phy input clk */
+	{.xscale = 1, .yscale = 6, .eq = 1}, /* divided by 6 */
+	{.xscale = 1, .yscale = 4, .eq = 1}, /* divided by 4 */
+	{.xscale = 1, .yscale = 3, .eq = 1}, /* divided by 3 */
+	{.xscale = 1, .yscale = 2, .eq = 1}, /* divided by 2 */
+};
+
 static struct clk gmac_phy_synth_clk = {
 	.en_reg = GMAC_CLK_CFG,
 	.en_reg_bit = GMAC_PHY_SYNT_ENB,
 	.pclk = &gmac_phy_input_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {gmac_rtbl, ARRAY_SIZE(gmac_rtbl), 0},
 	.private_data = &gmac_phy_synth_config,
 };
 
@@ -518,13 +580,23 @@ static struct pclk_sel clcd_synth_pclk_sel = {
 	.pclk_sel_mask = CLCD_SYNT_CLK_MASK,
 };
 
+/* clcd rate configuration table, in ascending order of rates */
+struct clcd_rate_tbl clcd_rtbl[] = {
+	/* For pll1div4 = 250 MHz */
+	{.div = 0x4000}, /* 62.5 MHz */
+	{.div = 0x2000}, /* 125 MHz */
+};
+
 /* clcd synth clock */
 static struct clk clcd_synth_clk = {
 	.en_reg = CLCD_CLK_SYNT,
 	.en_reg_bit = CLCD_SYNT_ENB,
 	.pclk_sel = &clcd_synth_pclk_sel,
 	.pclk_sel_shift = CLCD_SYNT_CLK_SHIFT,
+	.calc_rate = &clcd_calc_rate,
 	.recalc = &clcd_clk_recalc,
+	.set_rate = &clcd_clk_set_rate,
+	.rate_config = {clcd_rtbl, ARRAY_SIZE(clcd_rtbl), 1},
 	.private_data = &clcd_synth_config,
 };
 
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index f7dedc6..51cf304 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -60,13 +60,22 @@ static struct pll_clk_config pll1_config = {
 	.masks = &pll1_masks,
 };
 
+/* pll rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll_rtbl[] = {
+	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
+	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
+};
+
 /* PLL1 clock */
 static struct clk pll1_clk = {
 	.flags = ENABLED_ON_INIT,
 	.pclk = &osc_24m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
 	.private_data = &pll1_config,
 };
 
@@ -104,11 +113,22 @@ static struct bus_clk_config ahb_config = {
 	.masks = &ahb_masks,
 };
 
+/* ahb rate configuration table, in ascending order of rates */
+struct bus_rate_tbl bus_rtbl[] = {
+	{.div = 3}, /* == parent divided by 4 */
+	{.div = 2}, /* == parent divided by 3 */
+	{.div = 1}, /* == parent divided by 2 */
+	{.div = 0}, /* == parent divided by 1 */
+};
+
 /* ahb clock */
 static struct clk ahb_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
+	.set_rate = &bus_clk_set_rate,
+	.rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
 	.private_data = &ahb_config,
 };
 
@@ -130,12 +150,23 @@ static struct aux_clk_config uart_synth_config = {
 	.masks = &aux_masks,
 };
 
+/* aux rate configuration table, in ascending order of rates */
+struct aux_rate_tbl aux_rtbl[] = {
+	/* For PLL1 = 332 MHz */
+	{.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
+	{.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
+	{.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
+};
+
 /* uart synth clock */
 static struct clk uart_synth_clk = {
 	.en_reg = UART_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
 	.private_data = &uart_synth_config,
 };
 
@@ -178,7 +209,10 @@ static struct clk firda_synth_clk = {
 	.en_reg = FIRDA_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
 	.private_data = &firda_synth_config,
 };
 
@@ -218,6 +252,14 @@ static struct gpt_clk_masks gpt_masks = {
 	.nscale_sel_shift = GPT_NSCALE_SHIFT,
 };
 
+/* gpt rate configuration table, in ascending order of rates */
+struct gpt_rate_tbl gpt_rtbl[] = {
+	/* For pll1 = 332 MHz */
+	{.mscale = 4, .nscale = 0}, /* 41.5 MHz */
+	{.mscale = 2, .nscale = 0}, /* 55.3 MHz */
+	{.mscale = 1, .nscale = 0}, /* 83 MHz */
+};
+
 /* gpt0 synth clk config*/
 static struct gpt_clk_config gpt0_synth_config = {
 	.synth_reg = PRSC1_CLK_CFG,
@@ -228,7 +270,10 @@ static struct gpt_clk_config gpt0_synth_config = {
 static struct clk gpt0_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt0_synth_config,
 };
 
@@ -269,7 +314,10 @@ static struct gpt_clk_config gpt1_synth_config = {
 static struct clk gpt1_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt1_synth_config,
 };
 
@@ -310,7 +358,10 @@ static struct gpt_clk_config gpt2_synth_config = {
 static struct clk gpt2_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt2_synth_config,
 };
 
@@ -382,7 +433,10 @@ static struct bus_clk_config apb_config = {
 static struct clk apb_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &ahb_clk,
+	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
+	.set_rate = &bus_clk_set_rate,
+	.rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
 	.private_data = &apb_config,
 };
 
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 52d5bff..9171952 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -60,13 +60,22 @@ static struct pll_clk_config pll1_config = {
 	.masks = &pll1_masks,
 };
 
+/* pll rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll_rtbl[] = {
+	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
+	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
+};
+
 /* PLL1 clock */
 static struct clk pll1_clk = {
 	.flags = ENABLED_ON_INIT,
 	.pclk = &osc_30m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
 	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
 	.private_data = &pll1_config,
 };
 
@@ -104,11 +113,22 @@ static struct bus_clk_config ahb_config = {
 	.masks = &ahb_masks,
 };
 
+/* ahb rate configuration table, in ascending order of rates */
+struct bus_rate_tbl bus_rtbl[] = {
+	{.div = 3}, /* == parent divided by 4 */
+	{.div = 2}, /* == parent divided by 3 */
+	{.div = 1}, /* == parent divided by 2 */
+	{.div = 0}, /* == parent divided by 1 */
+};
+
 /* ahb clock */
 static struct clk ahb_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
+	.set_rate = &bus_clk_set_rate,
+	.rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
 	.private_data = &ahb_config,
 };
 
@@ -130,12 +150,23 @@ static struct aux_clk_config uart_synth_config = {
 	.masks = &aux_masks,
 };
 
+/* aux rate configuration table, in ascending order of rates */
+struct aux_rate_tbl aux_rtbl[] = {
+	/* For PLL1 = 332 MHz */
+	{.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
+	{.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
+	{.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
+};
+
 /* uart synth clock */
 static struct clk uart_synth_clk = {
 	.en_reg = UART_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
 	.private_data = &uart_synth_config,
 };
 
@@ -187,7 +218,10 @@ static struct clk firda_synth_clk = {
 	.en_reg = FIRDA_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
 	.private_data = &firda_synth_config,
 };
 
@@ -230,7 +264,10 @@ static struct clk clcd_synth_clk = {
 	.en_reg = CLCD_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1_clk,
+	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
+	.set_rate = &aux_clk_set_rate,
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
 	.private_data = &clcd_synth_config,
 };
 
@@ -270,6 +307,14 @@ static struct gpt_clk_masks gpt_masks = {
 	.nscale_sel_shift = GPT_NSCALE_SHIFT,
 };
 
+/* gpt rate configuration table, in ascending order of rates */
+struct gpt_rate_tbl gpt_rtbl[] = {
+	/* For pll1 = 332 MHz */
+	{.mscale = 4, .nscale = 0}, /* 41.5 MHz */
+	{.mscale = 2, .nscale = 0}, /* 55.3 MHz */
+	{.mscale = 1, .nscale = 0}, /* 83 MHz */
+};
+
 /* gpt0 synth clk config*/
 static struct gpt_clk_config gpt0_synth_config = {
 	.synth_reg = PRSC1_CLK_CFG,
@@ -280,7 +325,10 @@ static struct gpt_clk_config gpt0_synth_config = {
 static struct clk gpt0_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt0_synth_config,
 };
 
@@ -339,7 +387,10 @@ static struct gpt_clk_config gpt2_synth_config = {
 static struct clk gpt2_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt2_synth_config,
 };
 
@@ -380,7 +431,10 @@ static struct gpt_clk_config gpt3_synth_config = {
 static struct clk gpt3_synth_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &pll1_clk,
+	.calc_rate = &gpt_calc_rate,
 	.recalc = &gpt_clk_recalc,
+	.set_rate = &gpt_clk_set_rate,
+	.rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
 	.private_data = &gpt3_synth_config,
 };
 
@@ -453,7 +507,10 @@ static struct bus_clk_config apb_config = {
 static struct clk apb_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk = &ahb_clk,
+	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
+	.set_rate = &bus_clk_set_rate,
+	.rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
 	.private_data = &apb_config,
 };
 
@@ -580,6 +637,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
 	{ .con_id = "uart_synth_clk",	.clk = &uart_synth_clk},
 	{ .con_id = "firda_synth_clk",	.clk = &firda_synth_clk},
+	{ .con_id = "clcd_synth_clk",	.clk = &clcd_synth_clk},
 	{ .con_id = "gpt0_synth_clk",	.clk = &gpt0_synth_clk},
 	{ .con_id = "gpt2_synth_clk",	.clk = &gpt2_synth_clk},
 	{ .con_id = "gpt3_synth_clk",	.clk = &gpt3_synth_clk},
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index e871016..7d3338f 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -27,28 +27,11 @@ static LIST_HEAD(root_clks);
 static LIST_HEAD(clocks);
 #endif
 
-static void propagate_rate(struct clk *);
+static void propagate_rate(struct clk *, int on_init);
 #ifdef CONFIG_DEBUG_FS
 static int clk_debugfs_reparent(struct clk *);
 #endif
 
-static int clk_is_enabled(struct clk *clk)
-{
-	unsigned int val;
-
-	if (clk->flags & ALWAYS_ENABLED)
-		return 1;
-
-	BUG_ON(!clk->en_reg);
-	val = readl(clk->en_reg);
-	val = val & (1 << clk->en_reg_bit);
-
-	if (unlikely(clk->flags & RESET_TO_ENABLE))
-		return !val;
-	else
-		return !!val;
-}
-
 static int generic_clk_enable(struct clk *clk)
 {
 	unsigned int val;
@@ -126,7 +109,7 @@ static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
 #endif
 }
 
-void do_clk_disable(struct clk *clk)
+static void do_clk_disable(struct clk *clk)
 {
 	if (!clk)
 		return;
@@ -151,7 +134,7 @@ void do_clk_disable(struct clk *clk)
 	}
 }
 
-int do_clk_enable(struct clk *clk)
+static int do_clk_enable(struct clk *clk)
 {
 	int ret = 0;
 
@@ -176,8 +159,11 @@ int do_clk_enable(struct clk *clk)
 		 * Since the clock is going to be used for the first
 		 * time please reclac
 		 */
-		if (clk->recalc)
-			clk->recalc(clk);
+		if (clk->recalc) {
+			ret = clk->recalc(clk);
+			if (ret)
+				goto err;
+		}
 	}
 	clk->usage_count++;
 err:
@@ -248,8 +234,7 @@ EXPORT_SYMBOL(clk_get_rate);
  * @clk: clock source
  * @parent: parent clock source
  *
- * Returns success (0) or negative errno. clk usage_count must be zero
- * before calling this function.
+ * Returns success (0) or negative errno.
  */
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
@@ -258,8 +243,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 
 	if (!clk || !parent)
 		return -EFAULT;
-	if (clk->usage_count)
-		return -EPERM;
 	if (clk->pclk == parent)
 		return 0;
 	if (!clk->pclk_sel)
@@ -287,6 +270,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	/* reflect parent change in software */
 	clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
 
+	propagate_rate(clk, 0);
 	return 0;
 }
 EXPORT_SYMBOL(clk_set_parent);
@@ -300,8 +284,25 @@ EXPORT_SYMBOL(clk_set_parent);
  */
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-	/* TODO */
-	return -EINVAL;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (!clk || !rate)
+		return -EFAULT;
+
+	if (clk->set_rate) {
+		spin_lock_irqsave(&clocks_lock, flags);
+		ret = clk->set_rate(clk, rate);
+		if (!ret)
+			/* if successful -> propagate */
+			propagate_rate(clk, 0);
+		spin_unlock_irqrestore(&clocks_lock, flags);
+	} else if (clk->pclk) {
+		u32 mult = clk->div_factor ? clk->div_factor : 1;
+		ret = clk_set_rate(clk->pclk, mult * rate);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(clk_set_rate);
 
@@ -358,27 +359,112 @@ void clk_register(struct clk_lookup *cl)
 
 /**
  * propagate_rate - recalculate and propagate all clocks to children
+ * @pclk: parent clock required to be propogated
+ * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
  *
  * Recalculates all children clocks
  */
-void propagate_rate(struct clk *pclk)
+void propagate_rate(struct clk *pclk, int on_init)
 {
 	struct clk *clk, *_temp;
+	int ret = 0;
 
 	list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
-		/* recalc and propogate only if clk is enabled */
-		if (clk_is_enabled(clk)) {
-			if (clk->recalc)
-				clk->recalc(clk);
-			propagate_rate(clk);
+		if (clk->recalc) {
+			ret = clk->recalc(clk);
+			/*
+			 * recalc will return error if clk out is not programmed
+			 * In this case configure default rate.
+			 */
+			if (ret && clk->set_rate)
+				clk->set_rate(clk, 0);
 		}
+		propagate_rate(clk, on_init);
+
+		if (!on_init)
+			continue;
+
 		/* Enable clks enabled on init, in software view */
 		if (clk->flags & ENABLED_ON_INIT)
 			do_clk_enable(clk);
 	}
 }
 
-/*All recalc functions are called with lock held */
+/**
+ * round_rate - Returns index of closest programmable rate in rate_config tbl
+ * @clk: ptr to clock structure
+ * @drate: desired rate
+ * @rate: final rate will be returned in this variable only.
+ *
+ * Finds index in rate_config for highest clk rate which is less than
+ * requested rate. If there is no clk rate lesser than requested rate then
+ * -EINVAL is returned. This routine assumes that rate_config is written
+ * in incrementing order of clk rates.
+ * If drate passed is zero then default rate is programmed.
+ */
+static int round_rate(struct clk *clk, unsigned long drate, unsigned long *rate)
+{
+	unsigned long tmp = 0, prev_rate = 0;
+	int index;
+
+	if (!clk->calc_rate)
+		return -EFAULT;
+
+	/* Set default rate if desired rate is 0 */
+	if (!drate) {
+		index = clk->rate_config.default_index;
+		*rate = clk->calc_rate(clk, index);
+		return index;
+	}
+
+	/*
+	 * This loops ends on two conditions:
+	 * - as soon as clk is found with rate greater than requested rate.
+	 * - if all clks in rate_config are smaller than requested rate.
+	 */
+	for (index = 0; index < clk->rate_config.count; index++) {
+		prev_rate = tmp;
+		tmp = clk->calc_rate(clk, index);
+		if (drate < tmp) {
+			index--;
+			break;
+		}
+	}
+	/* return if can't find suitable clock */
+	if (index < 0) {
+		index = -EINVAL;
+		*rate = 0;
+	} else if (index == clk->rate_config.count) {
+		/* program with highest clk rate possible */
+		index = clk->rate_config.count - 1;
+		*rate = tmp;
+	} else
+		*rate = prev_rate;
+
+	return index;
+}
+
+/*All below functions are called with lock held */
+
+/*
+ * Calculates pll clk rate for specific value of mode, m, n and p
+ *
+ * In normal mode
+ * rate = (2 * M[15:8] * Fin)/(N * 2^P)
+ *
+ * In Dithered mode
+ * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
+ */
+unsigned long pll_calc_rate(struct clk *clk, int index)
+{
+	unsigned long rate = clk->pclk->rate;
+	struct pll_rate_tbl *tbls = clk->rate_config.tbls;
+	unsigned int mode;
+
+	mode = tbls[index].mode ? 256 : 1;
+	return (((2 * rate / 10000) * tbls[index].m) /
+			(mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
+}
 
 /*
  * calculates current programmed rate of pll1
@@ -389,7 +475,7 @@ void propagate_rate(struct clk *pclk)
  * In Dithered mode
  * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
  */
-void pll_clk_recalc(struct clk *clk)
+int pll_clk_recalc(struct clk *clk)
 {
 	struct pll_clk_config *config = clk->private_data;
 	unsigned int num = 2, den = 0, val, mode = 0;
@@ -415,13 +501,69 @@ void pll_clk_recalc(struct clk *clk)
 		den *= 256;
 	}
 
-	BUG_ON(!den);
+	if (!den)
+		return -EINVAL;
 
 	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	return 0;
+}
+
+/*
+ * Configures new clock rate of pll
+ */
+int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+	struct pll_rate_tbl *tbls = clk->rate_config.tbls;
+	struct pll_clk_config *config = clk->private_data;
+	unsigned long val, rate;
+	int i;
+
+	i = round_rate(clk, desired_rate, &rate);
+	if (i < 0)
+		return i;
+
+	val = readl(config->mode_reg) &
+		~(config->masks->mode_mask << config->masks->mode_shift);
+	val |= (tbls[i].mode & config->masks->mode_mask) <<
+		config->masks->mode_shift;
+	writel(val, config->mode_reg);
+
+	val = readl(config->cfg_reg) &
+		~(config->masks->div_p_mask << config->masks->div_p_shift);
+	val |= (tbls[i].p & config->masks->div_p_mask) <<
+		config->masks->div_p_shift;
+	val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
+	val |= (tbls[i].n & config->masks->div_n_mask) <<
+		config->masks->div_n_shift;
+	val &= ~(config->masks->dith_fdbk_m_mask <<
+			config->masks->dith_fdbk_m_shift);
+	if (tbls[i].mode)
+		val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
+			config->masks->dith_fdbk_m_shift;
+	else
+		val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
+			config->masks->norm_fdbk_m_shift;
+
+	writel(val, config->cfg_reg);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+/*
+ * Calculates ahb, apb clk rate for specific value of div
+ */
+unsigned long bus_calc_rate(struct clk *clk, int index)
+{
+	unsigned long rate = clk->pclk->rate;
+	struct bus_rate_tbl *tbls = clk->rate_config.tbls;
+
+	return rate / (tbls[index].div + 1);
 }
 
 /* calculates current programmed rate of ahb or apb bus */
-void bus_clk_recalc(struct clk *clk)
+int bus_clk_recalc(struct clk *clk)
 {
 	struct bus_clk_config *config = clk->private_data;
 	unsigned int div;
@@ -429,9 +571,50 @@ void bus_clk_recalc(struct clk *clk)
 	div = ((readl(config->reg) >> config->masks->shift) &
 			config->masks->mask) + 1;
 
-	BUG_ON(!div);
+	if (!div)
+		return -EINVAL;
 
 	clk->rate = (unsigned long)clk->pclk->rate / div;
+	return 0;
+}
+
+/* Configures new clock rate of AHB OR APB bus */
+int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+	struct bus_rate_tbl *tbls = clk->rate_config.tbls;
+	struct bus_clk_config *config = clk->private_data;
+	unsigned long val, rate;
+	int i;
+
+	i = round_rate(clk, desired_rate, &rate);
+	if (i < 0)
+		return i;
+
+	val = readl(config->reg) &
+		~(config->masks->mask << config->masks->shift);
+	val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
+	writel(val, config->reg);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+/*
+ * gives rate for different values of eq, x and y
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2		EQ1
+ * Fout2 = Fin * X/Y			EQ2
+ */
+unsigned long aux_calc_rate(struct clk *clk, int index)
+{
+	unsigned long rate = clk->pclk->rate;
+	struct aux_rate_tbl *tbls = clk->rate_config.tbls;
+	u8 eq = tbls[index].eq ? 1 : 2;
+
+	return (((rate/10000) * tbls[index].xscale) /
+			(tbls[index].yscale * eq)) * 10000;
 }
 
 /*
@@ -444,7 +627,7 @@ void bus_clk_recalc(struct clk *clk)
  *
  * Selection of eqn 1 or 2 is programmed in register
  */
-void aux_clk_recalc(struct clk *clk)
+int aux_clk_recalc(struct clk *clk)
 {
 	struct aux_clk_config *config = clk->private_data;
 	unsigned int num = 1, den = 1, val, eqn;
@@ -464,9 +647,56 @@ void aux_clk_recalc(struct clk *clk)
 	den *= (val >> config->masks->yscale_sel_shift) &
 		config->masks->yscale_sel_mask;
 
-	BUG_ON(!den);
+	if (!den)
+		return -EINVAL;
 
 	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	return 0;
+}
+
+/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
+int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+	struct aux_rate_tbl *tbls = clk->rate_config.tbls;
+	struct aux_clk_config *config = clk->private_data;
+	unsigned long val, rate;
+	int i;
+
+	i = round_rate(clk, desired_rate, &rate);
+	if (i < 0)
+		return i;
+
+	val = readl(config->synth_reg) &
+		~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
+	val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
+		config->masks->eq_sel_shift;
+	val &= ~(config->masks->xscale_sel_mask <<
+			config->masks->xscale_sel_shift);
+	val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
+		config->masks->xscale_sel_shift;
+	val &= ~(config->masks->yscale_sel_mask <<
+			config->masks->yscale_sel_shift);
+	val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
+		config->masks->yscale_sel_shift;
+	writel(val, config->synth_reg);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+/*
+ * Calculates gpt clk rate for different values of mscale and nscale
+ *
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+unsigned long gpt_calc_rate(struct clk *clk, int index)
+{
+	unsigned long rate = clk->pclk->rate;
+	struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
+
+	return rate / ((1 << (tbls[index].nscale + 1)) *
+			(tbls[index].mscale + 1));
 }
 
 /*
@@ -474,7 +704,7 @@ void aux_clk_recalc(struct clk *clk)
  * Fout from synthesizer can be given from below equations:
  * Fout= Fin/((2 ^ (N+1)) * (M+1))
  */
-void gpt_clk_recalc(struct clk *clk)
+int gpt_clk_recalc(struct clk *clk)
 {
 	struct gpt_clk_config *config = clk->private_data;
 	unsigned int div = 1, val;
@@ -485,9 +715,64 @@ void gpt_clk_recalc(struct clk *clk)
 	div *= 1 << (((val >> config->masks->nscale_sel_shift) &
 				config->masks->nscale_sel_mask) + 1);
 
-	BUG_ON(!div);
+	if (!div)
+		return -EINVAL;
 
 	clk->rate = (unsigned long)clk->pclk->rate / div;
+	return 0;
+}
+
+/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
+int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+	struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
+	struct gpt_clk_config *config = clk->private_data;
+	unsigned long val, rate;
+	int i;
+
+	i = round_rate(clk, desired_rate, &rate);
+	if (i < 0)
+		return i;
+
+	val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
+			config->masks->mscale_sel_shift);
+	val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
+		config->masks->mscale_sel_shift;
+	val &= ~(config->masks->nscale_sel_mask <<
+			config->masks->nscale_sel_shift);
+	val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
+		config->masks->nscale_sel_shift;
+	writel(val, config->synth_reg);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+/*
+ * Calculates clcd clk rate for different values of div
+ *
+ * Fout from synthesizer can be given from below equation:
+ * Fout= Fin/2*div (division factor)
+ * div is 17 bits:-
+ *	0-13 (fractional part)
+ *	14-16 (integer part)
+ * To calculate Fout we left shift val by 14 bits and divide Fin by
+ * complete div (including fractional part) and then right shift the
+ * result by 14 places.
+ */
+unsigned long clcd_calc_rate(struct clk *clk, int index)
+{
+	unsigned long rate = clk->pclk->rate;
+	struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
+
+	rate /= 1000;
+	rate <<= 12;
+	rate /= (2 * tbls[index].div);
+	rate >>= 12;
+	rate *= 1000;
+
+	return rate;
 }
 
 /*
@@ -501,7 +786,7 @@ void gpt_clk_recalc(struct clk *clk)
  * complete div (including fractional part) and then right shift the
  * result by 14 places.
  */
-void clcd_clk_recalc(struct clk *clk)
+int clcd_clk_recalc(struct clk *clk)
 {
 	struct clcd_clk_config *config = clk->private_data;
 	unsigned int div = 1;
@@ -512,23 +797,49 @@ void clcd_clk_recalc(struct clk *clk)
 	div = (val >> config->masks->div_factor_shift) &
 		config->masks->div_factor_mask;
 
-	prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
+	if (!div)
+		return -EINVAL;
 
-	BUG_ON(!div);
+	prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
 
 	clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
 	clk->rate *= 1000;
+	return 0;
+}
+
+/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
+int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+	struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
+	struct clcd_clk_config *config = clk->private_data;
+	unsigned long val, rate;
+	int i;
+
+	i = round_rate(clk, desired_rate, &rate);
+	if (i < 0)
+		return i;
+
+	val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
+			config->masks->div_factor_shift);
+	val |= (tbls[i].div & config->masks->div_factor_mask) <<
+		config->masks->div_factor_shift;
+	writel(val, config->synth_reg);
+
+	clk->rate = rate;
+
+	return 0;
 }
 
 /*
  * Used for clocks that always have value as the parent clock divided by a
  * fixed divisor
  */
-void follow_parent(struct clk *clk)
+int follow_parent(struct clk *clk)
 {
 	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
 
 	clk->rate = clk->pclk->rate/div_factor;
+	return 0;
 }
 
 /**
@@ -541,18 +852,20 @@ void recalc_root_clocks(void)
 {
 	struct clk *pclk;
 	unsigned long flags;
+	int ret = 0;
 
 	spin_lock_irqsave(&clocks_lock, flags);
 	list_for_each_entry(pclk, &root_clks, sibling) {
-		/*
-		 * It doesn't make a sense to recalc and propogate rate
-		 * if clk is not enabled in hw.
-		 */
-		if (clk_is_enabled(pclk)) {
-			if (pclk->recalc)
-				pclk->recalc(pclk);
-			propagate_rate(pclk);
+		if (pclk->recalc) {
+			ret = pclk->recalc(pclk);
+			/*
+			 * recalc will return error if clk out is not programmed
+			 * In this case configure default clock.
+			 */
+			if (ret && pclk->set_rate)
+				pclk->set_rate(pclk, 0);
 		}
+		propagate_rate(pclk, 1);
 		/* Enable clks enabled on init, in software view */
 		if (pclk->flags & ENABLED_ON_INIT)
 			do_clk_enable(pclk);
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 91f8e3f..30938ea 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -58,6 +58,18 @@ struct pclk_sel {
 };
 
 /**
+ * struct rate_config - clk rate configurations
+ * @tbls: array of device specific clk rate tables, in ascending order of rates
+ * @count: size of tbls array
+ * @default_index: default setting when originally disabled
+ */
+struct rate_config {
+	void *tbls;
+	u8 count;
+	u8 default_index;
+};
+
+/**
  * struct clk - clock structure
  * @usage_count: num of users who enabled this clock
  * @flags: flags for clock properties
@@ -66,6 +78,9 @@ struct pclk_sel {
  * @en_reg_bit: clk enable/disable bit
  * @ops: clk enable/disable ops - generic_clkops selected if NULL
  * @recalc: pointer to clock rate recalculate function
+ * @set_rate: pointer to clock set rate function
+ * @calc_rate: pointer to clock get rate function for index
+ * @rate_config: rate configuration information, used by set_rate
  * @div_factor: division factor to parent clock.
  * @pclk: current parent clk
  * @pclk_sel: pointer to parent selection structure
@@ -84,7 +99,10 @@ struct clk {
 	unsigned int *en_reg;
 	u8 en_reg_bit;
 	const struct clkops *ops;
-	void (*recalc) (struct clk *);
+	int (*recalc) (struct clk *);
+	int (*set_rate) (struct clk *, unsigned long rate);
+	unsigned long (*calc_rate)(struct clk *, int index);
+	struct rate_config rate_config;
 	unsigned int div_factor;
 
 	struct clk *pclk;
@@ -122,6 +140,14 @@ struct pll_clk_config {
 	struct pll_clk_masks *masks;
 };
 
+/* pll clk rate config structure */
+struct pll_rate_tbl {
+	u8 mode;
+	u16 m;
+	u8 n;
+	u8 p;
+};
+
 /* ahb and apb bus configuration structure */
 struct bus_clk_masks {
 	u32 mask;
@@ -133,6 +159,11 @@ struct bus_clk_config {
 	struct bus_clk_masks *masks;
 };
 
+/* ahb and apb clk bus rate config structure */
+struct bus_rate_tbl {
+	u8 div;
+};
+
 /* Aux clk configuration structure: applicable to UART and FIRDA */
 struct aux_clk_masks {
 	u32 eq_sel_mask;
@@ -150,6 +181,13 @@ struct aux_clk_config {
 	struct aux_clk_masks *masks;
 };
 
+/* aux clk rate config structure */
+struct aux_rate_tbl {
+	u16 xscale;
+	u16 yscale;
+	u8 eq;
+};
+
 /* GPT clk configuration structure */
 struct gpt_clk_masks {
 	u32 mscale_sel_mask;
@@ -163,6 +201,12 @@ struct gpt_clk_config {
 	struct gpt_clk_masks *masks;
 };
 
+/* gpt clk rate config structure */
+struct gpt_rate_tbl {
+	u16 mscale;
+	u16 nscale;
+};
+
 /* clcd clk configuration structure */
 struct clcd_synth_masks {
 	u32 div_factor_mask;
@@ -174,16 +218,31 @@ struct clcd_clk_config {
 	struct clcd_synth_masks *masks;
 };
 
+/* clcd clk rate config structure */
+struct clcd_rate_tbl {
+	u16 div;
+};
+
 /* platform specific clock functions */
 void clk_register(struct clk_lookup *cl);
 void recalc_root_clocks(void);
 
-/* clock recalc functions */
-void follow_parent(struct clk *clk);
-void pll_clk_recalc(struct clk *clk);
-void bus_clk_recalc(struct clk *clk);
-void gpt_clk_recalc(struct clk *clk);
-void aux_clk_recalc(struct clk *clk);
-void clcd_clk_recalc(struct clk *clk);
+/* clock recalc & set rate functions */
+int follow_parent(struct clk *clk);
+unsigned long pll_calc_rate(struct clk *clk, int index);
+int pll_clk_recalc(struct clk *clk);
+int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long bus_calc_rate(struct clk *clk, int index);
+int bus_clk_recalc(struct clk *clk);
+int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long gpt_calc_rate(struct clk *clk, int index);
+int gpt_clk_recalc(struct clk *clk);
+int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long aux_calc_rate(struct clk *clk, int index);
+int aux_clk_recalc(struct clk *clk);
+int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long clcd_calc_rate(struct clk *clk, int index);
+int clcd_clk_recalc(struct clk *clk);
+int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 
 #endif /* __PLAT_CLOCK_H */
-- 
1.7.2.2

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

* [PATCH 33/74] ST SPEAr: Adding support for SDHCI (SDIO)
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (24 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 32/74] ST SPEAr: Adding clk_set_rate support Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 34/74] ST SPEAr: Changing resource size of amba devices to SZ_4K Viresh KUMAR
                   ` (48 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/clock.c                  |   24 ++++----
 arch/arm/mach-spear13xx/include/mach/generic.h   |    1 +
 arch/arm/mach-spear13xx/include/mach/irqs.h      |    2 +-
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |    4 +-
 arch/arm/mach-spear13xx/include/mach/spear.h     |    2 +-
 arch/arm/mach-spear13xx/spear1300_evb.c          |    1 +
 arch/arm/mach-spear13xx/spear13xx.c              |   22 ++++++++
 arch/arm/mach-spear3xx/clock.c                   |   15 +++++
 arch/arm/mach-spear3xx/include/mach/generic.h    |   13 +++--
 arch/arm/mach-spear3xx/include/mach/irqs.h       |    4 +-
 arch/arm/mach-spear3xx/include/mach/spear300.h   |    4 +-
 arch/arm/mach-spear3xx/include/mach/spear320.h   |    6 +-
 arch/arm/mach-spear3xx/spear300.c                |   62 ++++++++++++++++++----
 arch/arm/mach-spear3xx/spear300_evb.c            |   18 ++++++-
 arch/arm/mach-spear3xx/spear320.c                |   43 ++++++++++++----
 arch/arm/mach-spear3xx/spear320_evb.c            |   15 +++++-
 16 files changed, 187 insertions(+), 49 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 630ab65..98ba04e 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -365,15 +365,15 @@ static struct clk uart_clk = {
 	.recalc = &follow_parent,
 };
 
-/* sd configurations */
-static struct aux_clk_config sd_synth_config = {
-	.synth_reg = SD_CLK_SYNT,
+/* sdhci configurations */
+static struct aux_clk_config sdhci_synth_config = {
+	.synth_reg = SDHCI_CLK_SYNT,
 	.masks = &aux_masks,
 };
 
-/* sd synth clock */
-static struct clk sd_synth_clk = {
-	.en_reg = SD_CLK_SYNT,
+/* sdhci synth clock */
+static struct clk sdhci_synth_clk = {
+	.en_reg = SDHCI_CLK_SYNT,
 	.en_reg_bit = AUX_SYNT_ENB,
 	.pclk = &pll1div2_clk,
 	.calc_rate = &aux_calc_rate,
@@ -383,11 +383,11 @@ static struct clk sd_synth_clk = {
 	.private_data = &sdhci_synth_config,
 };
 
-/* sd clock */
-static struct clk sd_clk = {
+/* sdhci clock */
+static struct clk sdhci_clk = {
 	.en_reg = PERIP1_CLK_ENB,
-	.en_reg_bit = SD_CLK_ENB,
-	.pclk = &sd_synth_clk,
+	.en_reg_bit = SDHCI_CLK_ENB,
+	.pclk = &sdhci_synth_clk,
 	.recalc = &follow_parent,
 };
 
@@ -833,7 +833,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.con_id = "gmii_txclk123_pad_clk",	.clk = &gmii_txclk125_pad},
 	{.con_id = "clcd_synth_clk",		.clk = &clcd_synth_clk},
 	{.con_id = "uart_synth_clk",		.clk = &uart_synth_clk},
-	{.con_id = "sd_synth_clk",		.clk = &sd_synth_clk},
+	{.con_id = "sdhci_synth_clk",		.clk = &sdhci_synth_clk},
 	{.con_id = "cfxd_synth_clk",		.clk = &cfxd_synth_clk},
 	{.con_id = "gmac_phy_input_clk",	.clk = &gmac_phy_input_clk},
 	{.con_id = "gmac_phy_synth_clk",	.clk = &gmac_phy_synth_clk},
@@ -862,7 +862,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "pcie1",		.clk = &pcie1_clk},
 	{.dev_id = "pcie2",		.clk = &pcie2_clk},
 	{.dev_id = "cfxd",		.clk = &cfxd_clk},
-	{.dev_id = "sd",		.clk = &sd_clk},
+	{.dev_id = "sdhci",		.clk = &sdhci_clk},
 	{.con_id = "fsmc",		.clk = &fsmc_clk},
 	{.dev_id = "sysram0",		.clk = &sysram0_clk},
 	{.dev_id = "sysram1",		.clk = &sysram1_clk},
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 967e96e..a09bf62 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -40,6 +40,7 @@ extern struct platform_device nand_device;
 extern struct platform_device ohci0_device;
 extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
+extern struct platform_device sdhci_device;
 extern struct platform_device smi_device;
 extern struct sys_timer spear13xx_timer;
 
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index 97d0d80..d2bfbb1 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -45,7 +45,7 @@
 #define IRQ_GPIO1		(IRQ_SHPI_START + 25)
 #define IRQ_PLAY_I2S1		(IRQ_SHPI_START + 26)
 #define IRQ_JPEG		(IRQ_SHPI_START + 27)
-#define IRQ_MMC			(IRQ_SHPI_START + 28)
+#define IRQ_SDHCI		(IRQ_SHPI_START + 28)
 #define IRQ_CF			(IRQ_SHPI_START + 29)
 #define IRQ_SMI			(IRQ_SHPI_START + 30)
 #define IRQ_SSP			(IRQ_SHPI_START + 31)
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index bc785f9..2529a48 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -120,7 +120,7 @@
 
 #define UART_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x254))
 #define GMAC_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x258))
-#define SD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x25c))
+#define SDHCI_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x25c))
 #define CFXD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x260))
 #define RAS_CLK_SYNT0		((unsigned int *)(MISC_BASE + 0x264))
 #define RAS_CLK_SYNT1		((unsigned int *)(MISC_BASE + 0x268))
@@ -145,7 +145,7 @@
 	#define SYSRAM0_CLK_ENB		3
 	#define FSMC_CLK_ENB		4
 	#define SMI_CLK_ENB		5
-	#define SD_CLK_ENB		6
+	#define SDHCI_CLK_ENB		6
 	#define CFXD_CLK_ENB		7
 	#define GMAC_CLK_ENB		8
 	#define UHC0_CLK_ENB		9
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index 716e215..282ef2f 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -84,7 +84,7 @@
 #define SPEAR13XX_FSMC_BASE		0xB0000000
 #define SPEAR13XX_JPEG_BASE		0xB2000000
 #define SPEAR13XX_MCIF_CF_BASE		0xB2800000
-#define SPEAR13XX_MCIF_MMC_BASE		0xB3000000
+#define SPEAR13XX_MCIF_SDHCI_BASE	0xB3000000
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR13XX_UART_BASE
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 6aaae5a..aed4bba 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -42,6 +42,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
+	&sdhci_device,
 	&smi_device,
 };
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 9e4a673..b06f59e 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -377,6 +377,28 @@ int enable_pcie0_clk(void)
 }
 #endif
 
+/* 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 sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 51cf304..b56a755 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -525,6 +525,16 @@ static struct clk fsmc_clk = {
 };
 #endif
 
+/* common clocks to spear300 and spear320 */
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
+/* sdhci clock */
+static struct clk sdhci_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &follow_parent,
+};
+#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
+
 /* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
 /* keyboard clock */
@@ -618,6 +628,11 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 	{ .dev_id = "pwm",		.clk = &pwm_clk},
 #endif
+
+	/* common clock to spear300 and spear320 */
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
+	{ .dev_id = "sdhci",	.clk = &sdhci_clk},
+#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
 };
 
 void __init clk_init(void)
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 04ce870..9bd9424 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -116,6 +116,7 @@ extern struct platform_device nand0_device;
 extern struct platform_device nand1_device;
 extern struct platform_device nand2_device;
 extern struct platform_device nand3_device;
+extern struct platform_device sdhci_device;
 
 /* pad mux modes */
 extern struct pmx_mode nand_mode;
@@ -144,12 +145,15 @@ extern struct pmx_dev pmx_telecom_camera;
 extern struct pmx_dev pmx_telecom_dac;
 extern struct pmx_dev pmx_telecom_i2s;
 extern struct pmx_dev pmx_telecom_boot_pins;
-extern struct pmx_dev pmx_telecom_sdio_4bit;
-extern struct pmx_dev pmx_telecom_sdio_8bit;
+extern struct pmx_dev pmx_telecom_sdhci_4bit;
+extern struct pmx_dev pmx_telecom_sdhci_8bit;
 extern struct pmx_dev pmx_gpio1;
 
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
+#define SDHCI_MEM_ENB	0x1
+#define I2S_MEM_ENB	0x2
+void sdhci_i2s_mem_enable(u8 mask);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
@@ -182,6 +186,7 @@ extern struct platform_device i2c1_device;
 extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
 extern struct platform_device pwm_device;
+extern struct platform_device sdhci_device;
 
 /* pad mux modes */
 extern struct pmx_mode auto_net_smii_mode;
@@ -194,14 +199,14 @@ extern struct pmx_dev pmx_clcd;
 extern struct pmx_dev pmx_emi;
 extern struct pmx_dev pmx_fsmc;
 extern struct pmx_dev pmx_spp;
-extern struct pmx_dev pmx_sdio;
+extern struct pmx_dev pmx_sdhci;
 extern struct pmx_dev pmx_i2s;
 extern struct pmx_dev pmx_uart1;
 extern struct pmx_dev pmx_uart1_modem;
 extern struct pmx_dev pmx_uart2;
 extern struct pmx_dev pmx_touchscreen;
 extern struct pmx_dev pmx_can;
-extern struct pmx_dev pmx_sdio_led;
+extern struct pmx_dev pmx_sdhci_led;
 extern struct pmx_dev pmx_pwm0;
 extern struct pmx_dev pmx_pwm1;
 extern struct pmx_dev pmx_pwm2;
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index 5ad7574..df0c1f3 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -69,7 +69,7 @@
 #define IRQ_CLCD				IRQ_GEN_RAS_3
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define IRQ_SDIO				IRQ_INTRCOMM_RAS_ARM
+#define IRQ_SDHCI				IRQ_INTRCOMM_RAS_ARM
 
 /* GPIO pins virtual irqs */
 #define SPEAR_GPIO_INT_BASE			(VIRQ_START + 9)
@@ -115,7 +115,7 @@
 #define VIRQ_SPP				(VIRQ_START + 2)
 
 /* IRQs sharing IRQ_GEN_RAS_2 */
-#define IRQ_SDIO				IRQ_GEN_RAS_2
+#define IRQ_SDHCI				IRQ_GEN_RAS_2
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
 #define VIRQ_PLGPIO				(VIRQ_START + 3)
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
index ccaa765..1059d5a 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear300.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -39,8 +39,8 @@
 #define SPEAR300_CLCD_BASE		0x60000000
 #define SPEAR300_CLCD_SIZE		0x10000000
 
-#define SPEAR300_SDIO_BASE		0x70000000
-#define SPEAR300_SDIO_SIZE		0x10000000
+#define SPEAR300_SDHCI_BASE		0x70000000
+#define SPEAR300_SDHCI_SIZE		0x10000000
 
 #define SPEAR300_NAND_0_BASE		0x80000000
 #define SPEAR300_NAND_0_SIZE		0x04000000
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index aa6727c..89f5bfb 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -28,8 +28,8 @@
 #define SPEAR320_I2S_BASE		0x60000000
 #define SPEAR320_I2S_SIZE		0x10000000
 
-#define SPEAR320_SDIO_BASE		0x70000000
-#define SPEAR320_SDIO_SIZE		0x10000000
+#define SPEAR320_SDHCI_BASE		0x70000000
+#define SPEAR320_SDHCI_SIZE		0x10000000
 
 #define SPEAR320_CLCD_BASE		0x90000000
 #define SPEAR320_CLCD_SIZE		0x10000000
@@ -77,7 +77,7 @@
 #define EMI_IRQ_MASK			(1 << 7)
 #define CLCD_IRQ_MASK			(1 << 8)
 #define SPP_IRQ_MASK			(1 << 9)
-#define SDIO_IRQ_MASK			(1 << 10)
+#define SDHCI_IRQ_MASK			(1 << 10)
 #define CAN_U_IRQ_MASK			(1 << 11)
 #define CAN_L_IRQ_MASK			(1 << 12)
 #define UART1_IRQ_MASK			(1 << 13)
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 3a86868..e11a625 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -311,7 +311,7 @@ struct pmx_dev pmx_telecom_boot_pins = {
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = {
+struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
@@ -324,14 +324,14 @@ struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_sdio_4bit = {
-	.name = "telecom_sdio_4bit",
-	.modes = pmx_telecom_sdio_4bit_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes),
+struct pmx_dev pmx_telecom_sdhci_4bit = {
+	.name = "telecom_sdhci_4bit",
+	.modes = pmx_telecom_sdhci_4bit_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = {
+struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
@@ -343,10 +343,10 @@ struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_sdio_8bit = {
-	.name = "telecom_sdio_8bit",
-	.modes = pmx_telecom_sdio_8bit_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes),
+struct pmx_dev pmx_telecom_sdhci_8bit = {
+	.name = "telecom_sdhci_8bit",
+	.modes = pmx_telecom_sdhci_8bit_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
 	.enb_on_reset = 1,
 };
 
@@ -524,6 +524,28 @@ struct platform_device nand3_device = {
 	.dev.platform_data = &nand3_platform_data,
 };
 
+/* sdhci (sdio) device declaration */
+static struct resource sdhci_resources[] = {
+	{
+		.start	= SPEAR300_SDHCI_BASE,
+		.end	= SPEAR300_SDHCI_BASE + SZ_256 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_SDHCI,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
@@ -577,6 +599,26 @@ struct spear_shirq shirq_ras1 = {
 	},
 };
 
+/* Function handling sdhci and i2s memory sharing */
+#define SDHCI_MEM_SELECT	0x20000000
+void sdhci_i2s_mem_enable(u8 mask)
+{
+	u32 val;
+	void __iomem *base = ioremap(SPEAR300_SOC_CONFIG_BASE,
+			SPEAR300_SOC_CONFIG_SIZE);
+	if (!base) {
+		pr_debug("sdhci_i2s_enb: ioremap fail\n");
+		return;
+	}
+
+	val = readl(base + MODE_CONFIG_REG);
+	if (mask == SDHCI_MEM_ENB)
+		val |= SDHCI_MEM_SELECT;
+	else
+		val &= ~SDHCI_MEM_SELECT;
+	writel(val, base + MODE_CONFIG_REG);
+}
+
 /* spear300 routines */
 void __init spear300_init(void)
 {
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 653adec..d6eb2a7 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -16,6 +16,7 @@
 #include <asm/mach-types.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <mach/generic.h>
 #include <mach/gpio.h>
 #include <mach/spear.h>
@@ -36,7 +37,7 @@ static struct pmx_dev *pmx_devs[] = {
 	/* spear300 specific devices */
 	&pmx_fsmc_2_chips,
 	&pmx_clcd,
-	&pmx_telecom_sdio_4bit,
+	&pmx_telecom_sdhci_4bit,
 	&pmx_gpio1,
 };
 
@@ -64,6 +65,15 @@ static struct platform_device *plat_devs[] __initdata = {
 
 	/* spear300 specific devices */
 	&kbd_device,
+	&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,
 };
 
 /* keyboard specific platform data */
@@ -134,6 +144,12 @@ static void __init spear300_evb_init(void)
 	nand_set_plat_data(&nand0_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
+	/* set sdhci device platform data */
+	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
+
+	/* Enable sdhci memory */
+	sdhci_i2s_mem_enable(SDHCI_MEM_ENB);
+
 	/* call spear300 machine init function */
 	spear300_init();
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 9c3d75f..341ba4a 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -13,6 +13,8 @@
 
 #include <linux/amba/pl022.h>
 #include <linux/ptrace.h>
+#include <linux/types.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <asm/irq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
@@ -113,7 +115,7 @@ struct pmx_dev pmx_spp = {
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdio_modes[] = {
+struct pmx_dev_mode pmx_sdhci_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
 			SMALL_PRINTERS_MODE,
@@ -121,10 +123,10 @@ struct pmx_dev_mode pmx_sdio_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_sdio = {
-	.name = "sdio",
-	.modes = pmx_sdio_modes,
-	.mode_count = ARRAY_SIZE(pmx_sdio_modes),
+struct pmx_dev pmx_sdhci = {
+	.name = "sdhci",
+	.modes = pmx_sdhci_modes,
+	.mode_count = ARRAY_SIZE(pmx_sdhci_modes),
 	.enb_on_reset = 1,
 };
 
@@ -218,17 +220,17 @@ struct pmx_dev pmx_can = {
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdio_led_modes[] = {
+struct pmx_dev_mode pmx_sdhci_led_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_sdio_led = {
-	.name = "sdio_led",
-	.modes = pmx_sdio_led_modes,
-	.mode_count = ARRAY_SIZE(pmx_sdio_led_modes),
+struct pmx_dev pmx_sdhci_led = {
+	.name = "sdhci_led",
+	.modes = pmx_sdhci_led_modes,
+	.mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
 	.enb_on_reset = 1,
 };
 
@@ -536,6 +538,27 @@ struct platform_device 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	= IRQ_SDHCI,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device sdhci_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+	},
+	.name = "sdhci",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(sdhci_resources),
+	.resource = sdhci_resources,
+};
 
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 99ae3ba..52f3b75 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <linux/spi/flash.h>
+#include <linux/mmc/sdhci-spear.h>
 #include <linux/spi/spi.h>
 #include <mach/generic.h>
 #include <mach/gpio.h>
@@ -33,7 +34,7 @@ static struct pmx_dev *pmx_devs[] = {
 
 	/* spear320 specific devices */
 	&pmx_fsmc,
-	&pmx_sdio,
+	&pmx_sdhci,
 	&pmx_i2s,
 	&pmx_uart1,
 	&pmx_uart2,
@@ -68,6 +69,15 @@ static struct platform_device *plat_devs[] __initdata = {
 	&i2c1_device,
 	&plgpio_device,
 	&pwm_device,
+	&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,
 };
 
 /* Currently no gpios are free on eval board so it is kept commented */
@@ -114,6 +124,9 @@ static void __init spear320_evb_init(void)
 {
 	unsigned int i;
 
+	/* set sdhci device platform data */
+	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
+
 	/* padmux initialization, must be done before spear320_init */
 	pmx_driver.mode = &auto_net_mii_mode;
 	pmx_driver.devs = pmx_devs;
-- 
1.7.2.2

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

* [PATCH 34/74] ST SPEAr: Changing resource size of amba devices to SZ_4K
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (25 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 33/74] ST SPEAr: Adding support for SDHCI (SDIO) Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration Viresh KUMAR
                   ` (47 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear3xx/spear300.c |    2 +-
 arch/arm/mach-spear3xx/spear320.c |    2 +-
 arch/arm/mach-spear3xx/spear3xx.c |    2 +-
 arch/arm/mach-spear6xx/spear6xx.c |    8 +++-----
 4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index e11a625..9c6b2ff 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -382,7 +382,7 @@ struct amba_device clcd_device = {
 	},
 	.res = {
 		.start = SPEAR300_CLCD_BASE,
-		.end = SPEAR300_CLCD_BASE + SPEAR300_CLCD_SIZE - 1,
+		.end = SPEAR300_CLCD_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.dma_mask = ~0,
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 341ba4a..14aa9a3 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -399,7 +399,7 @@ struct amba_device clcd_device = {
 	},
 	.res = {
 		.start = SPEAR320_CLCD_BASE,
-		.end = SPEAR320_CLCD_BASE + SPEAR320_CLCD_SIZE - 1,
+		.end = SPEAR320_CLCD_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.dma_mask = ~0,
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index fdb4fa8..b7f7ea7 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -79,7 +79,7 @@ struct amba_device uart_device = {
 	},
 	.res = {
 		.start = SPEAR3XX_ICM1_UART_BASE,
-		.end = SPEAR3XX_ICM1_UART_BASE + SPEAR3XX_ICM1_UART_SIZE - 1,
+		.end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.irq = {IRQ_UART, NO_IRQ},
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 876692e..489a36e 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -35,7 +35,7 @@ struct amba_device clcd_device = {
 	},
 	.res = {
 		.start = SPEAR6XX_ICM3_CLCD_BASE,
-		.end = SPEAR6XX_ICM3_CLCD_BASE + SPEAR6XX_ICM3_CLCD_SIZE - 1,
+		.end = SPEAR6XX_ICM3_CLCD_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	.dma_mask = ~0,
@@ -117,8 +117,7 @@ struct amba_device uart_device[] = {
 		},
 		.res = {
 			.start = SPEAR6XX_ICM1_UART0_BASE,
-			.end = SPEAR6XX_ICM1_UART0_BASE +
-				SPEAR6XX_ICM1_UART0_SIZE - 1,
+			.end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
 		.irq = {IRQ_UART_0, NO_IRQ},
@@ -128,8 +127,7 @@ struct amba_device uart_device[] = {
 		},
 		.res = {
 			.start = SPEAR6XX_ICM1_UART1_BASE,
-			.end = SPEAR6XX_ICM1_UART1_BASE +
-				SPEAR6XX_ICM1_UART1_SIZE - 1,
+			.end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
 		.irq = {IRQ_UART_1, NO_IRQ},
-- 
1.7.2.2

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

* [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (26 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 34/74] ST SPEAr: Changing resource size of amba devices to SZ_4K Viresh KUMAR
@ 2010-08-30 10:38 ` Viresh KUMAR
  2010-09-02 10:02   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 36/74] ST SPEAr: Replacing SIZE macro's with actual required size Viresh KUMAR
                   ` (46 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

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        |    5 +--
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300_evb.c          |    7 +---
 arch/arm/mach-spear3xx/spear310_evb.c          |    7 +---
 arch/arm/mach-spear3xx/spear320_evb.c          |    7 +---
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    7 +---
 arch/arm/plat-spear/include/plat/device.h      |   37 ++++++++++++++++++++++++
 9 files changed, 49 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/device.h

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index a09bf62..18800b0 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
+#include <plat/device.h>
 
 /*
  * Each GPT has 2 timer channels
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index aed4bba..db05747 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -121,8 +121,6 @@ static int spear1300_pcie_port_is_host(int port)
 
 static void __init spear1300_evb_init(void)
 {
-	unsigned int i;
-
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
@@ -150,8 +148,7 @@ static void __init spear1300_evb_init(void)
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-		amba_device_register(amba_devs[i], &iomem_resource);
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 9bd9424..ddfc382 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
+#include <plat/device.h>
 #include <plat/padmux.h>
 
 /* spear3xx declarations */
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index d6eb2a7..1bcbd95 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -11,9 +11,9 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/mtd/nand.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <linux/mmc/sdhci-spear.h>
@@ -130,8 +130,6 @@ static void __init spi_init(void)
 
 static void __init spear300_evb_init(void)
 {
-	unsigned int i;
-
 	/* padmux initialization, must be done before spear300_init */
 	pmx_driver.mode = &photo_frame_mode;
 	pmx_driver.devs = pmx_devs;
@@ -163,8 +161,7 @@ static void __init spear300_evb_init(void)
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-		amba_device_register(amba_devs[i], &iomem_resource);
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 663e78e..612eb04 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -11,9 +11,9 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/mtd/nand.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <mach/generic.h>
@@ -108,8 +108,6 @@ static void __init spi_init(void)
 
 static void __init spear310_evb_init(void)
 {
-	unsigned int i;
-
 	/* padmux initialization, must be done before spear310_init */
 	pmx_driver.mode = NULL;
 	pmx_driver.devs = pmx_devs;
@@ -132,8 +130,7 @@ static void __init spear310_evb_init(void)
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-		amba_device_register(amba_devs[i], &iomem_resource);
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 52f3b75..261c0b0 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -11,9 +11,9 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/mtd/nand.h>
 #include <linux/spi/flash.h>
 #include <linux/mmc/sdhci-spear.h>
 #include <linux/spi/spi.h>
@@ -122,8 +122,6 @@ static void __init spi_init(void)
 
 static void __init spear320_evb_init(void)
 {
-	unsigned int i;
-
 	/* set sdhci device platform data */
 	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
 
@@ -149,8 +147,7 @@ static void __init spear320_evb_init(void)
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-		amba_device_register(amba_devs[i], &iomem_resource);
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index dd29298..b33e436 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
+#include <plat/device.h>
 
 /*
  * Each GPT has 2 timer channels
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
index ae1055a..b03e761 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -11,9 +11,9 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <linux/mtd/nand.h>
 #include <linux/gpio.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
@@ -91,8 +91,6 @@ static void __init spi_init(void)
 
 static void __init spear600_evb_init(void)
 {
-	unsigned int i;
-
 	/* set nand device's plat data */
 	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
@@ -110,8 +108,7 @@ static void __init spear600_evb_init(void)
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-		amba_device_register(amba_devs[i], &iomem_resource);
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	spi_init();
 }
diff --git a/arch/arm/plat-spear/include/plat/device.h b/arch/arm/plat-spear/include/plat/device.h
new file mode 100644
index 0000000..008581b
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/device.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/plat-spear/include/plat/device.h
+ *
+ * device definitions for SPEAr platform
+ *
+ * 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_DEVICE_H
+#define __PLAT_DEVICE_H
+
+#include <linux/amba/bus.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+static inline void
+spear_amba_device_register(struct amba_device **devices, u32 count)
+{
+	u32 i;
+
+	for (i = 0; i < count; i++) {
+		struct clk *clk = clk_get_sys(devices[i]->dev.init_name, NULL);
+		if (IS_ERR(clk))
+			continue;
+
+		clk_enable(clk);
+		amba_device_register(devices[i], &iomem_resource);
+		clk_disable(clk);
+	}
+}
+
+#endif /* __PLAT_DEVICE_H */
-- 
1.7.2.2

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

* [PATCH 36/74] ST SPEAr: Replacing SIZE macro's with actual required size
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (27 preceding siblings ...)
  2010-08-30 10:38 ` [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 37/74] SPEAr: removing size based macros except those necessary Viresh KUMAR
                   ` (45 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

In arch specific files SIZE macro's were defined which were used for
creating memory/io mappings for sepecific devices. These macro's are
coming straight from h/w user manual and are much greated than required
sizes. Replacing these macros by actual required size.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/spear300.c |    9 +++------
 arch/arm/mach-spear3xx/spear310.c |    2 +-
 arch/arm/mach-spear3xx/spear320.c |    2 +-
 arch/arm/mach-spear3xx/spear3xx.c |    8 ++++----
 arch/arm/mach-spear6xx/spear6xx.c |   10 +++++-----
 5 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 9c6b2ff..c99db91 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -604,8 +604,7 @@ struct spear_shirq shirq_ras1 = {
 void sdhci_i2s_mem_enable(u8 mask)
 {
 	u32 val;
-	void __iomem *base = ioremap(SPEAR300_SOC_CONFIG_BASE,
-			SPEAR300_SOC_CONFIG_SIZE);
+	void __iomem *base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
 	if (!base) {
 		pr_debug("sdhci_i2s_enb: ioremap fail\n");
 		return;
@@ -628,8 +627,7 @@ void __init spear300_init(void)
 	spear3xx_init();
 
 	/* shared irq registeration */
-	shirq_ras1.regs.base =
-		ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE);
+	shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K);
 	if (shirq_ras1.regs.base) {
 		ret = spear_shirq_register(&shirq_ras1);
 		if (ret)
@@ -637,8 +635,7 @@ void __init spear300_init(void)
 	}
 
 	/* pmx initialization */
-	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
-			SPEAR300_SOC_CONFIG_SIZE);
+	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
 	if (pmx_driver.base) {
 		ret = pmx_register(&pmx_driver);
 		if (ret)
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 69350b7..b73e2df 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -362,7 +362,7 @@ void __init spear310_init(void)
 	spear3xx_init();
 
 	/* shared irq registeration */
-	base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE);
+	base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K);
 	if (base) {
 		/* shirq 1 */
 		shirq_ras1.regs.base = base;
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 14aa9a3..7a2e07c 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -694,7 +694,7 @@ void __init spear320_init(void)
 	spear3xx_init();
 
 	/* shared irq registeration */
-	base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE);
+	base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K);
 	if (base) {
 		/* shirq 1 */
 		shirq_ras1.regs.base = base;
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index b7f7ea7..18072ee 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -254,22 +254,22 @@ struct map_desc spear3xx_io_desc[] __initdata = {
 	{
 		.virtual	= VA_SPEAR3XX_ICM1_UART_BASE,
 		.pfn		= __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
-		.length		= SPEAR3XX_ICM1_UART_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR3XX_ML1_VIC_BASE,
 		.pfn		= __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
-		.length		= SPEAR3XX_ML1_VIC_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
 		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
-		.length		= SPEAR3XX_ICM3_SYS_CTRL_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR3XX_ICM3_MISC_REG_BASE,
 		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
-		.length		= SPEAR3XX_ICM3_MISC_REG_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	},
 };
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 489a36e..eb72c4c 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -408,27 +408,27 @@ static struct map_desc spear6xx_io_desc[] __initdata = {
 	{
 		.virtual	= VA_SPEAR6XX_ICM1_UART0_BASE,
 		.pfn		= __phys_to_pfn(SPEAR6XX_ICM1_UART0_BASE),
-		.length		= SPEAR6XX_ICM1_UART0_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR6XX_CPU_VIC_PRI_BASE,
 		.pfn		= __phys_to_pfn(SPEAR6XX_CPU_VIC_PRI_BASE),
-		.length		= SPEAR6XX_CPU_VIC_PRI_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR6XX_CPU_VIC_SEC_BASE,
 		.pfn		= __phys_to_pfn(SPEAR6XX_CPU_VIC_SEC_BASE),
-		.length		= SPEAR6XX_CPU_VIC_SEC_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR6XX_ICM3_SYS_CTRL_BASE,
 		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_SYS_CTRL_BASE),
-		.length		= SPEAR6XX_ICM3_MISC_REG_BASE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
 		.virtual	= VA_SPEAR6XX_ICM3_MISC_REG_BASE,
 		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE),
-		.length		= SPEAR6XX_ICM3_MISC_REG_SIZE,
+		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	},
 };
-- 
1.7.2.2

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

* [PATCH 37/74] SPEAr: removing size based macros except those necessary
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (28 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 36/74] ST SPEAr: Replacing SIZE macro's with actual required size Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file Viresh KUMAR
                   ` (44 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Size macros are defined in machine specific files which are really not
required. These size defines were coming straight from h/w user manual
which were much greater than required size. Hence these are removed for
any use.
Also the base addresses are defined as ulong.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/spear.h   |   91 ++++++------
 arch/arm/mach-spear3xx/include/mach/spear.h    |  134 +++++-------------
 arch/arm/mach-spear3xx/include/mach/spear300.h |   59 ++------
 arch/arm/mach-spear3xx/include/mach/spear310.h |   34 ++---
 arch/arm/mach-spear3xx/include/mach/spear320.h |   68 +++-------
 arch/arm/mach-spear6xx/include/mach/spear.h    |  174 ++++++-----------------
 6 files changed, 172 insertions(+), 388 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index 282ef2f..1a1af72 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -14,12 +14,13 @@
 #ifndef __MACH_SPEAR13XX_H
 #define __MACH_SPEAR13XX_H
 
+#include <asm/memory.h>
 #include <mach/spear1300.h>
 
-#define SPEAR13XX_L2CC_BASE		0xED000000
+#define SPEAR13XX_L2CC_BASE		UL(0xED000000)
 
 /* ARM9SMP peripheral base address */
-#define SPEAR13XX_A9SM_PERIP_BASE	0xEC800000
+#define SPEAR13XX_A9SM_PERIP_BASE	UL(0xEC800000)
 #define VA_SPEAR13XX_A9SM_PERIP_BASE	IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE)
 /* A9SM peripheral offsets */
 #define SPEAR13XX_SCU_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x00)
@@ -29,26 +30,26 @@
 #define SPEAR13XX_WDT_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x620)
 #define SPEAR13XX_GIC_DIST_BASE		(SPEAR13XX_A9SM_PERIP_BASE + 0x1000)
 
-#define SPEAR13XX_UART_BASE		0xE0000000
+#define SPEAR13XX_UART_BASE		UL(0xE0000000)
 #define VA_SPEAR13XX_UART_BASE		IO_ADDRESS(SPEAR13XX_UART_BASE)
 
-#define SPEAR13XX_ADC_BASE		0xE0080000
-#define SPEAR13XX_SSP_BASE		0xE0100000
-#define SPEAR13XX_I2S0_BASE		0xE0180000
-#define SPEAR13XX_I2S1_BASE		0xE0200000
-#define SPEAR13XX_I2C_BASE		0xE0280000
-#define SPEAR13XX_KBD_BASE		0xE0300000
-#define SPEAR13XX_GPT0_BASE		0xE0380000
-#define SPEAR13XX_GPT1_BASE		0xE0400000
-#define SPEAR13XX_GPT2_BASE		0xE0480000
-#define SPEAR13XX_GPT3_BASE		0xE0500000
-#define SPEAR13XX_RTC_BASE		0xE0580000
-#define SPEAR13XX_GPIO0_BASE		0xE0600000
-#define SPEAR13XX_GPIO1_BASE		0xE0680000
-#define SPEAR13XX_MISC_BASE		0xE0700000
+#define SPEAR13XX_ADC_BASE		UL(0xE0080000)
+#define SPEAR13XX_SSP_BASE		UL(0xE0100000)
+#define SPEAR13XX_I2S0_BASE		UL(0xE0180000)
+#define SPEAR13XX_I2S1_BASE		UL(0xE0200000)
+#define SPEAR13XX_I2C_BASE		UL(0xE0280000)
+#define SPEAR13XX_KBD_BASE		UL(0xE0300000)
+#define SPEAR13XX_GPT0_BASE		UL(0xE0380000)
+#define SPEAR13XX_GPT1_BASE		UL(0xE0400000)
+#define SPEAR13XX_GPT2_BASE		UL(0xE0480000)
+#define SPEAR13XX_GPT3_BASE		UL(0xE0500000)
+#define SPEAR13XX_RTC_BASE		UL(0xE0580000)
+#define SPEAR13XX_GPIO0_BASE		UL(0xE0600000)
+#define SPEAR13XX_GPIO1_BASE		UL(0xE0680000)
+#define SPEAR13XX_MISC_BASE		UL(0xE0700000)
 #define VA_SPEAR13XX_MISC_BASE		IO_ADDRESS(SPEAR13XX_MISC_BASE)
 
-#define SPEAR13XX_SYSRAM0_BASE		0xB3800000
+#define SPEAR13XX_SYSRAM0_BASE		UL(0xB3800000)
 #define SPEAR13XX_SYSRAM0_SIZE		0x00800000
 
 /*
@@ -57,34 +58,34 @@
  */
 #define SPEAR13XX_SYS_LOCATION		(SPEAR13XX_SYSRAM0_BASE + 0x600)
 
-#define SPEAR13XX_SYSRAM1_BASE		0xE0800000
+#define SPEAR13XX_SYSRAM1_BASE		UL(0xE0800000)
 #define SPEAR13XX_SYSRAM1_SIZE		0x00800000
-#define SPEAR13XX_CLCD_BASE		0xE1000000
-#define SPEAR13XX_C3_BASE		0xE1800000
-#define SPEAR13XX_GETH_BASE		0xE2000000
-#define SPEAR13XX_UPD_BASE		0xE2800000
-#define SPEAR13XX_UDC_BASE		0xE3800000
-#define SPEAR13XX_UHC0_OHCI_BASE	0xE4000000
-#define SPEAR13XX_UHC0_EHCI_BASE	0xE4800000
-#define SPEAR13XX_UHC1_OHCI_BASE	0xE5000000
-#define SPEAR13XX_UHC1_EHCI_BASE	0xE5800000
-#define SPEAR13XX_SMI_MEM_BASE		0xE6000000
-#define SPEAR13XX_SMI_CTRL_BASE		0xEA000000
-#define SPEAR13XX_DMAC0_BASE		0xEA800000
-#define SPEAR13XX_DMAC1_BASE		0xEB000000
-#define SPEAR13XX_MII_PHY_BASE		0xEB800000
-#define SPEAR13XX_MPMC_BASE		0xEC000000
-#define SPEAR13XX_PCIE0_BASE		0x80000000
-#define SPEAR13XX_PCIE1_BASE		0x90000000
-#define SPEAR13XX_PCIE2_BASE		0xC0000000
-#define SPEAR13XX_PCIE0_APP_BASE	0xB1000000
-#define SPEAR13XX_PCIE1_APP_BASE	0xB1800000
-#define SPEAR13XX_PCIE2_APP_BASE	0xB4000000
-#define SPEAR13XX_FSMC_MEM_BASE		0xA0000000
-#define SPEAR13XX_FSMC_BASE		0xB0000000
-#define SPEAR13XX_JPEG_BASE		0xB2000000
-#define SPEAR13XX_MCIF_CF_BASE		0xB2800000
-#define SPEAR13XX_MCIF_SDHCI_BASE	0xB3000000
+#define SPEAR13XX_CLCD_BASE		UL(0xE1000000)
+#define SPEAR13XX_C3_BASE		UL(0xE1800000)
+#define SPEAR13XX_GETH_BASE		UL(0xE2000000)
+#define SPEAR13XX_UPD_BASE		UL(0xE2800000)
+#define SPEAR13XX_UDC_BASE		UL(0xE3800000)
+#define SPEAR13XX_UHC0_OHCI_BASE	UL(0xE4000000)
+#define SPEAR13XX_UHC0_EHCI_BASE	UL(0xE4800000)
+#define SPEAR13XX_UHC1_OHCI_BASE	UL(0xE5000000)
+#define SPEAR13XX_UHC1_EHCI_BASE	UL(0xE5800000)
+#define SPEAR13XX_SMI_MEM_BASE		UL(0xE6000000)
+#define SPEAR13XX_SMI_CTRL_BASE		UL(0xEA000000)
+#define SPEAR13XX_DMAC0_BASE		UL(0xEA800000)
+#define SPEAR13XX_DMAC1_BASE		UL(0xEB000000)
+#define SPEAR13XX_MII_PHY_BASE		UL(0xEB800000)
+#define SPEAR13XX_MPMC_BASE		UL(0xEC000000)
+#define SPEAR13XX_PCIE0_BASE		UL(0x80000000)
+#define SPEAR13XX_PCIE1_BASE		UL(0x90000000)
+#define SPEAR13XX_PCIE2_BASE		UL(0xC0000000)
+#define SPEAR13XX_PCIE0_APP_BASE	UL(0xB1000000)
+#define SPEAR13XX_PCIE1_APP_BASE	UL(0xB1800000)
+#define SPEAR13XX_PCIE2_APP_BASE	UL(0xB4000000)
+#define SPEAR13XX_FSMC_MEM_BASE		UL(0xA0000000)
+#define SPEAR13XX_FSMC_BASE		UL(0xB0000000)
+#define SPEAR13XX_JPEG_BASE		UL(0xB2000000)
+#define SPEAR13XX_MCIF_CF_BASE		UL(0xB2800000)
+#define SPEAR13XX_MCIF_SDHCI_BASE	UL(0xB3000000)
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR13XX_UART_BASE
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
index dcca856..00828bb 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -14,124 +14,62 @@
 #ifndef __MACH_SPEAR3XX_H
 #define __MACH_SPEAR3XX_H
 
+#include <asm/memory.h>
 #include <mach/hardware.h>
 #include <mach/spear300.h>
 #include <mach/spear310.h>
 #include <mach/spear320.h>
 
-#define SPEAR3XX_ML_SDRAM_BASE		0x00000000
-#define SPEAR3XX_ML_SDRAM_SIZE		0x40000000
+#define SPEAR3XX_ML_SDRAM_BASE		UL(0x00000000)
 
-#define SPEAR3XX_ICM9_BASE		0xC0000000
-#define SPEAR3XX_ICM9_SIZE		0x10000000
+#define SPEAR3XX_ICM9_BASE		UL(0xC0000000)
 
 /* ICM1 - Low speed connection */
-#define SPEAR3XX_ICM1_2_BASE		0xD0000000
-#define SPEAR3XX_ICM1_2_SIZE		0x10000000
-
-#define SPEAR3XX_ICM1_UART_BASE		0xD0000000
+#define SPEAR3XX_ICM1_2_BASE		UL(0xD0000000)
+#define SPEAR3XX_ICM1_UART_BASE		UL(0xD0000000)
 #define VA_SPEAR3XX_ICM1_UART_BASE	IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
-#define SPEAR3XX_ICM1_UART_SIZE		0x00080000
-
-#define SPEAR3XX_ICM1_ADC_BASE		0xD0080000
-#define SPEAR3XX_ICM1_ADC_SIZE		0x00080000
-
-#define SPEAR3XX_ICM1_SSP_BASE		0xD0100000
-#define SPEAR3XX_ICM1_SSP_SIZE		0x00080000
-
-#define SPEAR3XX_ICM1_I2C_BASE		0xD0180000
-#define SPEAR3XX_ICM1_I2C_SIZE		0x00080000
-
-#define SPEAR3XX_ICM1_JPEG_BASE		0xD0800000
-#define SPEAR3XX_ICM1_JPEG_SIZE		0x00800000
-
-#define SPEAR3XX_ICM1_IRDA_BASE		0xD1000000
-#define SPEAR3XX_ICM1_IRDA_SIZE		0x00080000
-
-#define SPEAR3XX_ICM1_SRAM_BASE		0xD2800000
-#define SPEAR3XX_ICM1_SRAM_SIZE		0x05800000
+#define SPEAR3XX_ICM1_ADC_BASE		UL(0xD0080000)
+#define SPEAR3XX_ICM1_SSP_BASE		UL(0xD0100000)
+#define SPEAR3XX_ICM1_I2C_BASE		UL(0xD0180000)
+#define SPEAR3XX_ICM1_JPEG_BASE		UL(0xD0800000)
+#define SPEAR3XX_ICM1_IRDA_BASE		UL(0xD1000000)
+#define SPEAR3XX_ICM1_SRAM_BASE		UL(0xD2800000)
 
 /* ICM2 - Application Subsystem */
-#define SPEAR3XX_ICM2_HWACCEL0_BASE	0xD8800000
-#define SPEAR3XX_ICM2_HWACCEL0_SIZE	0x00800000
-
-#define SPEAR3XX_ICM2_HWACCEL1_BASE	0xD9000000
-#define SPEAR3XX_ICM2_HWACCEL1_SIZE	0x00800000
+#define SPEAR3XX_ICM2_HWACCEL0_BASE	UL(0xD8800000)
+#define SPEAR3XX_ICM2_HWACCEL1_BASE	UL(0xD9000000)
 
 /* ICM4 - High Speed Connection */
-#define SPEAR3XX_ICM4_BASE		0xE0000000
-#define SPEAR3XX_ICM4_SIZE		0x08000000
-
-#define SPEAR3XX_ICM4_MII_BASE		0xE0800000
-#define SPEAR3XX_ICM4_MII_SIZE		0x00800000
-
-#define SPEAR3XX_ICM4_USBD_FIFO_BASE	0xE1000000
-#define SPEAR3XX_ICM4_USBD_FIFO_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USBD_CSR_BASE	0xE1100000
-#define SPEAR3XX_ICM4_USBD_CSR_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USBD_PLDT_BASE	0xE1200000
-#define SPEAR3XX_ICM4_USBD_PLDT_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE	0xE1800000
-#define SPEAR3XX_ICM4_USB_EHCI0_1_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USB_OHCI0_BASE	0xE1900000
-#define SPEAR3XX_ICM4_USB_OHCI0_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USB_OHCI1_BASE	0xE2100000
-#define SPEAR3XX_ICM4_USB_OHCI1_SIZE	0x00100000
-
-#define SPEAR3XX_ICM4_USB_ARB_BASE	0xE2800000
-#define SPEAR3XX_ICM4_USB_ARB_SIZE	0x00010000
+#define SPEAR3XX_ICM4_BASE		UL(0xE0000000)
+#define SPEAR3XX_ICM4_MII_BASE		UL(0xE0800000)
+#define SPEAR3XX_ICM4_USBD_FIFO_BASE	UL(0xE1000000)
+#define SPEAR3XX_ICM4_USBD_CSR_BASE	UL(0xE1100000)
+#define SPEAR3XX_ICM4_USBD_PLDT_BASE	UL(0xE1200000)
+#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE	UL(0xE1800000)
+#define SPEAR3XX_ICM4_USB_OHCI0_BASE	UL(0xE1900000)
+#define SPEAR3XX_ICM4_USB_OHCI1_BASE	UL(0xE2100000)
+#define SPEAR3XX_ICM4_USB_ARB_BASE	UL(0xE2800000)
 
 /* ML1 - Multi Layer CPU Subsystem */
-#define SPEAR3XX_ICM3_ML1_2_BASE	0xF0000000
-#define SPEAR3XX_ICM3_ML1_2_SIZE	0x0F000000
-
-#define SPEAR3XX_ML1_TMR_BASE		0xF0000000
-#define SPEAR3XX_ML1_TMR_SIZE		0x00100000
-
-#define SPEAR3XX_ML1_VIC_BASE		0xF1100000
+#define SPEAR3XX_ICM3_ML1_2_BASE	UL(0xF0000000)
+#define SPEAR3XX_ML1_TMR_BASE		UL(0xF0000000)
+#define SPEAR3XX_ML1_VIC_BASE		UL(0xF1100000)
 #define VA_SPEAR3XX_ML1_VIC_BASE	IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
-#define SPEAR3XX_ML1_VIC_SIZE		0x00100000
 
 /* ICM3 - Basic Subsystem */
-#define SPEAR3XX_ICM3_SMEM_BASE		0xF8000000
-#define SPEAR3XX_ICM3_SMEM_SIZE		0x04000000
-
-#define SPEAR3XX_ICM3_SMI_CTRL_BASE	0xFC000000
-#define SPEAR3XX_ICM3_SMI_CTRL_SIZE	0x00200000
-
-#define SPEAR3XX_ICM3_DMA_BASE		0xFC400000
-#define SPEAR3XX_ICM3_DMA_SIZE		0x00200000
-
-#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE	0xFC600000
-#define SPEAR3XX_ICM3_SDRAM_CTRL_SIZE	0x00200000
-
-#define SPEAR3XX_ICM3_TMR0_BASE		0xFC800000
-#define SPEAR3XX_ICM3_TMR0_SIZE		0x00080000
-
-#define SPEAR3XX_ICM3_WDT_BASE		0xFC880000
-#define SPEAR3XX_ICM3_WDT_SIZE		0x00080000
-
-#define SPEAR3XX_ICM3_RTC_BASE		0xFC900000
-#define SPEAR3XX_ICM3_RTC_SIZE		0x00080000
-
-#define SPEAR3XX_ICM3_GPIO_BASE		0xFC980000
-#define SPEAR3XX_ICM3_GPIO_SIZE		0x00080000
-
-#define SPEAR3XX_ICM3_SYS_CTRL_BASE	0xFCA00000
+#define SPEAR3XX_ICM3_SMEM_BASE		UL(0xF8000000)
+#define SPEAR3XX_ICM3_SMI_CTRL_BASE	UL(0xFC000000)
+#define SPEAR3XX_ICM3_DMA_BASE		UL(0xFC400000)
+#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE	UL(0xFC600000)
+#define SPEAR3XX_ICM3_TMR0_BASE		UL(0xFC800000)
+#define SPEAR3XX_ICM3_WDT_BASE		UL(0xFC880000)
+#define SPEAR3XX_ICM3_RTC_BASE		UL(0xFC900000)
+#define SPEAR3XX_ICM3_GPIO_BASE		UL(0xFC980000)
+#define SPEAR3XX_ICM3_SYS_CTRL_BASE	UL(0xFCA00000)
 #define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE	IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
-#define SPEAR3XX_ICM3_SYS_CTRL_SIZE	0x00080000
-
-#define SPEAR3XX_ICM3_MISC_REG_BASE	0xFCA80000
+#define SPEAR3XX_ICM3_MISC_REG_BASE	UL(0xFCA80000)
 #define VA_SPEAR3XX_ICM3_MISC_REG_BASE	IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
-#define SPEAR3XX_ICM3_MISC_REG_SIZE	0x00080000
-
-#define SPEAR3XX_ICM3_TMR1_BASE		0xFCB00000
-#define SPEAR3XX_ICM3_TMR1_SIZE		0x00080000
+#define SPEAR3XX_ICM3_TMR1_BASE		UL(0xFCB00000)
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR3XX_ICM1_UART_BASE
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
index 1059d5a..c723515 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear300.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -17,11 +17,9 @@
 #define __MACH_SPEAR300_H
 
 /* Base address of various IPs */
-#define SPEAR300_TELECOM_BASE		0x50000000
-#define SPEAR300_TELECOM_SIZE		0x10000000
+#define SPEAR300_TELECOM_BASE		UL(0x50000000)
 
 /* Interrupt registers offsets and masks */
-#define SPEAR300_TELECOM_REG_SIZE	0x00010000
 #define INT_ENB_MASK_REG		0x54
 #define INT_STS_MASK_REG		0x58
 #define IT_PERS_S_IRQ_MASK		(1 << 0)
@@ -36,47 +34,20 @@
 
 #define SHIRQ_RAS1_MASK			0x1FF
 
-#define SPEAR300_CLCD_BASE		0x60000000
-#define SPEAR300_CLCD_SIZE		0x10000000
-
-#define SPEAR300_SDHCI_BASE		0x70000000
-#define SPEAR300_SDHCI_SIZE		0x10000000
-
-#define SPEAR300_NAND_0_BASE		0x80000000
-#define SPEAR300_NAND_0_SIZE		0x04000000
-
-#define SPEAR300_NAND_1_BASE		0x84000000
-#define SPEAR300_NAND_1_SIZE		0x04000000
-
-#define SPEAR300_NAND_2_BASE		0x88000000
-#define SPEAR300_NAND_2_SIZE		0x04000000
-
-#define SPEAR300_NAND_3_BASE		0x8c000000
-#define SPEAR300_NAND_3_SIZE		0x04000000
-
-#define SPEAR300_NOR_0_BASE		0x90000000
-#define SPEAR300_NOR_0_SIZE		0x01000000
-
-#define SPEAR300_NOR_1_BASE		0x91000000
-#define SPEAR300_NOR_1_SIZE		0x01000000
-
-#define SPEAR300_NOR_2_BASE		0x92000000
-#define SPEAR300_NOR_2_SIZE		0x01000000
-
-#define SPEAR300_NOR_3_BASE		0x93000000
-#define SPEAR300_NOR_3_SIZE		0x01000000
-
-#define SPEAR300_FSMC_BASE		0x94000000
-#define SPEAR300_FSMC_SIZE		0x05000000
-
-#define SPEAR300_SOC_CONFIG_BASE	0x99000000
-#define SPEAR300_SOC_CONFIG_SIZE	0x00000008
-
-#define SPEAR300_KEYBOARD_BASE		0xA0000000
-#define SPEAR300_KEYBOARD_SIZE		0x09000000
-
-#define SPEAR300_GPIO_BASE		0xA9000000
-#define SPEAR300_GPIO_SIZE		0x07000000
+#define SPEAR300_CLCD_BASE		UL(0x60000000)
+#define SPEAR300_SDHCI_BASE		UL(0x70000000)
+#define SPEAR300_NAND_0_BASE		UL(0x80000000)
+#define SPEAR300_NAND_1_BASE		UL(0x84000000)
+#define SPEAR300_NAND_2_BASE		UL(0x88000000)
+#define SPEAR300_NAND_3_BASE		UL(0x8c000000)
+#define SPEAR300_NOR_0_BASE		UL(0x90000000)
+#define SPEAR300_NOR_1_BASE		UL(0x91000000)
+#define SPEAR300_NOR_2_BASE		UL(0x92000000)
+#define SPEAR300_NOR_3_BASE		UL(0x93000000)
+#define SPEAR300_FSMC_BASE		UL(0x94000000)
+#define SPEAR300_SOC_CONFIG_BASE	UL(0x99000000)
+#define SPEAR300_KEYBOARD_BASE		UL(0xA0000000)
+#define SPEAR300_GPIO_BASE		UL(0xA9000000)
 
 #endif /* __MACH_SPEAR300_H */
 
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
index b27bb8a..1e85347 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear310.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -16,30 +16,18 @@
 #ifndef __MACH_SPEAR310_H
 #define __MACH_SPEAR310_H
 
-#define SPEAR310_NAND_BASE		0x40000000
-#define SPEAR310_NAND_SIZE		0x04000000
+#define SPEAR310_NAND_BASE		UL(0x40000000)
+#define SPEAR310_FSMC_BASE		UL(0x44000000)
+#define SPEAR310_UART1_BASE		UL(0xB2000000)
+#define SPEAR310_UART2_BASE		UL(0xB2080000)
+#define SPEAR310_UART3_BASE		UL(0xB2100000)
+#define SPEAR310_UART4_BASE		UL(0xB2180000)
+#define SPEAR310_UART5_BASE		UL(0xB2200000)
+#define SPEAR310_HDLC_BASE		UL(0xB2800000)
+#define SPEAR310_RS485_0_BASE		UL(0xB3000000)
+#define SPEAR310_RS485_1_BASE		UL(0xB3800000)
+#define SPEAR310_SOC_CONFIG_BASE	UL(0xB4000000)
 
-#define SPEAR310_FSMC_BASE		0x44000000
-#define SPEAR310_FSMC_SIZE		0x01000000
-
-#define SPEAR310_UART1_BASE		0xB2000000
-#define SPEAR310_UART2_BASE		0xB2080000
-#define SPEAR310_UART3_BASE		0xB2100000
-#define SPEAR310_UART4_BASE		0xB2180000
-#define SPEAR310_UART5_BASE		0xB2200000
-#define SPEAR310_UART_SIZE		0x00080000
-
-#define SPEAR310_HDLC_BASE		0xB2800000
-#define SPEAR310_HDLC_SIZE		0x00800000
-
-#define SPEAR310_RS485_0_BASE		0xB3000000
-#define SPEAR310_RS485_0_SIZE		0x00800000
-
-#define SPEAR310_RS485_1_BASE		0xB3800000
-#define SPEAR310_RS485_1_SIZE		0x00800000
-
-#define SPEAR310_SOC_CONFIG_BASE	0xB4000000
-#define SPEAR310_SOC_CONFIG_SIZE	0x00000070
 /* Interrupt registers offsets and masks */
 #define INT_STS_MASK_REG		0x04
 #define SMII0_IRQ_MASK			(1 << 0)
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index 89f5bfb..940f0d8 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -16,57 +16,25 @@
 #ifndef __MACH_SPEAR320_H
 #define __MACH_SPEAR320_H
 
-#define SPEAR320_EMI_CTRL_BASE		0x40000000
-#define SPEAR320_EMI_CTRL_SIZE		0x08000000
+#define SPEAR320_EMI_CTRL_BASE		UL(0x40000000)
+#define SPEAR320_FSMC_BASE		UL(0x4C000000)
+#define SPEAR320_NAND_BASE		UL(0x50000000)
+#define SPEAR320_I2S_BASE		UL(0x60000000)
+#define SPEAR320_SDHCI_BASE		UL(0x70000000)
+#define SPEAR320_CLCD_BASE		UL(0x90000000)
+#define SPEAR320_PAR_PORT_BASE		UL(0xA0000000)
+#define SPEAR320_CAN0_BASE		UL(0xA1000000)
+#define SPEAR320_CAN1_BASE		UL(0xA2000000)
+#define SPEAR320_UART1_BASE		UL(0xA3000000)
+#define SPEAR320_UART2_BASE		UL(0xA4000000)
+#define SPEAR320_SSP0_BASE		UL(0xA5000000)
+#define SPEAR320_SSP1_BASE		UL(0xA6000000)
+#define SPEAR320_I2C_BASE		UL(0xA7000000)
+#define SPEAR320_PWM_BASE		UL(0xA8000000)
+#define SPEAR320_SMII0_BASE		UL(0xAA000000)
+#define SPEAR320_SMII1_BASE		UL(0xAB000000)
+#define SPEAR320_SOC_CONFIG_BASE	UL(0xB3000000)
 
-#define SPEAR320_FSMC_BASE		0x4C000000
-#define SPEAR320_FSMC_SIZE		0x01000000
-
-#define SPEAR320_NAND_BASE		0x50000000
-#define SPEAR320_NAND_SIZE		0x04000000
-
-#define SPEAR320_I2S_BASE		0x60000000
-#define SPEAR320_I2S_SIZE		0x10000000
-
-#define SPEAR320_SDHCI_BASE		0x70000000
-#define SPEAR320_SDHCI_SIZE		0x10000000
-
-#define SPEAR320_CLCD_BASE		0x90000000
-#define SPEAR320_CLCD_SIZE		0x10000000
-
-#define SPEAR320_PAR_PORT_BASE		0xA0000000
-#define SPEAR320_PAR_PORT_SIZE		0x01000000
-
-#define SPEAR320_CAN0_BASE		0xA1000000
-#define SPEAR320_CAN0_SIZE		0x01000000
-
-#define SPEAR320_CAN1_BASE		0xA2000000
-#define SPEAR320_CAN1_SIZE		0x01000000
-
-#define SPEAR320_UART1_BASE		0xA3000000
-#define SPEAR320_UART2_BASE		0xA4000000
-#define SPEAR320_UART_SIZE		0x01000000
-
-#define SPEAR320_SSP0_BASE		0xA5000000
-#define SPEAR320_SSP0_SIZE		0x01000000
-
-#define SPEAR320_SSP1_BASE		0xA6000000
-#define SPEAR320_SSP1_SIZE		0x01000000
-
-#define SPEAR320_I2C_BASE		0xA7000000
-#define SPEAR320_I2C_SIZE		0x01000000
-
-#define SPEAR320_PWM_BASE		0xA8000000
-#define SPEAR320_PWM_SIZE		0x01000000
-
-#define SPEAR320_SMII0_BASE		0xAA000000
-#define SPEAR320_SMII0_SIZE		0x01000000
-
-#define SPEAR320_SMII1_BASE		0xAB000000
-#define SPEAR320_SMII1_SIZE		0x01000000
-
-#define SPEAR320_SOC_CONFIG_BASE	0xB3000000
-#define SPEAR320_SOC_CONFIG_SIZE	0x00000070
 /* Interrupt registers offsets and masks */
 #define INT_STS_MASK_REG		0x04
 #define INT_CLR_MASK_REG		0x04
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
index 31486e5..4a2ecc7 100644
--- a/arch/arm/mach-spear6xx/include/mach/spear.h
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -14,153 +14,71 @@
 #ifndef __MACH_SPEAR6XX_H
 #define __MACH_SPEAR6XX_H
 
+#include <asm/memory.h>
 #include <mach/hardware.h>
 #include <mach/spear600.h>
 
-#define SPEAR6XX_ML_SDRAM_BASE		0x00000000
-#define SPEAR6XX_ML_SDRAM_SIZE		0x40000000
-
+#define SPEAR6XX_ML_SDRAM_BASE		UL(0x00000000)
 /* ICM1 - Low speed connection */
-#define SPEAR6XX_ICM1_BASE		0xD0000000
-#define SPEAR6XX_ICM1_SIZE		0x08000000
+#define SPEAR6XX_ICM1_BASE		UL(0xD0000000)
 
-#define SPEAR6XX_ICM1_UART0_BASE	0xD0000000
+#define SPEAR6XX_ICM1_UART0_BASE	UL(0xD0000000)
 #define VA_SPEAR6XX_ICM1_UART0_BASE	IO_ADDRESS(SPEAR6XX_ICM1_UART0_BASE)
-#define SPEAR6XX_ICM1_UART0_SIZE	0x00080000
-
-#define SPEAR6XX_ICM1_UART1_BASE	0xD0080000
-#define SPEAR6XX_ICM1_UART1_SIZE	0x00080000
-
-#define SPEAR6XX_ICM1_SSP0_BASE		0xD0100000
-#define SPEAR6XX_ICM1_SSP0_SIZE		0x00080000
-
-#define SPEAR6XX_ICM1_SSP1_BASE		0xD0180000
-#define SPEAR6XX_ICM1_SSP1_SIZE		0x00080000
-
-#define SPEAR6XX_ICM1_I2C_BASE		0xD0200000
-#define SPEAR6XX_ICM1_I2C_SIZE		0x00080000
 
-#define SPEAR6XX_ICM1_JPEG_BASE		0xD0800000
-#define SPEAR6XX_ICM1_JPEG_SIZE		0x00800000
-
-#define SPEAR6XX_ICM1_IRDA_BASE		0xD1000000
-#define SPEAR6XX_ICM1_IRDA_SIZE		0x00800000
-
-#define SPEAR6XX_ICM1_FSMC_BASE		0xD1800000
-#define SPEAR6XX_ICM1_FSMC_SIZE		0x00800000
-
-#define SPEAR6XX_ICM1_NAND_BASE		0xD2000000
-#define SPEAR6XX_ICM1_NAND_SIZE		0x00800000
-
-#define SPEAR6XX_ICM1_SRAM_BASE		0xD2800000
-#define SPEAR6XX_ICM1_SRAM_SIZE		0x00800000
+#define SPEAR6XX_ICM1_UART1_BASE	UL(0xD0080000)
+#define SPEAR6XX_ICM1_SSP0_BASE		UL(0xD0100000)
+#define SPEAR6XX_ICM1_SSP1_BASE		UL(0xD0180000)
+#define SPEAR6XX_ICM1_I2C_BASE		UL(0xD0200000)
+#define SPEAR6XX_ICM1_JPEG_BASE		UL(0xD0800000)
+#define SPEAR6XX_ICM1_IRDA_BASE		UL(0xD1000000)
+#define SPEAR6XX_ICM1_FSMC_BASE		UL(0xD1800000)
+#define SPEAR6XX_ICM1_NAND_BASE		UL(0xD2000000)
+#define SPEAR6XX_ICM1_SRAM_BASE		UL(0xD2800000)
 
 /* ICM2 - Application Subsystem */
-#define SPEAR6XX_ICM2_BASE		0xD8000000
-#define SPEAR6XX_ICM2_SIZE		0x08000000
-
-#define SPEAR6XX_ICM2_TMR0_BASE		0xD8000000
-#define SPEAR6XX_ICM2_TMR0_SIZE		0x00080000
-
-#define SPEAR6XX_ICM2_TMR1_BASE		0xD8080000
-#define SPEAR6XX_ICM2_TMR1_SIZE		0x00080000
-
-#define SPEAR6XX_ICM2_GPIO_BASE		0xD8100000
-#define SPEAR6XX_ICM2_GPIO_SIZE		0x00080000
-
-#define SPEAR6XX_ICM2_SSP2_BASE		0xD8180000
-#define SPEAR6XX_ICM2_SSP2_SIZE		0x00080000
-
-#define SPEAR6XX_ICM2_ADC_BASE		0xD8200000
-#define SPEAR6XX_ICM2_ADC_SIZE		0x00080000
+#define SPEAR6XX_ICM2_BASE		UL(0xD8000000)
+#define SPEAR6XX_ICM2_TMR0_BASE		UL(0xD8000000)
+#define SPEAR6XX_ICM2_TMR1_BASE		UL(0xD8080000)
+#define SPEAR6XX_ICM2_GPIO_BASE		UL(0xD8100000)
+#define SPEAR6XX_ICM2_SSP2_BASE		UL(0xD8180000)
+#define SPEAR6XX_ICM2_ADC_BASE		UL(0xD8200000)
 
 /* ML-1, 2 - Multi Layer CPU Subsystem */
-#define SPEAR6XX_ML_CPU_BASE		0xF0000000
-#define SPEAR6XX_ML_CPU_SIZE		0x08000000
-
-#define SPEAR6XX_CPU_TMR_BASE		0xF0000000
-#define SPEAR6XX_CPU_TMR_SIZE		0x00100000
-
-#define SPEAR6XX_CPU_GPIO_BASE		0xF0100000
-#define SPEAR6XX_CPU_GPIO_SIZE		0x00100000
-
-#define SPEAR6XX_CPU_VIC_SEC_BASE	0xF1000000
+#define SPEAR6XX_ML_CPU_BASE		UL(0xF0000000)
+#define SPEAR6XX_CPU_TMR_BASE		UL(0xF0000000)
+#define SPEAR6XX_CPU_GPIO_BASE		UL(0xF0100000)
+#define SPEAR6XX_CPU_VIC_SEC_BASE	UL(0xF1000000)
 #define VA_SPEAR6XX_CPU_VIC_SEC_BASE	IO_ADDRESS(SPEAR6XX_CPU_VIC_SEC_BASE)
-#define SPEAR6XX_CPU_VIC_SEC_SIZE	0x00100000
-
-#define SPEAR6XX_CPU_VIC_PRI_BASE	0xF1100000
+#define SPEAR6XX_CPU_VIC_PRI_BASE	UL(0xF1100000)
 #define VA_SPEAR6XX_CPU_VIC_PRI_BASE	IO_ADDRESS(SPEAR6XX_CPU_VIC_PRI_BASE)
-#define SPEAR6XX_CPU_VIC_PRI_SIZE	0x00100000
 
 /* ICM3 - Basic Subsystem */
-#define SPEAR6XX_ICM3_BASE		0xF8000000
-#define SPEAR6XX_ICM3_SIZE		0x08000000
-
-#define SPEAR6XX_ICM3_SMEM_BASE		0xF8000000
-#define SPEAR6XX_ICM3_SMEM_SIZE		0x04000000
-
-#define SPEAR6XX_ICM3_SMI_CTRL_BASE	0xFC000000
-#define SPEAR6XX_ICM3_SMI_CTRL_SIZE	0x00200000
-
-#define SPEAR6XX_ICM3_CLCD_BASE		0xFC200000
-#define SPEAR6XX_ICM3_CLCD_SIZE		0x00200000
-
-#define SPEAR6XX_ICM3_DMA_BASE		0xFC400000
-#define SPEAR6XX_ICM3_DMA_SIZE		0x00200000
-
-#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE	0xFC600000
-#define SPEAR6XX_ICM3_SDRAM_CTRL_SIZE	0x00200000
-
-#define SPEAR6XX_ICM3_TMR_BASE		0xFC800000
-#define SPEAR6XX_ICM3_TMR_SIZE		0x00080000
-
-#define SPEAR6XX_ICM3_WDT_BASE		0xFC880000
-#define SPEAR6XX_ICM3_WDT_SIZE		0x00080000
-
-#define SPEAR6XX_ICM3_RTC_BASE		0xFC900000
-#define SPEAR6XX_ICM3_RTC_SIZE		0x00080000
-
-#define SPEAR6XX_ICM3_GPIO_BASE		0xFC980000
-#define SPEAR6XX_ICM3_GPIO_SIZE		0x00080000
-
-#define SPEAR6XX_ICM3_SYS_CTRL_BASE	0xFCA00000
+#define SPEAR6XX_ICM3_BASE		UL(0xF8000000)
+#define SPEAR6XX_ICM3_SMEM_BASE		UL(0xF8000000)
+#define SPEAR6XX_ICM3_SMI_CTRL_BASE	UL(0xFC000000)
+#define SPEAR6XX_ICM3_CLCD_BASE		UL(0xFC200000)
+#define SPEAR6XX_ICM3_DMA_BASE		UL(0xFC400000)
+#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE	UL(0xFC600000)
+#define SPEAR6XX_ICM3_TMR_BASE		UL(0xFC800000)
+#define SPEAR6XX_ICM3_WDT_BASE		UL(0xFC880000)
+#define SPEAR6XX_ICM3_RTC_BASE		UL(0xFC900000)
+#define SPEAR6XX_ICM3_GPIO_BASE		UL(0xFC980000)
+#define SPEAR6XX_ICM3_SYS_CTRL_BASE	UL(0xFCA00000)
 #define VA_SPEAR6XX_ICM3_SYS_CTRL_BASE	IO_ADDRESS(SPEAR6XX_ICM3_SYS_CTRL_BASE)
-#define SPEAR6XX_ICM3_SYS_CTRL_SIZE	0x00080000
-
-#define SPEAR6XX_ICM3_MISC_REG_BASE	0xFCA80000
+#define SPEAR6XX_ICM3_MISC_REG_BASE	UL(0xFCA80000)
 #define VA_SPEAR6XX_ICM3_MISC_REG_BASE	IO_ADDRESS(SPEAR6XX_ICM3_MISC_REG_BASE)
-#define SPEAR6XX_ICM3_MISC_REG_SIZE	0x00080000
 
 /* ICM4 - High Speed Connection */
-#define SPEAR6XX_ICM4_BASE		0xE0000000
-#define SPEAR6XX_ICM4_SIZE		0x08000000
-
-#define SPEAR6XX_ICM4_GMAC_BASE		0xE0800000
-#define SPEAR6XX_ICM4_GMAC_SIZE		0x00800000
-
-#define SPEAR6XX_ICM4_USBD_FIFO_BASE	0xE1000000
-#define SPEAR6XX_ICM4_USBD_FIFO_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USBD_CSR_BASE	0xE1100000
-#define SPEAR6XX_ICM4_USBD_CSR_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USBD_PLDT_BASE	0xE1200000
-#define SPEAR6XX_ICM4_USBD_PLDT_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USB_EHCI0_BASE	0xE1800000
-#define SPEAR6XX_ICM4_USB_EHCI0_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USB_OHCI0_BASE	0xE1900000
-#define SPEAR6XX_ICM4_USB_OHCI0_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USB_EHCI1_BASE	0xE2000000
-#define SPEAR6XX_ICM4_USB_EHCI1_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USB_OHCI1_BASE	0xE2100000
-#define SPEAR6XX_ICM4_USB_OHCI1_SIZE	0x00100000
-
-#define SPEAR6XX_ICM4_USB_ARB_BASE	0xE2800000
-#define SPEAR6XX_ICM4_USB_ARB_SIZE	0x00010000
+#define SPEAR6XX_ICM4_BASE		UL(0xE0000000)
+#define SPEAR6XX_ICM4_GMAC_BASE		UL(0xE0800000)
+#define SPEAR6XX_ICM4_USBD_FIFO_BASE	UL(0xE1000000)
+#define SPEAR6XX_ICM4_USBD_CSR_BASE	UL(0xE1100000)
+#define SPEAR6XX_ICM4_USBD_PLDT_BASE	UL(0xE1200000)
+#define SPEAR6XX_ICM4_USB_EHCI0_BASE	UL(0xE1800000)
+#define SPEAR6XX_ICM4_USB_OHCI0_BASE	UL(0xE1900000)
+#define SPEAR6XX_ICM4_USB_EHCI1_BASE	UL(0xE2000000)
+#define SPEAR6XX_ICM4_USB_OHCI1_BASE	UL(0xE2100000)
+#define SPEAR6XX_ICM4_USB_ARB_BASE	UL(0xE2800000)
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR6XX_ICM1_UART0_BASE
-- 
1.7.2.2

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

* [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (29 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 37/74] SPEAr: removing size based macros except those necessary Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 10:04   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 39/74] ST SPEAr: Adding miscellaneous devices and clocks Viresh KUMAR
                   ` (43 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/clock.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index b56a755..720f04f 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -614,6 +614,11 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 #endif
 
+	/* common clock to spear300 and spear320 */
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
+	{ .dev_id = "sdhci",	.clk = &sdhci_clk},
+#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
+
 	/* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
 	{ .dev_id = "keyboard",		.clk = &kbd_clk},
@@ -628,11 +633,6 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 	{ .dev_id = "pwm",		.clk = &pwm_clk},
 #endif
-
-	/* common clock to spear300 and spear320 */
-#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
-	{ .dev_id = "sdhci",	.clk = &sdhci_clk},
-#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
 };
 
 void __init clk_init(void)
-- 
1.7.2.2

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

* [PATCH 39/74] ST SPEAr: Adding miscellaneous devices and clocks
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (30 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310 Viresh KUMAR
                   ` (42 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/clock.c                |   87 +++++++++++++++++--
 arch/arm/mach-spear3xx/include/mach/generic.h |    7 ++
 arch/arm/mach-spear3xx/spear310.c             |  115 +++++++++++++++++++------
 arch/arm/mach-spear3xx/spear320.c             |   26 ++++++
 4 files changed, 201 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 720f04f..2b5d7e1 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -409,13 +409,6 @@ static struct clk usbd_clk = {
 	.recalc = &follow_parent,
 };
 
-/* clcd clock */
-static struct clk clcd_clk = {
-	.flags = ALWAYS_ENABLED,
-	.pclk = &pll3_48m_clk,
-	.recalc = &follow_parent,
-};
-
 /* clock derived from ahb clk */
 /* apb masks structure */
 static struct bus_clk_masks apb_masks = {
@@ -525,8 +518,32 @@ static struct clk fsmc_clk = {
 };
 #endif
 
+/* common clocks to spear310 and spear320 */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* uart1 clock */
+static struct clk uart1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* uart2 clock */
+static struct clk uart2_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
+
 /* common clocks to spear300 and spear320 */
 #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
+/* clcd clock */
+static struct clk clcd_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll3_48m_clk,
+	.recalc = &follow_parent,
+};
+
 /* sdhci clock */
 static struct clk sdhci_clk = {
 	.flags = ALWAYS_ENABLED,
@@ -537,6 +554,13 @@ static struct clk sdhci_clk = {
 
 /* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
+/* gpio1 clock */
+static struct clk gpio1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
 /* keyboard clock */
 static struct clk kbd_clk = {
 	.flags = ALWAYS_ENABLED,
@@ -548,7 +572,26 @@ static struct clk kbd_clk = {
 
 /* spear310 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR310
+/* uart3 clock */
+static struct clk uart3_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* uart4 clock */
+static struct clk uart4_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
 
+/* uart5 clock */
+static struct clk uart5_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
 #endif
 
 /* spear320 machine specific clock structures */
@@ -560,6 +603,20 @@ static struct clk i2c1_clk = {
 	.recalc = &follow_parent,
 };
 
+/* ssp1 clock */
+static struct clk ssp1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* ssp2 clock */
+static struct clk ssp2_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
 /* pwm clock */
 static struct clk pwm_clk = {
 	.flags = ALWAYS_ENABLED,
@@ -596,7 +653,6 @@ static struct clk_lookup spear_clk_lookups[] = {
 	/* clock derived from pll3 clk */
 	{ .con_id = "usbh_clk",		.clk = &usbh_clk},
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
-	{ .dev_id = "clcd",		.clk = &clcd_clk},
 	/* clock derived from ahb clk */
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
 	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
@@ -614,23 +670,36 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 #endif
 
+/* common clocks to spear310 and spear320 */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+	{ .dev_id = "uart1",		.clk = &uart1_clk},
+	{ .dev_id = "uart2",		.clk = &uart2_clk},
+#endif
+
 	/* common clock to spear300 and spear320 */
 #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
-	{ .dev_id = "sdhci",	.clk = &sdhci_clk},
+	{ .dev_id = "clcd",		.clk = &clcd_clk},
+	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
 #endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
 
 	/* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
+	{ .dev_id = "gpio1",		.clk = &gpio1_clk},
 	{ .dev_id = "keyboard",		.clk = &kbd_clk},
 #endif
 
 	/* spear310 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR310
+	{ .dev_id = "uart3",		.clk = &uart3_clk},
+	{ .dev_id = "uart4",		.clk = &uart4_clk},
+	{ .dev_id = "uart5",		.clk = &uart5_clk},
 
 #endif
 	/* spear320 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR320
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
+	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
+	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
 	{ .dev_id = "pwm",		.clk = &pwm_clk},
 #endif
 };
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index ddfc382..2fc36a8 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -162,6 +162,11 @@ extern struct clcd_board clcd_plat_data;
 /* spear310 declarations */
 #elif defined(CONFIG_MACH_SPEAR310)
 /* Add spear310 machine device structure declarations here */
+extern struct amba_device uart1_device;
+extern struct amba_device uart2_device;
+extern struct amba_device uart3_device;
+extern struct amba_device uart4_device;
+extern struct amba_device uart5_device;
 extern struct platform_device plgpio_device;
 extern struct platform_device nand_device;
 
@@ -183,6 +188,8 @@ void __init spear310_init(void);
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct amba_device ssp_device[];
+extern struct amba_device uart1_device;
+extern struct amba_device uart2_device;
 extern struct platform_device i2c1_device;
 extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index b73e2df..29e3c2c 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -142,6 +142,96 @@ struct pmx_driver pmx_driver = {
 };
 
 /* Add spear310 specific devices here */
+/* uart1 device registeration */
+struct amba_device uart1_device = {
+	.dev = {
+		.init_name = "uart1",
+	},
+	.res = {
+		.start = SPEAR310_UART1_BASE,
+		.end = SPEAR310_UART1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART1, NO_IRQ},
+};
+
+/* uart2 device registeration */
+struct amba_device uart2_device = {
+	.dev = {
+		.init_name = "uart2",
+	},
+	.res = {
+		.start = SPEAR310_UART2_BASE,
+		.end = SPEAR310_UART2_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART2, NO_IRQ},
+};
+
+/* uart3 device registeration */
+struct amba_device uart3_device = {
+	.dev = {
+		.init_name = "uart3",
+	},
+	.res = {
+		.start = SPEAR310_UART3_BASE,
+		.end = SPEAR310_UART3_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART3, NO_IRQ},
+};
+
+/* uart4 device registeration */
+struct amba_device uart4_device = {
+	.dev = {
+		.init_name = "uart4",
+	},
+	.res = {
+		.start = SPEAR310_UART4_BASE,
+		.end = SPEAR310_UART4_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART4, NO_IRQ},
+};
+
+/* uart5 device registeration */
+struct amba_device uart5_device = {
+	.dev = {
+		.init_name = "uart5",
+	},
+	.res = {
+		.start = SPEAR310_UART5_BASE,
+		.end = SPEAR310_UART5_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART5, NO_IRQ},
+};
+
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 /* plgpio device registeration */
 /*
  * pin to offset and offset to pin converter functions
@@ -178,31 +268,6 @@ int spear300_o2p(int offset)
 		return offset + 2;
 }
 
-/* nand device registeration */
-static struct nand_platform_data nand_platform_data;
-
-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 nand_device = {
-	.name = "nand",
-	.id = -1,
-	.resource = nand_resources,
-	.num_resources = ARRAY_SIZE(nand_resources),
-	.dev.platform_data = &nand_platform_data,
-};
-
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
 	.irq_base = SPEAR_PLGPIO_INT_BASE,
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 7a2e07c..3fbb1f6 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -447,6 +447,32 @@ struct amba_device ssp_device[] = {
 	}
 };
 
+/* uart1 device registeration */
+struct amba_device uart1_device = {
+	.dev = {
+		.init_name = "uart1",
+	},
+	.res = {
+		.start = SPEAR320_UART1_BASE,
+		.end = SPEAR320_UART1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART1, NO_IRQ},
+};
+
+/* uart2 device registeration */
+struct amba_device uart2_device = {
+	.dev = {
+		.init_name = "uart2",
+	},
+	.res = {
+		.start = SPEAR320_UART2_BASE,
+		.end = SPEAR320_UART2_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_UART2, NO_IRQ},
+};
+
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
-- 
1.7.2.2

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

* [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (31 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 39/74] ST SPEAr: Adding miscellaneous devices and clocks Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 10:07   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 41/74] ST SPEAr : Adding CAN platform support for SPEAr320 and SPEAr1310 Viresh KUMAR
                   ` (41 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bhupesh Sharma <bhupesh.sharma@st.com>

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/Makefile                                |    1 +
 arch/arm/configs/spear1310-smp_defconfig         |  875 ++++++++++++++++++++++
 arch/arm/mach-spear13xx/Kconfig                  |    6 +
 arch/arm/mach-spear13xx/Kconfig1310              |   17 +
 arch/arm/mach-spear13xx/Makefile                 |    6 +-
 arch/arm/mach-spear13xx/include/mach/irqs.h      |   37 +
 arch/arm/mach-spear13xx/include/mach/spear.h     |    1 +
 arch/arm/mach-spear13xx/include/mach/spear1310.h |   24 +
 arch/arm/mach-spear13xx/spear1310.c              |   25 +
 arch/arm/mach-spear13xx/spear1310_evb.c          |  161 ++++
 arch/arm/plat-spear/Makefile                     |    1 +
 11 files changed, 1153 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/configs/spear1310-smp_defconfig
 create mode 100644 arch/arm/mach-spear13xx/Kconfig1310
 create mode 100644 arch/arm/mach-spear13xx/include/mach/spear1310.h
 create mode 100644 arch/arm/mach-spear13xx/spear1310.c
 create mode 100644 arch/arm/mach-spear13xx/spear1310_evb.c

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d5177d7..950a9b5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -192,6 +192,7 @@ machine-$(CONFIG_ARCH_W90X900)		:= w90x900
 machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
 machine-$(CONFIG_MACH_SPEAR1300)	:= spear13xx
+machine-$(CONFIG_MACH_SPEAR1310)	:= spear13xx
 machine-$(CONFIG_MACH_SPEAR300)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
diff --git a/arch/arm/configs/spear1310-smp_defconfig b/arch/arm/configs/spear1310-smp_defconfig
new file mode 100644
index 0000000..2ca577b
--- /dev/null
+++ b/arch/arm/configs/spear1310-smp_defconfig
@@ -0,0 +1,875 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue May 25 16:10:10 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR3XX is not set
+# CONFIG_ARCH_SPEAR6XX is not set
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1310=y
+CONFIG_BOARD_SPEAR1310_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_LOCAL_TIMERS=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
index e285d87..cc8faa4 100644
--- a/arch/arm/mach-spear13xx/Kconfig
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -13,9 +13,15 @@ config MACH_SPEAR1300
 	help
 	  Supports ST SPEAr1300 Machine
 
+config MACH_SPEAR1310
+	bool "SPEAr1310"
+	help
+	  Supports ST SPEAr1310 Machine
+
 endchoice
 
 # Adding SPEAr13XX machine specific configuration files
 source "arch/arm/mach-spear13xx/Kconfig1300"
+source "arch/arm/mach-spear13xx/Kconfig1310"
 
 endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Kconfig1310 b/arch/arm/mach-spear13xx/Kconfig1310
new file mode 100644
index 0000000..ad61820
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig1310
@@ -0,0 +1,17 @@
+#
+# SPEAr1310 machine configuration file
+#
+
+if MACH_SPEAR1310
+
+choice
+	prompt "SPEAr1310 Boards"
+	default BOARD_SPEAR1310_EVB
+
+config BOARD_SPEAR1310_EVB
+	bool "SPEAr1310 Evaluation Board"
+	help
+	  Supports ST SPEAr1310 Evaluation Board
+endchoice
+
+endif #MACH_SPEAR1310
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
index b55f92e..168886e 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -10,6 +10,10 @@ obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 # spear1300 specific files
 obj-$(CONFIG_MACH_SPEAR1300)		+= spear1300.o
 obj-$(CONFIG_PCIEPORTBUS)		+= pcie.o
-
 # spear1300 boards files
 obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= spear1300_evb.o
+
+# spear1310 specific files
+obj-$(CONFIG_MACH_SPEAR1310)		+= spear1310.o
+# spear1310 boards files
+obj-$(CONFIG_BOARD_SPEAR1310_EVB)	+= spear1310_evb.o
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index d2bfbb1..1ca70a6 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2010 ST Microelectronics
  * Shiraz Hashim <shiraz.hashim@st.com>
+ * Bhupesh Sharma <bhupesh.sharma@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
@@ -84,6 +85,42 @@
 #define IRQ_PCIE1		(IRQ_SHPI_START + 69)
 #define IRQ_PCIE2		(IRQ_SHPI_START + 70)
 
+/* Add spear1310 specific IRQs here */
+#ifdef CONFIG_MACH_SPEAR1310
+#define IRQ_FSMC_PC1		(IRQ_SHPI_START + 76)
+#define IRQ_FSMC_PC2		(IRQ_SHPI_START + 77)
+#define IRQ_FSMC_PC3		(IRQ_SHPI_START + 78)
+#define IRQ_FSMC_PC4		(IRQ_SHPI_START + 79)
+#define IRQ_RS4850		(IRQ_SHPI_START + 80)
+#define IRQ_RS4851		(IRQ_SHPI_START + 81)
+#define IRQ_CCAN0		(IRQ_SHPI_START + 82)
+#define IRQ_CCAN1		(IRQ_SHPI_START + 83)
+#define IRQ_TDM0		(IRQ_SHPI_START + 84)
+#define IRQ_TDM1		(IRQ_SHPI_START + 85)
+#define IRQ_UART0		(IRQ_SHPI_START + 86)
+#define IRQ_UART1		(IRQ_SHPI_START + 87)
+#define IRQ_UART2		(IRQ_SHPI_START + 88)
+#define IRQ_UART3		(IRQ_SHPI_START + 89)
+#define IRQ_UART4		(IRQ_SHPI_START + 90)
+#define IRQ_I2C_CNTR		(IRQ_SHPI_START + 91)
+#define IRQ_GMAC0_SBD		(IRQ_SHPI_START + 92)
+#define IRQ_GMAC0_PMT		(IRQ_SHPI_START + 93)
+#define IRQ_GMAC1_SBD		(IRQ_SHPI_START + 94)
+#define IRQ_GMAC1_PMT		(IRQ_SHPI_START + 95)
+#define IRQ_GMAC2_SBD		(IRQ_SHPI_START + 96)
+#define IRQ_GMAC2_PMT		(IRQ_SHPI_START + 97)
+#define IRQ_GMAC3_SBD		(IRQ_SHPI_START + 98)
+#define IRQ_GMAC3_PMT		(IRQ_SHPI_START + 99)
+#define IRQ_GPIO		(IRQ_SHPI_START + 100)
+#define IRQ_PCI_BRDG_HOST_FATAL (IRQ_SHPI_START + 101)
+#define IRQ_PCI_INTA		(IRQ_SHPI_START + 102)
+#define IRQ_PCI_INTB		(IRQ_SHPI_START + 103)
+#define IRQ_PCI_INTC		(IRQ_SHPI_START + 104)
+#define IRQ_PCI_INTD		(IRQ_SHPI_START + 105)
+#define IRQ_PCI_ME_TO_ARM	(IRQ_SHPI_START + 106)
+#define IRQ_PCI_SERR_TO_ARM	(IRQ_SHPI_START + 107)
+#endif /* CONFIG_MACH_SPEAR1310 */
+
 #define IRQ_GIC_END		(IRQ_SHPI_START + 128)
 
 #define VIRQ_START		IRQ_GIC_END
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index 1a1af72..cf25eb5 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -16,6 +16,7 @@
 
 #include <asm/memory.h>
 #include <mach/spear1300.h>
+#include <mach/spear1310.h>
 
 #define SPEAR13XX_L2CC_BASE		UL(0xED000000)
 
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310.h b/arch/arm/mach-spear13xx/include/mach/spear1310.h
new file mode 100644
index 0000000..d1735e8
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/spear1310.h
+ *
+ * SPEAr1310 Machine specific definition
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@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.
+ */
+
+#ifdef CONFIG_MACH_SPEAR1310
+
+#ifndef __MACH_SPEAR1310_H
+#define __MACH_SPEAR1310_H
+
+#define SPEAR1310_CAN0_BASE		UL(0x6DA00000)
+#define SPEAR1310_CAN1_BASE		UL(0x6DB00000)
+
+#endif /* __MACH_SPEAR1310_H */
+
+#endif /* CONFIG_MACH_SPEAR1310 */
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
new file mode 100644
index 0000000..c3953a9
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear13xx/spear1310.c
+ *
+ * SPEAr1310 machine source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@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/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* Add spear1310 specific devices here */
+
+void __init spear1310_init(void)
+{
+	/* call spear13xx family common init function */
+	spear13xx_init();
+}
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
new file mode 100644
index 0000000..7591d89
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -0,0 +1,161 @@
+/*
+ * arch/arm/mach-spear13xx/spear1310_evb.c
+ *
+ * SPEAr1310 evaluation board source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@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/types.h>
+#include <linux/gpio.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <mach/pcie.h>
+#include <plat/keyboard.h>
+#include <plat/nand.h>
+#include <plat/smi.h>
+#include <plat/spi.h>
+
+static struct amba_device *amba_devs[] __initdata = {
+	&gpio_device[0],
+	&gpio_device[1],
+	&ssp_device,
+	&uart_device,
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+	&ehci0_device,
+	&ehci1_device,
+	&i2c_device,
+	&kbd_device,
+	&nand_device,
+	&ohci0_device,
+	&ohci1_device,
+	&rtc_device,
+	&sdhci_device,
+	&smi_device,
+	&pcie_gadget0_device,
+};
+
+/* keyboard specific platform data */
+static DECLARE_KEYMAP(spear_keymap);
+
+static struct kbd_platform_data kbd_data = {
+	.keymap = spear_keymap,
+	.keymapsize = ARRAY_SIZE(spear_keymap),
+	.rep = 1,
+};
+
+/* Currently no gpios are free on eval board so it is kept commented */
+#if 0
+/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
+DECLARE_SPI_CS_CONTROL(0, flash, /* mention gpio number here */);
+/* 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, /* mention gpio number here */);
+/* spi0 spidev Chip Info structure */
+DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
+#endif
+
+static struct spi_board_info __initdata spi_board_info[] = {
+#if 0
+	/* spi0 board info */
+	{
+		.modalias = "spidev",
+		.controller_data = &spi0_dev_chip_info,
+		.max_speed_hz = 10000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = 0,
+	}, {
+		.modalias = "m25p80",
+		.controller_data = &spi0_flash_chip_info,
+		.max_speed_hz = 1000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.mode = 0,
+	}
+#endif
+};
+
+static void __init spi_init(void)
+{
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
+#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.
+ * it is the responsibility of calling function to not send port number
+ * greter than max no of controller(3)
+ */
+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)
+{
+	/* set keyboard plat data */
+	kbd_set_plat_data(&kbd_device, &kbd_data);
+
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+	nand_mach_init(SPEAR_NAND_BW8);
+
+	/* call spear1310 machine init function */
+	spear1310_init();
+
+	/* Register slave devices on the I2C buses */
+	i2c_register_board_devices();
+
+	/* initialize serial nor related data in smi plat data */
+	smi_init_board_info(&smi_device);
+#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));
+
+	/* Add Amba Devices */
+	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
+
+	spi_init();
+}
+
+MACHINE_START(SPEAR1310, "ST-SPEAR1310-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear13xx_map_io,
+	.init_irq	=	spear13xx_init_irq,
+	.timer		=	&spear13xx_timer,
+	.init_machine	=	spear1310_evb_init,
+MACHINE_END
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index b8a7403..50c680c 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
 obj-$(CONFIG_MACH_SPEAR320)	+= plgpio.o
 obj-$(CONFIG_SPEAR_PWM)		+= pwm.o
 
+obj-$(CONFIG_BOARD_SPEAR1310_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR300_EVB)	+= i2c_eval_board.o
 obj-$(CONFIG_BOARD_SPEAR310_EVB)	+= i2c_eval_board.o
-- 
1.7.2.2

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

* [PATCH 41/74] ST SPEAr : Adding CAN platform support for SPEAr320 and SPEAr1310
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (32 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310 Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 42/74] ST SPEAr: Adding support for DDR in clock framework Viresh KUMAR
                   ` (40 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bhupesh Sharma <bhupesh.sharma@st.com>

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/clock.c                |   32 ++++++++++++++++++++
 arch/arm/mach-spear13xx/include/mach/generic.h |   21 +++++++++++--
 arch/arm/mach-spear13xx/spear1310.c            |   37 ++++++++++++++++++++++++
 arch/arm/mach-spear13xx/spear1310_evb.c        |    6 ++++
 arch/arm/mach-spear3xx/clock.c                 |   16 ++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    2 +
 arch/arm/mach-spear3xx/spear320.c              |   37 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |    2 +
 8 files changed, 150 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 98ba04e..1ee820a 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -803,6 +803,28 @@ static struct clk kbd_clk = {
 	.recalc = &follow_parent,
 };
 
+/* spear1300 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR1300
+
+#endif
+
+/* spear1310 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR1310
+/* can0 clock */
+static struct clk can0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* can1 clock */
+static struct clk can1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* array of all spear 13xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
 	/* root clks */
@@ -876,6 +898,16 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "gpio1",		.clk = &gpio1_clk},
 	{.dev_id = "keyboard",		.clk = &kbd_clk},
 	{.dev_id = "wdt",		.clk = &wdt_clk},
+
+	/* spear1300 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR1300
+#endif
+
+	/* spear1310 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR1310
+	{.dev_id = "spear_can.0",	.clk = &can0_clk},
+	{.dev_id = "spear_can.1",	.clk = &can1_clk},
+#endif
 };
 
 void __init clk_init(void)
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 18800b0..62d3d9b 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -45,17 +45,32 @@ extern struct platform_device sdhci_device;
 extern struct platform_device smi_device;
 extern struct sys_timer spear13xx_timer;
 
-/* Add spear1300 machine device structure declarations here */
-
 /* Add spear13xx family function declarations here */
 void __init clk_init(void);
 void __init i2c_register_board_devices(void);
 void __init spear_setup_timer(void);
-void __init spear1300_init(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 spear13xx_secondary_startup(void);
 
+/* spear1300 declarations */
+#ifdef CONFIG_MACH_SPEAR1300
+/* Add spear1300 machine function declarations here */
+void __init spear1300_init(void);
+
+#endif /* CONFIG_MACH_SPEAR1300 */
+
+/* spear1310 declarations */
+#ifdef CONFIG_MACH_SPEAR1310
+/* Add spear1310 machine device structure declarations here */
+extern struct platform_device can0_device;
+extern struct platform_device can1_device;
+
+/* Add spear1310 machine function declarations here */
+void __init spear1310_init(void);
+
+#endif /* CONFIG_MACH_SPEAR1310 */
+
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index c3953a9..906ede9 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -18,6 +18,43 @@
 
 /* Add spear1310 specific devices here */
 
+/* CAN device registeration */
+static struct resource can0_resources[] = {
+	{
+		.start = SPEAR1310_CAN0_BASE,
+		.end = SPEAR1310_CAN0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_CCAN0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device can0_device = {
+	.name = "spear_can",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(can0_resources),
+	.resource = can0_resources,
+};
+
+static struct resource can1_resources[] = {
+	{
+		.start = SPEAR1310_CAN1_BASE,
+		.end = SPEAR1310_CAN1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_CCAN1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device can1_device = {
+	.name = "spear_can",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(can1_resources),
+	.resource = can1_resources,
+};
+
 void __init spear1310_init(void)
 {
 	/* call spear13xx family common init function */
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 7591d89..8b02104 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -27,6 +27,7 @@
 #include <plat/spi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
+	/* spear13xx specific devices */
 	&gpio_device[0],
 	&gpio_device[1],
 	&ssp_device,
@@ -34,6 +35,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	/* spear13xx specific devices */
 	&ehci0_device,
 	&ehci1_device,
 	&i2c_device,
@@ -45,6 +47,10 @@ static struct platform_device *plat_devs[] __initdata = {
 	&sdhci_device,
 	&smi_device,
 	&pcie_gadget0_device,
+
+	/* spear1310 specific devices */
+	&can0_device,
+	&can1_device,
 };
 
 /* keyboard specific platform data */
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 2b5d7e1..96a51cc 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -596,6 +596,20 @@ static struct clk uart5_clk = {
 
 /* spear320 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR320
+/* can0 clock */
+static struct clk can0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* can1 clock */
+static struct clk can1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
 /* i2c1 clock */
 static struct clk i2c1_clk = {
 	.flags = ALWAYS_ENABLED,
@@ -697,6 +711,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 #endif
 	/* spear320 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR320
+	{ .dev_id = "spear_can.0",	.clk = &can0_clk},
+	{ .dev_id = "spear_can.1",	.clk = &can1_clk},
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
 	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 2fc36a8..75c1eef 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -190,6 +190,8 @@ extern struct amba_device clcd_device;
 extern struct amba_device ssp_device[];
 extern struct amba_device uart1_device;
 extern struct amba_device uart2_device;
+extern struct platform_device can0_device;
+extern struct platform_device can1_device;
 extern struct platform_device i2c1_device;
 extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 3fbb1f6..0c2f4a5 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -480,6 +480,43 @@ static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_count = SPEAR_PLGPIO_COUNT,
 };
 
+/* CAN device registeration */
+static struct resource can0_resources[] = {
+	{
+		.start = SPEAR320_CAN0_BASE,
+		.end = SPEAR320_CAN0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = VIRQ_CANU,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device can0_device = {
+	.name = "spear_can",
+	.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,
+	}, {
+		.start = VIRQ_CANL,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device can1_device = {
+	.name = "spear_can",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(can1_resources),
+	.resource = can1_resources,
+};
+
 /* i2c1 device registeration */
 static struct resource i2c1_resources[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 261c0b0..d55e1b2 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -66,6 +66,8 @@ static struct platform_device *plat_devs[] __initdata = {
 	&smi_device,
 
 	/* spear320 specific devices */
+	&can0_device,
+	&can1_device,
 	&i2c1_device,
 	&plgpio_device,
 	&pwm_device,
-- 
1.7.2.2

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

* [PATCH 42/74] ST SPEAr: Adding support for DDR in clock framework
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (33 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 41/74] ST SPEAr : Adding CAN platform support for SPEAr320 and SPEAr1310 Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver Viresh KUMAR
                   ` (39 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Changing rate of clk, which is ancestor of DDR requires to put DDR in refresh
mode before changing parents rate. For this DDR support is added in clock
framework. Now at boot time all ancestors of DDR is marked specially and
changing their rate must be first acked by ddr (i.e. ddr will run on that
clock). This patch adds support for this.

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/clock.c                  |   69 ++++++++---
 arch/arm/mach-spear13xx/include/mach/generic.h   |    2 +-
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |    4 +
 arch/arm/mach-spear13xx/spear13xx.c              |    2 +-
 arch/arm/mach-spear3xx/clock.c                   |  105 ++++++++++++++----
 arch/arm/mach-spear3xx/include/mach/generic.h    |    2 +-
 arch/arm/mach-spear3xx/include/mach/misc_regs.h  |    7 +
 arch/arm/mach-spear3xx/spear3xx.c                |    2 +-
 arch/arm/mach-spear6xx/clock.c                   |  105 ++++++++++++++----
 arch/arm/mach-spear6xx/include/mach/generic.h    |    2 +-
 arch/arm/mach-spear6xx/include/mach/misc_regs.h  |    7 +
 arch/arm/mach-spear6xx/spear6xx.c                |    2 +-
 arch/arm/plat-spear/clock.c                      |  133 ++++++++++++++++++---
 arch/arm/plat-spear/include/plat/clock.h         |   42 +++++--
 14 files changed, 385 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 1ee820a..30eba05 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -22,19 +22,19 @@
 /* root clks */
 /* 24 MHz oscillator clock */
 static struct clk osc1_24m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 24000000,
 };
 
 /* 32 KHz oscillator clock */
 static struct clk osc2_32k_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 32000,
 };
 
 /* 25 MHz MIPHY oscillator clock */
 static struct clk osc3_25m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 25000000,
 };
 
@@ -98,7 +98,7 @@ struct pll_rate_tbl pll_rtbl[] = {
 
 /* pll1 clock */
 static struct clk pll1_clk = {
-	.flags = ENABLED_ON_INIT,
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
 	.pclk_sel = &pll_pclk_sel,
 	.pclk_sel_shift = PLL1_CLK_SHIFT,
 	.en_reg = PLL1_CTR,
@@ -112,7 +112,7 @@ static struct clk pll1_clk = {
 
 /* pll1div2 clock */
 static struct clk pll1div2_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.div_factor = 2,
 	.recalc = &follow_parent,
@@ -120,7 +120,7 @@ static struct clk pll1div2_clk = {
 
 /* pll1div4 clock */
 static struct clk pll1div4_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.div_factor = 4,
 	.recalc = &follow_parent,
@@ -135,6 +135,7 @@ static struct pll_clk_config pll2_config = {
 
 /* pll2 clock */
 static struct clk pll2_clk = {
+	.flags = SYSTEM_CLK,
 	.pclk_sel = &pll_pclk_sel,
 	.pclk_sel_shift = PLL2_CLK_SHIFT,
 	.en_reg = PLL2_CTR,
@@ -155,6 +156,7 @@ static struct pll_clk_config pll3_config = {
 
 /* pll3 clock */
 static struct clk pll3_clk = {
+	.flags = SYSTEM_CLK,
 	.pclk_sel = &pll_pclk_sel,
 	.pclk_sel_shift = PLL3_CLK_SHIFT,
 	.en_reg = PLL3_CTR,
@@ -183,7 +185,7 @@ struct pll_rate_tbl pll4_rtbl[] = {
 
 /* pll4 (DDR) clock */
 static struct clk pll4_clk = {
-	.flags = ENABLED_ON_INIT,
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
 	.pclk = &osc1_24m_clk,
 	.en_reg = PLL4_CTR,
 	.en_reg_bit = PLL_ENABLE,
@@ -196,22 +198,54 @@ static struct clk pll4_clk = {
 
 /* pll5 USB 48 MHz clock */
 static struct clk pll5_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &osc1_24m_clk,
 	.rate = 48000000,
 };
 
 /* pll6 (MIPHY) clock */
 static struct clk pll6_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &osc3_25m_clk,
 	.rate = 25000000,
 };
 
 /* clocks derived from pll1 clk */
+/* ddr clock */
+struct ddr_rate_tbl ddr_rate_tbl = {
+	.minrate = 332000000,
+	.maxrate = 500000000,
+};
+
+static struct pclk_info ddr_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_val = MCTR_CLK_PLL1_VAL,
+	}, {
+		.pclk = &pll4_clk,
+		.pclk_val = MCTR_CLK_PLL4_VAL,
+	},
+};
+
+/* ddr parent select structure */
+static struct pclk_sel ddr_pclk_sel = {
+	.pclk_info = ddr_pclk_info,
+	.pclk_count = ARRAY_SIZE(ddr_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = MCTR_CLK_MASK,
+};
+
+static struct clk ddr_clk = {
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
+	.recalc = &follow_parent,
+	.pclk_sel = &ddr_pclk_sel,
+	.pclk_sel_shift = MCTR_CLK_SHIFT,
+	.private_data = &ddr_rate_tbl,
+};
+
 /* cpu clock */
 static struct clk cpu_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.div_factor = 2,
 	.recalc = &follow_parent,
@@ -219,7 +253,7 @@ static struct clk cpu_clk = {
 
 /* ahb clock */
 static struct clk ahb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.div_factor = 6,
 	.recalc = &follow_parent,
@@ -227,7 +261,7 @@ static struct clk ahb_clk = {
 
 /* apb clock */
 static struct clk apb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.div_factor = 12,
 	.recalc = &follow_parent,
@@ -844,6 +878,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.con_id = "pll6_clk",		.clk = &pll6_clk},
 
 	/* clock derived from pll1 clk */
+	{.con_id = "ddr_clk",		.clk = &ddr_clk},
 	{.con_id = "cpu_clk",		.clk = &cpu_clk},
 	{.con_id = "ahb_clk",		.clk = &ahb_clk},
 	{.con_id = "apb_clk",		.clk = &apb_clk},
@@ -910,12 +945,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 #endif
 };
 
-void __init clk_init(void)
+/* machine clk init */
+void __init spear13xx_clk_init(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
-		clk_register(&spear_clk_lookups[i]);
-
-	recalc_root_clocks();
+	clk_init(spear_clk_lookups, ARRAY_SIZE(spear_clk_lookups), &ddr_clk);
 }
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 62d3d9b..6f4e6b5 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -46,7 +46,7 @@ extern struct platform_device smi_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
-void __init clk_init(void);
+void __init spear13xx_clk_init(void);
 void __init i2c_register_board_devices(void);
 void __init spear_setup_timer(void);
 void __init spear13xx_map_io(void);
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index 2529a48..2db1ffe 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -98,6 +98,10 @@
 	#define CLCD_CLK_SHIFT		2
 	#define C3_CLK_MASK		1
 	#define C3_CLK_SHIFT		1
+	#define MCTR_CLK_SHIFT		10
+	#define MCTR_CLK_MASK		0x1
+	#define MCTR_CLK_PLL1_VAL	0x0
+	#define MCTR_CLK_PLL4_VAL	0x1
 
 #define GMAC_CLK_CFG		((unsigned int *)(MISC_BASE + 0x248))
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index b06f59e..4563551 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -443,7 +443,7 @@ void __init spear13xx_map_io(void)
 	iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
 
 	/* This will initialize clock framework */
-	clk_init();
+	spear13xx_clk_init();
 }
 
 static void __init spear13xx_timer_init(void)
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 96a51cc..41a2b5e 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -19,13 +19,13 @@
 /* root clks */
 /* 32 KHz oscillator clock */
 static struct clk osc_32k_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 32000,
 };
 
 /* 24 MHz oscillator clock */
 static struct clk osc_24m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 24000000,
 };
 
@@ -40,7 +40,7 @@ static struct clk rtc_clk = {
 
 /* clock derived from 24 MHz osc clk */
 /* pll masks structure */
-static struct pll_clk_masks pll1_masks = {
+static struct pll_clk_masks pll_masks = {
 	.mode_mask = PLL_MODE_MASK,
 	.mode_shift = PLL_MODE_SHIFT,
 	.norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
@@ -53,22 +53,22 @@ static struct pll_clk_masks pll1_masks = {
 	.div_n_shift = PLL_DIV_N_SHIFT,
 };
 
-/* pll1 configuration structure */
-static struct pll_clk_config pll1_config = {
-	.mode_reg = PLL1_CTR,
-	.cfg_reg = PLL1_FRQ,
-	.masks = &pll1_masks,
-};
-
 /* pll rate configuration table, in ascending order of rates */
 struct pll_rate_tbl pll_rtbl[] = {
 	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
 	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
 };
 
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+	.mode_reg = PLL1_CTR,
+	.cfg_reg = PLL1_FRQ,
+	.masks = &pll_masks,
+};
+
 /* PLL1 clock */
 static struct clk pll1_clk = {
-	.flags = ENABLED_ON_INIT,
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
 	.pclk = &osc_24m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
@@ -79,9 +79,29 @@ static struct clk pll1_clk = {
 	.private_data = &pll1_config,
 };
 
+/* pll2 configuration structure */
+static struct pll_clk_config pll2_config = {
+	.mode_reg = PLL2_CTR,
+	.cfg_reg = PLL2_FRQ,
+	.masks = &pll_masks,
+};
+
+/* PLL2 clock */
+static struct clk pll2_clk = {
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
+	.pclk = &osc_24m_clk,
+	.en_reg = PLL2_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
+	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
+	.private_data = &pll2_config,
+};
+
 /* PLL3 48 MHz clock */
 static struct clk pll3_48m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &osc_24m_clk,
 	.rate = 48000000,
 };
@@ -96,7 +116,7 @@ static struct clk wdt_clk = {
 /* clock derived from pll1 clk */
 /* cpu clock */
 static struct clk cpu_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.recalc = &follow_parent,
 };
@@ -123,7 +143,7 @@ struct bus_rate_tbl bus_rtbl[] = {
 
 /* ahb clock */
 static struct clk ahb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
@@ -410,6 +430,48 @@ static struct clk usbd_clk = {
 };
 
 /* clock derived from ahb clk */
+/* ahb multiplied by 2 clock */
+static struct clk ahbmult2_clk = {
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
+	.pclk = &ahb_clk,
+	.recalc = &ahbmult2_clk_recalc,
+};
+
+/* ddr clock */
+struct ddr_rate_tbl ddr_rate_tbl = {
+	.minrate = 166000000,
+	.maxrate = 332000000,
+};
+
+static struct pclk_info ddr_pclk_info[] = {
+	{
+		.pclk = &ahb_clk,
+		.pclk_val = MCTR_CLK_HCLK_VAL,
+	}, {
+		.pclk = &ahbmult2_clk,
+		.pclk_val = MCTR_CLK_2HCLK_VAL,
+	}, {
+		.pclk = &pll2_clk,
+		.pclk_val = MCTR_CLK_PLL2_VAL,
+	},
+};
+
+/* ddr parent select structure */
+static struct pclk_sel ddr_pclk_sel = {
+	.pclk_info = ddr_pclk_info,
+	.pclk_count = ARRAY_SIZE(ddr_pclk_info),
+	.pclk_sel_reg = PLL_CLK_CFG,
+	.pclk_sel_mask = MCTR_CLK_MASK,
+};
+
+static struct clk ddr_clk = {
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
+	.recalc = &follow_parent,
+	.pclk_sel = &ddr_pclk_sel,
+	.pclk_sel_shift = MCTR_CLK_SHIFT,
+	.private_data = &ddr_rate_tbl,
+};
+
 /* apb masks structure */
 static struct bus_clk_masks apb_masks = {
 	.mask = HCLK_PCLK_RATIO_MASK,
@@ -424,7 +486,7 @@ static struct bus_clk_config apb_config = {
 
 /* apb clock */
 static struct clk apb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &ahb_clk,
 	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
@@ -649,6 +711,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
 	/* clock derived from 24 MHz osc clk */
 	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
+	{ .con_id = "pll2_clk",		.clk = &pll2_clk},
 	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
 	{ .dev_id = "wdt",		.clk = &wdt_clk},
 	/* clock derived from pll1 clk */
@@ -668,6 +731,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "usbh_clk",		.clk = &usbh_clk},
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
 	/* clock derived from ahb clk */
+	{ .con_id = "ahbmult2_clk",	.clk = &ahbmult2_clk},
+	{ .con_id = "ddr_clk",		.clk = &ddr_clk},
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
 	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{ .dev_id = "dma",		.clk = &dma_clk},
@@ -720,12 +785,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 #endif
 };
 
-void __init clk_init(void)
+/* machine clk init */
+void __init spear3xx_clk_init(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
-		clk_register(&spear_clk_lookups[i]);
-
-	recalc_root_clocks();
+	clk_init(spear_clk_lookups, ARRAY_SIZE(spear_clk_lookups), &ddr_clk);
 }
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 75c1eef..4d04dbe 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -45,7 +45,7 @@ extern struct platform_device smi_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
-void __init clk_init(void);
+void __init spear3xx_clk_init(void);
 void __init i2c_register_board_devices(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
index 6cb4f3c..6316900 100644
--- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
@@ -46,6 +46,13 @@
 
 #define PLL2_MOD		((unsigned int *)(MISC_BASE + 0x01C))
 #define PLL_CLK_CFG		((unsigned int *)(MISC_BASE + 0x020))
+/* PLL_CLK_CFG register masks */
+#define MCTR_CLK_SHIFT		28
+#define MCTR_CLK_MASK		0x7
+#define MCTR_CLK_HCLK_VAL	0x0
+#define MCTR_CLK_2HCLK_VAL	0x1
+#define MCTR_CLK_PLL2_VAL	0x3
+
 #define CORE_CLK_CFG		((unsigned int *)(MISC_BASE + 0x024))
 /* CORE CLK CFG register masks */
 #define PLL_HCLK_RATIO_SHIFT	10
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 18072ee..a905b5d 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -280,7 +280,7 @@ void __init spear3xx_map_io(void)
 	iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
 
 	/* This will initialize clock framework */
-	clk_init();
+	spear3xx_clk_init();
 }
 
 /* pad multiplexing support */
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 9171952..99cc21d 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -19,13 +19,13 @@
 /* root clks */
 /* 32 KHz oscillator clock */
 static struct clk osc_32k_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 32000,
 };
 
 /* 30 MHz oscillator clock */
 static struct clk osc_30m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.rate = 30000000,
 };
 
@@ -40,7 +40,7 @@ static struct clk rtc_clk = {
 
 /* clock derived from 30 MHz osc clk */
 /* pll masks structure */
-static struct pll_clk_masks pll1_masks = {
+static struct pll_clk_masks pll_masks = {
 	.mode_mask = PLL_MODE_MASK,
 	.mode_shift = PLL_MODE_SHIFT,
 	.norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
@@ -53,22 +53,22 @@ static struct pll_clk_masks pll1_masks = {
 	.div_n_shift = PLL_DIV_N_SHIFT,
 };
 
-/* pll1 configuration structure */
-static struct pll_clk_config pll1_config = {
-	.mode_reg = PLL1_CTR,
-	.cfg_reg = PLL1_FRQ,
-	.masks = &pll1_masks,
-};
-
 /* pll rate configuration table, in ascending order of rates */
 struct pll_rate_tbl pll_rtbl[] = {
 	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
 	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
 };
 
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+	.mode_reg = PLL1_CTR,
+	.cfg_reg = PLL1_FRQ,
+	.masks = &pll_masks,
+};
+
 /* PLL1 clock */
 static struct clk pll1_clk = {
-	.flags = ENABLED_ON_INIT,
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
 	.pclk = &osc_30m_clk,
 	.en_reg = PLL1_CTR,
 	.en_reg_bit = PLL_ENABLE,
@@ -79,9 +79,29 @@ static struct clk pll1_clk = {
 	.private_data = &pll1_config,
 };
 
+/* pll2 configuration structure */
+static struct pll_clk_config pll2_config = {
+	.mode_reg = PLL2_CTR,
+	.cfg_reg = PLL2_FRQ,
+	.masks = &pll_masks,
+};
+
+/* PLL2 clock */
+static struct clk pll2_clk = {
+	.flags = ENABLED_ON_INIT | SYSTEM_CLK,
+	.pclk = &osc_30m_clk,
+	.en_reg = PLL2_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.calc_rate = &pll_calc_rate,
+	.recalc = &pll_clk_recalc,
+	.set_rate = &pll_clk_set_rate,
+	.rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
+	.private_data = &pll2_config,
+};
+
 /* PLL3 48 MHz clock */
 static struct clk pll3_48m_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &osc_30m_clk,
 	.rate = 48000000,
 };
@@ -96,7 +116,7 @@ static struct clk wdt_clk = {
 /* clock derived from pll1 clk */
 /* cpu clock */
 static struct clk cpu_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.recalc = &follow_parent,
 };
@@ -123,7 +143,7 @@ struct bus_rate_tbl bus_rtbl[] = {
 
 /* ahb clock */
 static struct clk ahb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &pll1_clk,
 	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
@@ -491,6 +511,48 @@ static struct clk usbd_clk = {
 };
 
 /* clock derived from ahb clk */
+/* ahb multiplied by 2 clock */
+static struct clk ahbmult2_clk = {
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
+	.pclk = &ahb_clk,
+	.recalc = &ahbmult2_clk_recalc,
+};
+
+/* ddr clock */
+struct ddr_rate_tbl ddr_rate_tbl = {
+	.minrate = 166000000,
+	.maxrate = 332000000,
+};
+
+static struct pclk_info ddr_pclk_info[] = {
+	{
+		.pclk = &ahb_clk,
+		.pclk_val = MCTR_CLK_HCLK_VAL,
+	}, {
+		.pclk = &ahbmult2_clk,
+		.pclk_val = MCTR_CLK_2HCLK_VAL,
+	}, {
+		.pclk = &pll2_clk,
+		.pclk_val = MCTR_CLK_PLL2_VAL,
+	},
+};
+
+/* ddr parent select structure */
+static struct pclk_sel ddr_pclk_sel = {
+	.pclk_info = ddr_pclk_info,
+	.pclk_count = ARRAY_SIZE(ddr_pclk_info),
+	.pclk_sel_reg = PLL_CLK_CFG,
+	.pclk_sel_mask = MCTR_CLK_MASK,
+};
+
+static struct clk ddr_clk = {
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
+	.recalc = &follow_parent,
+	.pclk_sel = &ddr_pclk_sel,
+	.pclk_sel_shift = MCTR_CLK_SHIFT,
+	.private_data = &ddr_rate_tbl,
+};
+
 /* apb masks structure */
 static struct bus_clk_masks apb_masks = {
 	.mask = HCLK_PCLK_RATIO_MASK,
@@ -505,7 +567,7 @@ static struct bus_clk_config apb_config = {
 
 /* apb clock */
 static struct clk apb_clk = {
-	.flags = ALWAYS_ENABLED,
+	.flags = ALWAYS_ENABLED | SYSTEM_CLK,
 	.pclk = &ahb_clk,
 	.calc_rate = &bus_calc_rate,
 	.recalc = &bus_clk_recalc,
@@ -630,6 +692,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
 	/* clock derived from 30 MHz os		 clk */
 	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
+	{ .con_id = "pll2_clk",		.clk = &pll2_clk},
 	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
 	{ .dev_id = "wdt",		.clk = &wdt_clk},
 	/* clock derived from pll1 clk */
@@ -654,6 +717,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "usbh.1_clk",	.clk = &usbh1_clk},
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
 	/* clock derived from ahb clk */
+	{ .con_id = "ahbmult2_clk",	.clk = &ahbmult2_clk},
+	{ .con_id = "ddr_clk",		.clk = &ddr_clk},
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
 	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{ .dev_id = "dma",		.clk = &dma_clk},
@@ -671,12 +736,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "gpio2",		.clk = &gpio2_clk},
 };
 
-void __init clk_init(void)
+/* machine clk init */
+void __init spear6xx_clk_init(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
-		clk_register(&spear_clk_lookups[i]);
-
-	recalc_root_clocks();
+	clk_init(spear_clk_lookups, ARRAY_SIZE(spear_clk_lookups), &ddr_clk);
 }
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index b33e436..4cccf99 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -52,7 +52,7 @@ void __init spear6xx_map_io(void);
 void __init spear6xx_init_irq(void);
 void __init spear6xx_init(void);
 void __init spear600_init(void);
-void __init clk_init(void);
+void __init spear6xx_clk_init(void);
 
 /* Add spear600 machine device structure declarations here */
 
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
index bd71e72..0f4562b 100644
--- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
@@ -47,6 +47,13 @@
 #define PLL2_MOD		((unsigned int *)(MISC_BASE + 0x01C))
 #define PLL_CLK_CFG		((unsigned int *)(MISC_BASE + 0x020))
 #define CORE_CLK_CFG		((unsigned int *)(MISC_BASE + 0x024))
+/* PLL_CLK_CFG register masks */
+#define MCTR_CLK_SHIFT		28
+#define MCTR_CLK_MASK		0x7
+#define MCTR_CLK_HCLK_VAL	0x0
+#define MCTR_CLK_2HCLK_VAL	0x1
+#define MCTR_CLK_PLL2_VAL	0x3
+
 /* CORE CLK CFG register masks */
 #define PLL_HCLK_RATIO_SHIFT	10
 #define PLL_HCLK_RATIO_MASK	0x3
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index eb72c4c..4490731 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -439,7 +439,7 @@ void __init spear6xx_map_io(void)
 	iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
 
 	/* This will initialize clock framework */
-	clk_init();
+	spear6xx_clk_init();
 }
 
 static void __init spear6xx_timer_init(void)
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index 7d3338f..fb1c87b 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -21,6 +21,8 @@
 #include <linux/spinlock.h>
 #include <plat/clock.h>
 
+/* pointer to ddr clock structure */
+static struct clk *ddr_clk;
 static DEFINE_SPINLOCK(clocks_lock);
 static LIST_HEAD(root_clks);
 #ifdef CONFIG_DEBUG_FS
@@ -160,7 +162,7 @@ static int do_clk_enable(struct clk *clk)
 		 * time please reclac
 		 */
 		if (clk->recalc) {
-			ret = clk->recalc(clk);
+			ret = clk->recalc(clk, &clk->rate, clk->pclk->rate);
 			if (ret)
 				goto err;
 		}
@@ -298,7 +300,16 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 			propagate_rate(clk, 0);
 		spin_unlock_irqrestore(&clocks_lock, flags);
 	} else if (clk->pclk) {
-		u32 mult = clk->div_factor ? clk->div_factor : 1;
+		u32 mult;
+		/*
+		 * if pclk is SYSTEM_CLK and clk is not SYSTEM_CLK then return
+		 * error
+		 */
+		if (clk->pclk->flags & SYSTEM_CLK)
+			if (!(clk->flags & SYSTEM_CLK))
+				return -EPERM;
+
+		mult = clk->div_factor ? clk->div_factor : 1;
 		ret = clk_set_rate(clk->pclk, mult * rate);
 	}
 
@@ -371,7 +382,7 @@ void propagate_rate(struct clk *pclk, int on_init)
 
 	list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
 		if (clk->recalc) {
-			ret = clk->recalc(clk);
+			ret = clk->recalc(clk, &clk->rate, clk->pclk->rate);
 			/*
 			 * recalc will return error if clk out is not programmed
 			 * In this case configure default rate.
@@ -390,6 +401,47 @@ void propagate_rate(struct clk *pclk, int on_init)
 	}
 }
 
+/* updates "rate" pointer with current_clk's output for input "rate" */
+static void rate_calc(struct clk *current_clk, struct clk *ancestor_clk,
+		unsigned long *rate)
+{
+	if (current_clk->pclk != ancestor_clk)
+		rate_calc(current_clk->pclk, ancestor_clk, rate);
+
+	if (current_clk->recalc)
+		current_clk->recalc(current_clk, rate, *rate);
+}
+
+/*
+ * Check if ancestor clk rate is acceptable to ddr or not.
+ * This will call recursive rate_calc function, starting from ddr upto ancestor
+ * clk mentioned. This will calculate divisions / multiplications by all
+ * intermediate ancestor clocks and return the final rate of ddr if ancestor clk
+ * sets its rate to "rate", value passed in function.
+ */
+static int ddr_rate_acceptable(struct clk *aclk, unsigned long rate)
+{
+	struct ddr_rate_tbl *tbl = ddr_clk->private_data;
+
+	rate_calc(ddr_clk, aclk, &rate);
+	if ((rate >= tbl->minrate) && (rate <= tbl->maxrate))
+		return true;
+
+	return false;
+}
+
+/* mark all ddr ancestors with DDR_ANCESTOR flag */
+static void mark_ddr_ancestors(struct clk *dclk)
+{
+	struct clk *clk = dclk->pclk;
+
+	/* mark all ancestors of DDR */
+	while (clk != NULL) {
+		clk->flags |= DDR_ANCESTOR;
+		clk = clk->pclk;
+	}
+}
+
 /**
  * round_rate - Returns index of closest programmable rate in rate_config tbl
  * @clk: ptr to clock structure
@@ -475,7 +527,7 @@ unsigned long pll_calc_rate(struct clk *clk, int index)
  * In Dithered mode
  * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
  */
-int pll_clk_recalc(struct clk *clk)
+int pll_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	struct pll_clk_config *config = clk->private_data;
 	unsigned int num = 2, den = 0, val, mode = 0;
@@ -504,7 +556,7 @@ int pll_clk_recalc(struct clk *clk)
 	if (!den)
 		return -EINVAL;
 
-	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	*rate = (((prate/10000) * num) / den) * 10000;
 	return 0;
 }
 
@@ -522,6 +574,25 @@ int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
 	if (i < 0)
 		return i;
 
+	/* if clk is ddrs ancestor, check if rate is acceptable to ddr */
+	if (ddr_clk && (clk->flags & DDR_ANCESTOR)) {
+		int ret;
+
+		ret = ddr_rate_acceptable(clk, rate);
+		if (ret == false)
+			return -EPERM;
+		else {
+			/*
+			 * call routine to put ddr in refresh mode, and
+			 * configure pll.
+			 */
+			/* TBD */
+			clk->rate = rate;
+		}
+
+		return ret;
+	}
+
 	val = readl(config->mode_reg) &
 		~(config->masks->mode_mask << config->masks->mode_shift);
 	val |= (tbls[i].mode & config->masks->mode_mask) <<
@@ -563,7 +634,7 @@ unsigned long bus_calc_rate(struct clk *clk, int index)
 }
 
 /* calculates current programmed rate of ahb or apb bus */
-int bus_clk_recalc(struct clk *clk)
+int bus_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	struct bus_clk_config *config = clk->private_data;
 	unsigned int div;
@@ -574,7 +645,7 @@ int bus_clk_recalc(struct clk *clk)
 	if (!div)
 		return -EINVAL;
 
-	clk->rate = (unsigned long)clk->pclk->rate / div;
+	*rate = prate / div;
 	return 0;
 }
 
@@ -600,6 +671,14 @@ int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
 	return 0;
 }
 
+/* calculates current programmed rate of ahbmult2 */
+int
+ahbmult2_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
+{
+	*rate = prate * 2;
+	return 0;
+}
+
 /*
  * gives rate for different values of eq, x and y
  *
@@ -627,7 +706,7 @@ unsigned long aux_calc_rate(struct clk *clk, int index)
  *
  * Selection of eqn 1 or 2 is programmed in register
  */
-int aux_clk_recalc(struct clk *clk)
+int aux_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	struct aux_clk_config *config = clk->private_data;
 	unsigned int num = 1, den = 1, val, eqn;
@@ -650,7 +729,7 @@ int aux_clk_recalc(struct clk *clk)
 	if (!den)
 		return -EINVAL;
 
-	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	*rate = (((prate / 10000) * num) / den) * 10000;
 	return 0;
 }
 
@@ -704,7 +783,7 @@ unsigned long gpt_calc_rate(struct clk *clk, int index)
  * Fout from synthesizer can be given from below equations:
  * Fout= Fin/((2 ^ (N+1)) * (M+1))
  */
-int gpt_clk_recalc(struct clk *clk)
+int gpt_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	struct gpt_clk_config *config = clk->private_data;
 	unsigned int div = 1, val;
@@ -718,7 +797,7 @@ int gpt_clk_recalc(struct clk *clk)
 	if (!div)
 		return -EINVAL;
 
-	clk->rate = (unsigned long)clk->pclk->rate / div;
+	*rate = prate / div;
 	return 0;
 }
 
@@ -786,11 +865,10 @@ unsigned long clcd_calc_rate(struct clk *clk, int index)
  * complete div (including fractional part) and then right shift the
  * result by 14 places.
  */
-int clcd_clk_recalc(struct clk *clk)
+int clcd_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	struct clcd_clk_config *config = clk->private_data;
 	unsigned int div = 1;
-	unsigned long prate;
 	unsigned int val;
 
 	val = readl(config->synth_reg);
@@ -800,10 +878,10 @@ int clcd_clk_recalc(struct clk *clk)
 	if (!div)
 		return -EINVAL;
 
-	prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
+	prate = prate / 1000; /* first level division, make it KHz */
 
-	clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
-	clk->rate *= 1000;
+	*rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
+	*rate *= 1000;
 	return 0;
 }
 
@@ -834,11 +912,11 @@ int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
  * Used for clocks that always have value as the parent clock divided by a
  * fixed divisor
  */
-int follow_parent(struct clk *clk)
+int follow_parent(struct clk *clk, unsigned long *rate, unsigned long prate)
 {
 	unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
 
-	clk->rate = clk->pclk->rate/div_factor;
+	*rate = prate / div_factor;
 	return 0;
 }
 
@@ -857,7 +935,7 @@ void recalc_root_clocks(void)
 	spin_lock_irqsave(&clocks_lock, flags);
 	list_for_each_entry(pclk, &root_clks, sibling) {
 		if (pclk->recalc) {
-			ret = pclk->recalc(pclk);
+			ret = pclk->recalc(pclk, &pclk->rate, pclk->pclk->rate);
 			/*
 			 * recalc will return error if clk out is not programmed
 			 * In this case configure default clock.
@@ -873,6 +951,23 @@ void recalc_root_clocks(void)
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
+void __init
+clk_init(struct clk_lookup *clk_lookups, u32 count, struct clk *dclk)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		clk_register(&clk_lookups[i]);
+
+	recalc_root_clocks();
+
+	/* Mark all ancestors of DDR with special flag */
+	if (dclk) {
+		ddr_clk = dclk;
+		mark_ddr_ancestors(dclk);
+	}
+}
+
 #ifdef CONFIG_DEBUG_FS
 /*
  *	debugfs support to trace clock tree hierarchy and attributes
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 30938ea..6d53fc8 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -19,9 +19,12 @@
 #include <linux/types.h>
 
 /* clk structure flags */
-#define	ALWAYS_ENABLED		(1 << 0) /* clock always enabled */
-#define	RESET_TO_ENABLE		(1 << 1) /* reset register bit to enable clk */
-#define	ENABLED_ON_INIT		(1 << 2) /* clocks enabled at init */
+#define ALWAYS_ENABLED		(1 << 0) /* clock always enabled */
+#define RESET_TO_ENABLE		(1 << 1) /* reset register bit to enable clk */
+#define ENABLED_ON_INIT		(1 << 2) /* clocks enabled@init */
+/* Only System clocks can call other sytem clocks set rate function */
+#define SYSTEM_CLK		(1 << 3)
+#define DDR_ANCESTOR		(1 << 4) /* ancestor clks of DDR */
 
 /**
  * struct clkops - clock operations
@@ -99,8 +102,9 @@ struct clk {
 	unsigned int *en_reg;
 	u8 en_reg_bit;
 	const struct clkops *ops;
-	int (*recalc) (struct clk *);
-	int (*set_rate) (struct clk *, unsigned long rate);
+	int (*recalc) (struct clk *clk, unsigned long *rate,
+			unsigned long prate);
+	int (*set_rate) (struct clk *clk, unsigned long rate);
 	unsigned long (*calc_rate)(struct clk *, int index);
 	struct rate_config rate_config;
 	unsigned int div_factor;
@@ -223,26 +227,42 @@ struct clcd_rate_tbl {
 	u16 div;
 };
 
+/* ddr min, max clk rate table */
+struct ddr_rate_tbl {
+	unsigned long minrate;
+	unsigned long maxrate;
+};
+
 /* platform specific clock functions */
+/*
+ * must be called from machine clock.c file, dclk is pointer to ddr_clk
+ * strucutre. Which is required by clock framework.
+ *
+ * Actually before changing rate of DDRs ancestor, we must put ddr in refresh
+ * state and then change parent.
+ */
+void clk_init(struct clk_lookup *clk_lookups, u32 count, struct clk *dclk);
 void clk_register(struct clk_lookup *cl);
 void recalc_root_clocks(void);
 
 /* clock recalc & set rate functions */
-int follow_parent(struct clk *clk);
+int follow_parent(struct clk *clk, unsigned long *rate, unsigned long prate);
 unsigned long pll_calc_rate(struct clk *clk, int index);
-int pll_clk_recalc(struct clk *clk);
+int pll_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 unsigned long bus_calc_rate(struct clk *clk, int index);
-int bus_clk_recalc(struct clk *clk);
+int bus_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+int ahbmult2_clk_recalc(struct clk *clk, unsigned long *rate,
+		unsigned long prate);
 unsigned long gpt_calc_rate(struct clk *clk, int index);
-int gpt_clk_recalc(struct clk *clk);
+int gpt_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 unsigned long aux_calc_rate(struct clk *clk, int index);
-int aux_clk_recalc(struct clk *clk);
+int aux_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 unsigned long clcd_calc_rate(struct clk *clk, int index);
-int clcd_clk_recalc(struct clk *clk);
+int clcd_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 
 #endif /* __PLAT_CLOCK_H */
-- 
1.7.2.2

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (34 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 42/74] ST SPEAr: Adding support for DDR in clock framework Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-06 22:40   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-08-30 10:39 ` [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver Viresh KUMAR
                   ` (38 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

2 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

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/clock.c                 |   12 +++
 arch/arm/mach-spear3xx/emi.c                   |   86 ++++++++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/emi.h      |   79 ++++++++++++++++++++++
 arch/arm/mach-spear3xx/include/mach/generic.h  |    2 +
 arch/arm/mach-spear3xx/include/mach/spear310.h |    9 +++
 arch/arm/mach-spear3xx/include/mach/spear320.h |    6 ++
 arch/arm/mach-spear3xx/spear310.c              |   20 ++++++
 arch/arm/mach-spear3xx/spear310_evb.c          |   18 +++++
 arch/arm/mach-spear3xx/spear320.c              |   20 ++++++
 arch/arm/mach-spear3xx/spear320_evb.c          |   17 +++++
 11 files changed, 273 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/clock.c b/arch/arm/mach-spear3xx/clock.c
index 41a2b5e..4f049fe 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -552,6 +552,15 @@ static struct clk adc_clk = {
 	.recalc = &follow_parent,
 };
 
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* emi clock */
+static struct clk emi_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* ssp clock */
 static struct clk ssp0_clk = {
 	.pclk = &apb_clk,
@@ -744,6 +753,9 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+	{ .dev_id = "physmap-flash",	.clk = &emi_clk},
+#endif
 #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
 	defined(CONFIG_MACH_SPEAR320)
 	{ .con_id = "fsmc",		.clk = &fsmc_clk},
diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c
new file mode 100644
index 0000000..dd5cb8e
--- /dev/null
+++ b/arch/arm/mach-spear3xx/emi.c
@@ -0,0 +1,86 @@
+/*
+ * 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 <mach/emi.h>
+
+int __init emi_init(struct platform_device *pdev, unsigned long base,
+		u32 bank, u32 width)
+{
+	void __iomem *emi_reg_base;
+	struct clk *clk;
+	int ret;
+
+	if (bank > (EMI_MAX_BANKS - 1))
+		return -EINVAL;
+
+	emi_reg_base = ioremap(base, EMI_REG_SIZE);
+	if (!emi_reg_base)
+		return -ENOMEM;
+
+	clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		iounmap(emi_reg_base);
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_enable(clk);
+	if (ret) {
+		iounmap(emi_reg_base);
+		return ret;
+	}
+
+	/* set the timing */
+	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 << bank, emi_reg_base + ACK_REG);
+
+	iounmap(emi_reg_base);
+
+	return 0;
+}
+
+void __init emi_init_board_info(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width)
+{
+	emi_init_plat_data(pdev, partitions, nr_partitions, width);
+}
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..f3cbfbc
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/emi.h
@@ -0,0 +1,79 @@
+/*
+ * 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 TIMEOUT_REG		(0x90)
+#define ACK_REG			(0x94)
+#define IRQ_REG			(0x98)
+
+#define EMI_MAX_BANKS		6
+
+#elif defined(CONFIG_MACH_SPEAR320)
+#define TIMEOUT_REG		(0x60)
+#define ACK_REG			(0x64)
+#define IRQ_REG			(0x68)
+
+#define 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)
+
+static inline void emi_init_plat_data(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width)
+{
+	struct physmap_flash_data *emi_plat_data;
+	emi_plat_data = dev_get_platdata(&pdev->dev);
+
+	if (partitions) {
+		emi_plat_data->parts = partitions;
+		emi_plat_data->nr_parts = nr_partitions;
+	}
+
+	emi_plat_data->width = width;
+}
+
+extern int __init emi_init(struct platform_device *pdev, unsigned long base,
+		u32 bank, u32 width);
+extern void __init emi_init_board_info(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width);
+#endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 4d04dbe..6c6eced 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -167,6 +167,7 @@ extern struct amba_device uart2_device;
 extern struct amba_device uart3_device;
 extern struct amba_device uart4_device;
 extern struct amba_device uart5_device;
+extern struct platform_device emi_nor_device;
 extern struct platform_device plgpio_device;
 extern struct platform_device nand_device;
 
@@ -192,6 +193,7 @@ extern struct amba_device uart1_device;
 extern struct amba_device uart2_device;
 extern struct platform_device can0_device;
 extern struct platform_device can1_device;
+extern struct platform_device emi_nor_device;
 extern struct platform_device i2c1_device;
 extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
index 1e85347..37556b6 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 940f0d8..4f60073 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.c b/arch/arm/mach-spear3xx/spear310.c
index 29e3c2c..32c492d 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/physmap.h>
 #include <linux/ptrace.h>
 #include <asm/irq.h>
 #include <mach/generic.h>
@@ -268,6 +269,25 @@ int spear300_o2p(int offset)
 		return offset + 2;
 }
 
+/* emi nor flash device registeration */
+static struct physmap_flash_data emi_norflash_data;
+
+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,
+	},
+};
+
+struct platform_device emi_nor_device = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.resource = emi_nor_resources,
+	.num_resources = ARRAY_SIZE(emi_nor_resources),
+	.dev.platform_data = &emi_norflash_data,
+};
+
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
 	.irq_base = SPEAR_PLGPIO_INT_BASE,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 612eb04..64d06f1 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -16,6 +16,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
+#include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/gpio.h>
 #include <mach/spear.h>
@@ -23,6 +24,15 @@
 #include <plat/smi.h>
 #include <plat/spi.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),
+};
+
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
@@ -60,6 +70,7 @@ static struct amba_device *amba_devs[] __initdata = {
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
+	&emi_nor_device,
 	&i2c_device,
 	&nand_device,
 	&ohci0_device,
@@ -126,12 +137,19 @@ static void __init spear310_evb_init(void)
 	/* initialize serial nor related data in smi plat data */
 	smi_init_board_info(&smi_device);
 
+	/* initialize emi related data in emi plat data */
+	emi_init_board_info(&emi_nor_device, partition_info,
+			ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH32);
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
+	/* Initialize emi regiters */
+	emi_init(&emi_nor_device, SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32);
+
 	spi_init();
 }
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 0c2f4a5..b13e0fc 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/amba/pl022.h>
+#include <linux/mtd/physmap.h>
 #include <linux/ptrace.h>
 #include <linux/types.h>
 #include <linux/mmc/sdhci-spear.h>
@@ -473,6 +474,25 @@ struct amba_device uart2_device = {
 	.irq = {VIRQ_UART2, NO_IRQ},
 };
 
+/* emi nor flash device registeration */
+static struct physmap_flash_data emi_norflash_data;
+
+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,
+	},
+};
+
+struct platform_device emi_nor_device = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.resource = emi_nor_resources,
+	.num_resources = ARRAY_SIZE(emi_nor_resources),
+	.dev.platform_data = &emi_norflash_data,
+};
+
 /* 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 d55e1b2..da57e97 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -17,6 +17,7 @@
 #include <linux/spi/flash.h>
 #include <linux/mmc/sdhci-spear.h>
 #include <linux/spi/spi.h>
+#include <mach/emi.h>
 #include <mach/generic.h>
 #include <mach/gpio.h>
 #include <mach/spear.h>
@@ -24,6 +25,15 @@
 #include <plat/smi.h>
 #include <plat/spi.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),
+};
+
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
@@ -145,12 +155,19 @@ static void __init spear320_evb_init(void)
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
+	/* initialize emi related data in emi plat data */
+	emi_init_board_info(&emi_nor_device, partition_info,
+			ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH16);
+
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
 
 	/* Add Amba Devices */
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
+	/* Initialize emi regiters */
+	emi_init(&emi_nor_device, SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16);
+
 	spi_init();
 }
 
-- 
1.7.2.2

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

* [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (35 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-01 22:43   ` Linus Walleij
  2010-08-30 10:39 ` [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs Viresh KUMAR
                   ` (37 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

SPEAr1300 SoC supports FSMC to interface with various memories (NOR/NAND/SRAM).
This patch adds the support for FSMC over NOR interface.

The driver being used is driver/mtd/maps/physmap.c

Signed-off-by: Vipin Kumar <vipin.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               |    2 +-
 arch/arm/mach-spear13xx/clock.c                |    2 +-
 arch/arm/mach-spear13xx/fsmc-nor.c             |   81 ++++++++++++++++++++++++
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   17 +++++
 arch/arm/mach-spear13xx/spear13xx.c            |   20 ++++++
 arch/arm/plat-spear/include/plat/fsmc.h        |   51 +++++++++++++++-
 7 files changed, 171 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/fsmc-nor.c

diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
index 168886e..8644c76 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -3,7 +3,7 @@
 #
 
 # common files
-obj-y					+= spear13xx.o clock.o
+obj-y					+= spear13xx.o clock.o fsmc-nor.o
 obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
 
diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 30eba05..c593608 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -920,7 +920,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "pcie2",		.clk = &pcie2_clk},
 	{.dev_id = "cfxd",		.clk = &cfxd_clk},
 	{.dev_id = "sdhci",		.clk = &sdhci_clk},
-	{.con_id = "fsmc",		.clk = &fsmc_clk},
+	{.dev_id = "fsmc",		.clk = &fsmc_clk},
 	{.dev_id = "sysram0",		.clk = &sysram0_clk},
 	{.dev_id = "sysram1",		.clk = &sysram1_clk},
 
diff --git a/arch/arm/mach-spear13xx/fsmc-nor.c b/arch/arm/mach-spear13xx/fsmc-nor.c
new file mode 100644
index 0000000..68f0ca0
--- /dev/null
+++ b/arch/arm/mach-spear13xx/fsmc-nor.c
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-spear13xx/fsmc-nor.c
+ *
+ * FSMC (Flexible Static Memory Controller) interface for NOR
+ *
+ * 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/err.h>
+#include <linux/io.h>
+#include <plat/fsmc.h>
+
+int __init fsmc_nor_init(struct platform_device *pdev, unsigned long base,
+		u32 bank, u32 width)
+{
+	void __iomem *fsmc_nor_base;
+	struct fsmc_regs *regs;
+	struct clk *clk;
+	int ret;
+	u32 ctrl;
+
+	if (bank > (FSMC_MAX_NOR_BANKS - 1))
+		return -EINVAL;
+
+	fsmc_nor_base = ioremap(base, FSMC_NOR_REG_SIZE);
+	if (!fsmc_nor_base)
+		return -ENOMEM;
+
+	clk = clk_get(NULL, "fsmc");
+	if (IS_ERR(clk)) {
+		iounmap(fsmc_nor_base);
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_enable(clk);
+	if (ret) {
+		iounmap(fsmc_nor_base);
+		return ret;
+	}
+
+	regs = (struct fsmc_regs *)fsmc_nor_base;
+
+	ctrl = WAIT_ENB | WRT_ENABLE | WPROT | NOR_DEV | BANK_ENABLE;
+
+	switch (width) {
+	case FSMC_FLASH_WIDTH8:
+		ctrl |= WIDTH_8;
+		break;
+
+	case FSMC_FLASH_WIDTH16:
+		ctrl |= WIDTH_16;
+		break;
+
+	default:
+		ctrl |= WIDTH_8;
+		break;
+	}
+
+	writel(ctrl, &regs->nor_bank_regs[bank].ctrl);
+	writel(0x0FFFFFFF, &regs->nor_bank_regs[bank].ctrl_tim);
+	writel(ctrl | RSTPWRDWN, &regs->nor_bank_regs[bank].ctrl);
+
+	iounmap(fsmc_nor_base);
+
+	return 0;
+}
+
+void __init fsmc_init_board_info(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width)
+{
+	fsmc_init_plat_data(pdev, partitions, nr_partitions, width);
+}
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 6f4e6b5..dfee834 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -38,6 +38,7 @@ extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
 extern struct platform_device kbd_device;
 extern struct platform_device nand_device;
+extern struct platform_device fsmc_nor_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-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index db05747..d030a85 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -21,11 +21,21 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <mach/pcie.h>
+#include <plat/fsmc.h>
 #include <plat/keyboard.h>
 #include <plat/nand.h>
 #include <plat/smi.h>
 #include <plat/spi.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),
+};
+
 static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[0],
 	&gpio_device[1],
@@ -143,6 +153,9 @@ static void __init spear1300_evb_init(void)
 	enable_pcie0_clk();
 	pcie_init(&spear1300_pcie_port_is_host);
 #endif
+	/* initialize fsmc related data in fsmc plat data */
+	fsmc_init_board_info(&fsmc_nor_device, partition_info,
+			ARRAY_SIZE(partition_info), FSMC_FLASH_WIDTH8);
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
@@ -150,6 +163,10 @@ static void __init spear1300_evb_init(void)
 	/* Add Amba Devices */
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
+	/* Initialize fsmc regiters */
+	fsmc_nor_init(&fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
+			FSMC_FLASH_WIDTH8);
+
 	spi_init();
 }
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 4563551..6d71aac 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/amba/pl022.h>
 #include <linux/amba/pl061.h>
+#include <linux/mtd/physmap.h>
 #include <linux/ptrace.h>
 #include <linux/io.h>
 #include <asm/hardware/gic.h>
@@ -130,6 +131,25 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* fsmc nor flash device registeration */
+static struct physmap_flash_data fsmc_norflash_data;
+
+static struct resource fsmc_nor_resources[] = {
+	{
+		.start	= SPEAR13XX_FSMC_MEM_BASE,
+		.end	= SPEAR13XX_FSMC_MEM_BASE + SZ_16M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device fsmc_nor_device = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.resource = fsmc_nor_resources,
+	.num_resources = ARRAY_SIZE(fsmc_nor_resources),
+	.dev.platform_data = &fsmc_norflash_data,
+};
+
 /* nand device registeration */
 void __init nand_mach_init(u32 busw)
 {
diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h
index c0fdcd3..5909afd 100644
--- a/arch/arm/plat-spear/include/plat/fsmc.h
+++ b/arch/arm/plat-spear/include/plat/fsmc.h
@@ -15,11 +15,36 @@
 #define __PLAT_FSMC_H
 
 #include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
 #include <linux/types.h>
 #include <asm/param.h>
 
+#define FSMC_MAX_NOR_BANKS	4
 #define FSMC_MAX_NAND_BANKS	4
 
+#define FSMC_FLASH_WIDTH8	1
+#define FSMC_FLASH_WIDTH16	2
+
+struct nor_bank_regs {
+	u32 ctrl;
+	u32 ctrl_tim;
+};
+
+/* ctrl register definitions */
+#define BANK_ENABLE		(1 << 0)
+#define MUXED			(1 << 1)
+#define NOR_DEV			(2 << 2)
+#define WIDTH_8			(0 << 4)
+#define WIDTH_16		(1 << 4)
+#define RSTPWRDWN		(1 << 6)
+#define WPROT			(1 << 7)
+#define WRT_ENABLE		(1 << 12)
+#define WAIT_ENB		(1 << 13)
+
+/* ctrl_tim register definitions */
+
 struct nand_bank_regs {
 	u32 pc;
 	u32 sts;
@@ -31,8 +56,11 @@ struct nand_bank_regs {
 	u32 ecc3;
 };
 
+#define FSMC_NOR_REG_SIZE	0x40
+
 struct fsmc_regs {
-	u8 reserved_1[0x40];
+	struct nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS];
+	u8 reserved_1[0x40 - 0x20];
 	struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
 	u8 reserved_2[0xfe0 - 0xc0];
 	u32 peripid0;			/* 0xfe0 */
@@ -106,4 +134,25 @@ struct fsmc_eccplace {
 	struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
 };
 
+static inline void fsmc_init_plat_data(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width)
+{
+	struct physmap_flash_data *fsmc_plat_data;
+	fsmc_plat_data = dev_get_platdata(&pdev->dev);
+
+	if (partitions) {
+		fsmc_plat_data->parts = partitions;
+		fsmc_plat_data->nr_parts = nr_partitions;
+	}
+
+	fsmc_plat_data->width = width;
+}
+
+extern int __init fsmc_nor_init(struct platform_device *pdev,
+		unsigned long base, u32 bank, u32 width);
+extern void __init fsmc_init_board_info(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int width);
+
 #endif /* __PLAT_FSMC_H */
-- 
1.7.2.2

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (36 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 10:22   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 46/74] SPEAr Clock Framework: Adding support for PLL frequency change Viresh KUMAR
                   ` (36 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

The secondary CPUs have been put in a WFE(Wait for Event) state. Using SEV
instruction sends an event to all CPUs.

Signed-off-by: Vipin Kumar <vipin.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/smp.h |    6 ++++++
 arch/arm/mach-spear13xx/platsmp.c          |    5 +++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h b/arch/arm/mach-spear13xx/include/mach/smp.h
index 6e028a1..e2e55fc 100644
--- a/arch/arm/mach-spear13xx/include/mach/smp.h
+++ b/arch/arm/mach-spear13xx/include/mach/smp.h
@@ -24,6 +24,12 @@
 		cpunum &= 0x0F;				\
 	})
 
+/*
+ * set_event() is used to wake up secondary core from wfe using sev. Booting
+ * code puts the second core into wfe(standby).
+ */
+#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
+
 /* We use IRQ1 as the IPI */
 static inline void smp_cross_call(const struct cpumask *mask)
 {
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
index 8b75d1b..73fbcdb 100644
--- a/arch/arm/mach-spear13xx/platsmp.c
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -133,6 +133,11 @@ static void __init poke_milo(void)
 			__io_address(SPEAR13XX_SYS_LOCATION));
 
 	mb();
+
+	/*
+	 * Send a 'sev' to wake the secondary core from WFE.
+	 */
+	set_event();
 }
 
 /*
-- 
1.7.2.2

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

* [PATCH 46/74] SPEAr Clock Framework: Adding support for PLL frequency change
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (37 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 47/74] SPEAr Power Management: Added the support for Standby mode Viresh KUMAR
                   ` (35 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/spear3xx.c        |    5 +
 arch/arm/mach-spear6xx/spear6xx.c        |    5 +
 arch/arm/plat-spear/Makefile             |    2 +-
 arch/arm/plat-spear/clock.c              |    6 +-
 arch/arm/plat-spear/include/plat/clock.h |    1 +
 arch/arm/plat-spear/pll_clk.S            |  187 ++++++++++++++++++++++++++++++
 6 files changed, 201 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/plat-spear/pll_clk.S

diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index a905b5d..23f92af 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -271,6 +271,11 @@ struct map_desc spear3xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR3XX_ICM3_SDRAM_CTRL_BASE),
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_SDRAM_CTRL_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
 	},
 };
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 4490731..f729e92 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -430,6 +430,11 @@ static struct map_desc spear6xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR6XX_ICM3_SDRAM_CTRL_BASE),
+		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_SDRAM_CTRL_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
 	},
 };
 
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 50c680c..0e2cf75 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y	:= clcd.o clock.o time.o smi.o
+obj-y	:= clcd.o clock.o pll_clk.o smi.o time.o
 
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index fb1c87b..ee8f82b 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -586,11 +586,10 @@ int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
 			 * call routine to put ddr in refresh mode, and
 			 * configure pll.
 			 */
-			/* TBD */
+			pll_set_rate(tbls[i].m, tbls[i].p, tbls[i].n);
 			clk->rate = rate;
 		}
-
-		return ret;
+		return 0;
 	}
 
 	val = readl(config->mode_reg) &
@@ -616,7 +615,6 @@ int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
 			config->masks->norm_fdbk_m_shift;
 
 	writel(val, config->cfg_reg);
-
 	clk->rate = rate;
 
 	return 0;
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 6d53fc8..09d61a4 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -264,5 +264,6 @@ int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
 unsigned long clcd_calc_rate(struct clk *clk, int index);
 int clcd_clk_recalc(struct clk *clk, unsigned long *rate, unsigned long prate);
 int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+void pll_set_rate(u16 pdiv, u8 nmul, u8 hclkdiv);
 
 #endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/pll_clk.S b/arch/arm/plat-spear/pll_clk.S
new file mode 100644
index 0000000..d0687b4
--- /dev/null
+++ b/arch/arm/plat-spear/pll_clk.S
@@ -0,0 +1,187 @@
+/*
+ * arch/arm/plat-spear/pll_clk.S
+ *
+ * SPEAR3xx and SPEAR6xx specific functions that will run in
+ * cache. These funstions intend to configure the PLL.
+ *
+ * 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>
+
+#if defined(CONFIG_ARCH_SPEAR3XX) || defined(CONFIG_ARCH_SPEAR6XX)
+.text
+ENTRY(pll_set_rate)
+	stmfd	sp!, {r0-r12, lr}
+
+	/* Lock down the TLB entry to the current victim */
+	mrc	p15, 0, r3, c10, c0, 0	/* read the lockdown register */
+	orr	r3, r3, #1		/* set the preserved bit */
+	mcr	p15, 0, r3, c10, c0, 0	/* write to the lockdown register */
+
+	/*
+	 * set r4 to the value of the address to be locked down.
+	 * Invalidate the TLB single entry in TLB to ensure that
+	 * the locked address is not already in TLB.
+	 * MPMC, System Controller & Miscellaneous register address
+	 * are locked down below.
+	 */
+
+	ldr	r4, MPMC_BASE_VA
+	/* Invalidate the MPMC virtual address in TLB. */
+	mcr	p15, 0, r4, c8, c7, 1
+	/* TLB will miss and entry will be reloaded */
+	ldr	r4, [r4]
+	/* read the lockdown register (victim will have rloaded) */
+	mrc	p15, 0, r3, c10, c0, 0
+
+	ldr	r4, SYS_CTRL_BASE_VA
+	/* Invalidate the System controller virtual address in TLB */
+	mcr	p15, 0, r4, c8, c7, 1
+	/* TLB will miss and entry will be reloaded */
+	ldr	r4, [r4]
+	/* read the lockdown register (victim will have rloaded) */
+	mrc	p15, 0, r3, c10, c0, 0
+
+	ldr	r4, MISC_BASE_VA
+	/* Invalidate the Miscellaneous registers virtual address in TLB */
+	mcr	p15, 0, r4, c8, c7, 1
+	/* TLB will miss and entry will be reloaded */
+	ldr	r4, [r4]
+	/* read the lockdown register (victim will have rloaded) */
+	mrc	p15, 0, r3, c10, c0, 0
+
+	/* clear preserve bit */
+	bic	r3, r3, #1
+	/* write to the lockdown register */
+	mcr	p15, 0, r3, c10, c0, 0
+
+	ldr	r7, MPMC_BASE_VA
+	ldr	r8, SYS_CTRL_BASE_VA
+	ldr	r6, MISC_BASE_VA
+	/* Prefetch certain instructions in the cache. */
+	adr	r4, cache_prefetch_start1
+	adr	r5, cache_prefetch_end1
+	mvn	r3, #0x1F
+	ands	r4, r3, r4
+	/* Lock Instructions in i-cache */
+fetch_loop:
+	/*
+	 * copy a cache-line-sized block of main memory to a cache
+	 * line in the I-cache.
+	 */
+	mcr	p15, 0, r4, c7, c13, 1
+	cmp	r4, r5
+	addls	r4, r4, #0x20
+	bls	fetch_loop
+cache_prefetch_start1:
+	/* Put SDRAM in self-refresh mode */
+	ldr	r3, [r7, #0x1c]
+	/* Clear START bit(24) of MEMCTL_GP_03 register in MPMC */
+	ldr	r4, =0x1000000
+	bic	r3, r3, r4
+	str	r3, [r7, #0x1c]
+
+	ldr	r3, [r7, #0xe4]
+	ldr	r4, =0xffff0000
+	/* Latch the current self refresh time */
+	mov	r9, r3
+	/* Increase the self refresh exit time */
+	bic	r3, r3, r4
+	ldr	r4, =0xffff
+	/* Program the SDRAM self refresh exit time on read command */
+	orr	r3, r3, r4, LSL #16
+	str	r3, [r7, #0xe4]
+
+	ldr	r3, [r7, #0x1c]
+	/* Set the SREFRESH bit(16) */
+	ldr	r4, =0x10000
+	orr	r3, r3, r4
+	str	r3, [r7, #0x1c]
+
+	/* Put the system in slow mode, use system controller */
+	ldr	r3, [r8]
+	bic	r3, r3, #0x7
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	orr	r3, r3, #0x2
+	str	r3, [r8]
+
+wait_till_slow_mode:
+	ldr	r3, [r8]
+	and	r3, r3, #0x78	/* Wait for the mode to be updated */
+	cmp	r3, #0x10	/* Poll the SCCTRL register status bits (6:3) */
+	bne wait_till_slow_mode
+
+	/*
+	 * reprogram the m(r0), p(r2), n(r1) values in the PLL
+	 * control registers (PLL_FRQ register in misc space).
+	 */
+	ldr	r3, [r6, #0x0c]
+	bic	r3, r3, #0x00ff
+	/* Program the PLL post divisor: p */
+	orr	r3, r3, r2
+	str	r3, [r6, #0x0c]
+
+	ldr	r3, [r6, #0x0c]
+	ldr	r4, =0xffff0000
+	bic	r3, r3, r4
+	bic	r3, r3, #0x0700
+	/* Program the PLL pre divisor: n */
+	orr	r3, r3, r1, LSL #8
+	/* Program the PLL feedback divisor: m */
+	orr	r3, r3, r0, LSL #24
+	str	r3, [r6, #0x0c]
+
+	/* Move the system in Normal mode, use system controller */
+	ldr	r3, [r8, #0x0]
+	ldr	r4, =0xfffffff8
+	/* Set the apt mode bits(2:0) in SCCTRL register */
+	and	r3, r3, r4
+	orr	r3, r3, #0x4
+	str	r3, [r8, #0x0]
+
+wait_till_normal_mode:
+	ldr	r3, [r8, #0x0]
+	and	r3, r3, #0x78
+	cmp	r3, #0x20	/* Poll the SCCTRL register status bits (6:3) */
+	bne wait_till_normal_mode
+
+	/* Exit DDR-SDRAM from self-refresh mode */
+	ldr	r10, MPMC_BASE_VA
+	/* Clear the SREFRESH bit(16) */
+	ldr	r3, [r10, #0x1c]
+	ldr	r4, =0x10000
+	bic	r3, r3, r4
+	str	r3, [r10, #0x1c]
+	/* Restore the SDRAM self refresh exit time on read command */
+	mov	r3, r9
+	str	r3, [r7, #0xe4]
+	/* Begin the command processing in controller */
+	ldr	r4, =0x1000000
+	orr	r3, r3, r4
+	/* Set START bit(24) of MEMCTL_GP_03 register in MPMC*/
+	str	r3, [r10, #0x1c]
+
+	ldmfd	sp!, {r0-r12, pc}
+
+/* This is the end of the code to be copied */
+
+SYS_CTRL_BASE_VA :
+	.word IO_ADDRESS(SYS_CTRL_BASE_PA)
+MPMC_BASE_VA :
+	.word IO_ADDRESS(MPMC_BASE_PA)
+MISC_BASE_VA :
+	.word IO_ADDRESS(MISC_BASE_PA)
+cache_prefetch_end1 :
+
+#elif defined(CONFIG_ARCH_SPEAR13XX)
+.text
+ENTRY(pll_set_rate)
+#endif
-- 
1.7.2.2

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

* [PATCH 47/74] SPEAr Power Management: Added the support for Standby mode.
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (38 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 46/74] SPEAr Clock Framework: Adding support for PLL frequency change Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume Viresh KUMAR
                   ` (34 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

OPEN POINTS: 	1. Suspend to RAM support needs to be added.
		2. The basic framework added for S2R.
		3. SPEAr13xx: The power domains need to be added.
		4. Extensive testing needs to be done.
		5. For SPEAr13xx: PLL-4 has not been switch off while moving
		into sleep. There is some problem in getting the pll back to on.
		6. Not functional on SPEAr6XX

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              |    5 +-
 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, 1093 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 8644c76..b786edc 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_BOARD_SPEAR1300_EVB)	+= spear1300_evb.o
 obj-$(CONFIG_MACH_SPEAR1310)		+= spear1310.o
 # spear1310 boards files
 obj-$(CONFIG_BOARD_SPEAR1310_EVB)	+= spear1310_evb.o
+obj-$(CONFIG_PM)	+= pm.o sleep.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..c8d13e6
--- /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/spear.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..6152043
--- /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/irqs.h>
+#include <mach/suspend.h>
+#include <mach/hardware.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 6d71aac..59eaf98 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -454,6 +454,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..a525173
--- /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/spear.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 23f92af..1f374b4 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -22,6 +22,8 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 
+#define SPEAR3XX_WKUP_SRCS	(1 << IRQ_MAC_1 | 1 << IRQ_USB_DEV | \
+				1 << IRQ_BASIC_RTC | 1 << IRQ_BASIC_GPIO)
 /* Add spear3xx machines common devices here */
 /* gpio device registeration */
 static struct pl061_platform_data gpio_plat_data = {
@@ -246,7 +248,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..e98e831
--- /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/spear.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 f729e92..725dbc4 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -24,6 +24,12 @@
 #include <mach/spear.h>
 #include <plat/nand.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 */
 
 /* CLCD device registration */
@@ -400,7 +406,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 0e2cf75..1c8ee4a 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -6,6 +6,7 @@
 obj-y	:= clcd.o clock.o pll_clk.o smi.o time.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
@@ -16,3 +17,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] 245+ messages in thread

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (39 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 47/74] SPEAr Power Management: Added the support for Standby mode Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 10:23   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework Viresh KUMAR
                   ` (33 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/common/gic.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 7dfa9a8..e816ef1 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -201,6 +201,18 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 	chip->unmask(irq);
 }
 
+#ifdef CONFIG_PM
+
+static int gic_set_wake(unsigned int irq, unsigned int on)
+{
+	return 0;
+}
+
+#else
+
+#define gic_set_wake NULL
+#endif
+
 static struct irq_chip gic_chip = {
 	.name		= "GIC",
 	.ack		= gic_ack_irq,
@@ -210,6 +222,7 @@ static struct irq_chip gic_chip = {
 #ifdef CONFIG_SMP
 	.set_affinity	= gic_set_cpu,
 #endif
+	.set_wake	= gic_set_wake,
 };
 
 void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
-- 
1.7.2.2

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

* [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (40 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 10:24   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 51/74] ST SPEAr1310: Adding fsmc nor support Viresh KUMAR
                   ` (32 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Deepak Sikri <deepak.sikri@st.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/Kconfig                |    2 +
 arch/arm/mach-spear13xx/clock.c |    1 +
 arch/arm/mach-spear3xx/clock.c  |    1 +
 arch/arm/mach-spear6xx/clock.c  |    1 +
 arch/arm/plat-spear/Makefile    |    2 +-
 arch/arm/plat-spear/cpufreq.c   |  160 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 166 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/plat-spear/cpufreq.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c4d1df3..ef92faa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -822,6 +822,8 @@ config PLAT_SPEAR
 	select COMMON_CLKDEV
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select ARCH_HAS_CPUFREQ
+
 	help
 	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
 
diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index c593608..7f07911 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -90,6 +90,7 @@ static struct pll_clk_config pll1_config = {
 /* pll rate configuration table, in ascending order of rates */
 struct pll_rate_tbl pll_rtbl[] = {
 	/* PCLK 24MHz */
+	{.mode = 0, .m = 0x64, .n = 0x03, .p = 0x2}, /* 400 MHz */
 	{.mode = 0, .m = 0x7D, .n = 0x03, .p = 0x2}, /* 500 MHz */
 	{.mode = 0, .m = 0xA6, .n = 0x03, .p = 0x2}, /* 664 MHz */
 	{.mode = 0, .m = 0xC8, .n = 0x03, .p = 0x2}, /* 800 MHz */
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 4f049fe..64d9cdc 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -55,6 +55,7 @@ static struct pll_clk_masks pll_masks = {
 
 /* pll rate configuration table, in ascending order of rates */
 struct pll_rate_tbl pll_rtbl[] = {
+	{.mode = 0, .m = 0x53, .n = 0x0C, .p = 0x1}, /* 166 MHz */
 	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
 	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
 };
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 99cc21d..f1429f5 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -55,6 +55,7 @@ static struct pll_clk_masks pll_masks = {
 
 /* pll rate configuration table, in ascending order of rates */
 struct pll_rate_tbl pll_rtbl[] = {
+	{.mode = 0, .m = 0x53, .n = 0x0C, .p = 0x1}, /* 166 MHz */
 	{.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
 	{.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
 };
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 1c8ee4a..c25e5b8 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -6,7 +6,7 @@
 obj-y	:= clcd.o clock.o pll_clk.o smi.o time.o
 
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
-
+obj-$(CONFIG_CPU_FREQ)		+= cpufreq.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/cpufreq.c b/arch/arm/plat-spear/cpufreq.c
new file mode 100644
index 0000000..3b1cac9
--- /dev/null
+++ b/arch/arm/plat-spear/cpufreq.c
@@ -0,0 +1,160 @@
+/*
+ * arch/arm/plat-spear/cpufreq.c
+ *
+ * CPU Frequency Scaling for SPEAr platform
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/system.h>
+
+#define CPU_CLK		"cpu_clk"
+
+#ifdef CONFIG_ARCH_SPEAR13XX
+#define MIN_CPU_FREQ	200000
+#define MAX_CPU_FREQ	500000
+
+static u32 spear_cpu_freq[] = {
+	200000,	/* 200 MHZ */
+	250000,	/* 250 MHZ */
+	332000,	/* 332 MHZ */
+	400000,	/* 400 MHZ */
+	500000,	/* 500 MHZ */
+};
+#elif defined(CONFIG_ARCH_SPEAR6XX) || defined(CONFIG_ARCH_SPEAR3XX)
+#define MIN_CPU_FREQ	166000
+#define MAX_CPU_FREQ	332000
+
+static u32 spear_cpu_freq[] = {
+	166000,	/* 166 MHZ */
+	266000,	/* 266 MHZ */
+	332000,	/* 333 MHZ */
+};
+#endif
+
+static struct
+	cpufreq_frequency_table spear_freq_tbl[ARRAY_SIZE(spear_cpu_freq) + 1];
+static struct clk *cpu_clk;
+
+int spear_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, spear_freq_tbl);
+}
+
+unsigned int spear_cpufreq_get(unsigned int cpu)
+{
+	unsigned long rate;
+
+	if (cpu)
+		return 0;
+
+	rate = clk_get_rate(cpu_clk) / 1000;
+	return rate;
+}
+
+static int spear_cpufreq_target(struct cpufreq_policy *policy,
+		unsigned int target_freq, unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	int ret = 0;
+	int index;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	if (cpufreq_frequency_table_target(policy, spear_freq_tbl,
+				target_freq, relation, &index))
+		return -EINVAL;
+
+	freqs.old = spear_cpufreq_get(0);
+	freqs.new = spear_cpu_freq[index];
+	freqs.cpu = policy->cpu;
+
+	if (freqs.old == target_freq)
+		return 0;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return ret;
+}
+
+static int spear_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int result;
+	int i = 0;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	cpu_clk = clk_get(NULL, CPU_CLK);
+	if (IS_ERR(cpu_clk))
+		return PTR_ERR(cpu_clk);
+
+	policy->cpuinfo.min_freq = MIN_CPU_FREQ;
+	policy->cpuinfo.max_freq = MAX_CPU_FREQ;
+	policy->cur = policy->min = policy->max = spear_cpufreq_get(0);
+
+	for (i = 0; i < ARRAY_SIZE(spear_cpu_freq); i++) {
+		spear_freq_tbl[i].index = i;
+		spear_freq_tbl[i].frequency = spear_cpu_freq[i];
+	}
+
+	spear_freq_tbl[i].index = i;
+	spear_freq_tbl[i].frequency = CPUFREQ_TABLE_END;
+	result = cpufreq_frequency_table_cpuinfo(policy, spear_freq_tbl);
+	if (!result)
+		cpufreq_frequency_table_get_attr(spear_freq_tbl,
+				policy->cpu);
+
+	policy->cpuinfo.transition_latency = 300*1000; /*250 uS*/
+
+	return 0;
+}
+
+static int spear_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	clk_put(cpu_clk);
+	return 0;
+}
+
+static struct freq_attr *spear_cpufreq_attr[] = {
+	 &cpufreq_freq_attr_scaling_available_freqs,
+	 NULL,
+};
+
+static struct cpufreq_driver spear_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= spear_cpufreq_verify,
+	.target		= spear_cpufreq_target,
+	.get		= spear_cpufreq_get,
+	.init		= spear_cpufreq_init,
+	.exit		= spear_cpufreq_exit,
+	.name		= "spear_cpufreq",
+	.attr		= spear_cpufreq_attr,
+};
+
+static int __init spear_cpufreq_register(void)
+{
+	return cpufreq_register_driver(&spear_driver);
+}
+
+arch_initcall(spear_cpufreq_register);
-- 
1.7.2.2

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

* [PATCH 51/74] ST SPEAr1310: Adding fsmc nor support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (41 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms Viresh KUMAR
                   ` (31 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Vipin Kumar <vipin.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/spear1310_evb.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 8b02104..fb4b7c0 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -23,9 +23,19 @@
 #include <mach/pcie.h>
 #include <plat/keyboard.h>
 #include <plat/nand.h>
+#include <plat/fsmc.h>
 #include <plat/smi.h>
 #include <plat/spi.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),
+};
+
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
 	&gpio_device[0],
@@ -143,6 +153,10 @@ static void __init spear1310_evb_init(void)
 
 	/* initialize serial nor related data in smi plat data */
 	smi_init_board_info(&smi_device);
+	/* initialize fsmc related data in fsmc plat data */
+	fsmc_init_board_info(&fsmc_nor_device, partition_info,
+			ARRAY_SIZE(partition_info), FSMC_FLASH_WIDTH8);
+
 #ifdef CONFIG_PCIEPORTBUS
 	/* Enable PCIE0 clk */
 	enable_pcie0_clk();
@@ -155,6 +169,10 @@ static void __init spear1310_evb_init(void)
 	/* Add Amba Devices */
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
+	/* Initialize fsmc regiters */
+	fsmc_nor_init(&fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
+			FSMC_FLASH_WIDTH8);
+
 	spi_init();
 }
 
-- 
1.7.2.2

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

* [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (42 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 51/74] ST SPEAr1310: Adding fsmc nor support Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-03  6:00   ` Sundar
  2010-08-30 10:39 ` [PATCH 53/74] ST SPEAr13xx: add l2 cache support Viresh KUMAR
                   ` (30 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Deepak Sikri <deepak.sikri@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/hotplug.c |  146 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-spear13xx/platsmp.c |   12 +++
 3 files changed, 159 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-spear13xx/hotplug.c

diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
index b786edc..b092231 100644
--- a/arch/arm/mach-spear13xx/Makefile
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_MACH_SPEAR1310)		+= spear1310.o
 # spear1310 boards files
 obj-$(CONFIG_BOARD_SPEAR1310_EVB)	+= spear1310_evb.o
 obj-$(CONFIG_PM)	+= pm.o sleep.o
+obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c
new file mode 100644
index 0000000..6405e49
--- /dev/null
+++ b/arch/arm/mach-spear13xx/hotplug.c
@@ -0,0 +1,146 @@
+/*
+ * linux/arch/arm/mach-spear13xx/hotplug.c
+ *
+ * Copyright (C) 2010 ST Microelectronics Ltd.
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * based upon linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static DECLARE_COMPLETION(cpu_killed);
+
+static inline void cpu_enter_lowpower(void)
+{
+	unsigned int v;
+
+	flush_cache_all();
+	asm volatile(
+	"	mcr	p15, 0, %1, c7, c5, 0\n"
+	"	mcr	p15, 0, %1, c7, c10, 4\n"
+	/*
+	 * Turn off coherency
+	 */
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, #0x20\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, #0x04\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	  : "=&r" (v)
+	  : "r" (0)
+	  : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+	unsigned int v;
+
+	asm volatile("mrc	p15, 0, %0, c1, c0, 0\n"
+	"	orr	%0, %0, #0x04\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	orr	%0, %0, #0x20\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	  : "=&r" (v)
+	  :
+	  : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+	/*
+	 * there is no power-control hardware on this platform, so all
+	 * we can do is put the core into WFI; this is safe as the calling
+	 * code will have already disabled interrupts
+	 */
+	for (;;) {
+		/*
+		 * here's the WFI
+		 */
+		asm(".word	0xe320f003\n"
+		    :
+		    :
+		    : "memory", "cc");
+
+		if (pen_release == cpu) {
+			/*
+			 * OK, proper wakeup, we're done
+			 */
+			break;
+		}
+
+		/*
+		 * getting here, means that we have come out of WFI without
+		 * having been woken up - this shouldn't happen
+		 *
+		 * The trouble is, letting people know about this is not really
+		 * possible, since we are currently running incoherently, and
+		 * therefore cannot safely call printk() or anything else
+		 */
+#ifdef DEBUG
+		pr_crit("CPU%u: spurious wakeup call\n", cpu);
+#endif
+	}
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+	return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __cpuinit platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+	unsigned int this_cpu = hard_smp_processor_id();
+
+	if (cpu != this_cpu) {
+		pr_crit("Eek! platform_cpu_die running on %u, should\
+				be %u\n", this_cpu, cpu);
+		BUG();
+	}
+#endif
+
+	printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+	complete(&cpu_killed);
+
+	/*
+	 * we're ready for shutdown now, so do it
+	 */
+	cpu_enter_lowpower();
+	platform_do_lowpower(cpu);
+
+	/*
+	 * bring this CPU back into the world of cache
+	 * coherency, and then restore interrupts
+	 */
+	cpu_leave_lowpower();
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+	/*
+	 * we don't allow CPU 0 to be shutdown (it is still too special
+	 * e.g. clock tick interrupts)
+	 */
+	return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
index 73fbcdb..2864a5c 100644
--- a/arch/arm/mach-spear13xx/platsmp.c
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -101,6 +101,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 	pen_release = cpu;
 	flush_cache_all();
 
+	/*
+	 * XXX
+	 *
+	 * This is a later addition to the booting protocol: the
+	 * bootMonitor now puts secondary cores into WFI, so
+	 * poke_milo() no longer gets the cores moving; we need
+	 * to send a soft interrupt to wake the secondary core.
+	 * Use smp_cross_call() for this, since there's little
+	 * point duplicating the code here
+	 */
+	smp_cross_call(cpumask_of(cpu));
+
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
 		smp_rmb();
-- 
1.7.2.2

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

* [PATCH 53/74] ST SPEAr13xx: add l2 cache support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (43 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 54/74] ST SPEAr: SDHCI- selecting SD_MMC from misc and fixing sdhci_synth rate to 48 MHz Viresh KUMAR
                   ` (29 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/spear1300_evb.c |   13 +++++++++++++
 arch/arm/mach-spear13xx/spear13xx.c     |    7 +++++++
 arch/arm/mm/Kconfig                     |    2 +-
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 5756a8c..95e25b7 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -26,6 +26,8 @@
 #include <plat/nand.h>
 #include <plat/smi.h>
 #include <plat/spi.h>
+#include <mach/hardware.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #define PARTITION(n, off, sz)	{.name = n, .offset = off, .size = sz}
 
@@ -132,6 +134,17 @@ static int spear1300_pcie_port_is_host(int port)
 
 static void __init spear1300_evb_init(void)
 {
+#ifdef CONFIG_CACHE_L2X0
+	/*
+	 * 256KB (16KB/way), 16-way associativity, parity not
+	 * supported
+	 * TODO: 0x249, picked from nomadik, to be analyzed
+	 * Comment from nomadik:
+	 * At full speed latency must be >=2, so 0x249 in low bits
+	 */
+	l2x0_init(__io_address(SPEAR13XX_L2CC_BASE), 0x00260249, 0xfe00ffff);
+#endif
+
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 01cb76c..0f42522 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -538,6 +538,13 @@ struct map_desc spear13xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(SPEAR13XX_A9SM_PERIP_BASE),
 		.length		= SZ_8K,
 		.type		= MT_DEVICE
+#ifdef CONFIG_CACHE_L2X0
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR13XX_L2CC_BASE),
+		.pfn		= __phys_to_pfn(SPEAR13XX_L2CC_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+#endif
 	}, {
 		.virtual	= IO_ADDRESS(SPEAR13XX_MISC_BASE),
 		.pfn		= __phys_to_pfn(SPEAR13XX_MISC_BASE),
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 33c3f57..cb0a30e 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -772,7 +772,7 @@ config CACHE_L2X0
 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
 		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
 		   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_S5PV310 || ARCH_TEGRA || \
-		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+		   ARCH_SPEAR13XX || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
 	default y
 	select OUTER_CACHE
 	select OUTER_CACHE_SYNC
-- 
1.7.2.2

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

* [PATCH 54/74] ST SPEAr: SDHCI- selecting SD_MMC from misc and fixing sdhci_synth rate to 48 MHz
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (44 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 53/74] ST SPEAr13xx: add l2 cache support Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 55/74] ST SPEAr13xx: Modified static mappings Viresh KUMAR
                   ` (28 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/clock.c                  |    9 +++++----
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |    5 +++++
 arch/arm/mach-spear13xx/spear13xx.c              |   12 +++++++++++-
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 7f07911..33ec3ab 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -354,6 +354,7 @@ static struct aux_clk_config uart_synth_config = {
 /* aux rate configuration table, in ascending order of rates */
 struct aux_rate_tbl aux_rtbl[] = {
 	/* For PLL1div2 = 500 MHz */
+	{.xscale = 2, .yscale = 21, .eq = 1}, /* 48 MHz */
 	{.xscale = 1, .yscale = 6, .eq = 1}, /* 83 MHz */
 	{.xscale = 1, .yscale = 4, .eq = 1}, /* 125 MHz */
 	{.xscale = 1, .yscale = 3, .eq = 1}, /* 166 MHz */
@@ -368,7 +369,7 @@ static struct clk uart_synth_clk = {
 	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
 	.set_rate = &aux_clk_set_rate,
-	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
 	.private_data = &uart_synth_config,
 };
 
@@ -414,7 +415,7 @@ static struct clk sdhci_synth_clk = {
 	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
 	.set_rate = &aux_clk_set_rate,
-	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
 	.private_data = &sdhci_synth_config,
 };
 
@@ -440,7 +441,7 @@ static struct clk cfxd_synth_clk = {
 	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
 	.set_rate = &aux_clk_set_rate,
-	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
 	.private_data = &cfxd_synth_config,
 };
 
@@ -466,7 +467,7 @@ static struct clk c3_synth_clk = {
 	.calc_rate = &aux_calc_rate,
 	.recalc = &aux_clk_recalc,
 	.set_rate = &aux_clk_set_rate,
-	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 0},
+	.rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
 	.private_data = &c3_synth_config,
 };
 
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index 2db1ffe..3cfd4fc 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -228,6 +228,11 @@
 
 #define PCIE_MIPHY_CFG		((unsigned int *)(MISC_BASE + 0x328))
 #define PERIP_CFG		((unsigned int *)(MISC_BASE + 0x32c))
+	#define MCIF_SEL_SHIFT	3
+	#define MCIF_SEL_MASK	0x3
+	#define SD_MMC_ACTIVE	0x1
+	#define CF_MMC_ACTIVE	0x2
+	#define XD_MMC_ACTIVE	0x3
 #define FSMC_CFG		((unsigned int *)(MISC_BASE + 0x330))
 	/* FSMC_CFG register masks */
 	#define FSMC_MEMSEL_MASK	0x3
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 0f42522..48cdff2 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -369,6 +369,16 @@ struct platform_device smi_device = {
 	.resource = smi_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
@@ -516,7 +526,7 @@ struct platform_device pcie_gadget2_device = {
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
-	/* nothing to do for now */
+	sdhci_enable();
 }
 
 /* This will initialize vic */
-- 
1.7.2.2

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

* [PATCH 55/74] ST SPEAr13xx: Modified static mappings
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (45 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 54/74] ST SPEAr: SDHCI- selecting SD_MMC from misc and fixing sdhci_synth rate to 48 MHz Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 56/74] SPEAr13xx: Adding and Updating Clock definitions Viresh KUMAR
                   ` (27 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

The new static io mappings map regions in 0xE...,.... space to
0xF...,.... and those in space 0x6...,.... to 0xE...,.... range.
This is done to accomodate regions of RAS configuration registers to be
used by clock frameowrk and possibly others.

Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/include/mach/hardware.h  |    7 ++++++-
 arch/arm/mach-spear13xx/include/mach/spear1310.h |    1 +
 arch/arm/mach-spear13xx/include/mach/vmalloc.h   |    2 +-
 arch/arm/mach-spear13xx/spear13xx.c              |    8 ++++++++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
index 4abc2c0..44cd0c2 100644
--- a/arch/arm/mach-spear13xx/include/mach/hardware.h
+++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
@@ -17,7 +17,12 @@
 #include <mach/spear.h>
 
 /* Vitual to physical translation of statically mapped space */
-#define IO_ADDRESS(x)		(x | 0xF0000000)
+/*
+ * if phy_addr is 0x8...,.... and above then map it to  0xF...,....
+ * else map it to 0xE...,....
+ */
+
+#define IO_ADDRESS(x)   ((x) | ((((x) >> 31) << 28) | 0xE0000000))
 
 /* typesafe io address */
 #define __io_address(n)		__io(IO_ADDRESS(n))
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310.h b/arch/arm/mach-spear13xx/include/mach/spear1310.h
index d1735e8..e3d347c 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear1310.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310.h
@@ -18,6 +18,7 @@
 
 #define SPEAR1310_CAN0_BASE		UL(0x6DA00000)
 #define SPEAR1310_CAN1_BASE		UL(0x6DB00000)
+#define SPEAR1310_RAS_BASE		UL(0x6C800000)
 
 #endif /* __MACH_SPEAR1310_H */
 
diff --git a/arch/arm/mach-spear13xx/include/mach/vmalloc.h b/arch/arm/mach-spear13xx/include/mach/vmalloc.h
index 85ad57e..9f329d1 100644
--- a/arch/arm/mach-spear13xx/include/mach/vmalloc.h
+++ b/arch/arm/mach-spear13xx/include/mach/vmalloc.h
@@ -13,6 +13,6 @@
 #ifndef __MACH_VMALLOC_H
 #define __MACH_VMALLOC_H
 
-#include <plat/vmalloc.h>
+#define VMALLOC_END		0xEC800000
 
 #endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 48cdff2..05ae8f5 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -570,6 +570,14 @@ struct map_desc spear13xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM1_BASE),
 		.length		= SZ_1M,
 		.type		= MT_MEMORY_NONCACHED
+#ifdef CONFIG_MACH_SPEAR1310
+	}, {
+		.virtual	= IO_ADDRESS(SPEAR1310_RAS_BASE),
+		.pfn		= __phys_to_pfn(SPEAR1310_RAS_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+
+#endif
 	},
 };
 
-- 
1.7.2.2

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

* [PATCH 56/74] SPEAr13xx: Adding and Updating Clock definitions
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (46 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 55/74] ST SPEAr13xx: Modified static mappings Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 57/74] SPEAr : Pad multiplexing handling modified Viresh KUMAR
                   ` (26 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear13xx/clock.c                  |  196 +++++++++++++++++++++-
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |   19 ++
 arch/arm/mach-spear13xx/include/mach/spear1310.h |    5 +
 3 files changed, 215 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 33ec3ab..cad2bbb 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -579,7 +579,7 @@ static struct pclk_sel gmac_phy_pclk_sel = {
 };
 
 /* gmac phy clock */
-static struct clk gmac_phy_clk = {
+static struct clk gmac_phy0_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk_sel = &gmac_phy_pclk_sel,
 	.pclk_sel_shift = GMAC_PHY_CLK_SHIFT,
@@ -697,8 +697,8 @@ static struct clk jpeg_clk = {
 	.recalc = &follow_parent,
 };
 
-/* gmac clock */
-static struct clk gmac_clk = {
+/* gmac clock :Fixed Part*/
+static struct clk gmac0_clk = {
 	.pclk = &ahb_clk,
 	.en_reg = PERIP1_CLK_ENB,
 	.en_reg_bit = GMAC_CLK_ENB,
@@ -839,6 +839,92 @@ static struct clk kbd_clk = {
 	.recalc = &follow_parent,
 };
 
+/* RAS CLOCKS */
+/* pll3 generated clock */
+static struct clk ras_pll3_clk = {
+	.pclk = &pll3_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = PLL3_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* pll2 generated clock */
+static struct clk ras_pll2_clk = {
+	.pclk = &pll2_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = PLL2_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* 125MHz clock generated on Tx pad */
+static struct clk ras_tx125_clk = {
+	.pclk = &gmii_txclk125_pad,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = C125_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* 30 MHz clock generated by USB PHy Pll */
+static struct clk ras_30Mhz_clk = {
+	.rate = 30000000,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = C30_CLK_ENB,
+};
+
+/* 48 MHz clock generated by USB PHy Pll */
+static struct clk ras_48Mhz_clk = {
+	.pclk = &pll5_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = C48_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* osc3 generated clock */
+static struct clk ras_osc3_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = OSC3_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* osc2 generated clock */
+static struct clk ras_osc2_clk = {
+	.pclk = &osc2_32k_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = OSC2_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* osc1 generated clock */
+static struct clk ras_osc1_clk = {
+	.pclk = &osc1_24m_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = OSC1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* apb generated clock */
+static struct clk ras_pclk_clk = {
+	.pclk = &apb_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = PCLK_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ahb generated clock */
+static struct clk ras_aclk_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = RAS_CLK_ENB,
+	.en_reg_bit = ACLK_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* External pad 50 MHz clock for phy operation */
+static struct clk ras_tx50_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 50000000,
+};
+
 /* spear1300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR1300
 
@@ -859,6 +945,85 @@ static struct clk can1_clk = {
 	.pclk = &apb_clk,
 	.recalc = &follow_parent,
 };
+
+/* gmac clocks :RAS part*/
+static struct clk gmac_ras1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ras_aclk_clk,
+	.recalc = &follow_parent,
+};
+
+static struct clk gmac_ras2_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ras_aclk_clk,
+	.recalc = &follow_parent,
+};
+
+static struct clk gmac_ras3_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ras_aclk_clk,
+	.recalc = &follow_parent,
+};
+
+static struct clk gmac_ras4_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ras_aclk_clk,
+	.recalc = &follow_parent,
+};
+
+/* phy clock parent select */
+static struct pclk_info phy_pclk_info[] = {
+	{
+		.pclk = &ras_pll2_clk,
+		.pclk_val = 0x8,
+	}, {
+		.pclk = &ras_tx125_clk,
+		.pclk_val = 0x4,
+	}, {
+		.pclk = &ras_tx50_clk,
+		.pclk_val = 0x0,
+	},
+};
+
+static struct pclk_sel phy_pclk_sel = {
+	.pclk_info = phy_pclk_info,
+	.pclk_count = ARRAY_SIZE(phy_pclk_info),
+	.pclk_sel_reg = (unsigned int *)(IO_ADDRESS(RAS_CTRL_REG1)),
+	.pclk_sel_mask = PHY_CLK_MASK,
+};
+
+/* Phy 1 Clock */
+struct clk gmac_phy1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &phy_pclk_sel,
+	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* Phy 2 Clock */
+static struct clk gmac_phy2_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &phy_pclk_sel,
+	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* Phy 3 Clock */
+static struct clk gmac_phy3_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &phy_pclk_sel,
+	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
+/* Phy 4 Clock */
+static struct clk gmac_phy4_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &phy_pclk_sel,
+	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.recalc = &follow_parent,
+};
+
 #endif
 
 /* array of all spear 13xx clock lookups */
@@ -896,7 +1061,20 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.con_id = "cfxd_synth_clk",		.clk = &cfxd_synth_clk},
 	{.con_id = "gmac_phy_input_clk",	.clk = &gmac_phy_input_clk},
 	{.con_id = "gmac_phy_synth_clk",	.clk = &gmac_phy_synth_clk},
-	{.con_id = "gmac_phy_clk",		.clk = &gmac_phy_clk},
+	{.dev_id = "stmmacphy.0",		.clk = &gmac_phy0_clk},
+
+	/* RAS clocks */
+	{.con_id = "ras_pll3_clk",		.clk = &ras_pll3_clk},
+	{.con_id = "ras_pll2_clk",		.clk = &ras_pll2_clk},
+	{.con_id = "ras_tx125_clk",		.clk = &ras_tx125_clk},
+	{.con_id = "ras_30Mhz_clk",		.clk = &ras_30Mhz_clk},
+	{.con_id = "ras_48Mhz_clk",		.clk = &ras_48Mhz_clk},
+	{.con_id = "ras_osc3_clk",		.clk = &ras_osc3_clk},
+	{.con_id = "ras_osc2_clk",		.clk = &ras_osc2_clk},
+	{.con_id = "ras_osc1_clk",		.clk = &ras_osc1_clk},
+	{.con_id = "ras_pclk_clk",		.clk = &ras_pclk_clk},
+	{.con_id = "ras_aclk_clk",		.clk = &ras_aclk_clk},
+	{.con_id = "ras_tx50_clk",		.clk = &ras_tx50_clk},
 
 	/* clocks having multiple parent source from above clocks */
 	{.dev_id = "clcd",		.clk = &clcd_clk},
@@ -915,7 +1093,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "dma0",		.clk = &dma0_clk},
 	{.dev_id = "dma1",		.clk = &dma1_clk},
 	{.dev_id = "jpeg",		.clk = &jpeg_clk},
-	{.dev_id = "gmac",		.clk = &gmac_clk},
+	{.dev_id = "stmmaceth.0",	.clk = &gmac0_clk},
 	{.dev_id = "c3",		.clk = &c3_clk},
 	{.dev_id = "pcie0",		.clk = &pcie0_clk},
 	{.dev_id = "pcie1",		.clk = &pcie1_clk},
@@ -944,6 +1122,14 @@ static struct clk_lookup spear_clk_lookups[] = {
 #ifdef CONFIG_MACH_SPEAR1310
 	{.dev_id = "spear_can.0",	.clk = &can0_clk},
 	{.dev_id = "spear_can.1",	.clk = &can1_clk},
+	{.dev_id = "stmmaceth.1",	.clk = &gmac_ras1_clk},
+	{.dev_id = "stmmaceth.2",	.clk = &gmac_ras2_clk},
+	{.dev_id = "stmmaceth.3",	.clk = &gmac_ras3_clk},
+	{.dev_id = "stmmaceth.4",	.clk = &gmac_ras4_clk},
+	{.dev_id = "stmmacphy.1",	.clk = &gmac_phy1_clk},
+	{.dev_id = "stmmacphy.2",	.clk = &gmac_phy2_clk},
+	{.dev_id = "stmmacphy.3",	.clk = &gmac_phy3_clk},
+	{.dev_id = "stmmacphy.4",	.clk = &gmac_phy4_clk},
 #endif
 };
 
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index 3cfd4fc..ea6096f 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -191,6 +191,25 @@
 	#define JPEG_SOF_RST		28
 #define PERIP2_SW_RST		((unsigned int *)(MISC_BASE + 0x280))
 #define RAS_CLK_ENB		((unsigned int *)(MISC_BASE + 0x284))
+	/* RAS_CLK_ENB register masks */
+	#define ACLK_CLK_ENB		0
+	#define PCLK_CLK_ENB		1
+	#define OSC1_CLK_ENB		2
+	#define OSC2_CLK_ENB		3
+	#define OSC3_CLK_ENB		4
+	#define C48_CLK_ENB		5
+	#define C30_CLK_ENB		6
+	#define C125_CLK_ENB		7
+	#define PLL2_CLK_ENB		8
+	#define PLL3_CLK_ENB		9
+	#define PCLK0_CLK_ENB		10
+	#define PCLK1_CLK_ENB		11
+	#define PCLK2_CLK_ENB		12
+	#define PCLK3_CLK_ENB		13
+	#define SYN0_CLK_ENB		14
+	#define SYN1_CLK_ENB		15
+	#define SYN2_CLK_ENB		16
+	#define SYN3_CLK_ENB		17
 #define RAS_SW_RST		((unsigned int *)(MISC_BASE + 0x288))
 #define PLL1_SYNT		((unsigned int *)(MISC_BASE + 0x28c))
 #define I2S_CLK_CFG		((unsigned int *)(MISC_BASE + 0x290))
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310.h b/arch/arm/mach-spear13xx/include/mach/spear1310.h
index e3d347c..fd97c64 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear1310.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310.h
@@ -20,6 +20,11 @@
 #define SPEAR1310_CAN1_BASE		UL(0x6DB00000)
 #define SPEAR1310_RAS_BASE		UL(0x6C800000)
 
+/* RAS Area Control Register */
+#define RAS_CTRL_REG1		(SPEAR1310_RAS_BASE + 0x4)
+#define PHY_CLK_MASK		0xF
+#define PHY_CLK_SHIFT		0
+
 #endif /* __MACH_SPEAR1310_H */
 
 #endif /* CONFIG_MACH_SPEAR1310 */
-- 
1.7.2.2

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

* [PATCH 57/74] SPEAr : Pad multiplexing handling modified
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (47 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 56/74] SPEAr13xx: Adding and Updating Clock definitions Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 58/74] SPEAr13xx : Fixed part devices in SPEAr13xx addded to the generic implementation Viresh KUMAR
                   ` (25 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Until now, the platform code assumed 1 32 bit register to be used for pad
multiplexing. This assumption is not true for SPEAr13xx devices, so the generic
implementation of pad multiplexing adopts a new concepts of multiple
multiplexing registers.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |    3 +
 arch/arm/mach-spear3xx/spear300.c             |  314 ++++++++++++++----
 arch/arm/mach-spear3xx/spear310.c             |  118 +++++--
 arch/arm/mach-spear3xx/spear320.c             |  387 +++++++++++++++++-----
 arch/arm/mach-spear3xx/spear3xx.c             |  451 ++++++++++++++++++++-----
 arch/arm/plat-spear/include/plat/padmux.h     |   28 ++-
 arch/arm/plat-spear/padmux.c                  |   28 +-
 7 files changed, 1040 insertions(+), 289 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 6c6eced..e5c025b 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -149,6 +149,7 @@ extern struct pmx_dev pmx_telecom_boot_pins;
 extern struct pmx_dev pmx_telecom_sdhci_4bit;
 extern struct pmx_dev pmx_telecom_sdhci_8bit;
 extern struct pmx_dev pmx_gpio1;
+#define PAD_MUX_CONFIG_REG	0x00
 
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
@@ -180,6 +181,7 @@ extern struct pmx_dev pmx_uart3_4_5;
 extern struct pmx_dev pmx_fsmc;
 extern struct pmx_dev pmx_rs485_0_1;
 extern struct pmx_dev pmx_tdm0;
+#define PAD_MUX_CONFIG_REG	0x08
 
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
@@ -229,6 +231,7 @@ extern struct pmx_dev pmx_mii1;
 extern struct pmx_dev pmx_smii0;
 extern struct pmx_dev pmx_smii1;
 extern struct pmx_dev pmx_i2c1;
+#define PAD_MUX_CONFIG_REG	0x0C
 
 /* Add spear320 machine function declarations here */
 void __init spear320_init(void);
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index c99db91..839e8b2 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -21,8 +21,6 @@
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG	0x00
 #define MODE_CONFIG_REG		0x04
 
 /* modes */
@@ -44,87 +42,97 @@
 struct pmx_mode nand_mode = {
 	.id = NAND_MODE,
 	.name = "nand mode",
-	.mask = 0x00,
+	.value = 0x00,
 };
 
 struct pmx_mode nor_mode = {
 	.id = NOR_MODE,
 	.name = "nor mode",
-	.mask = 0x01,
+	.value = 0x01,
 };
 
 struct pmx_mode photo_frame_mode = {
 	.id = PHOTO_FRAME_MODE,
 	.name = "photo frame mode",
-	.mask = 0x02,
+	.value = 0x02,
 };
 
 struct pmx_mode lend_ip_phone_mode = {
 	.id = LEND_IP_PHONE_MODE,
 	.name = "lend ip phone mode",
-	.mask = 0x03,
+	.value = 0x03,
 };
 
 struct pmx_mode hend_ip_phone_mode = {
 	.id = HEND_IP_PHONE_MODE,
 	.name = "hend ip phone mode",
-	.mask = 0x04,
+	.value = 0x04,
 };
 
 struct pmx_mode lend_wifi_phone_mode = {
 	.id = LEND_WIFI_PHONE_MODE,
 	.name = "lend wifi phone mode",
-	.mask = 0x05,
+	.value = 0x05,
 };
 
 struct pmx_mode hend_wifi_phone_mode = {
 	.id = HEND_WIFI_PHONE_MODE,
 	.name = "hend wifi phone mode",
-	.mask = 0x06,
+	.value = 0x06,
 };
 
 struct pmx_mode ata_pabx_wi2s_mode = {
 	.id = ATA_PABX_WI2S_MODE,
 	.name = "ata pabx wi2s mode",
-	.mask = 0x07,
+	.value = 0x07,
 };
 
 struct pmx_mode ata_pabx_i2s_mode = {
 	.id = ATA_PABX_I2S_MODE,
 	.name = "ata pabx i2s mode",
-	.mask = 0x08,
+	.value = 0x08,
 };
 
 struct pmx_mode caml_lcdw_mode = {
 	.id = CAML_LCDW_MODE,
 	.name = "caml lcdw mode",
-	.mask = 0x0C,
+	.value = 0x0C,
 };
 
 struct pmx_mode camu_lcd_mode = {
 	.id = CAMU_LCD_MODE,
 	.name = "camu lcd mode",
-	.mask = 0x0D,
+	.value = 0x0D,
 };
 
 struct pmx_mode camu_wlcd_mode = {
 	.id = CAMU_WLCD_MODE,
 	.name = "camu wlcd mode",
-	.mask = 0x0E,
+	.value = 0x0E,
 };
 
 struct pmx_mode caml_lcd_mode = {
 	.id = CAML_LCD_MODE,
 	.name = "caml lcd mode",
-	.mask = 0x0F,
+	.value = 0x0F,
 };
 
 /* devices */
-struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
+/* Pad multiplexing for FSMC 2 NAND devices */
+static struct pmx_mux_reg pmx_fsmc_2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
 	{
 		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
 			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
-		.mask = PMX_FIRDA_MASK,
+		.mux_regs = pmx_fsmc_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_fsmc_2_mux),
 	},
 };
 
@@ -132,14 +140,23 @@ struct pmx_dev pmx_fsmc_2_chips = {
 	.name = "fsmc_2_chips",
 	.modes = pmx_fsmc_2_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
+/* Pad multiplexing for FSMC 4 NAND devices */
+static struct pmx_mux_reg pmx_fsmc_4_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
 	{
 		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
 			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
-		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+		.mux_regs = pmx_fsmc_4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_fsmc_4_mux),
 	},
 };
 
@@ -147,16 +164,25 @@ struct pmx_dev pmx_fsmc_4_chips = {
 	.name = "fsmc_4_chips",
 	.modes = pmx_fsmc_4_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_keyboard_modes[] = {
+/* Pad multiplexing for Keyboard device */
+static struct pmx_mux_reg pmx_kbd_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_keyboard_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
 			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
 			CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE |
 			CAML_LCD_MODE,
-		.mask = 0x0,
+		.mux_regs = pmx_kbd_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_kbd_mux),
 	},
 };
 
@@ -164,17 +190,35 @@ struct pmx_dev pmx_keyboard = {
 	.name = "keyboard",
 	.modes = pmx_keyboard_modes,
 	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_clcd_modes[] = {
+/* Pad multiplexing for CLCD device */
+static struct pmx_mux_reg pmx_clcd_pfmode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_clcd_lcdmode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_clcd_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE,
-		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
+		.mux_regs = pmx_clcd_pfmode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd_pfmode_mux),
 	}, {
 		.ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
 			CAMU_LCD_MODE | CAML_LCD_MODE,
-		.mask = PMX_TIMER_3_4_MASK,
+		.mux_regs = pmx_clcd_lcdmode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd_lcdmode_mux),
 	},
 };
 
@@ -182,26 +226,71 @@ struct pmx_dev pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+/* Pad multiplexing for Telecom GPIO device */
+static struct pmx_mux_reg pmx_gpio_lcdmode_mux[] = {
 	{
-		.ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_gpio_fonemode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_gpio_atai2smode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_gpio_lendfonemode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_gpio_atawi2smode_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
+			| PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
+		.mux_regs = pmx_gpio_lcdmode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_lcdmode_mux),
 	}, {
 		.ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE,
-		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.mux_regs = pmx_gpio_fonemode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_fonemode_mux),
 	}, {
 		.ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE,
-		.mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
+		.mux_regs = pmx_gpio_atai2smode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_atai2smode_mux),
 	}, {
 		.ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE,
-		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
+		.mux_regs = pmx_gpio_lendfonemode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_lendfonemode_mux),
 	}, {
 		.ids = ATA_PABX_WI2S_MODE,
-		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
-			| PMX_UART0_MODEM_MASK,
+		.mux_regs = pmx_gpio_atawi2smode_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_atawi2smode_mux),
 	},
 };
 
@@ -209,17 +298,26 @@ struct pmx_dev pmx_telecom_gpio = {
 	.name = "telecom_gpio",
 	.modes = pmx_telecom_gpio_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
+/* Pad multiplexing for TDM device */
+static struct pmx_mux_reg pmx_tdm_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
 			| HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
 			| ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
 			| CAMU_WLCD_MODE | CAML_LCD_MODE,
-		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+		.mux_regs = pmx_tdm_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_tdm_mux),
 	},
 };
 
@@ -227,16 +325,25 @@ struct pmx_dev pmx_telecom_tdm = {
 	.name = "telecom_tdm",
 	.modes = pmx_telecom_tdm_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
+/* Pad multiplexing for spi cs i2c device */
+static struct pmx_mux_reg pmx_spi_cs_i2c_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
 			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
 			| ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE |
 			CAML_LCDW_MODE | CAML_LCD_MODE,
-		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.mux_regs = pmx_spi_cs_i2c_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_spi_cs_i2c_mux),
 	},
 };
 
@@ -244,16 +351,33 @@ struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
 	.name = "telecom_spi_cs_i2c_clk",
 	.modes = pmx_telecom_spi_cs_i2c_clk_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+static struct pmx_mux_reg pmx_caml_mux[] = {
 	{
-		.ids = CAML_LCDW_MODE | CAML_LCD_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_camu_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+	{
+		.ids = CAML_LCDW_MODE | CAML_LCD_MODE,
+		.mux_regs = pmx_caml_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_caml_mux),
 	}, {
 		.ids = CAMU_LCD_MODE | CAMU_WLCD_MODE,
-		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
+		.mux_regs = pmx_camu_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_camu_mux),
 	},
 };
 
@@ -261,14 +385,23 @@ struct pmx_dev pmx_telecom_camera = {
 	.name = "telecom_camera",
 	.modes = pmx_telecom_camera_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_dac_modes[] = {
+/* Pad multiplexing for dac device */
+static struct pmx_mux_reg pmx_dac_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_1_2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_dac_modes[] = {
 	{
 		.ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
 			| CAMU_WLCD_MODE | CAML_LCD_MODE,
-		.mask = PMX_TIMER_1_2_MASK,
+		.mux_regs = pmx_dac_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_dac_mux),
 	},
 };
 
@@ -276,16 +409,25 @@ struct pmx_dev pmx_telecom_dac = {
 	.name = "telecom_dac",
 	.modes = pmx_telecom_dac_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
+/* Pad multiplexing for spi cs i2c device */
+static struct pmx_mux_reg pmx_i2s_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
 			| LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
 			ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
 			| CAMU_WLCD_MODE | CAML_LCD_MODE,
-		.mask = PMX_UART0_MODEM_MASK,
+		.mux_regs = pmx_i2s_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2s_mux),
 	},
 };
 
@@ -293,14 +435,23 @@ struct pmx_dev pmx_telecom_i2s = {
 	.name = "telecom_i2s",
 	.modes = pmx_telecom_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+/* Pad multiplexing for bootpins device */
+static struct pmx_mux_reg pmx_bootpins_mux[] = {
 	{
-		.ids = NAND_MODE | NOR_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+	{
+		.ids = NAND_MODE | NOR_MODE,
+		.mux_regs = pmx_bootpins_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_bootpins_mux),
 	},
 };
 
@@ -308,19 +459,28 @@ struct pmx_dev pmx_telecom_boot_pins = {
 	.name = "telecom_boot_pins",
 	.modes = pmx_telecom_boot_pins_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
+/* Pad multiplexing for sdhci 4bit device */
+static struct pmx_mux_reg pmx_sdhci_4bit_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
 			HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
 			CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE |
 			ATA_PABX_I2S_MODE,
-		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
-			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
-			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+		.mux_regs = pmx_sdhci_4bit_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_sdhci_4bit_mux),
 	},
 };
 
@@ -328,18 +488,27 @@ struct pmx_dev pmx_telecom_sdhci_4bit = {
 	.name = "telecom_sdhci_4bit",
 	.modes = pmx_telecom_sdhci_4bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
+/* Pad multiplexing for spi cs i2c device */
+static struct pmx_mux_reg pmx_sdhci_8bit_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
 			HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
 			CAMU_WLCD_MODE | CAML_LCD_MODE,
-		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
-			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
-			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+		.mux_regs = pmx_sdhci_8bit_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_sdhci_8bit_mux),
 	},
 };
 
@@ -347,14 +516,23 @@ struct pmx_dev pmx_telecom_sdhci_8bit = {
 	.name = "telecom_sdhci_8bit",
 	.modes = pmx_telecom_sdhci_8bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_gpio1_modes[] = {
+/* Pad multiplexing for spi cs i2c device */
+static struct pmx_mux_reg pmx_gpio1_mux[] = {
 	{
-		.ids = PHOTO_FRAME_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio1_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE,
+		.mux_regs = pmx_gpio1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio1_mux),
 	},
 };
 
@@ -362,13 +540,11 @@ struct pmx_dev pmx_gpio1 = {
 	.name = "arm gpio1",
 	.modes = pmx_gpio1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio1_modes),
-	.enb_on_reset = 1,
 };
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
 	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
 };
 
 /* Add spear300 specific devices here */
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 32c492d..2f7493b 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -21,14 +21,21 @@
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG	0x08
 
 /* devices */
-struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+/* Pad multiplexing for emi_cs_0_1_4_5 devices */
+static struct pmx_mux_reg pmx_emi_cs_0_1_4_5_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+	{
+		.mux_regs = pmx_emi_cs_0_1_4_5_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_mux),
 	},
 };
 
@@ -36,13 +43,21 @@ struct pmx_dev pmx_emi_cs_0_1_4_5 = {
 	.name = "emi_cs_0_1_4_5",
 	.modes = pmx_emi_cs_0_1_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+/* Pad multiplexing for emi_cs_2_3 devices */
+static struct pmx_mux_reg pmx_emi_cs_2_3_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+	{
+		.mux_regs = pmx_emi_cs_2_3_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_emi_cs_2_3_mux),
 	},
 };
 
@@ -50,13 +65,21 @@ struct pmx_dev pmx_emi_cs_2_3 = {
 	.name = "emi_cs_2_3",
 	.modes = pmx_emi_cs_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modes[] = {
+/* Pad multiplexing for uart1 device */
+static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart1_modes[] = {
+	{
+		.mux_regs = pmx_uart1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_mux),
 	},
 };
 
@@ -64,13 +87,21 @@ struct pmx_dev pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart2_modes[] = {
+/* Pad multiplexing for uart2 device */
+static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart2_modes[] = {
+	{
+		.mux_regs = pmx_uart2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart2_mux),
 	},
 };
 
@@ -78,13 +109,21 @@ struct pmx_dev pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+/* Pad multiplexing for uart3_4_5 devices */
+static struct pmx_mux_reg pmx_uart3_4_5_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+	{
+		.mux_regs = pmx_uart3_4_5_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart3_4_5_mux),
 	},
 };
 
@@ -92,13 +131,21 @@ struct pmx_dev pmx_uart3_4_5 = {
 	.name = "uart3_4_5",
 	.modes = pmx_uart3_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_modes[] = {
+/* Pad multiplexing for fsmc device */
+static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
+	{
+		.mux_regs = pmx_fsmc_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_fsmc_mux),
 	},
 };
 
@@ -106,13 +153,21 @@ struct pmx_dev pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+/* Pad multiplexing for rs485_0_1 devices */
+static struct pmx_mux_reg pmx_rs485_0_1_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+	{
+		.mux_regs = pmx_rs485_0_1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_rs485_0_1_mux),
 	},
 };
 
@@ -120,13 +175,21 @@ struct pmx_dev pmx_rs485_0_1 = {
 	.name = "rs485_0_1",
 	.modes = pmx_rs485_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_tdm0_modes[] = {
+/* Pad multiplexing for tdm0 device */
+static struct pmx_mux_reg pmx_tdm0_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_tdm0_modes[] = {
+	{
+		.mux_regs = pmx_tdm0_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_tdm0_mux),
 	},
 };
 
@@ -134,13 +197,10 @@ struct pmx_dev pmx_tdm0 = {
 	.name = "tdm0",
 	.modes = pmx_tdm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_tdm0_modes),
-	.enb_on_reset = 1,
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
+struct pmx_driver pmx_driver;
 
 /* Add spear310 specific devices here */
 /* uart1 device registeration */
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index b13e0fc..50625df 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -24,8 +24,6 @@
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG	0x0C
 #define MODE_CONFIG_REG		0x10
 
 /* modes */
@@ -38,32 +36,42 @@
 struct pmx_mode auto_net_smii_mode = {
 	.id = AUTO_NET_SMII_MODE,
 	.name = "Automation Networking SMII Mode",
-	.mask = 0x00,
+	.value = 0x00,
 };
 
 struct pmx_mode auto_net_mii_mode = {
 	.id = AUTO_NET_MII_MODE,
 	.name = "Automation Networking MII Mode",
-	.mask = 0x01,
+	.value = 0x01,
 };
 
 struct pmx_mode auto_exp_mode = {
 	.id = AUTO_EXP_MODE,
 	.name = "Automation Expanded Mode",
-	.mask = 0x02,
+	.value = 0x02,
 };
 
 struct pmx_mode small_printers_mode = {
 	.id = SMALL_PRINTERS_MODE,
 	.name = "Small Printers Mode",
-	.mask = 0x03,
+	.value = 0x03,
 };
 
 /* devices */
-struct pmx_dev_mode pmx_clcd_modes[] = {
+/* Pad multiplexing for CLCD device */
+static struct pmx_mux_reg pmx_clcd_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_clcd_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mux_regs = pmx_clcd_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd_mux),
 	},
 };
 
@@ -71,13 +79,22 @@ struct pmx_dev pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_emi_modes[] = {
+/* Pad multiplexing for EMI (Parallel NOR flash) device */
+static struct pmx_mux_reg pmx_emi_mux[] = {
 	{
-		.ids = AUTO_EXP_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_emi_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mux_regs = pmx_emi_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_emi_mux),
 	},
 };
 
@@ -85,13 +102,22 @@ struct pmx_dev pmx_emi = {
 	.name = "emi",
 	.modes = pmx_emi_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_modes[] = {
+/* Pad multiplexing for FSMC (NAND flash) device */
+static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.ids = ALL_MODES,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mux_regs = pmx_fsmc_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_fsmc_mux),
 	},
 };
 
@@ -99,13 +125,22 @@ struct pmx_dev pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_spp_modes[] = {
+/* Pad multiplexing for SPP device */
+static struct pmx_mux_reg pmx_spp_mux[] = {
 	{
-		.ids = SMALL_PRINTERS_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_spp_modes[] = {
+	{
+		.ids = SMALL_PRINTERS_MODE,
+		.mux_regs = pmx_spp_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_spp_mux),
 	},
 };
 
@@ -113,14 +148,23 @@ struct pmx_dev pmx_spp = {
 	.name = "spp",
 	.modes = pmx_spp_modes,
 	.mode_count = ARRAY_SIZE(pmx_spp_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdhci_modes[] = {
+/* Pad multiplexing for SDHCI device */
+static struct pmx_mux_reg pmx_sdhci_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_sdhci_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
 			SMALL_PRINTERS_MODE,
-		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+		.mux_regs = pmx_sdhci_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_sdhci_mux),
 	},
 };
 
@@ -128,13 +172,22 @@ struct pmx_dev pmx_sdhci = {
 	.name = "sdhci",
 	.modes = pmx_sdhci_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_i2s_modes[] = {
+/* Pad multiplexing for I2S device */
+static struct pmx_mux_reg pmx_i2s_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2s_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mux_regs = pmx_i2s_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2s_mux),
 	},
 };
 
@@ -142,13 +195,22 @@ struct pmx_dev pmx_i2s = {
 	.name = "i2s",
 	.modes = pmx_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2s_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modes[] = {
+/* Pad multiplexing for UART1 device */
+static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.ids = ALL_MODES,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart1_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mux_regs = pmx_uart1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_mux),
 	},
 };
 
@@ -156,18 +218,36 @@ struct pmx_dev pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+/* Pad multiplexing for UART1 Modem device */
+static struct pmx_mux_reg pmx_uart1_modem_autoexp_mux[] = {
 	{
-		.ids = AUTO_EXP_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
 			PMX_SSP_CS_MASK,
-	}, {
-		.ids = SMALL_PRINTERS_MODE,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_uart1_modem_smallpri_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
 			PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mux_regs = pmx_uart1_modem_autoexp_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_modem_autoexp_mux),
+	}, {
+		.ids = SMALL_PRINTERS_MODE,
+		.mux_regs = pmx_uart1_modem_smallpri_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_modem_smallpri_mux),
 	},
 };
 
@@ -175,13 +255,22 @@ struct pmx_dev pmx_uart1_modem = {
 	.name = "uart1_modem",
 	.modes = pmx_uart1_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart2_modes[] = {
+/* Pad multiplexing for UART2 device */
+static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.ids = ALL_MODES,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart2_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mux_regs = pmx_uart2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart2_mux),
 	},
 };
 
@@ -189,13 +278,22 @@ struct pmx_dev pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_touchscreen_modes[] = {
+/* Pad multiplexing for Touchscreen device */
+static struct pmx_mux_reg pmx_touchscreen_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_touchscreen_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mux_regs = pmx_touchscreen_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_touchscreen_mux),
 	},
 };
 
@@ -203,14 +301,23 @@ struct pmx_dev pmx_touchscreen = {
 	.name = "touchscreen",
 	.modes = pmx_touchscreen_modes,
 	.mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_can_modes[] = {
+/* Pad multiplexing for CAN device */
+static struct pmx_mux_reg pmx_can_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_can_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
+		.mux_regs = pmx_can_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_can_mux),
 	},
 };
 
@@ -218,13 +325,22 @@ struct pmx_dev pmx_can = {
 	.name = "can",
 	.modes = pmx_can_modes,
 	.mode_count = ARRAY_SIZE(pmx_can_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdhci_led_modes[] = {
+/* Pad multiplexing for SDHCI LED device */
+static struct pmx_mux_reg pmx_sdhci_led_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mux_regs = pmx_sdhci_led_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_sdhci_led_mux),
 	},
 };
 
@@ -232,16 +348,34 @@ struct pmx_dev pmx_sdhci_led = {
 	.name = "sdhci_led",
 	.modes = pmx_sdhci_led_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm0_modes[] = {
+/* Pad multiplexing for PWM0 device */
+static struct pmx_mux_reg pmx_pwm0_net_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_pwm0_autoexpsmallpri_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_pwm0_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mux_regs = pmx_pwm0_net_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm0_net_mux),
 	}, {
 		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-		.mask = PMX_MII_MASK,
+		.mux_regs = pmx_pwm0_autoexpsmallpri_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm0_autoexpsmallpri_mux),
 	},
 };
 
@@ -249,16 +383,34 @@ struct pmx_dev pmx_pwm0 = {
 	.name = "pwm0",
 	.modes = pmx_pwm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm0_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm1_modes[] = {
+/* Pad multiplexing for PWM1 device */
+static struct pmx_mux_reg pmx_pwm1_net_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_pwm1_autoexpsmallpri_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_pwm1_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mux_regs = pmx_pwm1_net_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm1_net_mux),
 	}, {
 		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-		.mask = PMX_MII_MASK,
+		.mux_regs = pmx_pwm1_autoexpsmallpri_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm1_autoexpsmallpri_mux),
 	},
 };
 
@@ -266,16 +418,34 @@ struct pmx_dev pmx_pwm1 = {
 	.name = "pwm1",
 	.modes = pmx_pwm1_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm2_modes[] = {
+/* Pad multiplexing for PWM2 device */
+static struct pmx_mux_reg pmx_pwm2_net_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_mux_reg pmx_pwm2_autoexpsmallpri_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_pwm2_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mux_regs = pmx_pwm2_net_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm2_net_mux),
 	}, {
 		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-		.mask = PMX_MII_MASK,
+		.mux_regs = pmx_pwm2_autoexpsmallpri_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm2_autoexpsmallpri_mux),
 	},
 };
 
@@ -283,13 +453,22 @@ struct pmx_dev pmx_pwm2 = {
 	.name = "pwm2",
 	.modes = pmx_pwm2_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm2_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm3_modes[] = {
+/* Pad multiplexing for PWM3 device */
+static struct pmx_mux_reg pmx_pwm3_mux[] = {
 	{
-		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_pwm3_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.mux_regs = pmx_pwm3_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pwm3_mux),
 	},
 };
 
@@ -297,13 +476,22 @@ struct pmx_dev pmx_pwm3 = {
 	.name = "pwm3",
 	.modes = pmx_pwm3_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm3_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_ssp1_modes[] = {
+/* Pad multiplexing for SSP1 device */
+static struct pmx_mux_reg pmx_ssp1_mux[] = {
 	{
-		.ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_ssp1_modes[] = {
+	{
+		.ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.mux_regs = pmx_ssp1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_ssp1_mux),
 	},
 };
 
@@ -311,13 +499,22 @@ struct pmx_dev pmx_ssp1 = {
 	.name = "ssp1",
 	.modes = pmx_ssp1_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_ssp2_modes[] = {
+/* Pad multiplexing for SSP2 device */
+static struct pmx_mux_reg pmx_ssp2_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_ssp2_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mux_regs = pmx_ssp2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_ssp2_mux),
 	},
 };
 
@@ -325,13 +522,22 @@ struct pmx_dev pmx_ssp2 = {
 	.name = "ssp2",
 	.modes = pmx_ssp2_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp2_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_mii1_modes[] = {
+/* Pad multiplexing for mii1 device */
+static struct pmx_mux_reg pmx_mii1_mux[] = {
 	{
-		.ids = AUTO_NET_MII_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_mii1_modes[] = {
+	{
+		.ids = AUTO_NET_MII_MODE,
+		.mux_regs = pmx_mii1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_mii1_mux),
 	},
 };
 
@@ -339,13 +545,22 @@ struct pmx_dev pmx_mii1 = {
 	.name = "mii1",
 	.modes = pmx_mii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_smii0_modes[] = {
+/* Pad multiplexing for smii0 device */
+static struct pmx_mux_reg pmx_smii0_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_smii0_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.mux_regs = pmx_smii0_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_smii0_mux),
 	},
 };
 
@@ -353,13 +568,22 @@ struct pmx_dev pmx_smii0 = {
 	.name = "smii0",
 	.modes = pmx_smii0_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii0_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_smii1_modes[] = {
+/* Pad multiplexing for smii1 device */
+static struct pmx_mux_reg pmx_smii1_mux[] = {
 	{
-		.ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_smii1_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
+		.mux_regs = pmx_smii1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_smii1_mux),
 	},
 };
 
@@ -367,13 +591,22 @@ struct pmx_dev pmx_smii1 = {
 	.name = "smii1",
 	.modes = pmx_smii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_i2c1_modes[] = {
+/* Pad multiplexing for i2c1 device */
+static struct pmx_mux_reg pmx_i2c1_mux[] = {
 	{
-		.ids = AUTO_EXP_MODE,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2c1_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mux_regs = pmx_i2c1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2c1_mux),
 	},
 };
 
@@ -381,13 +614,11 @@ struct pmx_dev pmx_i2c1 = {
 	.name = "i2c1",
 	.modes = pmx_i2c1_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
-	.enb_on_reset = 1,
 };
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
 	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
 };
 
 /* Add spear320 specific devices here */
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 1f374b4..1a5fe3a 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -293,10 +293,21 @@ void __init spear3xx_map_io(void)
 
 /* pad multiplexing support */
 /* devices */
-struct pmx_dev_mode pmx_firda_modes[] = {
+
+/* Pad multiplexing for firda device */
+static struct pmx_mux_reg pmx_firda_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
+		.value = PMX_FIRDA_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_firda_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_firda_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_firda_mux),
 	},
 };
 
@@ -304,13 +315,22 @@ struct pmx_dev pmx_firda = {
 	.name = "firda",
 	.modes = pmx_firda_modes,
 	.mode_count = ARRAY_SIZE(pmx_firda_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_i2c_modes[] = {
+/* Pad multiplexing for i2c device */
+static struct pmx_mux_reg pmx_i2c_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
+		.value = PMX_I2C_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2c_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_i2c_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2c_mux),
 	},
 };
 
@@ -318,13 +338,22 @@ struct pmx_dev pmx_i2c = {
 	.name = "i2c",
 	.modes = pmx_i2c_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+/* Pad multiplexing for firda device */
+static struct pmx_mux_reg pmx_ssp_cs_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = PMX_SSP_CS_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_ssp_cs_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_ssp_cs_mux),
 	},
 };
 
@@ -332,13 +361,22 @@ struct pmx_dev pmx_ssp_cs = {
 	.name = "ssp_chip_selects",
 	.modes = pmx_ssp_cs_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_ssp_modes[] = {
+/* Pad multiplexing for ssp device */
+static struct pmx_mux_reg pmx_ssp_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
+		.value = PMX_SSP_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_ssp_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_ssp_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_ssp_mux),
 	},
 };
 
@@ -346,13 +384,22 @@ struct pmx_dev pmx_ssp = {
 	.name = "ssp",
 	.modes = pmx_ssp_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_mii_modes[] = {
+/* Pad multiplexing for mii device */
+static struct pmx_mux_reg pmx_mii_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = PMX_MII_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_mii_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_mii_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_mii_mux),
 	},
 };
 
@@ -360,13 +407,22 @@ struct pmx_dev pmx_mii = {
 	.name = "mii",
 	.modes = pmx_mii_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+/* Pad multiplexing for gpio pin0 device */
+static struct pmx_mux_reg pmx_gpio_pin0_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
+		.value = PMX_GPIO_PIN0_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin0_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin0_mux),
 	},
 };
 
@@ -374,13 +430,22 @@ struct pmx_dev pmx_gpio_pin0 = {
 	.name = "gpio_pin0",
 	.modes = pmx_gpio_pin0_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+/* Pad multiplexing for gpio pin1 device */
+static struct pmx_mux_reg pmx_gpio_pin1_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
+		.value = PMX_GPIO_PIN1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin1_mux),
 	},
 };
 
@@ -388,13 +453,22 @@ struct pmx_dev pmx_gpio_pin1 = {
 	.name = "gpio_pin1",
 	.modes = pmx_gpio_pin1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+/* Pad multiplexing for gpio pin2 device */
+static struct pmx_mux_reg pmx_gpio_pin2_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
+		.value = PMX_GPIO_PIN2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin2_mux),
 	},
 };
 
@@ -402,13 +476,22 @@ struct pmx_dev pmx_gpio_pin2 = {
 	.name = "gpio_pin2",
 	.modes = pmx_gpio_pin2_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+/* Pad multiplexing for gpio pin3 device */
+static struct pmx_mux_reg pmx_gpio_pin3_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
+		.value = PMX_GPIO_PIN3_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin3_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin3_mux),
 	},
 };
 
@@ -416,13 +499,22 @@ struct pmx_dev pmx_gpio_pin3 = {
 	.name = "gpio_pin3",
 	.modes = pmx_gpio_pin3_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+/* Pad multiplexing for gpio pin4 device */
+static struct pmx_mux_reg pmx_gpio_pin4_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
+		.value = PMX_GPIO_PIN4_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin4_mux),
 	},
 };
 
@@ -430,13 +522,22 @@ struct pmx_dev pmx_gpio_pin4 = {
 	.name = "gpio_pin4",
 	.modes = pmx_gpio_pin4_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+/* Pad multiplexing for gpio pin5 device */
+static struct pmx_mux_reg pmx_gpio_pin5_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
+		.value = PMX_GPIO_PIN5_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_gpio_pin5_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpio_pin5_mux),
 	},
 };
 
@@ -444,13 +545,22 @@ struct pmx_dev pmx_gpio_pin5 = {
 	.name = "gpio_pin5",
 	.modes = pmx_gpio_pin5_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+/* Pad multiplexing for uart0 modem device */
+static struct pmx_mux_reg pmx_uart0_modem_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = PMX_UART0_MODEM_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_uart0_modem_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart0_modem_mux),
 	},
 };
 
@@ -458,13 +568,22 @@ struct pmx_dev pmx_uart0_modem = {
 	.name = "uart0_modem",
 	.modes = pmx_uart0_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_uart0_modes[] = {
+/* Pad multiplexing for uart0 device */
+static struct pmx_mux_reg pmx_uart0_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
+		.value = PMX_UART0_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart0_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_uart0_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart0_mux),
 	},
 };
 
@@ -472,13 +591,22 @@ struct pmx_dev pmx_uart0 = {
 	.name = "uart0",
 	.modes = pmx_uart0_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+/* Pad multiplexing for timer 3, 4 device */
+static struct pmx_mux_reg pmx_timer_3_4_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
+		.value = PMX_TIMER_3_4_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_timer_3_4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_timer_3_4_mux),
 	},
 };
 
@@ -486,13 +614,22 @@ struct pmx_dev pmx_timer_3_4 = {
 	.name = "timer_3_4",
 	.modes = pmx_timer_3_4_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
-	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+/* Pad multiplexing for gpio pin0 device */
+static struct pmx_mux_reg pmx_timer_1_2_mux[] = {
 	{
-		.ids = 0xffffffff,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
+		.value = PMX_TIMER_1_2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_timer_1_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_timer_1_2_mux),
 	},
 };
 
@@ -500,15 +637,24 @@ struct pmx_dev pmx_timer_1_2 = {
 	.name = "timer_1_2",
 	.modes = pmx_timer_1_2_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
-	.enb_on_reset = 0,
 };
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 /* plgpios devices */
-struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+/* Pad multiplexing for plgpio_0_1 devices */
+static struct pmx_mux_reg pmx_plgpio_0_1_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_0_1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_0_1_mux),
 	},
 };
 
@@ -516,13 +662,22 @@ struct pmx_dev pmx_plgpio_0_1 = {
 	.name = "plgpio 0 and 1",
 	.modes = pmx_plgpio_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+/* Pad multiplexing for plgpio_2_3 devices */
+static struct pmx_mux_reg pmx_plgpio_2_3_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_2_3_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_2_3_mux),
 	},
 };
 
@@ -530,13 +685,22 @@ struct pmx_dev pmx_plgpio_2_3 = {
 	.name = "plgpio 2 and 3",
 	.modes = pmx_plgpio_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+/* Pad multiplexing for plgpio_4_5 devices */
+static struct pmx_mux_reg pmx_plgpio_4_5_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_4_5_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_4_5_mux),
 	},
 };
 
@@ -544,13 +708,22 @@ struct pmx_dev pmx_plgpio_4_5 = {
 	.name = "plgpio 4 and 5",
 	.modes = pmx_plgpio_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+/* Pad multiplexing for plgpio_6_9 devices */
+static struct pmx_mux_reg pmx_plgpio_6_9_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_6_9_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_6_9_mux),
 	},
 };
 
@@ -558,13 +731,22 @@ struct pmx_dev pmx_plgpio_6_9 = {
 	.name = "plgpio 6 to 9",
 	.modes = pmx_plgpio_6_9_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+/* Pad multiplexing for plgpio_10_27 devices */
+static struct pmx_mux_reg pmx_plgpio_10_27_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_10_27_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_10_27_mux),
 	},
 };
 
@@ -572,13 +754,22 @@ struct pmx_dev pmx_plgpio_10_27 = {
 	.name = "plgpio 10 to 27",
 	.modes = pmx_plgpio_10_27_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+/* Pad multiplexing for plgpio_28 devices */
+static struct pmx_mux_reg pmx_plgpio_28_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_28_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_28_mux),
 	},
 };
 
@@ -586,13 +777,22 @@ struct pmx_dev pmx_plgpio_28 = {
 	.name = "plgpio 28",
 	.modes = pmx_plgpio_28_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+/* Pad multiplexing for plgpio_29 devices */
+static struct pmx_mux_reg pmx_plgpio_29_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_29_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_29_mux),
 	},
 };
 
@@ -600,13 +800,22 @@ struct pmx_dev pmx_plgpio_29 = {
 	.name = "plgpio 29",
 	.modes = pmx_plgpio_29_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+/* Pad multiplexing for plgpio_30 device */
+static struct pmx_mux_reg pmx_plgpio_30_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_30_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_30_mux),
 	},
 };
 
@@ -614,13 +823,22 @@ struct pmx_dev pmx_plgpio_30 = {
 	.name = "plgpio 30",
 	.modes = pmx_plgpio_30_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+/* Pad multiplexing for plgpio_31 device */
+static struct pmx_mux_reg pmx_plgpio_31_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_31_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_31_mux),
 	},
 };
 
@@ -628,13 +846,22 @@ struct pmx_dev pmx_plgpio_31 = {
 	.name = "plgpio 31",
 	.modes = pmx_plgpio_31_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+/* Pad multiplexing for plgpio_32 device */
+static struct pmx_mux_reg pmx_plgpio_32_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_32_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_32_mux),
 	},
 };
 
@@ -642,13 +869,22 @@ struct pmx_dev pmx_plgpio_32 = {
 	.name = "plgpio 32",
 	.modes = pmx_plgpio_32_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+/* Pad multiplexing for plgpio_33 device */
+static struct pmx_mux_reg pmx_plgpio_33_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_33_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_33_mux),
 	},
 };
 
@@ -656,13 +892,22 @@ struct pmx_dev pmx_plgpio_33 = {
 	.name = "plgpio 33",
 	.modes = pmx_plgpio_33_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+/* Pad multiplexing for plgpio_34_36 device */
+static struct pmx_mux_reg pmx_plgpio_34_36_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_34_36_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_34_36_mux),
 	},
 };
 
@@ -670,13 +915,22 @@ struct pmx_dev pmx_plgpio_34_36 = {
 	.name = "plgpio 34 to 36",
 	.modes = pmx_plgpio_34_36_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+/* Pad multiplexing for plgpio_37_42 device */
+static struct pmx_mux_reg pmx_plgpio_37_42_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_37_42_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_37_42_mux),
 	},
 };
 
@@ -684,13 +938,22 @@ struct pmx_dev pmx_plgpio_37_42 = {
 	.name = "plgpio 37 to 42",
 	.modes = pmx_plgpio_37_42_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+/* Pad multiplexing for plgpio_43_44_47_48 device */
+static struct pmx_mux_reg pmx_plgpio_43_44_47_48_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_43_44_47_48_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_43_44_47_48_mux),
 	},
 };
 
@@ -698,13 +961,22 @@ struct pmx_dev pmx_plgpio_43_44_47_48 = {
 	.name = "plgpio 43, 44, 47 and 48",
 	.modes = pmx_plgpio_43_44_47_48_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
-	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+/* Pad multiplexing for plgpio_45_46_49_50 device */
+static struct pmx_mux_reg pmx_plgpio_45_46_49_50_mux[] = {
 	{
-		.ids = 0x00,
+		.offset = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mux_regs = pmx_plgpio_45_46_49_50_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_plgpio_45_46_49_50_mux),
 	},
 };
 
@@ -712,7 +984,6 @@ struct pmx_dev pmx_plgpio_45_46_49_50 = {
 	.name = "plgpio 45, 46, 49 and 50",
 	.modes = pmx_plgpio_45_46_49_50_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
-	.enb_on_reset = 1,
 };
 #endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
 
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
index 877f3ad..1b69ca5 100644
--- a/arch/arm/plat-spear/include/plat/padmux.h
+++ b/arch/arm/plat-spear/include/plat/padmux.h
@@ -28,26 +28,42 @@ struct pmx_reg {
 };
 
 /*
+ * struct pmx_mux_reg: configuration structure every group of modes of a device
+ *
+ * offset: multiplexing register offset
+ * mask: mask for supported mode
+ * value: value to be written
+ */
+struct pmx_mux_reg {
+	u32 offset;
+	u32 mask;
+	u32 value;
+};
+
+/*
  * struct pmx_dev_mode: configuration structure every group of modes of a device
  *
  * ids: all modes for this configuration
- * mask: mask for supported mode
+ * mux_regs: array of mux registers, masks and values to enable the device in
+ *		this group of modes
+ * mux_reg_cnt: count of mux_regs elements
  */
 struct pmx_dev_mode {
 	u32 ids;
-	u32 mask;
+	struct pmx_mux_reg *mux_regs;
+	u8 mux_reg_cnt;
 };
 
 /*
  * struct pmx_mode: mode definition structure
  *
  * name: mode name
- * mask: mode mask
+ * value: mode value
  */
 struct pmx_mode {
 	char *name;
 	u32 id;
-	u32 mask;
+	u32 value;
 };
 
 /*
@@ -57,14 +73,12 @@ struct pmx_mode {
  * modes: device configuration array for different modes supported
  * mode_count: size of modes array
  * is_active: is peripheral active/enabled
- * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg
  */
 struct pmx_dev {
 	char *name;
 	struct pmx_dev_mode *modes;
 	u8 mode_count;
 	bool is_active;
-	bool enb_on_reset;
 };
 
 /*
@@ -75,7 +89,6 @@ struct pmx_dev {
  * devs_count: ARRAY_SIZE of devs
  * base: base address of soc config registers
  * mode_reg: structure of mode config register
- * mux_reg: structure of device mux config register
  */
 struct pmx_driver {
 	struct pmx_mode *mode;
@@ -83,7 +96,6 @@ struct pmx_driver {
 	u8 devs_count;
 	u32 *base;
 	struct pmx_reg mode_reg;
-	struct pmx_reg mux_reg;
 };
 
 /* pmx functions */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
index 555eec6..f30f94b 100644
--- a/arch/arm/plat-spear/padmux.c
+++ b/arch/arm/plat-spear/padmux.c
@@ -21,13 +21,11 @@
  *
  * base: base address of configuration registers
  * mode_reg: mode configurations
- * mux_reg: muxing configurations
  * active_mode: pointer to current active mode
  */
 struct pmx {
 	u32 base;
 	struct pmx_reg mode_reg;
-	struct pmx_reg mux_reg;
 	struct pmx_mode *active_mode;
 };
 
@@ -51,7 +49,7 @@ static int pmx_mode_set(struct pmx_mode *mode)
 
 	val = readl(pmx->base + pmx->mode_reg.offset);
 	val &= ~pmx->mode_reg.mask;
-	val |= mode->mask & pmx->mode_reg.mask;
+	val |= mode->value & pmx->mode_reg.mask;
 	writel(val, pmx->base + pmx->mode_reg.offset);
 
 	return 0;
@@ -66,19 +64,18 @@ static int pmx_mode_set(struct pmx_mode *mode)
  * If peripheral is not supported by current mode then request is rejected.
  * Conflicts between peripherals are not handled and peripherals will be
  * enabled in the order they are present in pmx_dev array.
- * In case of conflicts last peripheral enabled will be present.
+ * In case of conflicts last peripheral enabled will remain present.
  * Returns -ve on Err otherwise 0
  */
 static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
 {
-	u32 val, i, mask;
+	u32 val, i;
 
 	if (!count)
 		return -EINVAL;
 
-	val = readl(pmx->base + pmx->mux_reg.offset);
 	for (i = 0; i < count; i++) {
-		u8 j = 0;
+		u8 k, j = 0;
 
 		if (!devs[i]->name || !devs[i]->modes) {
 			printk(KERN_ERR "padmux: dev name or modes is null\n");
@@ -103,15 +100,18 @@ static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
 		}
 
 		/* enable peripheral */
-		mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
-		if (devs[i]->enb_on_reset)
-			val &= ~mask;
-		else
-			val |= mask;
+		for (k = 0; k < devs[i]->modes[j].mux_reg_cnt; k++) {
+			struct pmx_mux_reg *mux_reg =
+				&devs[i]->modes[j].mux_regs[k];
+
+			val = readl(pmx->base + mux_reg->offset);
+			val &= ~mux_reg->mask;
+			val |= mux_reg->value & mux_reg->mask;
+			writel(val, pmx->base + mux_reg->offset);
+		}
 
 		devs[i]->is_active = true;
 	}
-	writel(val, pmx->base + pmx->mux_reg.offset);
 	kfree(pmx);
 
 	/* this will ensure that multiplexing can't be changed now */
@@ -144,8 +144,6 @@ int pmx_register(struct pmx_driver *driver)
 	pmx->base = (u32)driver->base;
 	pmx->mode_reg.offset = driver->mode_reg.offset;
 	pmx->mode_reg.mask = driver->mode_reg.mask;
-	pmx->mux_reg.offset = driver->mux_reg.offset;
-	pmx->mux_reg.mask = driver->mux_reg.mask;
 
 	/* choose mode to enable */
 	if (driver->mode) {
-- 
1.7.2.2

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

* [PATCH 58/74] SPEAr13xx : Fixed part devices in SPEAr13xx addded to the generic implementation
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (48 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 57/74] SPEAr : Pad multiplexing handling modified Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 59/74] SPEAr : Adding SPEAr1310 pad multiplexing devices Viresh KUMAR
                   ` (24 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Vipin Kumar <vipin.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 |  164 ++++++++
 arch/arm/mach-spear13xx/include/mach/spear.h   |    3 +
 arch/arm/mach-spear13xx/spear1300.c            |   15 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   25 ++
 arch/arm/mach-spear13xx/spear1310.c            |   15 +
 arch/arm/mach-spear13xx/spear1310_evb.c        |   25 ++
 arch/arm/mach-spear13xx/spear13xx.c            |  528 ++++++++++++++++++++++++
 arch/arm/plat-spear/Makefile                   |    1 +
 8 files changed, 776 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 3f54563..a7abb3b 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -20,6 +20,168 @@
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 #include <plat/device.h>
+#include <plat/padmux.h>
+
+/*
+ * Function enable (Pad multiplexing register) offsets
+ */
+#define PAD_MUX_CONFIG_REG_0	0x0
+#define PAD_MUX_CONFIG_REG_1	0x4
+#define PAD_MUX_CONFIG_REG_2	0x8
+#define PAD_MUX_CONFIG_REG_3	0xC
+
+/* pad mux declarations */
+#define PMX_I2S1_MASK		(1 << 3)
+#define PMX_I2S2_MASK		(1 << 16)	/* Offset 4 */
+#define PMX_CLCD1_MASK		(1 << 5)
+#define PMX_CLCD2_MASK		(1 << 3)	/* Offset 4 */
+#define PMX_EGPIO00_MASK	(1 << 6)
+#define PMX_EGPIO01_MASK	(1 << 7)
+#define PMX_EGPIO02_MASK	(1 << 8)
+#define PMX_EGPIO03_MASK	(1 << 9)
+#define PMX_EGPIO04_MASK	(1 << 10)
+#define PMX_EGPIO05_MASK	(1 << 11)
+#define PMX_EGPIO06_MASK	(1 << 12)
+#define PMX_EGPIO07_MASK	(1 << 13)
+#define PMX_EGPIO08_MASK	(1 << 14)
+#define PMX_EGPIO09_MASK	(1 << 15)
+#define PMX_EGPIO10_MASK	(1 << 5)	/* Offset 4 */
+#define PMX_EGPIO11_MASK	(1 << 6)	/* Offset 4 */
+#define PMX_EGPIO12_MASK	(1 << 7)	/* Offset 4 */
+#define PMX_EGPIO13_MASK	(1 << 8)	/* Offset 4 */
+#define PMX_EGPIO14_MASK	(1 << 9)	/* Offset 4 */
+#define PMX_EGPIO15_MASK	(1 << 10)	/* Offset 4 */
+#define PMX_EGPIO_0_GRP_MASK	(PMX_EGPIO00_MASK | PMX_EGPIO01_MASK | \
+		PMX_EGPIO02_MASK | PMX_EGPIO03_MASK | PMX_EGPIO04_MASK | \
+		PMX_EGPIO05_MASK | PMX_EGPIO06_MASK | PMX_EGPIO07_MASK | \
+		PMX_EGPIO08_MASK | PMX_EGPIO09_MASK)
+#define PMX_EGPIO_1_GRP_MASK	(PMX_EGPIO10_MASK | PMX_EGPIO11_MASK | \
+		PMX_EGPIO12_MASK | PMX_EGPIO13_MASK | PMX_EGPIO14_MASK | \
+		PMX_EGPIO15_MASK)
+
+#define PMX_SMI_MASK		(1 << 16)
+#define PMX_SMINCS2_MASK	(1 << 1)	/* Offset 4 */
+#define PMX_SMINCS3_MASK	(1 << 2)	/* Offset 4 */
+
+#define PMX_GMIICLK_MASK			(1 << 18)
+#define PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK	(1 << 19)
+#define PMX_RXCLK_RDV_TXEN_D03_MASK		(1 << 20)
+#define PMX_GMIID47_MASK			(1 << 21)
+#define PMX_MDC_MDIO_MASK			(1 << 22)
+
+#define PMX_GMII_MASK		(PMX_GMIICLK_MASK | \
+		PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \
+		PMX_RXCLK_RDV_TXEN_D03_MASK | PMX_GMIID47_MASK | \
+		PMX_MDC_MDIO_MASK)
+
+#define PMX_NAND8_MASK		(1 << 17)
+#define PMX_NFAD023_MASK	(1 << 24)
+#define PMX_NFAD24_MASK		(1 << 25)
+#define PMX_NFAD25_MASK		(1 << 26)
+#define PMX_NFWPRT1_MASK	(1 << 24)	/* Offset 4 */
+#define PMX_NFWPRT2_MASK	(1 << 26)	/* Offset 4 */
+#define PMX_NFWPRT3_MASK	(1 << 28)
+#define PMX_NFRSTPWDWN0_MASK	(1 << 29)
+#define PMX_NFRSTPWDWN1_MASK	(1 << 30)
+#define PMX_NFRSTPWDWN2_MASK	(1 << 31)
+#define PMX_NFRSTPWDWN3_MASK	(1 << 0)	/* Offset 4 */
+#define PMX_NFCE1_MASK		(1 << 20)	/* Offset 4 */
+#define PMX_NFCE2_MASK		(1 << 22)	/* Offset 4 */
+#define PMX_NFCE3_MASK		(1 << 27)
+#define PMX_NFIO815_MASK	(1 << 18)	/* Offset 4 */
+
+#define PMX_NAND8BIT_0_MASK	(PMX_NAND8_MASK | PMX_NFAD023_MASK | \
+		PMX_NFAD24_MASK | PMX_NFAD25_MASK | PMX_NFWPRT3_MASK | \
+		PMX_NFRSTPWDWN0_MASK | PMX_NFRSTPWDWN1_MASK | \
+		PMX_NFRSTPWDWN2_MASK | PMX_NFCE3_MASK)
+#define PMX_NAND8BIT_1_MASK	(PMX_NFRSTPWDWN3_MASK)
+
+#define PMX_NAND8BIT4DEV_0_MASK	(PMX_NAND8BIT_0_MASK)
+#define PMX_NAND8BIT4DEV_1_MASK	(PMX_NAND8BIT_1_MASK | PMX_NFCE1_MASK | \
+		PMX_NFCE2_MASK | PMX_NFWPRT1_MASK | PMX_NFWPRT2_MASK)
+
+#define PMX_NAND16BIT_0_MASK	(PMX_NAND8BIT_0_MASK)
+#define PMX_NAND16BIT_1_MASK	(PMX_NAND8BIT_1_MASK | PMX_NFIO815_MASK)
+#define PMX_NAND16BIT4DEV_0_MASK	(PMX_NAND8BIT4DEV_0_MASK)
+#define PMX_NAND16BIT4DEV_1_MASK	(PMX_NAND8BIT4DEV_1_MASK | \
+					PMX_NFIO815_MASK)
+
+#define PMX_KBD_ROW0_MASK	(1 << 25)	/* Offset 4 */
+#define PMX_KBD_ROW1_MASK	(1 << 23)	/* Offset 4 */
+#define PMX_KBD_ROWCOL25_MASK	(1 << 17)	/* Offset 4 */
+#define PMX_KBD_ROWCOL68_MASK	(1 << 4)	/* Offset 4 */
+#define PMX_KBD_COL0_MASK	(1 << 21)	/* Offset 4 */
+#define PMX_KBD_COL1_MASK	(1 << 19)	/* Offset 4 */
+#define PMX_KEYBOARD_MASK	(PMX_KBD_ROW0_MASK | PMX_KBD_ROW1_MASK | \
+		PMX_KBD_ROWCOL25_MASK | PMX_KBD_ROWCOL68_MASK | \
+		PMX_KBD_COL0_MASK | PMX_KBD_COL1_MASK)
+
+#define PMX_UART0_MASK		(1 << 1)
+#define PMX_I2C_MASK		(1 << 2)
+#define PMX_SSP_MASK		(1 << 4)
+#define PMX_UART0_MODEM_MASK	(1 << 11)	/* Offset 4 */
+#define PMX_GPT0_TMR1_MASK	(1 << 12)	/* Offset 4 */
+#define PMX_GPT0_TMR2_MASK	(1 << 13)	/* Offset 4 */
+#define PMX_GPT1_TMR1_MASK	(1 << 14)	/* Offset 4 */
+#define PMX_GPT1_TMR2_MASK	(1 << 15)	/* Offset 4 */
+
+#define PMX_MCIDATA0_MASK	(1 << 27)	/* Offset 4 */
+#define PMX_MCIDATA1_MASK	(1 << 28)	/* Offset 4 */
+#define PMX_MCIDATA2_MASK	(1 << 29)	/* Offset 4 */
+#define PMX_MCIDATA3_MASK	(1 << 30)	/* Offset 4 */
+#define PMX_MCIDATA4_MASK	(1 << 31)	/* Offset 4 */
+#define PMX_MCIDATA5_MASK	(1 << 0)	/* Offset 8 */
+#define PMX_MCIDATA6_MASK	(1 << 1)	/* Offset 8 */
+#define PMX_MCIDATA7_MASK	(1 << 2)	/* Offset 8 */
+#define PMX_MCIDATA1SD_MASK	(1 << 3)	/* Offset 8 */
+#define PMX_MCIDATA2SD_MASK	(1 << 4)	/* Offset 8 */
+#define PMX_MCIDATA3SD_MASK	(1 << 5)	/* Offset 8 */
+#define PMX_MCIADDR0ALE_MASK	(1 << 6)	/* Offset 8 */
+#define PMX_MCIADDR1CLECLK_MASK	(1 << 7)	/* Offset 8 */
+#define PMX_MCIADDR2_MASK	(1 << 8)	/* Offset 8 */
+#define PMX_MCICECF_MASK	(1 << 9)	/* Offset 8 */
+#define PMX_MCICEXD_MASK	(1 << 10)	/* Offset 8 */
+#define PMX_MCICESDMMC_MASK	(1 << 11)	/* Offset 8 */
+#define PMX_MCICDCF1_MASK	(1 << 12)	/* Offset 8 */
+#define PMX_MCICDCF2_MASK	(1 << 13)	/* Offset 8 */
+#define PMX_MCICDXD_MASK	(1 << 14)	/* Offset 8 */
+#define PMX_MCICDSDMMC_MASK	(1 << 15)	/* Offset 8 */
+#define PMX_MCIDATADIR_MASK	(1 << 16)	/* Offset 8 */
+#define PMX_MCIDMARQWP_MASK	(1 << 17)	/* Offset 8 */
+#define PMX_MCIIORDRE_MASK	(1 << 18)	/* Offset 8 */
+#define PMX_MCIIOWRWE_MASK	(1 << 19)	/* Offset 8 */
+#define PMX_MCIRESETCF_MASK	(1 << 20)	/* Offset 8 */
+#define PMX_MCICS0CE_MASK	(1 << 21)	/* Offset 8 */
+#define PMX_MCICFINTR_MASK	(1 << 22)	/* Offset 8 */
+#define PMX_MCIIORDY_MASK	(1 << 23)	/* Offset 8 */
+#define PMX_MCICS1_MASK		(1 << 24)	/* Offset 8 */
+#define PMX_MCIDMAACK_MASK	(1 << 25)	/* Offset 8 */
+#define PMX_MCISDCMD_MASK	(1 << 26)	/* Offset 8 */
+#define PMX_MCILEDS_MASK	(1 << 27)	/* Offset 8 */
+
+#define PMX_MCIFALL_1_MASK	(0xF8000000)
+#define PMX_MCIFALL_2_MASK	(0x0FFFFFFF)
+
+/* pad mux devices */
+extern struct pmx_dev pmx_i2c;
+extern struct pmx_dev pmx_ssp;
+extern struct pmx_dev pmx_i2s2;
+extern struct pmx_dev pmx_clcd1;
+extern struct pmx_dev pmx_clcd2;
+extern struct pmx_dev pmx_egpio_grp;
+extern struct pmx_dev pmx_smi_2_chips;
+extern struct pmx_dev pmx_smi_4_chips;
+extern struct pmx_dev pmx_gmii;
+extern struct pmx_dev pmx_nand_8bit;
+extern struct pmx_dev pmx_nand_16bit;
+extern struct pmx_dev pmx_keyboard;
+extern struct pmx_dev pmx_uart0;
+extern struct pmx_dev pmx_uart0_modem;
+extern struct pmx_dev pmx_gpt_0_1;
+extern struct pmx_dev pmx_gpt_0_2;
+extern struct pmx_dev pmx_gpt_1_1;
+extern struct pmx_dev pmx_gpt_1_2;
+extern struct pmx_dev pmx_mcif;
 
 /*
  * Each GPT has 2 timer channels
@@ -29,6 +191,8 @@
 #define SPEAR_GPT0_CHAN0_IRQ	IRQ_GPT0_TMR0
 #define SPEAR_GPT0_CHAN1_IRQ	IRQ_GPT0_TMR1
 
+extern struct pmx_driver pmx_driver;
+
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device gpio_device[];
 extern struct amba_device ssp_device;
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index d043280..03f9616 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -88,6 +88,9 @@
 #define SPEAR13XX_MCIF_CF_BASE		UL(0xB2800000)
 #define SPEAR13XX_MCIF_SDHCI_BASE	UL(0xB3000000)
 
+/* Pad multiplexing base */
+#define SPEAR13XX_FUNC_ENB_BASE		UL(0xE0700650)
+
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR13XX_UART_BASE
 #define VA_SPEAR_DBG_UART_BASE		VA_SPEAR13XX_UART_BASE
diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
index c1b82f1..4569cb5 100644
--- a/arch/arm/mach-spear13xx/spear1300.c
+++ b/arch/arm/mach-spear13xx/spear1300.c
@@ -14,10 +14,25 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 
+/* pmx driver structure */
+struct pmx_driver pmx_driver;
+
 /* Add spear1300 specific devices here */
 
 void __init spear1300_init(void)
 {
+	int ret;
+
 	/* call spear13xx family common init function */
 	spear13xx_init();
+
+	/* pmx initialization */
+	pmx_driver.base = ioremap(SPEAR13XX_FUNC_ENB_BASE, SZ_4K);
+	if (pmx_driver.base) {
+		ret = pmx_register(&pmx_driver);
+		if (ret)
+			pr_err("padmux: registeration failed. err no: %d\n",
+					ret);
+		iounmap(pmx_driver.base);
+	}
 }
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 95e25b7..0d24fa3 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -38,6 +38,26 @@ static struct mtd_partition partition_info[] = {
 	PARTITION("Root File System", 0x380000, 84 * 0x20000),
 };
 
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+	/* spear13xx specific devices */
+	&pmx_i2c,
+	&pmx_i2s1,
+	&pmx_i2s2,
+	&pmx_clcd1,
+	&pmx_clcd2,
+	&pmx_egpio_grp,
+	&pmx_gmii,
+	&pmx_keyboard,
+	&pmx_mcif,
+	&pmx_nand_8bit,
+	&pmx_smi_4_chips,
+	&pmx_ssp,
+	&pmx_uart0,
+
+	/* spear1300 specific devices */
+};
+
 static struct amba_device *amba_devs[] __initdata = {
 	&gpio_device[0],
 	&gpio_device[1],
@@ -134,6 +154,11 @@ static int spear1300_pcie_port_is_host(int port)
 
 static void __init spear1300_evb_init(void)
 {
+	/* padmux initialization, must be done before spear1300_init */
+	pmx_driver.mode = NULL;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+
 #ifdef CONFIG_CACHE_L2X0
 	/*
 	 * 256KB (16KB/way), 16-way associativity, parity not
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 906ede9..86ad9f8 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -16,6 +16,9 @@
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+/* pmx driver structure */
+struct pmx_driver pmx_driver;
+
 /* Add spear1310 specific devices here */
 
 /* CAN device registeration */
@@ -57,6 +60,18 @@ struct platform_device can1_device = {
 
 void __init spear1310_init(void)
 {
+	int ret;
+
 	/* call spear13xx family common init function */
 	spear13xx_init();
+
+	/* pmx initialization */
+	pmx_driver.base = ioremap(SPEAR13XX_FUNC_ENB_BASE, SZ_4K);
+	if (pmx_driver.base) {
+		ret = pmx_register(&pmx_driver);
+		if (ret)
+			pr_err("padmux: registeration failed. err no: %d\n",
+					ret);
+		iounmap(pmx_driver.base);
+	}
 }
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index fb4b7c0..b0e3cc4 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -36,6 +36,26 @@ static struct mtd_partition partition_info[] = {
 	PARTITION("Root File System", 0x380000, 84 * 0x20000),
 };
 
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+	/* spear13xx specific devices */
+	&pmx_i2c,
+	&pmx_i2s1,
+	&pmx_i2s2,
+	&pmx_clcd1,
+	&pmx_clcd2,
+	&pmx_egpio_grp,
+	&pmx_gmii,
+	&pmx_keyboard,
+	&pmx_mcif,
+	&pmx_nand_8bit,
+	&pmx_smi_4_chips,
+	&pmx_ssp,
+	&pmx_uart0,
+
+	/* spear1310 specific devices */
+};
+
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
 	&gpio_device[0],
@@ -137,6 +157,11 @@ int spear1310_pcie_port_is_host(int port)
 
 static void __init spear1310_evb_init(void)
 {
+	/* padmux initialization, must be done before spear1300_init */
+	pmx_driver.mode = NULL;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 05ae8f5..9167bc8 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -602,3 +602,531 @@ static void __init spear13xx_timer_init(void)
 struct sys_timer spear13xx_timer = {
 	.init = spear13xx_timer_init,
 };
+
+/* pad multiplexing support */
+/* devices */
+
+/* Pad multiplexing for i2c device */
+static struct pmx_mux_reg pmx_i2c_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_I2C_MASK,
+		.value = PMX_I2C_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2c_modes[] = {
+	{
+		.mux_regs = pmx_i2c_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2c_mux),
+	},
+};
+
+struct pmx_dev pmx_i2c = {
+	.name = "i2c",
+	.modes = pmx_i2c_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
+};
+
+/* Pad multiplexing for ssp device */
+static struct pmx_mux_reg pmx_ssp_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_SSP_MASK,
+		.value = PMX_SSP_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_ssp_modes[] = {
+	{
+		.mux_regs = pmx_ssp_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_ssp_mux),
+	},
+};
+
+struct pmx_dev pmx_ssp = {
+	.name = "ssp",
+	.modes = pmx_ssp_modes,
+	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
+};
+
+/* Pad multiplexing for i2s1 device */
+static struct pmx_mux_reg pmx_i2s1_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_I2S1_MASK,
+		.value = PMX_I2S1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2s1_modes[] = {
+	{
+		.mux_regs = pmx_i2s1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2s1_mux),
+	},
+};
+
+struct pmx_dev pmx_i2s1 = {
+	.name = "i2s1",
+	.modes = pmx_i2s1_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2s1_modes),
+};
+
+/* Pad multiplexing for i2s2 device */
+static struct pmx_mux_reg pmx_i2s2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_I2S2_MASK,
+		.value = PMX_I2S2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2s2_modes[] = {
+	{
+		.mux_regs = pmx_i2s2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2s2_mux),
+	},
+};
+
+struct pmx_dev pmx_i2s2 = {
+	.name = "i2s2",
+	.modes = pmx_i2s2_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2s2_modes),
+};
+
+/* Pad multiplexing for clcd1 device */
+static struct pmx_mux_reg pmx_clcd1_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_CLCD1_MASK,
+		.value = PMX_CLCD1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_clcd1_modes[] = {
+	{
+		.mux_regs = pmx_clcd1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd1_mux),
+	},
+};
+
+struct pmx_dev pmx_clcd1 = {
+	.name = "clcd1",
+	.modes = pmx_clcd1_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd1_modes),
+};
+
+/* Pad multiplexing for clcd2 device */
+static struct pmx_mux_reg pmx_clcd2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_CLCD2_MASK,
+		.value = PMX_CLCD2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_clcd2_modes[] = {
+	{
+		.mux_regs = pmx_clcd2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd2_mux),
+	},
+};
+
+struct pmx_dev pmx_clcd2 = {
+	.name = "clcd2",
+	.modes = pmx_clcd2_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd2_modes),
+};
+
+/*
+ * By default, all EGPIOs are enabled.
+ * TBD : Board specific enabling of specific GPIOs only
+ */
+static struct pmx_mux_reg pmx_egpio_grp_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_EGPIO_0_GRP_MASK,
+		.value = PMX_EGPIO_0_GRP_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_EGPIO_1_GRP_MASK,
+		.value = PMX_EGPIO_1_GRP_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_egpio_grp_modes[] = {
+	{
+		.mux_regs = pmx_egpio_grp_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_egpio_grp_mux),
+	},
+};
+
+struct pmx_dev pmx_egpio_grp = {
+	.name = "egpios",
+	.modes = pmx_egpio_grp_modes,
+	.mode_count = ARRAY_SIZE(pmx_egpio_grp_modes),
+};
+
+/* Pad multiplexing for smi 2 chips device */
+static struct pmx_mux_reg pmx_smi_2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_SMI_MASK,
+		.value = PMX_SMI_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_smi_2_modes[] = {
+	{
+		.mux_regs = pmx_smi_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_smi_2_mux),
+	},
+};
+
+struct pmx_dev pmx_smi_2_chips = {
+	.name = "smi_2_chips",
+	.modes = pmx_smi_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_smi_2_modes),
+};
+
+/* Pad multiplexing for smi 4 chips device */
+static struct pmx_mux_reg pmx_smi_4_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_SMI_MASK,
+		.value = PMX_SMI_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+		.value = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_smi_4_modes[] = {
+	{
+		.mux_regs = pmx_smi_4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_smi_4_mux),
+	},
+};
+
+struct pmx_dev pmx_smi_4_chips = {
+	.name = "smi_4_chips",
+	.modes = pmx_smi_4_modes,
+	.mode_count = ARRAY_SIZE(pmx_smi_4_modes),
+};
+
+/* Pad multiplexing for gmii device */
+static struct pmx_mux_reg pmx_gmii_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_GMII_MASK,
+		.value = PMX_GMII_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gmii_modes[] = {
+	{
+		.mux_regs = pmx_gmii_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gmii_mux),
+	},
+};
+
+struct pmx_dev pmx_gmii = {
+	.name = "gmii",
+	.modes = pmx_gmii_modes,
+	.mode_count = ARRAY_SIZE(pmx_gmii_modes),
+};
+
+/* Pad multiplexing for nand 8bit (4 chips) */
+static struct pmx_mux_reg pmx_nand8_4_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_NAND8BIT4DEV_0_MASK,
+		.value = PMX_NAND8BIT4DEV_0_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND8BIT4DEV_1_MASK,
+		.value = PMX_NAND8BIT4DEV_1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_nand8_4_modes[] = {
+	{
+		.mux_regs = pmx_nand8_4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_nand8_4_mux),
+	},
+};
+
+struct pmx_dev pmx_nand_8bit_4_chips = {
+	.name = "nand-8bit_4_chips",
+	.modes = pmx_nand8_4_modes,
+	.mode_count = ARRAY_SIZE(pmx_nand8_4_modes),
+};
+
+/* Pad multiplexing for nand 8bit device */
+static struct pmx_mux_reg pmx_nand8_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_NAND8BIT_0_MASK,
+		.value = PMX_NAND8BIT_0_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND8BIT_1_MASK,
+		.value = PMX_NAND8BIT_1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_nand8_modes[] = {
+	{
+		.mux_regs = pmx_nand8_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_nand8_mux),
+	},
+};
+
+struct pmx_dev pmx_nand_8bit = {
+	.name = "nand-8bit",
+	.modes = pmx_nand8_modes,
+	.mode_count = ARRAY_SIZE(pmx_nand8_modes),
+};
+
+/*
+ * Pad multiplexing for nand 16bit device
+ * Note : Enabling pmx_nand_16bit means that all the required pads for
+ *   16bit nand device operations are enabled. These also include pads
+ *   for 8bit devices
+ */
+static struct pmx_mux_reg pmx_nand16_4_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_NAND16BIT4DEV_0_MASK,
+		.value = PMX_NAND16BIT4DEV_0_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND16BIT4DEV_1_MASK,
+		.value = PMX_NAND16BIT4DEV_1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_nand16_4_modes[] = {
+	{
+		.mux_regs = pmx_nand16_4_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_nand16_4_mux),
+	},
+};
+
+struct pmx_dev pmx_nand_16bit_4_chips = {
+	.name = "nand-16bit_4_chips",
+	.modes = pmx_nand16_4_modes,
+	.mode_count = ARRAY_SIZE(pmx_nand16_4_modes),
+};
+
+/* Pad multiplexing for nand 16bit device */
+static struct pmx_mux_reg pmx_nand16_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_NAND16BIT_0_MASK,
+		.value = PMX_NAND16BIT_0_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND16BIT_1_MASK,
+		.value = PMX_NAND16BIT_1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_nand16_modes[] = {
+	{
+		.mux_regs = pmx_nand16_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_nand16_mux),
+	},
+};
+
+struct pmx_dev pmx_nand_16bit = {
+	.name = "nand-16bit",
+	.modes = pmx_nand16_modes,
+	.mode_count = ARRAY_SIZE(pmx_nand16_modes),
+};
+
+/* Pad multiplexing for keyboard device */
+static struct pmx_mux_reg pmx_keyboard_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_KEYBOARD_MASK,
+		.value = PMX_KEYBOARD_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NFIO815_MASK | PMX_NFCE1_MASK | \
+			PMX_NFCE2_MASK | PMX_NFWPRT1_MASK | PMX_NFWPRT2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_keyboard_modes[] = {
+	{
+		.mux_regs = pmx_keyboard_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_keyboard_mux),
+	},
+};
+
+struct pmx_dev pmx_keyboard = {
+	.name = "keyboard",
+	.modes = pmx_keyboard_modes,
+	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
+};
+
+/* Pad multiplexing for uart0 device */
+static struct pmx_mux_reg pmx_uart0_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_UART0_MASK,
+		.value = PMX_UART0_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart0_modes[] = {
+	{
+		.mux_regs = pmx_uart0_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart0_mux),
+	},
+};
+
+struct pmx_dev pmx_uart0 = {
+	.name = "uart0",
+	.modes = pmx_uart0_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
+};
+
+/* Pad multiplexing for uart0_modem device */
+static struct pmx_mux_reg pmx_uart0_modem_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_UART0_MODEM_MASK,
+		.value = PMX_UART0_MODEM_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+	{
+		.mux_regs = pmx_uart0_modem_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart0_modem_mux),
+	},
+};
+
+struct pmx_dev pmx_uart0_modem = {
+	.name = "uart0_modem",
+	.modes = pmx_uart0_modem_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
+};
+
+/* Pad multiplexing for gpt_0_1 device */
+static struct pmx_mux_reg pmx_gpt_0_1_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_GPT0_TMR1_MASK,
+		.value = PMX_GPT0_TMR1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpt_0_1_modes[] = {
+	{
+		.mux_regs = pmx_gpt_0_1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpt_0_1_mux),
+	},
+};
+
+struct pmx_dev pmx_gpt_0_1 = {
+	.name = "gpt_0_1",
+	.modes = pmx_gpt_0_1_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpt_0_1_modes),
+};
+
+/* Pad multiplexing for gpt_0_2 device */
+static struct pmx_mux_reg pmx_gpt_0_2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_GPT0_TMR2_MASK,
+		.value = PMX_GPT0_TMR2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpt_0_2_modes[] = {
+	{
+		.mux_regs = pmx_gpt_0_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpt_0_2_mux),
+	},
+};
+
+struct pmx_dev pmx_gpt_0_2 = {
+	.name = "gpt_0_2",
+	.modes = pmx_gpt_0_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpt_0_2_modes),
+};
+
+/* Pad multiplexing for gpt_1_1 device */
+static struct pmx_mux_reg pmx_gpt_1_1_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_GPT1_TMR1_MASK,
+		.value = PMX_GPT1_TMR1_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpt_1_1_modes[] = {
+	{
+		.mux_regs = pmx_gpt_1_1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpt_1_1_mux),
+	},
+};
+
+struct pmx_dev pmx_gpt_1_1 = {
+	.name = "gpt_1_1",
+	.modes = pmx_gpt_1_1_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpt_1_1_modes),
+};
+
+/* Pad multiplexing for gpt_1_2 device */
+static struct pmx_mux_reg pmx_gpt_1_2_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_GPT1_TMR2_MASK,
+		.value = PMX_GPT1_TMR2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_gpt_1_2_modes[] = {
+	{
+		.mux_regs = pmx_gpt_1_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gpt_1_2_mux),
+	},
+};
+
+struct pmx_dev pmx_gpt_1_2 = {
+	.name = "gpt_1_2",
+	.modes = pmx_gpt_1_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpt_1_2_modes),
+};
+
+/* Pad multiplexing for mcif device */
+static struct pmx_mux_reg pmx_mcif_mux[] = {
+	{
+		.offset = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_MCIFALL_1_MASK,
+		.value = PMX_MCIFALL_1_MASK,
+	}, {
+		.offset = PAD_MUX_CONFIG_REG_2,
+		.mask = PMX_MCIFALL_2_MASK,
+		.value = PMX_MCIFALL_2_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_mcif_modes[] = {
+	{
+		.mux_regs = pmx_mcif_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_mcif_mux),
+	},
+};
+
+struct pmx_dev pmx_mcif = {
+	.name = "mcif",
+	.modes = pmx_mcif_modes,
+	.mode_count = ARRAY_SIZE(pmx_mcif_modes),
+};
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index c25e5b8..79503dd 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -5,6 +5,7 @@
 # Common support
 obj-y	:= clcd.o clock.o pll_clk.o smi.o time.o
 
+obj-$(CONFIG_ARCH_SPEAR13XX)	+= padmux.o
 obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq.o
 obj-$(CONFIG_MACH_SPEAR310)	+= plgpio.o
-- 
1.7.2.2

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

* [PATCH 59/74] SPEAr : Adding SPEAr1310 pad multiplexing devices
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (49 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 58/74] SPEAr13xx : Fixed part devices in SPEAr13xx addded to the generic implementation Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 60/74] ST SPEAr3xx: Passing pmx devices address from machine *.c files Viresh KUMAR
                   ` (23 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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

This patch makes the following changes
-> Addition of SPEAr1310 pad multiplexing devices.
-> A few bugfixes eg. clcd1 and clcd2 removed and clcd/clcd_hires added
-> Support for modifying multiple regiters in different address ranges

Signed-off-by: Vipin Kumar <vipin.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 |   46 +++-
 arch/arm/mach-spear13xx/include/mach/spear.h   |    3 -
 arch/arm/mach-spear13xx/spear1300.c            |   11 +-
 arch/arm/mach-spear13xx/spear1300_evb.c        |    5 +-
 arch/arm/mach-spear13xx/spear1310.c            |  316 +++++++++++++++++++++++-
 arch/arm/mach-spear13xx/spear1310_evb.c        |   17 +-
 arch/arm/mach-spear13xx/spear13xx.c            |  169 ++++++++-----
 arch/arm/mach-spear3xx/include/mach/generic.h  |   12 +-
 arch/arm/mach-spear3xx/include/mach/spear300.h |    1 -
 arch/arm/mach-spear3xx/spear300.c              |   66 +++---
 arch/arm/mach-spear3xx/spear310.c              |   20 +-
 arch/arm/mach-spear3xx/spear320.c              |   61 ++---
 arch/arm/mach-spear3xx/spear3xx.c              |   60 +++---
 arch/arm/plat-spear/include/plat/padmux.h      |   10 +-
 arch/arm/plat-spear/padmux.c                   |   36 ++-
 15 files changed, 591 insertions(+), 242 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index a7abb3b..d453b60 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -25,10 +25,19 @@
 /*
  * Function enable (Pad multiplexing register) offsets
  */
-#define PAD_MUX_CONFIG_REG_0	0x0
-#define PAD_MUX_CONFIG_REG_1	0x4
-#define PAD_MUX_CONFIG_REG_2	0x8
-#define PAD_MUX_CONFIG_REG_3	0xC
+/* Pad multiplexing base */
+#define SPEAR13XX_FUNC_ENB_BASE		UL(0xE0700650)
+
+#define PAD_MUX_CONFIG_REG_0	UL(0xE0700650)
+#define PAD_MUX_CONFIG_REG_1	UL(0xE0700654)
+#define PAD_MUX_CONFIG_REG_2	UL(0xE0700658)
+#define PAD_MUX_CONFIG_REG_3	UL(0xE070065C)
+
+#if defined(CONFIG_MACH_SPEAR1310)
+#define SPEAR1310_FUNC_CNTL_0	UL(0x6C800000)
+
+#define PMX_SMII_MASK		(1 << 24)	/* Func cntl reg0 */
+#endif
 
 /* pad mux declarations */
 #define PMX_I2S1_MASK		(1 << 3)
@@ -112,9 +121,8 @@
 #define PMX_KBD_ROWCOL68_MASK	(1 << 4)	/* Offset 4 */
 #define PMX_KBD_COL0_MASK	(1 << 21)	/* Offset 4 */
 #define PMX_KBD_COL1_MASK	(1 << 19)	/* Offset 4 */
-#define PMX_KEYBOARD_MASK	(PMX_KBD_ROW0_MASK | PMX_KBD_ROW1_MASK | \
-		PMX_KBD_ROWCOL25_MASK | PMX_KBD_ROWCOL68_MASK | \
-		PMX_KBD_COL0_MASK | PMX_KBD_COL1_MASK)
+#define PMX_KEYBOARD_6X6_MASK	(PMX_KBD_ROW0_MASK | PMX_KBD_ROW1_MASK | \
+		PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL0_MASK | PMX_KBD_COL1_MASK)
 
 #define PMX_UART0_MASK		(1 << 1)
 #define PMX_I2C_MASK		(1 << 2)
@@ -165,16 +173,18 @@
 /* pad mux devices */
 extern struct pmx_dev pmx_i2c;
 extern struct pmx_dev pmx_ssp;
+extern struct pmx_dev pmx_i2s1;
 extern struct pmx_dev pmx_i2s2;
-extern struct pmx_dev pmx_clcd1;
-extern struct pmx_dev pmx_clcd2;
+extern struct pmx_dev pmx_clcd;
+extern struct pmx_dev pmx_clcd_hires;
 extern struct pmx_dev pmx_egpio_grp;
 extern struct pmx_dev pmx_smi_2_chips;
 extern struct pmx_dev pmx_smi_4_chips;
 extern struct pmx_dev pmx_gmii;
 extern struct pmx_dev pmx_nand_8bit;
 extern struct pmx_dev pmx_nand_16bit;
-extern struct pmx_dev pmx_keyboard;
+extern struct pmx_dev pmx_keyboard_6x6;
+extern struct pmx_dev pmx_keyboard_9x9;
 extern struct pmx_dev pmx_uart0;
 extern struct pmx_dev pmx_uart0_modem;
 extern struct pmx_dev pmx_gpt_0_1;
@@ -183,6 +193,22 @@ extern struct pmx_dev pmx_gpt_1_1;
 extern struct pmx_dev pmx_gpt_1_2;
 extern struct pmx_dev pmx_mcif;
 
+#if defined(CONFIG_MACH_SPEAR1310)
+extern struct pmx_dev pmx_uart1_modem;
+extern struct pmx_dev pmx_uart_1;
+extern struct pmx_dev pmx_uart_2;
+extern struct pmx_dev pmx_uart_3_4_5;
+extern struct pmx_dev pmx_rs485_hdlc_1_2;
+extern struct pmx_dev pmx_tdm_hdlc_1_2;
+extern struct pmx_dev pmx_nand32bit;
+extern struct pmx_dev pmx_gmii1;
+extern struct pmx_dev pmx_rgmii;
+extern struct pmx_dev pmx_i2c1;
+extern struct pmx_dev pmx_smii_0_1_2;
+extern struct pmx_dev pmx_can;
+extern struct pmx_dev pmx_uart1_modem;
+#endif
+
 /*
  * Each GPT has 2 timer channels
  * Following GPT channels will be used as clock source and clockevent
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index 03f9616..d043280 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -88,9 +88,6 @@
 #define SPEAR13XX_MCIF_CF_BASE		UL(0xB2800000)
 #define SPEAR13XX_MCIF_SDHCI_BASE	UL(0xB3000000)
 
-/* Pad multiplexing base */
-#define SPEAR13XX_FUNC_ENB_BASE		UL(0xE0700650)
-
 /* Debug uart for linux, will be used for debug and uncompress messages */
 #define SPEAR_DBG_UART_BASE		SPEAR13XX_UART_BASE
 #define VA_SPEAR_DBG_UART_BASE		VA_SPEAR13XX_UART_BASE
diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
index 4569cb5..28822a3 100644
--- a/arch/arm/mach-spear13xx/spear1300.c
+++ b/arch/arm/mach-spear13xx/spear1300.c
@@ -27,12 +27,7 @@ void __init spear1300_init(void)
 	spear13xx_init();
 
 	/* pmx initialization */
-	pmx_driver.base = ioremap(SPEAR13XX_FUNC_ENB_BASE, SZ_4K);
-	if (pmx_driver.base) {
-		ret = pmx_register(&pmx_driver);
-		if (ret)
-			pr_err("padmux: registeration failed. err no: %d\n",
-					ret);
-		iounmap(pmx_driver.base);
-	}
+	ret = pmx_register(&pmx_driver);
+	if (ret)
+		pr_err("padmux: registeration failed. err no: %d\n", ret);
 }
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 0d24fa3..e297981 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -44,11 +44,10 @@ static struct pmx_dev *pmx_devs[] = {
 	&pmx_i2c,
 	&pmx_i2s1,
 	&pmx_i2s2,
-	&pmx_clcd1,
-	&pmx_clcd2,
+	&pmx_clcd,
 	&pmx_egpio_grp,
 	&pmx_gmii,
-	&pmx_keyboard,
+	&pmx_keyboard_6x6,
 	&pmx_mcif,
 	&pmx_nand_8bit,
 	&pmx_smi_4_chips,
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 86ad9f8..3b38a4c 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -19,6 +19,311 @@
 /* pmx driver structure */
 struct pmx_driver pmx_driver;
 
+/* Pad multiplexing for uart1_modem device */
+static struct pmx_mux_reg pmx_uart1_modem_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_I2S1_MASK | PMX_SSP_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+	{
+		.mux_regs = pmx_uart1_modem_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_modem_mux),
+	},
+};
+
+struct pmx_dev pmx_uart1_modem = {
+	.name = "uart1_modem",
+	.modes = pmx_uart1_modem_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
+};
+
+/* Pad multiplexing for uart1 device */
+static struct pmx_mux_reg pmx_uart1_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_SSP_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart1_modes[] = {
+	{
+		.mux_regs = pmx_uart1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart1_mux),
+	},
+};
+
+struct pmx_dev pmx_uart_1 = {
+	.name = "uart1",
+	.modes = pmx_uart1_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
+};
+
+/* Pad multiplexing for uart2 device */
+static struct pmx_mux_reg pmx_uart2_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_SSP_MASK | PMX_CLCD1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart2_modes[] = {
+	{
+		.mux_regs = pmx_uart2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart2_mux),
+	},
+};
+
+struct pmx_dev pmx_uart_2 = {
+	.name = "uart2",
+	.modes = pmx_uart2_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
+};
+
+/* Pad multiplexing for uart_3_4_5 device */
+static struct pmx_mux_reg pmx_uart_3_4_5_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_CLCD1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_uart_3_4_5_modes[] = {
+	{
+		.mux_regs = pmx_uart_3_4_5_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_uart_3_4_5_mux),
+	},
+};
+
+struct pmx_dev pmx_uart_3_4_5 = {
+	.name = "uart_3_4_5",
+	.modes = pmx_uart_3_4_5_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart_3_4_5_modes),
+};
+
+/* Pad multiplexing for rs485_hdlc_1_2 device */
+static struct pmx_mux_reg pmx_rs485_hdlc_1_2_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_CLCD1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_rs485_hdlc_1_2_modes[] = {
+	{
+		.mux_regs = pmx_rs485_hdlc_1_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_rs485_hdlc_1_2_mux),
+	},
+};
+
+struct pmx_dev pmx_rs485_hdlc_1_2 = {
+	.name = "rs485_hdlc_1_2",
+	.modes = pmx_rs485_hdlc_1_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_rs485_hdlc_1_2_modes),
+};
+
+/* Pad multiplexing for tdm_hdlc_1_2 device */
+static struct pmx_mux_reg pmx_tdm_hdlc_1_2_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_CLCD1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_tdm_hdlc_1_2_modes[] = {
+	{
+		.mux_regs = pmx_tdm_hdlc_1_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_tdm_hdlc_1_2_mux),
+	},
+};
+
+struct pmx_dev pmx_tdm_hdlc_1_2 = {
+	.name = "tdm_hdlc_1_2",
+	.modes = pmx_tdm_hdlc_1_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_tdm_hdlc_1_2_modes),
+};
+
+/* Pad multiplexing for fsmc32bit device */
+static struct pmx_mux_reg pmx_fsmc32bit_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_EGPIO_0_GRP_MASK | PMX_SMI_MASK | \
+			PMX_NAND16BIT4DEV_0_MASK | PMX_CLCD1_MASK,
+		.value = 0,
+	}, {
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_KEYBOARD_6X6_MASK | PMX_NAND16BIT4DEV_1_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_fsmc32bit_modes[] = {
+	{
+		.mux_regs = pmx_fsmc32bit_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_fsmc32bit_mux),
+	},
+};
+
+struct pmx_dev pmx_fsmc32bit_4_chips = {
+	.name = "fsmc32bit",
+	.modes = pmx_fsmc32bit_modes,
+	.mode_count = ARRAY_SIZE(pmx_fsmc32bit_modes),
+};
+
+/* Pad multiplexing for gmii1 device */
+static struct pmx_mux_reg pmx_gmii1_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_GMII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_gmii1_modes[] = {
+	{
+		.mux_regs = pmx_gmii1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_gmii1_mux),
+	},
+};
+
+struct pmx_dev pmx_gmii1 = {
+	.name = "gmii1",
+	.modes = pmx_gmii1_modes,
+	.mode_count = ARRAY_SIZE(pmx_gmii1_modes),
+};
+
+/* Pad multiplexing for rgmii device */
+static struct pmx_mux_reg pmx_rgmii_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_GMII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_rgmii_modes[] = {
+	{
+		.mux_regs = pmx_rgmii_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_rgmii_mux),
+	},
+};
+
+struct pmx_dev pmx_rgmii = {
+	.name = "rgmii",
+	.modes = pmx_rgmii_modes,
+	.mode_count = ARRAY_SIZE(pmx_rgmii_modes),
+};
+
+/* Pad multiplexing for i2c1 device */
+static struct pmx_mux_reg pmx_i2c1_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_i2c1_modes[] = {
+	{
+		.mux_regs = pmx_i2c1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_i2c1_mux),
+	},
+};
+
+struct pmx_dev pmx_i2c1 = {
+	.name = "i2c1",
+	.modes = pmx_i2c1_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
+};
+
+/* Pad multiplexing for smii_0_1_2 device */
+static struct pmx_mux_reg pmx_smii_0_1_2_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_CLCD2_MASK | PMX_KBD_ROWCOL68_MASK | \
+			PMX_EGPIO_1_GRP_MASK | PMX_GPT0_TMR1_MASK | \
+			PMX_GPT0_TMR2_MASK | PMX_GPT1_TMR1_MASK | \
+			PMX_GPT1_TMR2_MASK,
+		.value = 0,
+	}, {
+		.address = SPEAR1310_FUNC_CNTL_0,
+		.mask = PMX_SMII_MASK,
+		.value = PMX_SMII_MASK,
+	},
+};
+
+static struct pmx_dev_mode pmx_smii_0_1_2_modes[] = {
+	{
+		.mux_regs = pmx_smii_0_1_2_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_smii_0_1_2_mux),
+	},
+};
+
+struct pmx_dev pmx_smii_0_1_2 = {
+	.name = "smii_0_1_2",
+	.modes = pmx_smii_0_1_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_smii_0_1_2_modes),
+};
+
+/* Pad multiplexing for pci1 device */
+static struct pmx_mux_reg pmx_pci1_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_CLCD2_MASK | PMX_KBD_ROWCOL68_MASK | \
+			PMX_EGPIO_1_GRP_MASK | PMX_GPT0_TMR1_MASK | \
+			PMX_GPT0_TMR2_MASK | PMX_GPT1_TMR1_MASK | \
+			PMX_GPT1_TMR2_MASK,
+		.value = 0,
+	}, {
+		.address = SPEAR1310_FUNC_CNTL_0,
+		.mask = PMX_SMII_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_pci1_modes[] = {
+	{
+		.mux_regs = pmx_pci1_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_pci1_mux),
+	},
+};
+
+struct pmx_dev pmx_pci1 = {
+	.name = "pci1",
+	.modes = pmx_pci1_modes,
+	.mode_count = ARRAY_SIZE(pmx_pci1_modes),
+};
+
+/* Pad multiplexing for can device */
+static struct pmx_mux_reg pmx_can_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_I2S2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_can_modes[] = {
+	{
+		.mux_regs = pmx_can_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_can_mux),
+	},
+};
+
+struct pmx_dev pmx_can = {
+	.name = "can",
+	.modes = pmx_can_modes,
+	.mode_count = ARRAY_SIZE(pmx_can_modes),
+};
+
 /* Add spear1310 specific devices here */
 
 /* CAN device registeration */
@@ -66,12 +371,7 @@ void __init spear1310_init(void)
 	spear13xx_init();
 
 	/* pmx initialization */
-	pmx_driver.base = ioremap(SPEAR13XX_FUNC_ENB_BASE, SZ_4K);
-	if (pmx_driver.base) {
-		ret = pmx_register(&pmx_driver);
-		if (ret)
-			pr_err("padmux: registeration failed. err no: %d\n",
-					ret);
-		iounmap(pmx_driver.base);
-	}
+	ret = pmx_register(&pmx_driver);
+	if (ret)
+		pr_err("padmux: registeration failed. err no: %d\n", ret);
 }
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index b0e3cc4..dec9ceb 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -41,26 +41,29 @@ static struct pmx_dev *pmx_devs[] = {
 	/* spear13xx specific devices */
 	&pmx_i2c,
 	&pmx_i2s1,
-	&pmx_i2s2,
-	&pmx_clcd1,
-	&pmx_clcd2,
 	&pmx_egpio_grp,
 	&pmx_gmii,
-	&pmx_keyboard,
+	&pmx_keyboard_6x6,
 	&pmx_mcif,
 	&pmx_nand_8bit,
-	&pmx_smi_4_chips,
-	&pmx_ssp,
+	&pmx_smi_2_chips,
 	&pmx_uart0,
 
 	/* spear1310 specific devices */
+	&pmx_can,
+	&pmx_i2c1,
+	&pmx_smii_0_1_2,
+	&pmx_rs485_hdlc_1_2,
+	&pmx_tdm_hdlc_1_2,
+	&pmx_uart_1,
+	&pmx_uart_2,
+	&pmx_uart_3_4_5,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
 	&gpio_device[0],
 	&gpio_device[1],
-	&ssp_device,
 	&uart_device,
 };
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 9167bc8..c02073f 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -609,7 +609,7 @@ struct sys_timer spear13xx_timer = {
 /* Pad multiplexing for i2c device */
 static struct pmx_mux_reg pmx_i2c_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_I2C_MASK,
 		.value = PMX_I2C_MASK,
 	},
@@ -631,7 +631,7 @@ struct pmx_dev pmx_i2c = {
 /* Pad multiplexing for ssp device */
 static struct pmx_mux_reg pmx_ssp_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_SSP_MASK,
 		.value = PMX_SSP_MASK,
 	},
@@ -653,7 +653,7 @@ struct pmx_dev pmx_ssp = {
 /* Pad multiplexing for i2s1 device */
 static struct pmx_mux_reg pmx_i2s1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_I2S1_MASK,
 		.value = PMX_I2S1_MASK,
 	},
@@ -675,7 +675,7 @@ struct pmx_dev pmx_i2s1 = {
 /* Pad multiplexing for i2s2 device */
 static struct pmx_mux_reg pmx_i2s2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_I2S2_MASK,
 		.value = PMX_I2S2_MASK,
 	},
@@ -694,48 +694,52 @@ struct pmx_dev pmx_i2s2 = {
 	.mode_count = ARRAY_SIZE(pmx_i2s2_modes),
 };
 
-/* Pad multiplexing for clcd1 device */
-static struct pmx_mux_reg pmx_clcd1_mux[] = {
+/* Pad multiplexing for clcd device */
+static struct pmx_mux_reg pmx_clcd_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_CLCD1_MASK,
 		.value = PMX_CLCD1_MASK,
 	},
 };
 
-static struct pmx_dev_mode pmx_clcd1_modes[] = {
+static struct pmx_dev_mode pmx_clcd_modes[] = {
 	{
-		.mux_regs = pmx_clcd1_mux,
-		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd1_mux),
+		.mux_regs = pmx_clcd_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd_mux),
 	},
 };
 
-struct pmx_dev pmx_clcd1 = {
-	.name = "clcd1",
-	.modes = pmx_clcd1_modes,
-	.mode_count = ARRAY_SIZE(pmx_clcd1_modes),
+struct pmx_dev pmx_clcd = {
+	.name = "clcd",
+	.modes = pmx_clcd_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
 };
 
-/* Pad multiplexing for clcd2 device */
-static struct pmx_mux_reg pmx_clcd2_mux[] = {
+/* Pad multiplexing for clcd_hires device */
+static struct pmx_mux_reg pmx_clcd_hires_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_0,
+		.mask = PMX_CLCD1_MASK,
+		.value = PMX_CLCD1_MASK,
+	}, {
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_CLCD2_MASK,
 		.value = PMX_CLCD2_MASK,
 	},
 };
 
-static struct pmx_dev_mode pmx_clcd2_modes[] = {
+static struct pmx_dev_mode pmx_clcd_hires_modes[] = {
 	{
-		.mux_regs = pmx_clcd2_mux,
-		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd2_mux),
+		.mux_regs = pmx_clcd_hires_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_clcd_hires_mux),
 	},
 };
 
-struct pmx_dev pmx_clcd2 = {
-	.name = "clcd2",
-	.modes = pmx_clcd2_modes,
-	.mode_count = ARRAY_SIZE(pmx_clcd2_modes),
+struct pmx_dev pmx_clcd_hires = {
+	.name = "clcd_high_res",
+	.modes = pmx_clcd_hires_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd_hires_modes),
 };
 
 /*
@@ -744,11 +748,11 @@ struct pmx_dev pmx_clcd2 = {
  */
 static struct pmx_mux_reg pmx_egpio_grp_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_EGPIO_0_GRP_MASK,
 		.value = PMX_EGPIO_0_GRP_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_EGPIO_1_GRP_MASK,
 		.value = PMX_EGPIO_1_GRP_MASK,
 	},
@@ -770,7 +774,7 @@ struct pmx_dev pmx_egpio_grp = {
 /* Pad multiplexing for smi 2 chips device */
 static struct pmx_mux_reg pmx_smi_2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_SMI_MASK,
 		.value = PMX_SMI_MASK,
 	},
@@ -792,11 +796,11 @@ struct pmx_dev pmx_smi_2_chips = {
 /* Pad multiplexing for smi 4 chips device */
 static struct pmx_mux_reg pmx_smi_4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_SMI_MASK,
 		.value = PMX_SMI_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
 		.value = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
 	},
@@ -818,7 +822,7 @@ struct pmx_dev pmx_smi_4_chips = {
 /* Pad multiplexing for gmii device */
 static struct pmx_mux_reg pmx_gmii_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_GMII_MASK,
 		.value = PMX_GMII_MASK,
 	},
@@ -840,13 +844,13 @@ struct pmx_dev pmx_gmii = {
 /* Pad multiplexing for nand 8bit (4 chips) */
 static struct pmx_mux_reg pmx_nand8_4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_NAND8BIT4DEV_0_MASK,
 		.value = PMX_NAND8BIT4DEV_0_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
-		.mask = PMX_NAND8BIT4DEV_1_MASK,
-		.value = PMX_NAND8BIT4DEV_1_MASK,
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND8BIT4DEV_1_MASK | PMX_KEYBOARD_6X6_MASK,
+		.value = PMX_NAND8BIT4DEV_1_MASK | PMX_KEYBOARD_6X6_MASK,
 	},
 };
 
@@ -863,16 +867,16 @@ struct pmx_dev pmx_nand_8bit_4_chips = {
 	.mode_count = ARRAY_SIZE(pmx_nand8_4_modes),
 };
 
-/* Pad multiplexing for nand 8bit device */
+/* Pad multiplexing for nand 8bit device (cs0 only) */
 static struct pmx_mux_reg pmx_nand8_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_NAND8BIT_0_MASK,
 		.value = PMX_NAND8BIT_0_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
-		.mask = PMX_NAND8BIT_1_MASK,
-		.value = PMX_NAND8BIT_1_MASK,
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND8BIT_1_MASK | PMX_KEYBOARD_6X6_MASK,
+		.value = PMX_NAND8BIT_1_MASK | PMX_KEYBOARD_6X6_MASK,
 	},
 };
 
@@ -897,13 +901,13 @@ struct pmx_dev pmx_nand_8bit = {
  */
 static struct pmx_mux_reg pmx_nand16_4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_NAND16BIT4DEV_0_MASK,
 		.value = PMX_NAND16BIT4DEV_0_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
-		.mask = PMX_NAND16BIT4DEV_1_MASK,
-		.value = PMX_NAND16BIT4DEV_1_MASK,
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND16BIT4DEV_1_MASK | PMX_KEYBOARD_6X6_MASK,
+		.value = PMX_NAND16BIT4DEV_1_MASK | PMX_KEYBOARD_6X6_MASK,
 	},
 };
 
@@ -920,16 +924,16 @@ struct pmx_dev pmx_nand_16bit_4_chips = {
 	.mode_count = ARRAY_SIZE(pmx_nand16_4_modes),
 };
 
-/* Pad multiplexing for nand 16bit device */
+/* Pad multiplexing for nand 16bit device (cs0 only) */
 static struct pmx_mux_reg pmx_nand16_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_NAND16BIT_0_MASK,
 		.value = PMX_NAND16BIT_0_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
-		.mask = PMX_NAND16BIT_1_MASK,
-		.value = PMX_NAND16BIT_1_MASK,
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NAND16BIT_1_MASK | PMX_KEYBOARD_6X6_MASK,
+		.value = PMX_NAND16BIT_1_MASK | PMX_KEYBOARD_6X6_MASK,
 	},
 };
 
@@ -946,37 +950,64 @@ struct pmx_dev pmx_nand_16bit = {
 	.mode_count = ARRAY_SIZE(pmx_nand16_modes),
 };
 
-/* Pad multiplexing for keyboard device */
-static struct pmx_mux_reg pmx_keyboard_mux[] = {
+/* Pad multiplexing for keyboard_6x6 device */
+static struct pmx_mux_reg pmx_keyboard_6x6_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
-		.mask = PMX_KEYBOARD_MASK,
-		.value = PMX_KEYBOARD_MASK,
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_KEYBOARD_6X6_MASK,
+		.value = PMX_KEYBOARD_6X6_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_NFIO815_MASK | PMX_NFCE1_MASK | \
 			PMX_NFCE2_MASK | PMX_NFWPRT1_MASK | PMX_NFWPRT2_MASK,
 		.value = 0,
 	},
 };
 
-static struct pmx_dev_mode pmx_keyboard_modes[] = {
+static struct pmx_dev_mode pmx_keyboard_6x6_modes[] = {
 	{
-		.mux_regs = pmx_keyboard_mux,
-		.mux_reg_cnt = ARRAY_SIZE(pmx_keyboard_mux),
+		.mux_regs = pmx_keyboard_6x6_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_keyboard_6x6_mux),
 	},
 };
 
-struct pmx_dev pmx_keyboard = {
-	.name = "keyboard",
-	.modes = pmx_keyboard_modes,
-	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
+struct pmx_dev pmx_keyboard_6x6 = {
+	.name = "keyboard_6x6",
+	.modes = pmx_keyboard_6x6_modes,
+	.mode_count = ARRAY_SIZE(pmx_keyboard_6x6_modes),
+};
+
+/* Pad multiplexing for keyboard_9x9 device */
+static struct pmx_mux_reg pmx_keyboard_9x9_mux[] = {
+	{
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_KEYBOARD_6X6_MASK | PMX_KBD_ROWCOL68_MASK,
+		.value = PMX_KEYBOARD_6X6_MASK | PMX_KBD_ROWCOL68_MASK,
+	}, {
+		.address = PAD_MUX_CONFIG_REG_1,
+		.mask = PMX_NFIO815_MASK | PMX_NFCE1_MASK | \
+			PMX_NFCE2_MASK | PMX_NFWPRT1_MASK | PMX_NFWPRT2_MASK,
+		.value = 0,
+	},
+};
+
+static struct pmx_dev_mode pmx_keyboard_9x9_modes[] = {
+	{
+		.mux_regs = pmx_keyboard_9x9_mux,
+		.mux_reg_cnt = ARRAY_SIZE(pmx_keyboard_9x9_mux),
+	},
+};
+
+struct pmx_dev pmx_keyboard_9x9 = {
+	.name = "keyboard_9x9",
+	.modes = pmx_keyboard_9x9_modes,
+	.mode_count = ARRAY_SIZE(pmx_keyboard_9x9_modes),
 };
 
 /* Pad multiplexing for uart0 device */
 static struct pmx_mux_reg pmx_uart0_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_0,
+		.address = PAD_MUX_CONFIG_REG_0,
 		.mask = PMX_UART0_MASK,
 		.value = PMX_UART0_MASK,
 	},
@@ -998,7 +1029,7 @@ struct pmx_dev pmx_uart0 = {
 /* Pad multiplexing for uart0_modem device */
 static struct pmx_mux_reg pmx_uart0_modem_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = PMX_UART0_MODEM_MASK,
 	},
@@ -1020,7 +1051,7 @@ struct pmx_dev pmx_uart0_modem = {
 /* Pad multiplexing for gpt_0_1 device */
 static struct pmx_mux_reg pmx_gpt_0_1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_GPT0_TMR1_MASK,
 		.value = PMX_GPT0_TMR1_MASK,
 	},
@@ -1042,7 +1073,7 @@ struct pmx_dev pmx_gpt_0_1 = {
 /* Pad multiplexing for gpt_0_2 device */
 static struct pmx_mux_reg pmx_gpt_0_2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_GPT0_TMR2_MASK,
 		.value = PMX_GPT0_TMR2_MASK,
 	},
@@ -1064,7 +1095,7 @@ struct pmx_dev pmx_gpt_0_2 = {
 /* Pad multiplexing for gpt_1_1 device */
 static struct pmx_mux_reg pmx_gpt_1_1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_GPT1_TMR1_MASK,
 		.value = PMX_GPT1_TMR1_MASK,
 	},
@@ -1086,7 +1117,7 @@ struct pmx_dev pmx_gpt_1_1 = {
 /* Pad multiplexing for gpt_1_2 device */
 static struct pmx_mux_reg pmx_gpt_1_2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_GPT1_TMR2_MASK,
 		.value = PMX_GPT1_TMR2_MASK,
 	},
@@ -1108,11 +1139,11 @@ struct pmx_dev pmx_gpt_1_2 = {
 /* Pad multiplexing for mcif device */
 static struct pmx_mux_reg pmx_mcif_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG_1,
+		.address = PAD_MUX_CONFIG_REG_1,
 		.mask = PMX_MCIFALL_1_MASK,
 		.value = PMX_MCIFALL_1_MASK,
 	}, {
-		.offset = PAD_MUX_CONFIG_REG_2,
+		.address = PAD_MUX_CONFIG_REG_2,
 		.mask = PMX_MCIFALL_2_MASK,
 		.value = PMX_MCIFALL_2_MASK,
 	},
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index e5c025b..a79855f 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -149,7 +149,10 @@ extern struct pmx_dev pmx_telecom_boot_pins;
 extern struct pmx_dev pmx_telecom_sdhci_4bit;
 extern struct pmx_dev pmx_telecom_sdhci_8bit;
 extern struct pmx_dev pmx_gpio1;
-#define PAD_MUX_CONFIG_REG	0x00
+
+/* pad multiplexing support */
+#define PAD_MUX_CONFIG_REG	0x99000000
+#define MODE_CONFIG_REG		0x99000004
 
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
@@ -181,7 +184,7 @@ extern struct pmx_dev pmx_uart3_4_5;
 extern struct pmx_dev pmx_fsmc;
 extern struct pmx_dev pmx_rs485_0_1;
 extern struct pmx_dev pmx_tdm0;
-#define PAD_MUX_CONFIG_REG	0x08
+#define PAD_MUX_CONFIG_REG	0xB4000008
 
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
@@ -231,7 +234,10 @@ extern struct pmx_dev pmx_mii1;
 extern struct pmx_dev pmx_smii0;
 extern struct pmx_dev pmx_smii1;
 extern struct pmx_dev pmx_i2c1;
-#define PAD_MUX_CONFIG_REG	0x0C
+
+/* pad multiplexing support */
+#define PAD_MUX_CONFIG_REG	0xB300000C
+#define MODE_CONFIG_REG		0xB3000010
 
 /* Add spear320 machine function declarations here */
 void __init spear320_init(void);
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
index c723515..4fd2d22 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear300.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -45,7 +45,6 @@
 #define SPEAR300_NOR_2_BASE		UL(0x92000000)
 #define SPEAR300_NOR_3_BASE		UL(0x93000000)
 #define SPEAR300_FSMC_BASE		UL(0x94000000)
-#define SPEAR300_SOC_CONFIG_BASE	UL(0x99000000)
 #define SPEAR300_KEYBOARD_BASE		UL(0xA0000000)
 #define SPEAR300_GPIO_BASE		UL(0xA9000000)
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 839e8b2..b8af1c9 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -20,9 +20,6 @@
 #include <plat/nand.h>
 #include <plat/shirq.h>
 
-/* pad multiplexing support */
-#define MODE_CONFIG_REG		0x04
-
 /* modes */
 #define NAND_MODE			(1 << 0)
 #define NOR_MODE			(1 << 1)
@@ -121,7 +118,7 @@ struct pmx_mode caml_lcd_mode = {
 /* Pad multiplexing for FSMC 2 NAND devices */
 static struct pmx_mux_reg pmx_fsmc_2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -145,7 +142,7 @@ struct pmx_dev pmx_fsmc_2_chips = {
 /* Pad multiplexing for FSMC 4 NAND devices */
 static struct pmx_mux_reg pmx_fsmc_4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
 		.value = 0,
 	},
@@ -169,7 +166,7 @@ struct pmx_dev pmx_fsmc_4_chips = {
 /* Pad multiplexing for Keyboard device */
 static struct pmx_mux_reg pmx_kbd_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -195,7 +192,7 @@ struct pmx_dev pmx_keyboard = {
 /* Pad multiplexing for CLCD device */
 static struct pmx_mux_reg pmx_clcd_pfmode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -203,7 +200,7 @@ static struct pmx_mux_reg pmx_clcd_pfmode_mux[] = {
 
 static struct pmx_mux_reg pmx_clcd_lcdmode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -231,7 +228,7 @@ struct pmx_dev pmx_clcd = {
 /* Pad multiplexing for Telecom GPIO device */
 static struct pmx_mux_reg pmx_gpio_lcdmode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -239,7 +236,7 @@ static struct pmx_mux_reg pmx_gpio_lcdmode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_fonemode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -247,7 +244,7 @@ static struct pmx_mux_reg pmx_gpio_fonemode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_atai2smode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -255,7 +252,7 @@ static struct pmx_mux_reg pmx_gpio_atai2smode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_lendfonemode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -263,7 +260,7 @@ static struct pmx_mux_reg pmx_gpio_lendfonemode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_atawi2smode_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
 			| PMX_UART0_MODEM_MASK,
 		.value = 0,
@@ -303,7 +300,7 @@ struct pmx_dev pmx_telecom_gpio = {
 /* Pad multiplexing for TDM device */
 static struct pmx_mux_reg pmx_tdm_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -330,7 +327,7 @@ struct pmx_dev pmx_telecom_tdm = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_spi_cs_i2c_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -355,7 +352,7 @@ struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
 
 static struct pmx_mux_reg pmx_caml_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -363,7 +360,7 @@ static struct pmx_mux_reg pmx_caml_mux[] = {
 
 static struct pmx_mux_reg pmx_camu_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
 		.value = 0,
 	},
@@ -390,7 +387,7 @@ struct pmx_dev pmx_telecom_camera = {
 /* Pad multiplexing for dac device */
 static struct pmx_mux_reg pmx_dac_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -414,7 +411,7 @@ struct pmx_dev pmx_telecom_dac = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_i2s_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -440,7 +437,7 @@ struct pmx_dev pmx_telecom_i2s = {
 /* Pad multiplexing for bootpins device */
 static struct pmx_mux_reg pmx_bootpins_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
 		.value = 0,
@@ -464,7 +461,7 @@ struct pmx_dev pmx_telecom_boot_pins = {
 /* Pad multiplexing for sdhci 4bit device */
 static struct pmx_mux_reg pmx_sdhci_4bit_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
 			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
@@ -493,7 +490,7 @@ struct pmx_dev pmx_telecom_sdhci_4bit = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_sdhci_8bit_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
 			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
@@ -521,7 +518,7 @@ struct pmx_dev pmx_telecom_sdhci_8bit = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_gpio1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
 		.value = 0,
@@ -544,7 +541,7 @@ struct pmx_dev pmx_gpio1 = {
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
-	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
+	.mode_reg = {.address = MODE_CONFIG_REG, .mask = 0x0000000f},
 };
 
 /* Add spear300 specific devices here */
@@ -780,18 +777,20 @@ struct spear_shirq shirq_ras1 = {
 void sdhci_i2s_mem_enable(u8 mask)
 {
 	u32 val;
-	void __iomem *base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
-	if (!base) {
+	void __iomem *config = ioremap(MODE_CONFIG_REG, SZ_16);
+	if (!config) {
 		pr_debug("sdhci_i2s_enb: ioremap fail\n");
 		return;
 	}
 
-	val = readl(base + MODE_CONFIG_REG);
+	val = readl(config);
 	if (mask == SDHCI_MEM_ENB)
 		val |= SDHCI_MEM_SELECT;
 	else
 		val &= ~SDHCI_MEM_SELECT;
-	writel(val, base + MODE_CONFIG_REG);
+	writel(val, config);
+
+	iounmap(config);
 }
 
 /* spear300 routines */
@@ -811,12 +810,7 @@ void __init spear300_init(void)
 	}
 
 	/* pmx initialization */
-	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
-	if (pmx_driver.base) {
-		ret = pmx_register(&pmx_driver);
-		if (ret)
-			printk(KERN_ERR "padmux: registeration failed. err no"
-					": %d\n", ret);
-		iounmap(pmx_driver.base);
-	}
+	ret = pmx_register(&pmx_driver);
+	if (ret)
+		pr_err("padmux: registeration failed. err no: %d\n", ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 2f7493b..5d8c3ae 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -26,7 +26,7 @@
 /* Pad multiplexing for emi_cs_0_1_4_5 devices */
 static struct pmx_mux_reg pmx_emi_cs_0_1_4_5_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -48,7 +48,7 @@ struct pmx_dev pmx_emi_cs_0_1_4_5 = {
 /* Pad multiplexing for emi_cs_2_3 devices */
 static struct pmx_mux_reg pmx_emi_cs_2_3_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -70,7 +70,7 @@ struct pmx_dev pmx_emi_cs_2_3 = {
 /* Pad multiplexing for uart1 device */
 static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -92,7 +92,7 @@ struct pmx_dev pmx_uart1 = {
 /* Pad multiplexing for uart2 device */
 static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -114,7 +114,7 @@ struct pmx_dev pmx_uart2 = {
 /* Pad multiplexing for uart3_4_5 devices */
 static struct pmx_mux_reg pmx_uart3_4_5_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -136,7 +136,7 @@ struct pmx_dev pmx_uart3_4_5 = {
 /* Pad multiplexing for fsmc device */
 static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -158,7 +158,7 @@ struct pmx_dev pmx_fsmc = {
 /* Pad multiplexing for rs485_0_1 devices */
 static struct pmx_mux_reg pmx_rs485_0_1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -180,7 +180,7 @@ struct pmx_dev pmx_rs485_0_1 = {
 /* Pad multiplexing for tdm0 device */
 static struct pmx_mux_reg pmx_tdm0_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -535,9 +535,7 @@ void __init spear310_init(void)
 	}
 
 	/* pmx initialization */
-	pmx_driver.base = base;
 	ret = pmx_register(&pmx_driver);
 	if (ret)
-		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
-				ret);
+		pr_err("padmux: registeration failed. err no: %d\n", ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 50625df..29faf46 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -23,9 +23,6 @@
 #include <plat/nand.h>
 #include <plat/shirq.h>
 
-/* pad multiplexing support */
-#define MODE_CONFIG_REG		0x10
-
 /* modes */
 #define AUTO_NET_SMII_MODE	(1 << 0)
 #define AUTO_NET_MII_MODE	(1 << 1)
@@ -61,7 +58,7 @@ struct pmx_mode small_printers_mode = {
 /* Pad multiplexing for CLCD device */
 static struct pmx_mux_reg pmx_clcd_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -84,7 +81,7 @@ struct pmx_dev pmx_clcd = {
 /* Pad multiplexing for EMI (Parallel NOR flash) device */
 static struct pmx_mux_reg pmx_emi_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -107,7 +104,7 @@ struct pmx_dev pmx_emi = {
 /* Pad multiplexing for FSMC (NAND flash) device */
 static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -130,7 +127,7 @@ struct pmx_dev pmx_fsmc = {
 /* Pad multiplexing for SPP device */
 static struct pmx_mux_reg pmx_spp_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -153,7 +150,7 @@ struct pmx_dev pmx_spp = {
 /* Pad multiplexing for SDHCI device */
 static struct pmx_mux_reg pmx_sdhci_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -177,7 +174,7 @@ struct pmx_dev pmx_sdhci = {
 /* Pad multiplexing for I2S device */
 static struct pmx_mux_reg pmx_i2s_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -200,7 +197,7 @@ struct pmx_dev pmx_i2s = {
 /* Pad multiplexing for UART1 device */
 static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
 		.value = 0,
 	},
@@ -223,7 +220,7 @@ struct pmx_dev pmx_uart1 = {
 /* Pad multiplexing for UART1 Modem device */
 static struct pmx_mux_reg pmx_uart1_modem_autoexp_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
 			PMX_SSP_CS_MASK,
 		.value = 0,
@@ -232,7 +229,7 @@ static struct pmx_mux_reg pmx_uart1_modem_autoexp_mux[] = {
 
 static struct pmx_mux_reg pmx_uart1_modem_smallpri_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
 			PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
 		.value = 0,
@@ -260,7 +257,7 @@ struct pmx_dev pmx_uart1_modem = {
 /* Pad multiplexing for UART2 device */
 static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -283,7 +280,7 @@ struct pmx_dev pmx_uart2 = {
 /* Pad multiplexing for Touchscreen device */
 static struct pmx_mux_reg pmx_touchscreen_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -306,7 +303,7 @@ struct pmx_dev pmx_touchscreen = {
 /* Pad multiplexing for CAN device */
 static struct pmx_mux_reg pmx_can_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
 		.value = 0,
@@ -330,7 +327,7 @@ struct pmx_dev pmx_can = {
 /* Pad multiplexing for SDHCI LED device */
 static struct pmx_mux_reg pmx_sdhci_led_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -353,7 +350,7 @@ struct pmx_dev pmx_sdhci_led = {
 /* Pad multiplexing for PWM0 device */
 static struct pmx_mux_reg pmx_pwm0_net_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -361,7 +358,7 @@ static struct pmx_mux_reg pmx_pwm0_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm0_autoexpsmallpri_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -388,7 +385,7 @@ struct pmx_dev pmx_pwm0 = {
 /* Pad multiplexing for PWM1 device */
 static struct pmx_mux_reg pmx_pwm1_net_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -396,7 +393,7 @@ static struct pmx_mux_reg pmx_pwm1_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm1_autoexpsmallpri_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -423,7 +420,7 @@ struct pmx_dev pmx_pwm1 = {
 /* Pad multiplexing for PWM2 device */
 static struct pmx_mux_reg pmx_pwm2_net_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -431,7 +428,7 @@ static struct pmx_mux_reg pmx_pwm2_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm2_autoexpsmallpri_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -458,7 +455,7 @@ struct pmx_dev pmx_pwm2 = {
 /* Pad multiplexing for PWM3 device */
 static struct pmx_mux_reg pmx_pwm3_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -481,7 +478,7 @@ struct pmx_dev pmx_pwm3 = {
 /* Pad multiplexing for SSP1 device */
 static struct pmx_mux_reg pmx_ssp1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -504,7 +501,7 @@ struct pmx_dev pmx_ssp1 = {
 /* Pad multiplexing for SSP2 device */
 static struct pmx_mux_reg pmx_ssp2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -527,7 +524,7 @@ struct pmx_dev pmx_ssp2 = {
 /* Pad multiplexing for mii1 device */
 static struct pmx_mux_reg pmx_mii1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -550,7 +547,7 @@ struct pmx_dev pmx_mii1 = {
 /* Pad multiplexing for smii0 device */
 static struct pmx_mux_reg pmx_smii0_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -573,7 +570,7 @@ struct pmx_dev pmx_smii0 = {
 /* Pad multiplexing for smii1 device */
 static struct pmx_mux_reg pmx_smii1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -596,7 +593,7 @@ struct pmx_dev pmx_smii1 = {
 /* Pad multiplexing for i2c1 device */
 static struct pmx_mux_reg pmx_i2c1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -618,7 +615,7 @@ struct pmx_dev pmx_i2c1 = {
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
-	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
+	.mode_reg = {.address = MODE_CONFIG_REG, .mask = 0x00000007},
 };
 
 /* Add spear320 specific devices here */
@@ -1030,9 +1027,7 @@ void __init spear320_init(void)
 	}
 
 	/* pmx initialization */
-	pmx_driver.base = base;
 	ret = pmx_register(&pmx_driver);
 	if (ret)
-		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
-				ret);
+		pr_err("padmux: registeration failed. err no: %d\n", ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 1a5fe3a..41ec74e 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -297,7 +297,7 @@ void __init spear3xx_map_io(void)
 /* Pad multiplexing for firda device */
 static struct pmx_mux_reg pmx_firda_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = PMX_FIRDA_MASK,
 	},
@@ -320,7 +320,7 @@ struct pmx_dev pmx_firda = {
 /* Pad multiplexing for i2c device */
 static struct pmx_mux_reg pmx_i2c_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
 		.value = PMX_I2C_MASK,
 	},
@@ -343,7 +343,7 @@ struct pmx_dev pmx_i2c = {
 /* Pad multiplexing for firda device */
 static struct pmx_mux_reg pmx_ssp_cs_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = PMX_SSP_CS_MASK,
 	},
@@ -366,7 +366,7 @@ struct pmx_dev pmx_ssp_cs = {
 /* Pad multiplexing for ssp device */
 static struct pmx_mux_reg pmx_ssp_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
 		.value = PMX_SSP_MASK,
 	},
@@ -389,7 +389,7 @@ struct pmx_dev pmx_ssp = {
 /* Pad multiplexing for mii device */
 static struct pmx_mux_reg pmx_mii_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = PMX_MII_MASK,
 	},
@@ -412,7 +412,7 @@ struct pmx_dev pmx_mii = {
 /* Pad multiplexing for gpio pin0 device */
 static struct pmx_mux_reg pmx_gpio_pin0_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
 		.value = PMX_GPIO_PIN0_MASK,
 	},
@@ -435,7 +435,7 @@ struct pmx_dev pmx_gpio_pin0 = {
 /* Pad multiplexing for gpio pin1 device */
 static struct pmx_mux_reg pmx_gpio_pin1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
 		.value = PMX_GPIO_PIN1_MASK,
 	},
@@ -458,7 +458,7 @@ struct pmx_dev pmx_gpio_pin1 = {
 /* Pad multiplexing for gpio pin2 device */
 static struct pmx_mux_reg pmx_gpio_pin2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
 		.value = PMX_GPIO_PIN2_MASK,
 	},
@@ -481,7 +481,7 @@ struct pmx_dev pmx_gpio_pin2 = {
 /* Pad multiplexing for gpio pin3 device */
 static struct pmx_mux_reg pmx_gpio_pin3_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
 		.value = PMX_GPIO_PIN3_MASK,
 	},
@@ -504,7 +504,7 @@ struct pmx_dev pmx_gpio_pin3 = {
 /* Pad multiplexing for gpio pin4 device */
 static struct pmx_mux_reg pmx_gpio_pin4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
 		.value = PMX_GPIO_PIN4_MASK,
 	},
@@ -527,7 +527,7 @@ struct pmx_dev pmx_gpio_pin4 = {
 /* Pad multiplexing for gpio pin5 device */
 static struct pmx_mux_reg pmx_gpio_pin5_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
 		.value = PMX_GPIO_PIN5_MASK,
 	},
@@ -550,7 +550,7 @@ struct pmx_dev pmx_gpio_pin5 = {
 /* Pad multiplexing for uart0 modem device */
 static struct pmx_mux_reg pmx_uart0_modem_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = PMX_UART0_MODEM_MASK,
 	},
@@ -573,7 +573,7 @@ struct pmx_dev pmx_uart0_modem = {
 /* Pad multiplexing for uart0 device */
 static struct pmx_mux_reg pmx_uart0_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
 		.value = PMX_UART0_MASK,
 	},
@@ -596,7 +596,7 @@ struct pmx_dev pmx_uart0 = {
 /* Pad multiplexing for timer 3, 4 device */
 static struct pmx_mux_reg pmx_timer_3_4_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = PMX_TIMER_3_4_MASK,
 	},
@@ -619,7 +619,7 @@ struct pmx_dev pmx_timer_3_4 = {
 /* Pad multiplexing for gpio pin0 device */
 static struct pmx_mux_reg pmx_timer_1_2_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = PMX_TIMER_1_2_MASK,
 	},
@@ -644,7 +644,7 @@ struct pmx_dev pmx_timer_1_2 = {
 /* Pad multiplexing for plgpio_0_1 devices */
 static struct pmx_mux_reg pmx_plgpio_0_1_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -667,7 +667,7 @@ struct pmx_dev pmx_plgpio_0_1 = {
 /* Pad multiplexing for plgpio_2_3 devices */
 static struct pmx_mux_reg pmx_plgpio_2_3_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
 		.value = 0,
 	},
@@ -690,7 +690,7 @@ struct pmx_dev pmx_plgpio_2_3 = {
 /* Pad multiplexing for plgpio_4_5 devices */
 static struct pmx_mux_reg pmx_plgpio_4_5_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
 		.value = 0,
 	},
@@ -713,7 +713,7 @@ struct pmx_dev pmx_plgpio_4_5 = {
 /* Pad multiplexing for plgpio_6_9 devices */
 static struct pmx_mux_reg pmx_plgpio_6_9_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
 		.value = 0,
 	},
@@ -736,7 +736,7 @@ struct pmx_dev pmx_plgpio_6_9 = {
 /* Pad multiplexing for plgpio_10_27 devices */
 static struct pmx_mux_reg pmx_plgpio_10_27_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -759,7 +759,7 @@ struct pmx_dev pmx_plgpio_10_27 = {
 /* Pad multiplexing for plgpio_28 devices */
 static struct pmx_mux_reg pmx_plgpio_28_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
 		.value = 0,
 	},
@@ -782,7 +782,7 @@ struct pmx_dev pmx_plgpio_28 = {
 /* Pad multiplexing for plgpio_29 devices */
 static struct pmx_mux_reg pmx_plgpio_29_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
 		.value = 0,
 	},
@@ -805,7 +805,7 @@ struct pmx_dev pmx_plgpio_29 = {
 /* Pad multiplexing for plgpio_30 device */
 static struct pmx_mux_reg pmx_plgpio_30_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
 		.value = 0,
 	},
@@ -828,7 +828,7 @@ struct pmx_dev pmx_plgpio_30 = {
 /* Pad multiplexing for plgpio_31 device */
 static struct pmx_mux_reg pmx_plgpio_31_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
 		.value = 0,
 	},
@@ -851,7 +851,7 @@ struct pmx_dev pmx_plgpio_31 = {
 /* Pad multiplexing for plgpio_32 device */
 static struct pmx_mux_reg pmx_plgpio_32_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
 		.value = 0,
 	},
@@ -874,7 +874,7 @@ struct pmx_dev pmx_plgpio_32 = {
 /* Pad multiplexing for plgpio_33 device */
 static struct pmx_mux_reg pmx_plgpio_33_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
 		.value = 0,
 	},
@@ -897,7 +897,7 @@ struct pmx_dev pmx_plgpio_33 = {
 /* Pad multiplexing for plgpio_34_36 device */
 static struct pmx_mux_reg pmx_plgpio_34_36_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -920,7 +920,7 @@ struct pmx_dev pmx_plgpio_34_36 = {
 /* Pad multiplexing for plgpio_37_42 device */
 static struct pmx_mux_reg pmx_plgpio_37_42_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -943,7 +943,7 @@ struct pmx_dev pmx_plgpio_37_42 = {
 /* Pad multiplexing for plgpio_43_44_47_48 device */
 static struct pmx_mux_reg pmx_plgpio_43_44_47_48_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -966,7 +966,7 @@ struct pmx_dev pmx_plgpio_43_44_47_48 = {
 /* Pad multiplexing for plgpio_45_46_49_50 device */
 static struct pmx_mux_reg pmx_plgpio_45_46_49_50_mux[] = {
 	{
-		.offset = PAD_MUX_CONFIG_REG,
+		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
index 1b69ca5..1959235 100644
--- a/arch/arm/plat-spear/include/plat/padmux.h
+++ b/arch/arm/plat-spear/include/plat/padmux.h
@@ -19,23 +19,23 @@
 /*
  * struct pmx_reg: configuration structure for mode reg and mux reg
  *
- * offset: offset of mode reg
+ * address: physical address of mode reg
  * mask: mask of mode reg
  */
 struct pmx_reg {
-	u32 offset;
+	u32 address;
 	u32 mask;
 };
 
 /*
  * struct pmx_mux_reg: configuration structure every group of modes of a device
  *
- * offset: multiplexing register offset
+ * address: physical address of multiplexing register
  * mask: mask for supported mode
  * value: value to be written
  */
 struct pmx_mux_reg {
-	u32 offset;
+	u32 address;
 	u32 mask;
 	u32 value;
 };
@@ -87,14 +87,12 @@ struct pmx_dev {
  * mode: mode to be set
  * devs: array of pointer to pmx devices
  * devs_count: ARRAY_SIZE of devs
- * base: base address of soc config registers
  * mode_reg: structure of mode config register
  */
 struct pmx_driver {
 	struct pmx_mode *mode;
 	struct pmx_dev **devs;
 	u8 devs_count;
-	u32 *base;
 	struct pmx_reg mode_reg;
 };
 
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
index f30f94b..97e4d96 100644
--- a/arch/arm/plat-spear/padmux.c
+++ b/arch/arm/plat-spear/padmux.c
@@ -19,12 +19,10 @@
 /*
  * struct pmx: pmx definition structure
  *
- * base: base address of configuration registers
  * mode_reg: mode configurations
  * active_mode: pointer to current active mode
  */
 struct pmx {
-	u32 base;
 	struct pmx_reg mode_reg;
 	struct pmx_mode *active_mode;
 };
@@ -40,17 +38,22 @@ static struct pmx *pmx;
  */
 static int pmx_mode_set(struct pmx_mode *mode)
 {
-	u32 val;
+	u32 val, *address;
 
 	if (!mode->name)
 		return -EFAULT;
 
 	pmx->active_mode = mode;
 
-	val = readl(pmx->base + pmx->mode_reg.offset);
-	val &= ~pmx->mode_reg.mask;
-	val |= mode->value & pmx->mode_reg.mask;
-	writel(val, pmx->base + pmx->mode_reg.offset);
+	address = ioremap(pmx->mode_reg.address, SZ_16);
+	if (address) {
+		val = readl(address);
+		val &= ~pmx->mode_reg.mask;
+		val |= mode->value & pmx->mode_reg.mask;
+		writel(val, address);
+
+		iounmap(address);
+	}
 
 	return 0;
 }
@@ -70,6 +73,7 @@ static int pmx_mode_set(struct pmx_mode *mode)
 static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
 {
 	u32 val, i;
+	u32 *address;
 
 	if (!count)
 		return -EINVAL;
@@ -104,10 +108,15 @@ static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
 			struct pmx_mux_reg *mux_reg =
 				&devs[i]->modes[j].mux_regs[k];
 
-			val = readl(pmx->base + mux_reg->offset);
-			val &= ~mux_reg->mask;
-			val |= mux_reg->value & mux_reg->mask;
-			writel(val, pmx->base + mux_reg->offset);
+			address = ioremap(mux_reg->address, SZ_16);
+			if (address) {
+				val = readl(address);
+				val &= ~mux_reg->mask;
+				val |= mux_reg->value & mux_reg->mask;
+				writel(val, address);
+
+				iounmap(address);
+			}
 		}
 
 		devs[i]->is_active = true;
@@ -134,15 +143,14 @@ int pmx_register(struct pmx_driver *driver)
 
 	if (pmx)
 		return -EPERM;
-	if (!driver->base || !driver->devs)
+	if (!driver->devs)
 		return -EFAULT;
 
 	pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
 	if (!pmx)
 		return -ENOMEM;
 
-	pmx->base = (u32)driver->base;
-	pmx->mode_reg.offset = driver->mode_reg.offset;
+	pmx->mode_reg.address = driver->mode_reg.address;
 	pmx->mode_reg.mask = driver->mode_reg.mask;
 
 	/* choose mode to enable */
-- 
1.7.2.2

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

* [PATCH 60/74] ST SPEAr3xx: Passing pmx devices address from machine *.c files
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (50 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 59/74] SPEAr : Adding SPEAr1310 pad multiplexing devices Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 61/74] SPEAr3xx: Make local structres static Viresh KUMAR
                   ` (22 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

All spear3xx machines have different pad mux register addresses.
In order to have single image for all spear3xx boards, we need to pass
this address from machine specific files to fix addresses of pmx devs found
in spear3xx.c

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |   11 +++---
 arch/arm/mach-spear3xx/spear300.c             |   27 +++-----------
 arch/arm/mach-spear3xx/spear310.c             |   11 ++----
 arch/arm/mach-spear3xx/spear320.c             |   31 ++--------------
 arch/arm/mach-spear3xx/spear3xx.c             |   48 +++++++++---------------
 5 files changed, 36 insertions(+), 92 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index a79855f..e3b9c17 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -51,6 +51,7 @@ void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
 void __init spear3xx_init_irq(void);
 void __init spear3xx_init(void);
+void spear3xx_pmx_init_addr(struct pmx_driver *driver, unsigned int addr);
 
 /* pad mux declarations */
 #define PMX_FIRDA_MASK		(1 << 14)
@@ -151,8 +152,8 @@ extern struct pmx_dev pmx_telecom_sdhci_8bit;
 extern struct pmx_dev pmx_gpio1;
 
 /* pad multiplexing support */
-#define PAD_MUX_CONFIG_REG	0x99000000
-#define MODE_CONFIG_REG		0x99000004
+#define SPEAR300_PAD_MUX_CONFIG_REG	0x99000000
+#define SPEAR300_MODE_CONFIG_REG	0x99000004
 
 /* Add spear300 machine function declarations here */
 void __init spear300_init(void);
@@ -184,7 +185,7 @@ extern struct pmx_dev pmx_uart3_4_5;
 extern struct pmx_dev pmx_fsmc;
 extern struct pmx_dev pmx_rs485_0_1;
 extern struct pmx_dev pmx_tdm0;
-#define PAD_MUX_CONFIG_REG	0xB4000008
+#define SPEAR310_PAD_MUX_CONFIG_REG	0xB4000008
 
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
@@ -236,8 +237,8 @@ extern struct pmx_dev pmx_smii1;
 extern struct pmx_dev pmx_i2c1;
 
 /* pad multiplexing support */
-#define PAD_MUX_CONFIG_REG	0xB300000C
-#define MODE_CONFIG_REG		0xB3000010
+#define SPEAR320_PAD_MUX_CONFIG_REG	0xB300000C
+#define SPEAR320_MODE_CONFIG_REG	0xB3000010
 
 /* Add spear320 machine function declarations here */
 void __init spear320_init(void);
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index b8af1c9..fb11f7c 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -118,7 +118,6 @@ struct pmx_mode caml_lcd_mode = {
 /* Pad multiplexing for FSMC 2 NAND devices */
 static struct pmx_mux_reg pmx_fsmc_2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -142,7 +141,6 @@ struct pmx_dev pmx_fsmc_2_chips = {
 /* Pad multiplexing for FSMC 4 NAND devices */
 static struct pmx_mux_reg pmx_fsmc_4_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
 		.value = 0,
 	},
@@ -166,7 +164,6 @@ struct pmx_dev pmx_fsmc_4_chips = {
 /* Pad multiplexing for Keyboard device */
 static struct pmx_mux_reg pmx_kbd_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -192,7 +189,6 @@ struct pmx_dev pmx_keyboard = {
 /* Pad multiplexing for CLCD device */
 static struct pmx_mux_reg pmx_clcd_pfmode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -200,7 +196,6 @@ static struct pmx_mux_reg pmx_clcd_pfmode_mux[] = {
 
 static struct pmx_mux_reg pmx_clcd_lcdmode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -228,7 +223,6 @@ struct pmx_dev pmx_clcd = {
 /* Pad multiplexing for Telecom GPIO device */
 static struct pmx_mux_reg pmx_gpio_lcdmode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -236,7 +230,6 @@ static struct pmx_mux_reg pmx_gpio_lcdmode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_fonemode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -244,7 +237,6 @@ static struct pmx_mux_reg pmx_gpio_fonemode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_atai2smode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -252,7 +244,6 @@ static struct pmx_mux_reg pmx_gpio_atai2smode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_lendfonemode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -260,7 +251,6 @@ static struct pmx_mux_reg pmx_gpio_lendfonemode_mux[] = {
 
 static struct pmx_mux_reg pmx_gpio_atawi2smode_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
 			| PMX_UART0_MODEM_MASK,
 		.value = 0,
@@ -300,7 +290,6 @@ struct pmx_dev pmx_telecom_gpio = {
 /* Pad multiplexing for TDM device */
 static struct pmx_mux_reg pmx_tdm_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -327,7 +316,6 @@ struct pmx_dev pmx_telecom_tdm = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_spi_cs_i2c_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -352,7 +340,6 @@ struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
 
 static struct pmx_mux_reg pmx_caml_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -360,7 +347,6 @@ static struct pmx_mux_reg pmx_caml_mux[] = {
 
 static struct pmx_mux_reg pmx_camu_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
 		.value = 0,
 	},
@@ -387,7 +373,6 @@ struct pmx_dev pmx_telecom_camera = {
 /* Pad multiplexing for dac device */
 static struct pmx_mux_reg pmx_dac_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -411,7 +396,6 @@ struct pmx_dev pmx_telecom_dac = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_i2s_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -437,7 +421,6 @@ struct pmx_dev pmx_telecom_i2s = {
 /* Pad multiplexing for bootpins device */
 static struct pmx_mux_reg pmx_bootpins_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
 		.value = 0,
@@ -461,7 +444,6 @@ struct pmx_dev pmx_telecom_boot_pins = {
 /* Pad multiplexing for sdhci 4bit device */
 static struct pmx_mux_reg pmx_sdhci_4bit_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
 			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
@@ -490,7 +472,6 @@ struct pmx_dev pmx_telecom_sdhci_4bit = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_sdhci_8bit_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
 			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
@@ -518,7 +499,6 @@ struct pmx_dev pmx_telecom_sdhci_8bit = {
 /* Pad multiplexing for spi cs i2c device */
 static struct pmx_mux_reg pmx_gpio1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
 			PMX_TIMER_3_4_MASK,
 		.value = 0,
@@ -541,7 +521,7 @@ struct pmx_dev pmx_gpio1 = {
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
-	.mode_reg = {.address = MODE_CONFIG_REG, .mask = 0x0000000f},
+	.mode_reg = {.address = SPEAR300_MODE_CONFIG_REG, .mask = 0x0000000f},
 };
 
 /* Add spear300 specific devices here */
@@ -777,7 +757,7 @@ struct spear_shirq shirq_ras1 = {
 void sdhci_i2s_mem_enable(u8 mask)
 {
 	u32 val;
-	void __iomem *config = ioremap(MODE_CONFIG_REG, SZ_16);
+	void __iomem *config = ioremap(SPEAR300_MODE_CONFIG_REG, SZ_16);
 	if (!config) {
 		pr_debug("sdhci_i2s_enb: ioremap fail\n");
 		return;
@@ -809,6 +789,9 @@ void __init spear300_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ\n");
 	}
 
+	/* This fixes addresses of all pmx devices for spear300 */
+	spear3xx_pmx_init_addr(&pmx_driver, SPEAR300_PAD_MUX_CONFIG_REG);
+
 	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 5d8c3ae..227af86 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -26,7 +26,6 @@
 /* Pad multiplexing for emi_cs_0_1_4_5 devices */
 static struct pmx_mux_reg pmx_emi_cs_0_1_4_5_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -48,7 +47,6 @@ struct pmx_dev pmx_emi_cs_0_1_4_5 = {
 /* Pad multiplexing for emi_cs_2_3 devices */
 static struct pmx_mux_reg pmx_emi_cs_2_3_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -70,7 +68,6 @@ struct pmx_dev pmx_emi_cs_2_3 = {
 /* Pad multiplexing for uart1 device */
 static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -92,7 +89,6 @@ struct pmx_dev pmx_uart1 = {
 /* Pad multiplexing for uart2 device */
 static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -114,7 +110,6 @@ struct pmx_dev pmx_uart2 = {
 /* Pad multiplexing for uart3_4_5 devices */
 static struct pmx_mux_reg pmx_uart3_4_5_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -136,7 +131,6 @@ struct pmx_dev pmx_uart3_4_5 = {
 /* Pad multiplexing for fsmc device */
 static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -158,7 +152,6 @@ struct pmx_dev pmx_fsmc = {
 /* Pad multiplexing for rs485_0_1 devices */
 static struct pmx_mux_reg pmx_rs485_0_1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -180,7 +173,6 @@ struct pmx_dev pmx_rs485_0_1 = {
 /* Pad multiplexing for tdm0 device */
 static struct pmx_mux_reg pmx_tdm0_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -534,6 +526,9 @@ void __init spear310_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
 
+	/* This fixes addresses of all pmx devices for spear310 */
+	spear3xx_pmx_init_addr(&pmx_driver, SPEAR310_PAD_MUX_CONFIG_REG);
+
 	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 29faf46..5e0303f 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -58,7 +58,6 @@ struct pmx_mode small_printers_mode = {
 /* Pad multiplexing for CLCD device */
 static struct pmx_mux_reg pmx_clcd_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -81,7 +80,6 @@ struct pmx_dev pmx_clcd = {
 /* Pad multiplexing for EMI (Parallel NOR flash) device */
 static struct pmx_mux_reg pmx_emi_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -104,7 +102,6 @@ struct pmx_dev pmx_emi = {
 /* Pad multiplexing for FSMC (NAND flash) device */
 static struct pmx_mux_reg pmx_fsmc_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -127,7 +124,6 @@ struct pmx_dev pmx_fsmc = {
 /* Pad multiplexing for SPP device */
 static struct pmx_mux_reg pmx_spp_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -150,7 +146,6 @@ struct pmx_dev pmx_spp = {
 /* Pad multiplexing for SDHCI device */
 static struct pmx_mux_reg pmx_sdhci_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -174,7 +169,6 @@ struct pmx_dev pmx_sdhci = {
 /* Pad multiplexing for I2S device */
 static struct pmx_mux_reg pmx_i2s_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -197,7 +191,6 @@ struct pmx_dev pmx_i2s = {
 /* Pad multiplexing for UART1 device */
 static struct pmx_mux_reg pmx_uart1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
 		.value = 0,
 	},
@@ -220,7 +213,6 @@ struct pmx_dev pmx_uart1 = {
 /* Pad multiplexing for UART1 Modem device */
 static struct pmx_mux_reg pmx_uart1_modem_autoexp_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
 			PMX_SSP_CS_MASK,
 		.value = 0,
@@ -229,7 +221,6 @@ static struct pmx_mux_reg pmx_uart1_modem_autoexp_mux[] = {
 
 static struct pmx_mux_reg pmx_uart1_modem_smallpri_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
 			PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
 		.value = 0,
@@ -257,7 +248,6 @@ struct pmx_dev pmx_uart1_modem = {
 /* Pad multiplexing for UART2 device */
 static struct pmx_mux_reg pmx_uart2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -280,7 +270,6 @@ struct pmx_dev pmx_uart2 = {
 /* Pad multiplexing for Touchscreen device */
 static struct pmx_mux_reg pmx_touchscreen_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -303,7 +292,6 @@ struct pmx_dev pmx_touchscreen = {
 /* Pad multiplexing for CAN device */
 static struct pmx_mux_reg pmx_can_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
 			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
 		.value = 0,
@@ -327,7 +315,6 @@ struct pmx_dev pmx_can = {
 /* Pad multiplexing for SDHCI LED device */
 static struct pmx_mux_reg pmx_sdhci_led_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -350,7 +337,6 @@ struct pmx_dev pmx_sdhci_led = {
 /* Pad multiplexing for PWM0 device */
 static struct pmx_mux_reg pmx_pwm0_net_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -358,7 +344,6 @@ static struct pmx_mux_reg pmx_pwm0_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm0_autoexpsmallpri_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -385,7 +370,6 @@ struct pmx_dev pmx_pwm0 = {
 /* Pad multiplexing for PWM1 device */
 static struct pmx_mux_reg pmx_pwm1_net_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -393,7 +377,6 @@ static struct pmx_mux_reg pmx_pwm1_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm1_autoexpsmallpri_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -420,7 +403,6 @@ struct pmx_dev pmx_pwm1 = {
 /* Pad multiplexing for PWM2 device */
 static struct pmx_mux_reg pmx_pwm2_net_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -428,7 +410,6 @@ static struct pmx_mux_reg pmx_pwm2_net_mux[] = {
 
 static struct pmx_mux_reg pmx_pwm2_autoexpsmallpri_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -455,7 +436,6 @@ struct pmx_dev pmx_pwm2 = {
 /* Pad multiplexing for PWM3 device */
 static struct pmx_mux_reg pmx_pwm3_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -478,7 +458,6 @@ struct pmx_dev pmx_pwm3 = {
 /* Pad multiplexing for SSP1 device */
 static struct pmx_mux_reg pmx_ssp1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -501,7 +480,6 @@ struct pmx_dev pmx_ssp1 = {
 /* Pad multiplexing for SSP2 device */
 static struct pmx_mux_reg pmx_ssp2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -524,7 +502,6 @@ struct pmx_dev pmx_ssp2 = {
 /* Pad multiplexing for mii1 device */
 static struct pmx_mux_reg pmx_mii1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -547,7 +524,6 @@ struct pmx_dev pmx_mii1 = {
 /* Pad multiplexing for smii0 device */
 static struct pmx_mux_reg pmx_smii0_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -570,7 +546,6 @@ struct pmx_dev pmx_smii0 = {
 /* Pad multiplexing for smii1 device */
 static struct pmx_mux_reg pmx_smii1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -593,7 +568,6 @@ struct pmx_dev pmx_smii1 = {
 /* Pad multiplexing for i2c1 device */
 static struct pmx_mux_reg pmx_i2c1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = 0x0,
 		.value = 0,
 	},
@@ -615,7 +589,7 @@ struct pmx_dev pmx_i2c1 = {
 
 /* pmx driver structure */
 struct pmx_driver pmx_driver = {
-	.mode_reg = {.address = MODE_CONFIG_REG, .mask = 0x00000007},
+	.mode_reg = {.address = SPEAR320_MODE_CONFIG_REG, .mask = 0x00000007},
 };
 
 /* Add spear320 specific devices here */
@@ -1026,6 +1000,9 @@ void __init spear320_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
 
+	/* This fixes addresses of all pmx devices for spear320 */
+	spear3xx_pmx_init_addr(&pmx_driver, SPEAR320_PAD_MUX_CONFIG_REG);
+
 	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 41ec74e..a1b2fa3 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -297,7 +297,6 @@ void __init spear3xx_map_io(void)
 /* Pad multiplexing for firda device */
 static struct pmx_mux_reg pmx_firda_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = PMX_FIRDA_MASK,
 	},
@@ -320,7 +319,6 @@ struct pmx_dev pmx_firda = {
 /* Pad multiplexing for i2c device */
 static struct pmx_mux_reg pmx_i2c_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
 		.value = PMX_I2C_MASK,
 	},
@@ -343,7 +341,6 @@ struct pmx_dev pmx_i2c = {
 /* Pad multiplexing for firda device */
 static struct pmx_mux_reg pmx_ssp_cs_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = PMX_SSP_CS_MASK,
 	},
@@ -366,7 +363,6 @@ struct pmx_dev pmx_ssp_cs = {
 /* Pad multiplexing for ssp device */
 static struct pmx_mux_reg pmx_ssp_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
 		.value = PMX_SSP_MASK,
 	},
@@ -389,7 +385,6 @@ struct pmx_dev pmx_ssp = {
 /* Pad multiplexing for mii device */
 static struct pmx_mux_reg pmx_mii_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = PMX_MII_MASK,
 	},
@@ -412,7 +407,6 @@ struct pmx_dev pmx_mii = {
 /* Pad multiplexing for gpio pin0 device */
 static struct pmx_mux_reg pmx_gpio_pin0_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
 		.value = PMX_GPIO_PIN0_MASK,
 	},
@@ -435,7 +429,6 @@ struct pmx_dev pmx_gpio_pin0 = {
 /* Pad multiplexing for gpio pin1 device */
 static struct pmx_mux_reg pmx_gpio_pin1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
 		.value = PMX_GPIO_PIN1_MASK,
 	},
@@ -458,7 +451,6 @@ struct pmx_dev pmx_gpio_pin1 = {
 /* Pad multiplexing for gpio pin2 device */
 static struct pmx_mux_reg pmx_gpio_pin2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
 		.value = PMX_GPIO_PIN2_MASK,
 	},
@@ -481,7 +473,6 @@ struct pmx_dev pmx_gpio_pin2 = {
 /* Pad multiplexing for gpio pin3 device */
 static struct pmx_mux_reg pmx_gpio_pin3_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
 		.value = PMX_GPIO_PIN3_MASK,
 	},
@@ -504,7 +495,6 @@ struct pmx_dev pmx_gpio_pin3 = {
 /* Pad multiplexing for gpio pin4 device */
 static struct pmx_mux_reg pmx_gpio_pin4_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
 		.value = PMX_GPIO_PIN4_MASK,
 	},
@@ -527,7 +517,6 @@ struct pmx_dev pmx_gpio_pin4 = {
 /* Pad multiplexing for gpio pin5 device */
 static struct pmx_mux_reg pmx_gpio_pin5_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
 		.value = PMX_GPIO_PIN5_MASK,
 	},
@@ -550,7 +539,6 @@ struct pmx_dev pmx_gpio_pin5 = {
 /* Pad multiplexing for uart0 modem device */
 static struct pmx_mux_reg pmx_uart0_modem_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = PMX_UART0_MODEM_MASK,
 	},
@@ -573,7 +561,6 @@ struct pmx_dev pmx_uart0_modem = {
 /* Pad multiplexing for uart0 device */
 static struct pmx_mux_reg pmx_uart0_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
 		.value = PMX_UART0_MASK,
 	},
@@ -596,7 +583,6 @@ struct pmx_dev pmx_uart0 = {
 /* Pad multiplexing for timer 3, 4 device */
 static struct pmx_mux_reg pmx_timer_3_4_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = PMX_TIMER_3_4_MASK,
 	},
@@ -619,7 +605,6 @@ struct pmx_dev pmx_timer_3_4 = {
 /* Pad multiplexing for gpio pin0 device */
 static struct pmx_mux_reg pmx_timer_1_2_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = PMX_TIMER_1_2_MASK,
 	},
@@ -644,7 +629,6 @@ struct pmx_dev pmx_timer_1_2 = {
 /* Pad multiplexing for plgpio_0_1 devices */
 static struct pmx_mux_reg pmx_plgpio_0_1_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_FIRDA_MASK,
 		.value = 0,
 	},
@@ -667,7 +651,6 @@ struct pmx_dev pmx_plgpio_0_1 = {
 /* Pad multiplexing for plgpio_2_3 devices */
 static struct pmx_mux_reg pmx_plgpio_2_3_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MASK,
 		.value = 0,
 	},
@@ -690,7 +673,6 @@ struct pmx_dev pmx_plgpio_2_3 = {
 /* Pad multiplexing for plgpio_4_5 devices */
 static struct pmx_mux_reg pmx_plgpio_4_5_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_I2C_MASK,
 		.value = 0,
 	},
@@ -713,7 +695,6 @@ struct pmx_dev pmx_plgpio_4_5 = {
 /* Pad multiplexing for plgpio_6_9 devices */
 static struct pmx_mux_reg pmx_plgpio_6_9_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_MASK,
 		.value = 0,
 	},
@@ -736,7 +717,6 @@ struct pmx_dev pmx_plgpio_6_9 = {
 /* Pad multiplexing for plgpio_10_27 devices */
 static struct pmx_mux_reg pmx_plgpio_10_27_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_MII_MASK,
 		.value = 0,
 	},
@@ -759,7 +739,6 @@ struct pmx_dev pmx_plgpio_10_27 = {
 /* Pad multiplexing for plgpio_28 devices */
 static struct pmx_mux_reg pmx_plgpio_28_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN0_MASK,
 		.value = 0,
 	},
@@ -782,7 +761,6 @@ struct pmx_dev pmx_plgpio_28 = {
 /* Pad multiplexing for plgpio_29 devices */
 static struct pmx_mux_reg pmx_plgpio_29_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN1_MASK,
 		.value = 0,
 	},
@@ -805,7 +783,6 @@ struct pmx_dev pmx_plgpio_29 = {
 /* Pad multiplexing for plgpio_30 device */
 static struct pmx_mux_reg pmx_plgpio_30_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN2_MASK,
 		.value = 0,
 	},
@@ -828,7 +805,6 @@ struct pmx_dev pmx_plgpio_30 = {
 /* Pad multiplexing for plgpio_31 device */
 static struct pmx_mux_reg pmx_plgpio_31_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN3_MASK,
 		.value = 0,
 	},
@@ -851,7 +827,6 @@ struct pmx_dev pmx_plgpio_31 = {
 /* Pad multiplexing for plgpio_32 device */
 static struct pmx_mux_reg pmx_plgpio_32_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN4_MASK,
 		.value = 0,
 	},
@@ -874,7 +849,6 @@ struct pmx_dev pmx_plgpio_32 = {
 /* Pad multiplexing for plgpio_33 device */
 static struct pmx_mux_reg pmx_plgpio_33_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_GPIO_PIN5_MASK,
 		.value = 0,
 	},
@@ -897,7 +871,6 @@ struct pmx_dev pmx_plgpio_33 = {
 /* Pad multiplexing for plgpio_34_36 device */
 static struct pmx_mux_reg pmx_plgpio_34_36_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_SSP_CS_MASK,
 		.value = 0,
 	},
@@ -920,7 +893,6 @@ struct pmx_dev pmx_plgpio_34_36 = {
 /* Pad multiplexing for plgpio_37_42 device */
 static struct pmx_mux_reg pmx_plgpio_37_42_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_UART0_MODEM_MASK,
 		.value = 0,
 	},
@@ -943,7 +915,6 @@ struct pmx_dev pmx_plgpio_37_42 = {
 /* Pad multiplexing for plgpio_43_44_47_48 device */
 static struct pmx_mux_reg pmx_plgpio_43_44_47_48_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_1_2_MASK,
 		.value = 0,
 	},
@@ -966,7 +937,6 @@ struct pmx_dev pmx_plgpio_43_44_47_48 = {
 /* Pad multiplexing for plgpio_45_46_49_50 device */
 static struct pmx_mux_reg pmx_plgpio_45_46_49_50_mux[] = {
 	{
-		.address = PAD_MUX_CONFIG_REG,
 		.mask = PMX_TIMER_3_4_MASK,
 		.value = 0,
 	},
@@ -995,3 +965,21 @@ static void __init spear3xx_timer_init(void)
 struct sys_timer spear3xx_timer = {
 	.init = spear3xx_timer_init,
 };
+
+/* This fixes addresses of all pmx devices for different machines */
+void spear3xx_pmx_init_addr(struct pmx_driver *driver, unsigned int addr)
+{
+	int i;
+	for (i = 0; i < driver->devs_count; i++) {
+		int j;
+		struct pmx_dev *pdev = driver->devs[i];
+
+		for (j = 0; j < pdev->mode_count; j++) {
+			int k;
+			struct pmx_dev_mode *mode = &pdev->modes[j];
+
+			for (k = 0; k < mode->mux_reg_cnt; k++)
+				mode->mux_regs[k].address = addr;
+		}
+	}
+}
-- 
1.7.2.2

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

* [PATCH 61/74] SPEAr3xx: Make local structres static
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (51 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 60/74] ST SPEAr3xx: Passing pmx devices address from machine *.c files Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 62/74] SPEAR3xx: Rename register/irq defines to remove naming conflicts Viresh KUMAR
                   ` (21 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ryan Mallon <ryan@bluewatersys.com>

Several structures in arch/arm/mach-spear3xx are not marked static
like they should be. Fix this.

Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/spear300.c |    6 +++---
 arch/arm/mach-spear3xx/spear310.c |   16 ++++++++--------
 arch/arm/mach-spear3xx/spear320.c |   12 ++++++------
 arch/arm/mach-spear3xx/spear3xx.c |    2 --
 4 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index fb11f7c..9750875 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -114,7 +114,6 @@ struct pmx_mode caml_lcd_mode = {
 	.value = 0x0F,
 };
 
-/* devices */
 /* Pad multiplexing for FSMC 2 NAND devices */
 static struct pmx_mux_reg pmx_fsmc_2_mux[] = {
 	{
@@ -700,7 +699,7 @@ struct platform_device sdhci_device = {
 };
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
 		.virq = VIRQ_IT_PERS_S,
 		.enb_mask = IT_PERS_S_IRQ_MASK,
@@ -740,7 +739,8 @@ struct shirq_dev_config shirq_ras1_config[] = {
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
+
+static struct spear_shirq shirq_ras1 = {
 	.irq = IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 227af86..5c913f5 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -374,7 +374,7 @@ struct platform_device plgpio_device = {
 
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
 		.virq = VIRQ_SMII0,
 		.status_mask = SMII0_IRQ_MASK,
@@ -402,7 +402,7 @@ struct shirq_dev_config shirq_ras1_config[] = {
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
+static struct spear_shirq shirq_ras1 = {
 	.irq = IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
@@ -414,7 +414,7 @@ struct spear_shirq shirq_ras1 = {
 	},
 };
 
-struct shirq_dev_config shirq_ras2_config[] = {
+static struct shirq_dev_config shirq_ras2_config[] = {
 	{
 		.virq = VIRQ_UART1,
 		.status_mask = UART1_IRQ_MASK,
@@ -433,7 +433,7 @@ struct shirq_dev_config shirq_ras2_config[] = {
 	},
 };
 
-struct spear_shirq shirq_ras2 = {
+static struct spear_shirq shirq_ras2 = {
 	.irq = IRQ_GEN_RAS_2,
 	.dev_config = shirq_ras2_config,
 	.dev_count = ARRAY_SIZE(shirq_ras2_config),
@@ -445,14 +445,14 @@ struct spear_shirq shirq_ras2 = {
 	},
 };
 
-struct shirq_dev_config shirq_ras3_config[] = {
+static struct shirq_dev_config shirq_ras3_config[] = {
 	{
 		.virq = VIRQ_EMI,
 		.status_mask = EMI_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras3 = {
+static struct spear_shirq shirq_ras3 = {
 	.irq = IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
@@ -464,7 +464,7 @@ struct spear_shirq shirq_ras3 = {
 	},
 };
 
-struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
 		.virq = VIRQ_TDM_HDLC,
 		.status_mask = TDM_HDLC_IRQ_MASK,
@@ -477,7 +477,7 @@ struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	},
 };
 
-struct spear_shirq shirq_intrcomm_ras = {
+static struct spear_shirq shirq_intrcomm_ras = {
 	.irq = IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 5e0303f..d39fda3 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -846,7 +846,7 @@ struct platform_device sdhci_device = {
 };
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
 		.virq = VIRQ_EMI,
 		.status_mask = EMI_IRQ_MASK,
@@ -862,7 +862,7 @@ struct shirq_dev_config shirq_ras1_config[] = {
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
+static struct spear_shirq shirq_ras1 = {
 	.irq = IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
@@ -875,7 +875,7 @@ struct spear_shirq shirq_ras1 = {
 	},
 };
 
-struct shirq_dev_config shirq_ras3_config[] = {
+static struct shirq_dev_config shirq_ras3_config[] = {
 	{
 		.virq = VIRQ_PLGPIO,
 		.enb_mask = GPIO_IRQ_MASK,
@@ -894,7 +894,7 @@ struct shirq_dev_config shirq_ras3_config[] = {
 	},
 };
 
-struct spear_shirq shirq_ras3 = {
+static struct spear_shirq shirq_ras3 = {
 	.irq = IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
@@ -908,7 +908,7 @@ struct spear_shirq shirq_ras3 = {
 	},
 };
 
-struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
 		.virq = VIRQ_CANU,
 		.status_mask = CAN_U_IRQ_MASK,
@@ -956,7 +956,7 @@ struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	},
 };
 
-struct spear_shirq shirq_intrcomm_ras = {
+static struct spear_shirq shirq_intrcomm_ras = {
 	.irq = IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index a1b2fa3..1e2371f 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -292,7 +292,6 @@ void __init spear3xx_map_io(void)
 }
 
 /* pad multiplexing support */
-/* devices */
 
 /* Pad multiplexing for firda device */
 static struct pmx_mux_reg pmx_firda_mux[] = {
@@ -625,7 +624,6 @@ struct pmx_dev pmx_timer_1_2 = {
 };
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* plgpios devices */
 /* Pad multiplexing for plgpio_0_1 devices */
 static struct pmx_mux_reg pmx_plgpio_0_1_mux[] = {
 	{
-- 
1.7.2.2

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

* [PATCH 62/74] SPEAR3xx: Rename register/irq defines to remove naming conflicts
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (52 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 61/74] SPEAr3xx: Make local structres static Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 63/74] SPEAr3xx: Rework pmx_dev code to remove conflicts Viresh KUMAR
                   ` (20 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ryan Mallon <ryan@bluewatersys.com>

Prefix register and irq defintions to remove naming conflicts between
the three SPEAr3xx platforms.

Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h  |    4 +-
 arch/arm/mach-spear3xx/include/mach/gpio.h     |    3 +-
 arch/arm/mach-spear3xx/include/mach/irqs.h     |  207 ++++++++++++------------
 arch/arm/mach-spear3xx/include/mach/spear300.h |   26 ++--
 arch/arm/mach-spear3xx/include/mach/spear310.h |   44 +++---
 arch/arm/mach-spear3xx/include/mach/spear320.h |   48 +++---
 arch/arm/mach-spear3xx/spear300.c              |   73 ++++-----
 arch/arm/mach-spear3xx/spear310.c              |  108 ++++++------
 arch/arm/mach-spear3xx/spear320.c              |  158 +++++++++---------
 arch/arm/mach-spear3xx/spear3xx.c              |   25 ++--
 10 files changed, 349 insertions(+), 347 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index e3b9c17..896c1b0 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -28,8 +28,8 @@
  * Following GPT channels will be used as clock source and clockevent
  */
 #define SPEAR_GPT0_BASE		SPEAR3XX_ML1_TMR_BASE
-#define SPEAR_GPT0_CHAN0_IRQ	IRQ_CPU_GPT1_1
-#define SPEAR_GPT0_CHAN1_IRQ	IRQ_CPU_GPT1_2
+#define SPEAR_GPT0_CHAN0_IRQ	SPEAR3XX_IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ	SPEAR3XX_IRQ_CPU_GPT1_2
 
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device gpio_device;
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
index e531f6d..f15248c 100644
--- a/arch/arm/mach-spear3xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -51,8 +51,9 @@
 #define RAS_GPIO_5		13
 #define RAS_GPIO_6		14
 #define RAS_GPIO_7		15
+#endif
 
-#elif defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 #define PLGPIO_0		8
 #define PLGPIO_1		9
 #define PLGPIO_2		10
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index df0c1f3..6e26544 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -15,139 +15,140 @@
 #define __MACH_IRQS_H
 
 /* SPEAr3xx IRQ definitions */
-#define IRQ_HW_ACCEL_MOD_0			0
-#define IRQ_INTRCOMM_RAS_ARM			1
-#define IRQ_CPU_GPT1_1				2
-#define IRQ_CPU_GPT1_2				3
-#define IRQ_BASIC_GPT1_1			4
-#define IRQ_BASIC_GPT1_2			5
-#define IRQ_BASIC_GPT2_1			6
-#define IRQ_BASIC_GPT2_2			7
-#define IRQ_BASIC_DMA				8
-#define IRQ_BASIC_SMI				9
-#define IRQ_BASIC_RTC				10
-#define IRQ_BASIC_GPIO				11
-#define IRQ_BASIC_WDT				12
-#define IRQ_DDR_CONTROLLER			13
-#define IRQ_SYS_ERROR				14
-#define IRQ_WAKEUP_RCV				15
-#define IRQ_JPEG				16
-#define IRQ_IRDA				17
-#define IRQ_ADC					18
-#define IRQ_UART				19
-#define IRQ_SSP					20
-#define IRQ_I2C					21
-#define IRQ_MAC_1				22
-#define IRQ_MAC_2				23
-#define IRQ_USB_DEV				24
-#define IRQ_USB_H_OHCI_0			25
-#define IRQ_USB_H_EHCI_0			26
-#define IRQ_USB_H_EHCI_1			IRQ_USB_H_EHCI_0
-#define IRQ_USB_H_OHCI_1			27
-#define IRQ_GEN_RAS_1				28
-#define IRQ_GEN_RAS_2				29
-#define IRQ_GEN_RAS_3				30
-#define IRQ_HW_ACCEL_MOD_1			31
-#define IRQ_VIC_END				32
-
-#define VIRQ_START				IRQ_VIC_END
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_0		0
+#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM		1
+#define SPEAR3XX_IRQ_CPU_GPT1_1			2
+#define SPEAR3XX_IRQ_CPU_GPT1_2			3
+#define SPEAR3XX_IRQ_BASIC_GPT1_1		4
+#define SPEAR3XX_IRQ_BASIC_GPT1_2		5
+#define SPEAR3XX_IRQ_BASIC_GPT2_1		6
+#define SPEAR3XX_IRQ_BASIC_GPT2_2		7
+#define SPEAR3XX_IRQ_BASIC_DMA			8
+#define SPEAR3XX_IRQ_BASIC_SMI			9
+#define SPEAR3XX_IRQ_BASIC_RTC			10
+#define SPEAR3XX_IRQ_BASIC_GPIO			11
+#define SPEAR3XX_IRQ_BASIC_WDT			12
+#define SPEAR3XX_IRQ_DDR_CONTROLLER		13
+#define SPEAR3XX_IRQ_SYS_ERROR			14
+#define SPEAR3XX_IRQ_WAKEUP_RCV			15
+#define SPEAR3XX_IRQ_JPEG			16
+#define SPEAR3XX_IRQ_IRDA			17
+#define SPEAR3XX_IRQ_ADC			18
+#define SPEAR3XX_IRQ_UART			19
+#define SPEAR3XX_IRQ_SSP			20
+#define SPEAR3XX_IRQ_I2C			21
+#define SPEAR3XX_IRQ_MAC_1			22
+#define SPEAR3XX_IRQ_MAC_2			23
+#define SPEAR3XX_IRQ_USB_DEV			24
+#define SPEAR3XX_IRQ_USB_H_OHCI_0		25
+#define SPEAR3XX_IRQ_USB_H_EHCI_0		26
+#define SPEAR3XX_IRQ_USB_H_EHCI_1		SPEAR3XX_IRQ_USB_H_EHCI_0
+#define SPEAR3XX_IRQ_USB_H_OHCI_1		27
+#define SPEAR3XX_IRQ_GEN_RAS_1			28
+#define SPEAR3XX_IRQ_GEN_RAS_2			29
+#define SPEAR3XX_IRQ_GEN_RAS_3			30
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_1		31
+#define SPEAR3XX_IRQ_VIC_END			32
+
+#define SPEAR3XX_VIRQ_START			SPEAR3XX_IRQ_VIC_END
 
 /* SPEAr300 Virtual irq definitions */
-#ifdef CONFIG_MACH_SPEAR300
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_IT_PERS_S				(VIRQ_START + 0)
-#define VIRQ_IT_CHANGE_S			(VIRQ_START + 1)
-#define VIRQ_I2S				(VIRQ_START + 2)
-#define VIRQ_TDM				(VIRQ_START + 3)
-#define VIRQ_CAMERA_L				(VIRQ_START + 4)
-#define VIRQ_CAMERA_F				(VIRQ_START + 5)
-#define VIRQ_CAMERA_V				(VIRQ_START + 6)
-#define VIRQ_KEYBOARD				(VIRQ_START + 7)
-#define VIRQ_GPIO1				(VIRQ_START + 8)
+#define SPEAR300_VIRQ_IT_PERS_S			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR300_VIRQ_IT_CHANGE_S		(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR300_VIRQ_I2S			(SPEAR3XX_VIRQ_START + 2)
+#define SPEAR300_VIRQ_TDM			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR300_VIRQ_CAMERA_L			(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR300_VIRQ_CAMERA_F			(SPEAR3XX_VIRQ_START + 5)
+#define SPEAR300_VIRQ_CAMERA_V			(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR300_VIRQ_KEYBOARD			(SPEAR3XX_VIRQ_START + 7)
+#define SPEAR300_VIRQ_GPIO1			(SPEAR3XX_VIRQ_START + 8)
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define IRQ_CLCD				IRQ_GEN_RAS_3
+#define SPEAR300_IRQ_CLCD			SPEAR3XX_IRQ_GEN_RAS_3
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define IRQ_SDHCI				IRQ_INTRCOMM_RAS_ARM
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 9)
-#define SPEAR_GPIO1_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END			(SPEAR_GPIO1_INT_BASE + 8)
+#define SPEAR300_IRQ_SDHCI			SPEAR3XX_IRQ_INTRCOMM_RAS_ARM
 
 /* SPEAr310 Virtual irq definitions */
-#elif defined(CONFIG_MACH_SPEAR310)
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_SMII0				(VIRQ_START + 0)
-#define VIRQ_SMII1				(VIRQ_START + 1)
-#define VIRQ_SMII2				(VIRQ_START + 2)
-#define VIRQ_SMII3				(VIRQ_START + 3)
-#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 4)
-#define VIRQ_WAKEUP_SMII1			(VIRQ_START + 5)
-#define VIRQ_WAKEUP_SMII2			(VIRQ_START + 6)
-#define VIRQ_WAKEUP_SMII3			(VIRQ_START + 7)
+#define SPEAR310_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR310_VIRQ_SMII1			(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR310_VIRQ_SMII2			(SPEAR3XX_VIRQ_START + 2)
+#define SPEAR310_VIRQ_SMII3			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR310_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR310_VIRQ_WAKEUP_SMII1		(SPEAR3XX_VIRQ_START + 5)
+#define SPEAR310_VIRQ_WAKEUP_SMII2		(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR310_VIRQ_WAKEUP_SMII3		(SPEAR3XX_VIRQ_START + 7)
 
 /* IRQs sharing IRQ_GEN_RAS_2 */
-#define VIRQ_UART1				(VIRQ_START + 8)
-#define VIRQ_UART2				(VIRQ_START + 9)
-#define VIRQ_UART3				(VIRQ_START + 10)
-#define VIRQ_UART4				(VIRQ_START + 11)
-#define VIRQ_UART5				(VIRQ_START + 12)
+#define SPEAR310_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
+#define SPEAR310_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
+#define SPEAR310_VIRQ_UART3			(SPEAR3XX_VIRQ_START + 10)
+#define SPEAR310_VIRQ_UART4			(SPEAR3XX_VIRQ_START + 11)
+#define SPEAR310_VIRQ_UART5			(SPEAR3XX_VIRQ_START + 12)
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define VIRQ_EMI				(VIRQ_START + 13)
-#define VIRQ_PLGPIO				(VIRQ_START + 14)
+#define SPEAR310_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 13)
+#define SPEAR310_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 14)
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define VIRQ_TDM_HDLC				(VIRQ_START + 15)
-#define VIRQ_RS485_0				(VIRQ_START + 16)
-#define VIRQ_RS485_1				(VIRQ_START + 17)
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 18)
+#define SPEAR310_VIRQ_TDM_HDLC			(SPEAR3XX_VIRQ_START + 15)
+#define SPEAR310_VIRQ_RS485_0			(SPEAR3XX_VIRQ_START + 16)
+#define SPEAR310_VIRQ_RS485_1			(SPEAR3XX_VIRQ_START + 17)
 
 /* SPEAr320 Virtual irq definitions */
-#else
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_EMI				(VIRQ_START + 0)
-#define VIRQ_CLCD				(VIRQ_START + 1)
-#define VIRQ_SPP				(VIRQ_START + 2)
+#define SPEAR320_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR320_VIRQ_CLCD			(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR320_VIRQ_SPP			(SPEAR3XX_VIRQ_START + 2)
 
 /* IRQs sharing IRQ_GEN_RAS_2 */
-#define IRQ_SDHCI				IRQ_GEN_RAS_2
+#define SPEAR320_IRQ_SDHCI			SPEAR3XX_IRQ_GEN_RAS_2
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define VIRQ_PLGPIO				(VIRQ_START + 3)
-#define VIRQ_I2S_PLAY				(VIRQ_START + 4)
-#define VIRQ_I2S_REC				(VIRQ_START + 5)
+#define SPEAR320_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR320_VIRQ_I2S_PLAY			(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR320_VIRQ_I2S_REC			(SPEAR3XX_VIRQ_START + 5)
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define VIRQ_CANU				(VIRQ_START + 6)
-#define VIRQ_CANL				(VIRQ_START + 7)
-#define VIRQ_UART1				(VIRQ_START + 8)
-#define VIRQ_UART2				(VIRQ_START + 9)
-#define VIRQ_SSP1				(VIRQ_START + 10)
-#define VIRQ_SSP2				(VIRQ_START + 11)
-#define VIRQ_SMII0				(VIRQ_START + 12)
-#define VIRQ_MII1_SMII1				(VIRQ_START + 13)
-#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 14)
-#define VIRQ_WAKEUP_MII1_SMII1			(VIRQ_START + 15)
-#define VIRQ_I2C1				(VIRQ_START + 16)
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 17)
+#define SPEAR320_VIRQ_CANU			(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR320_VIRQ_CANL			(SPEAR3XX_VIRQ_START + 7)
+#define SPEAR320_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
+#define SPEAR320_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
+#define SPEAR320_VIRQ_SSP1			(SPEAR3XX_VIRQ_START + 10)
+#define SPEAR320_VIRQ_SSP2			(SPEAR3XX_VIRQ_START + 11)
+#define SPEAR320_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 12)
+#define SPEAR320_VIRQ_MII1_SMII1		(SPEAR3XX_VIRQ_START + 13)
+#define SPEAR320_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 14)
+#define SPEAR320_VIRQ_WAKEUP_MII1_SMII1		(SPEAR3XX_VIRQ_START + 15)
+#define SPEAR320_VIRQ_I2C1			(SPEAR3XX_VIRQ_START + 16)
 
+/*
+ * GPIO pins virtual irqs
+ * Use the lowest number for the GPIO virtual IRQs base on which subarchs
+ * we have compiled in
+ */
+#if defined(CONFIG_MACH_SPEAR310)
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 18)
+#elif defined(CONFIG_MACH_SPEAR320)
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 17)
+#else
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 9)
 #endif
 
-/* PLGPIO Virtual IRQs */
-#define SPEAR_PLGPIO_COUNT	102
+#define SPEAR300_GPIO1_INT_BASE			(SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_PLGPIO_COUNT	102
+
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-#define SPEAR_PLGPIO_INT_BASE	(SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END	(SPEAR_PLGPIO_INT_BASE + SPEAR_PLGPIO_COUNT)
+#define SPEAR3XX_PLGPIO_INT_BASE		(SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_GPIO_INT_END			(SPEAR3XX_PLGPIO_INT_BASE + \
+							SPEAR3XX_PLGPIO_COUNT)
+#else
+#define SPEAR3XX_GPIO_INT_END	(SPEAR300_GPIO1_INT_BASE + 8)
 #endif
 
-#define VIRQ_END		SPEAR_GPIO_INT_END
-#define NR_IRQS			VIRQ_END
+#define SPEAR3XX_VIRQ_END	SPEAR3XX_GPIO_INT_END
+#define NR_IRQS			SPEAR3XX_VIRQ_END
 
 #endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
index 4fd2d22..7d5db76 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear300.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -20,19 +20,19 @@
 #define SPEAR300_TELECOM_BASE		UL(0x50000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_ENB_MASK_REG		0x54
-#define INT_STS_MASK_REG		0x58
-#define IT_PERS_S_IRQ_MASK		(1 << 0)
-#define IT_CHANGE_S_IRQ_MASK		(1 << 1)
-#define I2S_IRQ_MASK			(1 << 2)
-#define TDM_IRQ_MASK			(1 << 3)
-#define CAMERA_L_IRQ_MASK		(1 << 4)
-#define CAMERA_F_IRQ_MASK		(1 << 5)
-#define CAMERA_V_IRQ_MASK		(1 << 6)
-#define KEYBOARD_IRQ_MASK		(1 << 7)
-#define GPIO1_IRQ_MASK			(1 << 8)
-
-#define SHIRQ_RAS1_MASK			0x1FF
+#define SPEAR300_INT_ENB_MASK_REG	0x54
+#define SPEAR300_INT_STS_MASK_REG	0x58
+#define SPEAR300_IT_PERS_S_IRQ_MASK	(1 << 0)
+#define SPEAR300_IT_CHANGE_S_IRQ_MASK	(1 << 1)
+#define SPEAR300_I2S_IRQ_MASK		(1 << 2)
+#define SPEAR300_TDM_IRQ_MASK		(1 << 3)
+#define SPEAR300_CAMERA_L_IRQ_MASK	(1 << 4)
+#define SPEAR300_CAMERA_F_IRQ_MASK	(1 << 5)
+#define SPEAR300_CAMERA_V_IRQ_MASK	(1 << 6)
+#define SPEAR300_KEYBOARD_IRQ_MASK	(1 << 7)
+#define SPEAR300_GPIO1_IRQ_MASK		(1 << 8)
+
+#define SPEAR300_SHIRQ_RAS1_MASK	0x1FF
 
 #define SPEAR300_CLCD_BASE		UL(0x60000000)
 #define SPEAR300_SDHCI_BASE		UL(0x70000000)
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
index 37556b6..0780c47 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear310.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -38,29 +38,29 @@
 #define SPEAR310_SOC_CONFIG_BASE	UL(0xB4000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_STS_MASK_REG		0x04
-#define SMII0_IRQ_MASK			(1 << 0)
-#define SMII1_IRQ_MASK			(1 << 1)
-#define SMII2_IRQ_MASK			(1 << 2)
-#define SMII3_IRQ_MASK			(1 << 3)
-#define WAKEUP_SMII0_IRQ_MASK		(1 << 4)
-#define WAKEUP_SMII1_IRQ_MASK		(1 << 5)
-#define WAKEUP_SMII2_IRQ_MASK		(1 << 6)
-#define WAKEUP_SMII3_IRQ_MASK		(1 << 7)
-#define UART1_IRQ_MASK			(1 << 8)
-#define UART2_IRQ_MASK			(1 << 9)
-#define UART3_IRQ_MASK			(1 << 10)
-#define UART4_IRQ_MASK			(1 << 11)
-#define UART5_IRQ_MASK			(1 << 12)
-#define EMI_IRQ_MASK			(1 << 13)
-#define TDM_HDLC_IRQ_MASK		(1 << 14)
-#define RS485_0_IRQ_MASK		(1 << 15)
-#define RS485_1_IRQ_MASK		(1 << 16)
+#define SPEAR310_INT_STS_MASK_REG	0x04
+#define SPEAR310_SMII0_IRQ_MASK		(1 << 0)
+#define SPEAR310_SMII1_IRQ_MASK		(1 << 1)
+#define SPEAR310_SMII2_IRQ_MASK		(1 << 2)
+#define SPEAR310_SMII3_IRQ_MASK		(1 << 3)
+#define SPEAR310_WAKEUP_SMII0_IRQ_MASK	(1 << 4)
+#define SPEAR310_WAKEUP_SMII1_IRQ_MASK	(1 << 5)
+#define SPEAR310_WAKEUP_SMII2_IRQ_MASK	(1 << 6)
+#define SPEAR310_WAKEUP_SMII3_IRQ_MASK	(1 << 7)
+#define SPEAR310_UART1_IRQ_MASK		(1 << 8)
+#define SPEAR310_UART2_IRQ_MASK		(1 << 9)
+#define SPEAR310_UART3_IRQ_MASK		(1 << 10)
+#define SPEAR310_UART4_IRQ_MASK		(1 << 11)
+#define SPEAR310_UART5_IRQ_MASK		(1 << 12)
+#define SPEAR310_EMI_IRQ_MASK		(1 << 13)
+#define SPEAR310_TDM_HDLC_IRQ_MASK	(1 << 14)
+#define SPEAR310_RS485_0_IRQ_MASK	(1 << 15)
+#define SPEAR310_RS485_1_IRQ_MASK	(1 << 16)
 
-#define SHIRQ_RAS1_MASK			0x000FF
-#define SHIRQ_RAS2_MASK			0x01F00
-#define SHIRQ_RAS3_MASK			0x02000
-#define SHIRQ_INTRCOMM_RAS_MASK		0x1C000
+#define SPEAR310_SHIRQ_RAS1_MASK	0x000FF
+#define SPEAR310_SHIRQ_RAS2_MASK	0x01F00
+#define SPEAR310_SHIRQ_RAS3_MASK	0x02000
+#define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK	0x1C000
 
 #endif /* __MACH_SPEAR310_H */
 
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index 4f60073..30ea941 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -42,31 +42,31 @@
 #define SPEAR320_SOC_CONFIG_BASE	UL(0xB3000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_STS_MASK_REG		0x04
-#define INT_CLR_MASK_REG		0x04
-#define INT_ENB_MASK_REG		0x08
-#define GPIO_IRQ_MASK			(1 << 0)
-#define I2S_PLAY_IRQ_MASK		(1 << 1)
-#define I2S_REC_IRQ_MASK		(1 << 2)
-#define EMI_IRQ_MASK			(1 << 7)
-#define CLCD_IRQ_MASK			(1 << 8)
-#define SPP_IRQ_MASK			(1 << 9)
-#define SDHCI_IRQ_MASK			(1 << 10)
-#define CAN_U_IRQ_MASK			(1 << 11)
-#define CAN_L_IRQ_MASK			(1 << 12)
-#define UART1_IRQ_MASK			(1 << 13)
-#define UART2_IRQ_MASK			(1 << 14)
-#define SSP1_IRQ_MASK			(1 << 15)
-#define SSP2_IRQ_MASK			(1 << 16)
-#define SMII0_IRQ_MASK			(1 << 17)
-#define MII1_SMII1_IRQ_MASK		(1 << 18)
-#define WAKEUP_SMII0_IRQ_MASK		(1 << 19)
-#define WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
-#define I2C1_IRQ_MASK			(1 << 21)
+#define SPEAR320_INT_STS_MASK_REG		0x04
+#define SPEAR320_INT_CLR_MASK_REG		0x04
+#define SPEAR320_INT_ENB_MASK_REG		0x08
+#define SPEAR320_GPIO_IRQ_MASK			(1 << 0)
+#define SPEAR320_I2S_PLAY_IRQ_MASK		(1 << 1)
+#define SPEAR320_I2S_REC_IRQ_MASK		(1 << 2)
+#define SPEAR320_EMI_IRQ_MASK			(1 << 7)
+#define SPEAR320_CLCD_IRQ_MASK			(1 << 8)
+#define SPEAR320_SPP_IRQ_MASK			(1 << 9)
+#define SPEAR320_SDHCI_IRQ_MASK			(1 << 10)
+#define SPEAR320_CAN_U_IRQ_MASK			(1 << 11)
+#define SPEAR320_CAN_L_IRQ_MASK			(1 << 12)
+#define SPEAR320_UART1_IRQ_MASK			(1 << 13)
+#define SPEAR320_UART2_IRQ_MASK			(1 << 14)
+#define SPEAR320_SSP1_IRQ_MASK			(1 << 15)
+#define SPEAR320_SSP2_IRQ_MASK			(1 << 16)
+#define SPEAR320_SMII0_IRQ_MASK			(1 << 17)
+#define SPEAR320_MII1_SMII1_IRQ_MASK		(1 << 18)
+#define SPEAR320_WAKEUP_SMII0_IRQ_MASK		(1 << 19)
+#define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
+#define SPEAR320_I2C1_IRQ_MASK			(1 << 21)
 
-#define SHIRQ_RAS1_MASK			0x000380
-#define SHIRQ_RAS3_MASK			0x000007
-#define SHIRQ_INTRCOMM_RAS_MASK		0x3FF800
+#define SPEAR320_SHIRQ_RAS1_MASK		0x000380
+#define SPEAR320_SHIRQ_RAS3_MASK		0x000007
+#define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK	0x3FF800
 
 #endif /* __MACH_SPEAR320_H */
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 9750875..c2d4a91 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -538,13 +538,13 @@ struct amba_device clcd_device = {
 		.flags = IORESOURCE_MEM,
 	},
 	.dma_mask = ~0,
-	.irq = {IRQ_CLCD, NO_IRQ},
+	.irq = {SPEAR300_IRQ_CLCD, NO_IRQ},
 };
 
 /* arm gpio1 device registeration */
 static struct pl061_platform_data gpio1_plat_data = {
 	.gpio_base	= 8,
-	.irq_base	= SPEAR_GPIO1_INT_BASE,
+	.irq_base	= SPEAR300_GPIO1_INT_BASE,
 };
 
 struct amba_device gpio1_device = {
@@ -557,7 +557,7 @@ struct amba_device gpio1_device = {
 		.end = SPEAR300_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_GPIO1, NO_IRQ},
+	.irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
 };
 
 /* keyboard device registration */
@@ -567,7 +567,7 @@ static struct resource kbd_resources[] = {
 		.end = SPEAR300_KEYBOARD_BASE + SZ_1K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_KEYBOARD,
+		.start = SPEAR300_VIRQ_KEYBOARD,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -683,7 +683,7 @@ static struct resource sdhci_resources[] = {
 		.end	= SPEAR300_SDHCI_BASE + SZ_256 - 1,
 		.flags	= IORESOURCE_MEM,
 	}, {
-		.start	= IRQ_SDHCI,
+		.start	= SPEAR300_IRQ_SDHCI,
 		.flags	= IORESOURCE_IRQ,
 	}
 };
@@ -701,53 +701,52 @@ struct platform_device sdhci_device = {
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_IT_PERS_S,
-		.enb_mask = IT_PERS_S_IRQ_MASK,
-		.status_mask = IT_PERS_S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_IT_PERS_S,
+		.enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
+		.status_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_IT_CHANGE_S,
-		.enb_mask = IT_CHANGE_S_IRQ_MASK,
-		.status_mask = IT_CHANGE_S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_IT_CHANGE_S,
+		.enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
+		.status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S,
-		.enb_mask = I2S_IRQ_MASK,
-		.status_mask = I2S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_I2S,
+		.enb_mask = SPEAR300_I2S_IRQ_MASK,
+		.status_mask = SPEAR300_I2S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_TDM,
-		.enb_mask = TDM_IRQ_MASK,
-		.status_mask = TDM_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_TDM,
+		.enb_mask = SPEAR300_TDM_IRQ_MASK,
+		.status_mask = SPEAR300_TDM_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_L,
-		.enb_mask = CAMERA_L_IRQ_MASK,
-		.status_mask = CAMERA_L_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_L,
+		.enb_mask = SPEAR300_CAMERA_L_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_L_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_F,
-		.enb_mask = CAMERA_F_IRQ_MASK,
-		.status_mask = CAMERA_F_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_F,
+		.enb_mask = SPEAR300_CAMERA_F_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_F_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_V,
-		.enb_mask = CAMERA_V_IRQ_MASK,
-		.status_mask = CAMERA_V_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_V,
+		.enb_mask = SPEAR300_CAMERA_V_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_V_IRQ_MASK,
 	}, {
-		.virq = VIRQ_KEYBOARD,
-		.enb_mask = KEYBOARD_IRQ_MASK,
-		.status_mask = KEYBOARD_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_KEYBOARD,
+		.enb_mask = SPEAR300_KEYBOARD_IRQ_MASK,
+		.status_mask = SPEAR300_KEYBOARD_IRQ_MASK,
 	}, {
-		.virq = VIRQ_GPIO1,
-		.enb_mask = GPIO1_IRQ_MASK,
-		.status_mask = GPIO1_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_GPIO1,
+		.enb_mask = SPEAR300_GPIO1_IRQ_MASK,
+		.status_mask = SPEAR300_GPIO1_IRQ_MASK,
 	},
 };
 
-
 static struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
-		.enb_reg = INT_ENB_MASK_REG,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.enb_reg = SPEAR300_INT_ENB_MASK_REG,
+		.status_reg = SPEAR300_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK,
 		.clear_reg = -1,
 	},
 };
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 5c913f5..7a3903a 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -205,7 +205,7 @@ struct amba_device uart1_device = {
 		.end = SPEAR310_UART1_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART1, NO_IRQ},
+	.irq = {SPEAR310_VIRQ_UART1, NO_IRQ},
 };
 
 /* uart2 device registeration */
@@ -218,7 +218,7 @@ struct amba_device uart2_device = {
 		.end = SPEAR310_UART2_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART2, NO_IRQ},
+	.irq = {SPEAR310_VIRQ_UART2, NO_IRQ},
 };
 
 /* uart3 device registeration */
@@ -231,7 +231,7 @@ struct amba_device uart3_device = {
 		.end = SPEAR310_UART3_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART3, NO_IRQ},
+	.irq = {SPEAR310_VIRQ_UART3, NO_IRQ},
 };
 
 /* uart4 device registeration */
@@ -244,7 +244,7 @@ struct amba_device uart4_device = {
 		.end = SPEAR310_UART4_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART4, NO_IRQ},
+	.irq = {SPEAR310_VIRQ_UART4, NO_IRQ},
 };
 
 /* uart5 device registeration */
@@ -257,7 +257,7 @@ struct amba_device uart5_device = {
 		.end = SPEAR310_UART5_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART5, NO_IRQ},
+	.irq = {SPEAR310_VIRQ_UART5, NO_IRQ},
 };
 
 /* nand device registeration */
@@ -342,8 +342,8 @@ struct platform_device emi_nor_device = {
 
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
-	.irq_base = SPEAR_PLGPIO_INT_BASE,
-	.gpio_count = SPEAR_PLGPIO_COUNT,
+	.irq_base = SPEAR3XX_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR3XX_PLGPIO_COUNT,
 	.p2o = spear300_p2o,
 	.o2p = spear300_o2p,
 	/* list of registers with inconsistency */
@@ -357,7 +357,7 @@ static struct resource plgpio_resources[] = {
 		.end = SPEAR310_SOC_CONFIG_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_PLGPIO,
+		.start = SPEAR310_VIRQ_PLGPIO,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -376,115 +376,115 @@ struct platform_device plgpio_device = {
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_SMII0,
-		.status_mask = SMII0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII0,
+		.status_mask = SPEAR310_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII1,
-		.status_mask = SMII1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII1,
+		.status_mask = SPEAR310_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII2,
-		.status_mask = SMII2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII2,
+		.status_mask = SPEAR310_SMII2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII3,
-		.status_mask = SMII3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII3,
+		.status_mask = SPEAR310_SMII3_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII0,
-		.status_mask = WAKEUP_SMII0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII0,
+		.status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII1,
-		.status_mask = WAKEUP_SMII1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII1,
+		.status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII2,
-		.status_mask = WAKEUP_SMII2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII2,
+		.status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII3,
-		.status_mask = WAKEUP_SMII3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII3,
+		.status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK,
 		.clear_reg = -1,
 	},
 };
 
 static struct shirq_dev_config shirq_ras2_config[] = {
 	{
-		.virq = VIRQ_UART1,
-		.status_mask = UART1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART1,
+		.status_mask = SPEAR310_UART1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART2,
-		.status_mask = UART2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART2,
+		.status_mask = SPEAR310_UART2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART3,
-		.status_mask = UART3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART3,
+		.status_mask = SPEAR310_UART3_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART4,
-		.status_mask = UART4_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART4,
+		.status_mask = SPEAR310_UART4_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART5,
-		.status_mask = UART5_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART5,
+		.status_mask = SPEAR310_UART5_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_ras2 = {
-	.irq = IRQ_GEN_RAS_2,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_2,
 	.dev_config = shirq_ras2_config,
 	.dev_count = ARRAY_SIZE(shirq_ras2_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS2_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK,
 		.clear_reg = -1,
 	},
 };
 
 static struct shirq_dev_config shirq_ras3_config[] = {
 	{
-		.virq = VIRQ_EMI,
-		.status_mask = EMI_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_EMI,
+		.status_mask = SPEAR310_EMI_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_ras3 = {
-	.irq = IRQ_GEN_RAS_3,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS3_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK,
 		.clear_reg = -1,
 	},
 };
 
 static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
-		.virq = VIRQ_TDM_HDLC,
-		.status_mask = TDM_HDLC_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_TDM_HDLC,
+		.status_mask = SPEAR310_TDM_HDLC_IRQ_MASK,
 	}, {
-		.virq = VIRQ_RS485_0,
-		.status_mask = RS485_0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_RS485_0,
+		.status_mask = SPEAR310_RS485_0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_RS485_1,
-		.status_mask = RS485_1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_RS485_1,
+		.status_mask = SPEAR310_RS485_1_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_intrcomm_ras = {
-	.irq = IRQ_INTRCOMM_RAS_ARM,
+	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK,
 		.clear_reg = -1,
 	},
 };
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index d39fda3..7470870 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -606,7 +606,7 @@ struct amba_device clcd_device = {
 		.flags = IORESOURCE_MEM,
 	},
 	.dma_mask = ~0,
-	.irq = {VIRQ_CLCD, NO_IRQ},
+	.irq = {SPEAR320_VIRQ_CLCD, NO_IRQ},
 };
 
 /* ssp device registeration */
@@ -634,7 +634,7 @@ struct amba_device ssp_device[] = {
 			.end = SPEAR320_SSP0_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {VIRQ_SSP1, NO_IRQ},
+		.irq = {SPEAR320_VIRQ_SSP1, NO_IRQ},
 	}, {
 		.dev = {
 			.coherent_dma_mask = ~0,
@@ -646,7 +646,7 @@ struct amba_device ssp_device[] = {
 			.end = SPEAR320_SSP1_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {VIRQ_SSP2, NO_IRQ},
+		.irq = {SPEAR320_VIRQ_SSP2, NO_IRQ},
 	}
 };
 
@@ -660,7 +660,7 @@ struct amba_device uart1_device = {
 		.end = SPEAR320_UART1_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART1, NO_IRQ},
+	.irq = {SPEAR320_VIRQ_UART1, NO_IRQ},
 };
 
 /* uart2 device registeration */
@@ -673,7 +673,7 @@ struct amba_device uart2_device = {
 		.end = SPEAR320_UART2_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_UART2, NO_IRQ},
+	.irq = {SPEAR320_VIRQ_UART2, NO_IRQ},
 };
 
 /* emi nor flash device registeration */
@@ -698,8 +698,8 @@ struct platform_device emi_nor_device = {
 /* plgpio device registeration */
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
-	.irq_base = SPEAR_PLGPIO_INT_BASE,
-	.gpio_count = SPEAR_PLGPIO_COUNT,
+	.irq_base = SPEAR3XX_PLGPIO_INT_BASE,
+	.gpio_count = SPEAR3XX_PLGPIO_COUNT,
 };
 
 /* CAN device registeration */
@@ -709,7 +709,7 @@ static struct resource can0_resources[] = {
 		.end = SPEAR320_CAN0_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_CANU,
+		.start = SPEAR320_VIRQ_CANU,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -727,7 +727,7 @@ static struct resource can1_resources[] = {
 		.end = SPEAR320_CAN1_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_CANL,
+		.start = SPEAR320_VIRQ_CANL,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -746,7 +746,7 @@ static struct resource i2c1_resources[] = {
 		.end = SPEAR320_I2C_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_I2C1 ,
+		.start = SPEAR320_VIRQ_I2C1 ,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -792,7 +792,7 @@ static struct resource plgpio_resources[] = {
 		.end = SPEAR320_SOC_CONFIG_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = VIRQ_PLGPIO,
+		.start = SPEAR320_VIRQ_PLGPIO,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -830,7 +830,7 @@ static struct resource sdhci_resources[] = {
 		.end	= SPEAR320_SDHCI_BASE + SZ_256 - 1,
 		.flags	= IORESOURCE_MEM,
 	}, {
-		.start	= IRQ_SDHCI,
+		.start	= SPEAR320_IRQ_SDHCI,
 		.flags	= IORESOURCE_IRQ,
 	}
 };
@@ -848,123 +848,123 @@ struct platform_device sdhci_device = {
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_EMI,
-		.status_mask = EMI_IRQ_MASK,
-		.clear_mask = EMI_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_EMI,
+		.status_mask = SPEAR320_EMI_IRQ_MASK,
+		.clear_mask = SPEAR320_EMI_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CLCD,
-		.status_mask = CLCD_IRQ_MASK,
-		.clear_mask = CLCD_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CLCD,
+		.status_mask = SPEAR320_CLCD_IRQ_MASK,
+		.clear_mask = SPEAR320_CLCD_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SPP,
-		.status_mask = SPP_IRQ_MASK,
-		.clear_mask = SPP_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SPP,
+		.status_mask = SPEAR320_SPP_IRQ_MASK,
+		.clear_mask = SPEAR320_SPP_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
 
 static struct shirq_dev_config shirq_ras3_config[] = {
 	{
-		.virq = VIRQ_PLGPIO,
-		.enb_mask = GPIO_IRQ_MASK,
-		.status_mask = GPIO_IRQ_MASK,
-		.clear_mask = GPIO_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_PLGPIO,
+		.enb_mask = SPEAR320_GPIO_IRQ_MASK,
+		.status_mask = SPEAR320_GPIO_IRQ_MASK,
+		.clear_mask = SPEAR320_GPIO_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S_PLAY,
-		.enb_mask = I2S_PLAY_IRQ_MASK,
-		.status_mask = I2S_PLAY_IRQ_MASK,
-		.clear_mask = I2S_PLAY_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2S_PLAY,
+		.enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+		.status_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+		.clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S_REC,
-		.enb_mask = I2S_REC_IRQ_MASK,
-		.status_mask = I2S_REC_IRQ_MASK,
-		.clear_mask = I2S_REC_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2S_REC,
+		.enb_mask = SPEAR320_I2S_REC_IRQ_MASK,
+		.status_mask = SPEAR320_I2S_REC_IRQ_MASK,
+		.clear_mask = SPEAR320_I2S_REC_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_ras3 = {
-	.irq = IRQ_GEN_RAS_3,
+	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
 	.regs = {
-		.enb_reg = INT_ENB_MASK_REG,
+		.enb_reg = SPEAR320_INT_ENB_MASK_REG,
 		.reset_to_enb = 1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS3_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
 
 static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
-		.virq = VIRQ_CANU,
-		.status_mask = CAN_U_IRQ_MASK,
-		.clear_mask = CAN_U_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CANU,
+		.status_mask = SPEAR320_CAN_U_IRQ_MASK,
+		.clear_mask = SPEAR320_CAN_U_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CANL,
-		.status_mask = CAN_L_IRQ_MASK,
-		.clear_mask = CAN_L_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CANL,
+		.status_mask = SPEAR320_CAN_L_IRQ_MASK,
+		.clear_mask = SPEAR320_CAN_L_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART1,
-		.status_mask = UART1_IRQ_MASK,
-		.clear_mask = UART1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_UART1,
+		.status_mask = SPEAR320_UART1_IRQ_MASK,
+		.clear_mask = SPEAR320_UART1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART2,
-		.status_mask = UART2_IRQ_MASK,
-		.clear_mask = UART2_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_UART2,
+		.status_mask = SPEAR320_UART2_IRQ_MASK,
+		.clear_mask = SPEAR320_UART2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SSP1,
-		.status_mask = SSP1_IRQ_MASK,
-		.clear_mask = SSP1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SSP1,
+		.status_mask = SPEAR320_SSP1_IRQ_MASK,
+		.clear_mask = SPEAR320_SSP1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SSP2,
-		.status_mask = SSP2_IRQ_MASK,
-		.clear_mask = SSP2_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SSP2,
+		.status_mask = SPEAR320_SSP2_IRQ_MASK,
+		.clear_mask = SPEAR320_SSP2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII0,
-		.status_mask = SMII0_IRQ_MASK,
-		.clear_mask = SMII0_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SMII0,
+		.status_mask = SPEAR320_SMII0_IRQ_MASK,
+		.clear_mask = SPEAR320_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_MII1_SMII1,
-		.status_mask = MII1_SMII1_IRQ_MASK,
-		.clear_mask = MII1_SMII1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_MII1_SMII1,
+		.status_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
+		.clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII0,
-		.status_mask = WAKEUP_SMII0_IRQ_MASK,
-		.clear_mask = WAKEUP_SMII0_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_WAKEUP_SMII0,
+		.status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
+		.clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_MII1_SMII1,
-		.status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
-		.clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1,
+		.status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
+		.clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2C1,
-		.status_mask = I2C1_IRQ_MASK,
-		.clear_mask = I2C1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2C1,
+		.status_mask = SPEAR320_I2C1_IRQ_MASK,
+		.clear_mask = SPEAR320_I2C1_IRQ_MASK,
 	},
 };
 
 static struct spear_shirq shirq_intrcomm_ras = {
-	.irq = IRQ_INTRCOMM_RAS_ARM,
+	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 1e2371f..46093e2 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -22,13 +22,14 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 
-#define SPEAR3XX_WKUP_SRCS	(1 << IRQ_MAC_1 | 1 << IRQ_USB_DEV | \
-				1 << IRQ_BASIC_RTC | 1 << IRQ_BASIC_GPIO)
+#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 registeration */
 static struct pl061_platform_data gpio_plat_data = {
 	.gpio_base	= 0,
-	.irq_base	= SPEAR_GPIO_INT_BASE,
+	.irq_base	= SPEAR3XX_GPIO_INT_BASE,
 };
 
 struct amba_device gpio_device = {
@@ -41,7 +42,7 @@ struct amba_device gpio_device = {
 		.end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_BASIC_GPIO, NO_IRQ},
+	.irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
 };
 
 /* ssp device registeration */
@@ -71,7 +72,7 @@ struct amba_device ssp0_device = {
 		.end = SPEAR3XX_ICM1_SSP_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_SSP, NO_IRQ},
+	.irq = {SPEAR3XX_IRQ_SSP, NO_IRQ},
 };
 
 /* uart device registeration */
@@ -84,7 +85,7 @@ struct amba_device uart_device = {
 		.end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_UART, NO_IRQ},
+	.irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
 };
 
 /* watchdog device registeration */
@@ -106,7 +107,7 @@ static struct resource i2c_resources[] = {
 		.end = SPEAR3XX_ICM1_I2C_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = IRQ_I2C,
+		.start = SPEAR3XX_IRQ_I2C,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -129,7 +130,7 @@ static struct resource ehci_resources[] = {
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = IRQ_USB_H_EHCI_0,
+		.start = SPEAR3XX_IRQ_USB_H_EHCI_0,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -141,7 +142,7 @@ static struct resource ohci0_resources[] = {
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = IRQ_USB_H_OHCI_0,
+		.start = SPEAR3XX_IRQ_USB_H_OHCI_0,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -153,7 +154,7 @@ static struct resource ohci1_resources[] = {
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = IRQ_USB_H_OHCI_1,
+		.start = SPEAR3XX_IRQ_USB_H_OHCI_1,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -208,7 +209,7 @@ static struct resource rtc_resources[] = {
 		.end = SPEAR3XX_ICM3_RTC_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = IRQ_BASIC_RTC,
+		.start = SPEAR3XX_IRQ_BASIC_RTC,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -227,7 +228,7 @@ static struct resource smi_resources[] = {
 		.end = SPEAR3XX_ICM3_SMI_CTRL_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = IRQ_BASIC_SMI,
+		.start = SPEAR3XX_IRQ_BASIC_SMI,
 		.flags = IORESOURCE_IRQ,
 	},
 };
-- 
1.7.2.2

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

* [PATCH 63/74] SPEAr3xx: Rework pmx_dev code to remove conflicts
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (53 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 62/74] SPEAR3xx: Rename register/irq defines to remove naming conflicts Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 64/74] SPEAr3xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
                   ` (19 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ryan Mallon <ryan@bluewatersys.com>

Prefix the pmx_devs to remove naming conflicts between the three
SPEAr3xx platforms. Also make pmx_driver static to each platform and
rework the init code to pass the devices rather than export the
pmx_driver structure.

Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |  129 +++++++++++++------------
 arch/arm/mach-spear3xx/spear300.c             |   40 ++++----
 arch/arm/mach-spear3xx/spear300_evb.c         |   25 ++---
 arch/arm/mach-spear3xx/spear310.c             |   28 +++---
 arch/arm/mach-spear3xx/spear310_evb.c         |   41 ++++-----
 arch/arm/mach-spear3xx/spear320.c             |   56 ++++++-----
 arch/arm/mach-spear3xx/spear320_evb.c         |   35 +++----
 arch/arm/mach-spear3xx/spear3xx.c             |   60 ++++++------
 8 files changed, 206 insertions(+), 208 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 896c1b0..6f4b90d 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -71,21 +71,21 @@ void spear3xx_pmx_init_addr(struct pmx_driver *driver, unsigned int addr);
 #define PMX_TIMER_1_2_MASK	(1 << 0)
 
 /* pad mux devices */
-extern struct pmx_dev pmx_firda;
-extern struct pmx_dev pmx_i2c;
-extern struct pmx_dev pmx_ssp_cs;
-extern struct pmx_dev pmx_ssp;
-extern struct pmx_dev pmx_mii;
-extern struct pmx_dev pmx_gpio_pin0;
-extern struct pmx_dev pmx_gpio_pin1;
-extern struct pmx_dev pmx_gpio_pin2;
-extern struct pmx_dev pmx_gpio_pin3;
-extern struct pmx_dev pmx_gpio_pin4;
-extern struct pmx_dev pmx_gpio_pin5;
-extern struct pmx_dev pmx_uart0_modem;
-extern struct pmx_dev pmx_uart0;
-extern struct pmx_dev pmx_timer_3_4;
-extern struct pmx_dev pmx_timer_1_2;
+extern struct pmx_dev spear3xx_pmx_firda;
+extern struct pmx_dev spear3xx_pmx_i2c;
+extern struct pmx_dev spear3xx_pmx_ssp_cs;
+extern struct pmx_dev spear3xx_pmx_ssp;
+extern struct pmx_dev spear3xx_pmx_mii;
+extern struct pmx_dev spear3xx_pmx_gpio_pin0;
+extern struct pmx_dev spear3xx_pmx_gpio_pin1;
+extern struct pmx_dev spear3xx_pmx_gpio_pin2;
+extern struct pmx_dev spear3xx_pmx_gpio_pin3;
+extern struct pmx_dev spear3xx_pmx_gpio_pin4;
+extern struct pmx_dev spear3xx_pmx_gpio_pin5;
+extern struct pmx_dev spear3xx_pmx_uart0_modem;
+extern struct pmx_dev spear3xx_pmx_uart0;
+extern struct pmx_dev spear3xx_pmx_timer_3_4;
+extern struct pmx_dev spear3xx_pmx_timer_1_2;
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 /* padmux plgpio devices */
@@ -106,8 +106,6 @@ extern struct pmx_dev pmx_plgpio_43_44_47_48;
 extern struct pmx_dev pmx_plgpio_45_46_49_50;
 #endif
 
-extern struct pmx_driver pmx_driver;
-
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
 /* Add spear300 machine device structure declarations here */
@@ -136,27 +134,28 @@ extern struct pmx_mode camu_wlcd_mode;
 extern struct pmx_mode caml_lcd_mode;
 
 /* pad mux devices */
-extern struct pmx_dev pmx_fsmc_2_chips;
-extern struct pmx_dev pmx_fsmc_4_chips;
-extern struct pmx_dev pmx_keyboard;
-extern struct pmx_dev pmx_clcd;
-extern struct pmx_dev pmx_telecom_gpio;
-extern struct pmx_dev pmx_telecom_tdm;
-extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk;
-extern struct pmx_dev pmx_telecom_camera;
-extern struct pmx_dev pmx_telecom_dac;
-extern struct pmx_dev pmx_telecom_i2s;
-extern struct pmx_dev pmx_telecom_boot_pins;
-extern struct pmx_dev pmx_telecom_sdhci_4bit;
-extern struct pmx_dev pmx_telecom_sdhci_8bit;
-extern struct pmx_dev pmx_gpio1;
+extern struct pmx_dev spear300_pmx_fsmc_2_chips;
+extern struct pmx_dev spear300_pmx_fsmc_4_chips;
+extern struct pmx_dev spear300_pmx_keyboard;
+extern struct pmx_dev spear300_pmx_clcd;
+extern struct pmx_dev spear300_pmx_telecom_gpio;
+extern struct pmx_dev spear300_pmx_telecom_tdm;
+extern struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk;
+extern struct pmx_dev spear300_pmx_telecom_camera;
+extern struct pmx_dev spear300_pmx_telecom_dac;
+extern struct pmx_dev spear300_pmx_telecom_i2s;
+extern struct pmx_dev spear300_pmx_telecom_boot_pins;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_4bit;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_8bit;
+extern struct pmx_dev spear300_pmx_gpio1;
 
 /* pad multiplexing support */
 #define SPEAR300_PAD_MUX_CONFIG_REG	0x99000000
 #define SPEAR300_MODE_CONFIG_REG	0x99000004
 
 /* Add spear300 machine function declarations here */
-void __init spear300_init(void);
+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
 void sdhci_i2s_mem_enable(u8 mask);
@@ -177,18 +176,19 @@ extern struct platform_device plgpio_device;
 extern struct platform_device nand_device;
 
 /* pad mux devices */
-extern struct pmx_dev pmx_emi_cs_0_1_4_5;
-extern struct pmx_dev pmx_emi_cs_2_3;
-extern struct pmx_dev pmx_uart1;
-extern struct pmx_dev pmx_uart2;
-extern struct pmx_dev pmx_uart3_4_5;
-extern struct pmx_dev pmx_fsmc;
-extern struct pmx_dev pmx_rs485_0_1;
-extern struct pmx_dev pmx_tdm0;
+extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
+extern struct pmx_dev spear310_pmx_emi_cs_2_3;
+extern struct pmx_dev spear310_pmx_uart1;
+extern struct pmx_dev spear310_pmx_uart2;
+extern struct pmx_dev spear310_pmx_uart3_4_5;
+extern struct pmx_dev spear310_pmx_fsmc;
+extern struct pmx_dev spear310_pmx_rs485_0_1;
+extern struct pmx_dev spear310_pmx_tdm0;
 #define SPEAR310_PAD_MUX_CONFIG_REG	0xB4000008
 
 /* Add spear310 machine function declarations here */
-void __init spear310_init(void);
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 /* spear320 declarations */
 #elif defined(CONFIG_MACH_SPEAR320)
@@ -213,35 +213,36 @@ extern struct pmx_mode auto_exp_mode;
 extern struct pmx_mode small_printers_mode;
 
 /* pad mux devices */
-extern struct pmx_dev pmx_clcd;
-extern struct pmx_dev pmx_emi;
-extern struct pmx_dev pmx_fsmc;
-extern struct pmx_dev pmx_spp;
-extern struct pmx_dev pmx_sdhci;
-extern struct pmx_dev pmx_i2s;
-extern struct pmx_dev pmx_uart1;
-extern struct pmx_dev pmx_uart1_modem;
-extern struct pmx_dev pmx_uart2;
-extern struct pmx_dev pmx_touchscreen;
-extern struct pmx_dev pmx_can;
-extern struct pmx_dev pmx_sdhci_led;
-extern struct pmx_dev pmx_pwm0;
-extern struct pmx_dev pmx_pwm1;
-extern struct pmx_dev pmx_pwm2;
-extern struct pmx_dev pmx_pwm3;
-extern struct pmx_dev pmx_ssp1;
-extern struct pmx_dev pmx_ssp2;
-extern struct pmx_dev pmx_mii1;
-extern struct pmx_dev pmx_smii0;
-extern struct pmx_dev pmx_smii1;
-extern struct pmx_dev pmx_i2c1;
+extern struct pmx_dev spear320_pmx_clcd;
+extern struct pmx_dev spear320_pmx_emi;
+extern struct pmx_dev spear320_pmx_fsmc;
+extern struct pmx_dev spear320_pmx_spp;
+extern struct pmx_dev spear320_pmx_sdhci;
+extern struct pmx_dev spear320_pmx_i2s;
+extern struct pmx_dev spear320_pmx_uart1;
+extern struct pmx_dev spear320_pmx_uart1_modem;
+extern struct pmx_dev spear320_pmx_uart2;
+extern struct pmx_dev spear320_pmx_touchscreen;
+extern struct pmx_dev spear320_pmx_can;
+extern struct pmx_dev spear320_pmx_sdhci_led;
+extern struct pmx_dev spear320_pmx_pwm0;
+extern struct pmx_dev spear320_pmx_pwm1;
+extern struct pmx_dev spear320_pmx_pwm2;
+extern struct pmx_dev spear320_pmx_pwm3;
+extern struct pmx_dev spear320_pmx_ssp1;
+extern struct pmx_dev spear320_pmx_ssp2;
+extern struct pmx_dev spear320_pmx_mii1;
+extern struct pmx_dev spear320_pmx_smii0;
+extern struct pmx_dev spear320_pmx_smii1;
+extern struct pmx_dev spear320_pmx_i2c1;
 
 /* pad multiplexing support */
 #define SPEAR320_PAD_MUX_CONFIG_REG	0xB300000C
 #define SPEAR320_MODE_CONFIG_REG	0xB3000010
 
 /* Add spear320 machine function declarations here */
-void __init spear320_init(void);
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index c2d4a91..272cd80 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -131,7 +131,7 @@ static struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_fsmc_2_chips = {
+struct pmx_dev spear300_pmx_fsmc_2_chips = {
 	.name = "fsmc_2_chips",
 	.modes = pmx_fsmc_2_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
@@ -154,7 +154,7 @@ static struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_fsmc_4_chips = {
+struct pmx_dev spear300_pmx_fsmc_4_chips = {
 	.name = "fsmc_4_chips",
 	.modes = pmx_fsmc_4_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
@@ -179,7 +179,7 @@ static struct pmx_dev_mode pmx_keyboard_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_keyboard = {
+struct pmx_dev spear300_pmx_keyboard = {
 	.name = "keyboard",
 	.modes = pmx_keyboard_modes,
 	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
@@ -213,7 +213,7 @@ static struct pmx_dev_mode pmx_clcd_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_clcd = {
+struct pmx_dev spear300_pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
@@ -280,7 +280,7 @@ static struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_gpio = {
+struct pmx_dev spear300_pmx_telecom_gpio = {
 	.name = "telecom_gpio",
 	.modes = pmx_telecom_gpio_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
@@ -306,7 +306,7 @@ static struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_tdm = {
+struct pmx_dev spear300_pmx_telecom_tdm = {
 	.name = "telecom_tdm",
 	.modes = pmx_telecom_tdm_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
@@ -331,7 +331,7 @@ static struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
+struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk = {
 	.name = "telecom_spi_cs_i2c_clk",
 	.modes = pmx_telecom_spi_cs_i2c_clk_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
@@ -363,7 +363,7 @@ static struct pmx_dev_mode pmx_telecom_camera_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_camera = {
+struct pmx_dev spear300_pmx_telecom_camera = {
 	.name = "telecom_camera",
 	.modes = pmx_telecom_camera_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
@@ -386,7 +386,7 @@ static struct pmx_dev_mode pmx_telecom_dac_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_dac = {
+struct pmx_dev spear300_pmx_telecom_dac = {
 	.name = "telecom_dac",
 	.modes = pmx_telecom_dac_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
@@ -411,7 +411,7 @@ static struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_i2s = {
+struct pmx_dev spear300_pmx_telecom_i2s = {
 	.name = "telecom_i2s",
 	.modes = pmx_telecom_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
@@ -434,7 +434,7 @@ static struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_boot_pins = {
+struct pmx_dev spear300_pmx_telecom_boot_pins = {
 	.name = "telecom_boot_pins",
 	.modes = pmx_telecom_boot_pins_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
@@ -462,7 +462,7 @@ static struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_sdhci_4bit = {
+struct pmx_dev spear300_pmx_telecom_sdhci_4bit = {
 	.name = "telecom_sdhci_4bit",
 	.modes = pmx_telecom_sdhci_4bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
@@ -489,7 +489,7 @@ static struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_telecom_sdhci_8bit = {
+struct pmx_dev spear300_pmx_telecom_sdhci_8bit = {
 	.name = "telecom_sdhci_8bit",
 	.modes = pmx_telecom_sdhci_8bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
@@ -512,14 +512,14 @@ static struct pmx_dev_mode pmx_gpio1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio1 = {
+struct pmx_dev spear300_pmx_gpio1 = {
 	.name = "arm gpio1",
 	.modes = pmx_gpio1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio1_modes),
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
+static struct pmx_driver pmx_driver = {
 	.mode_reg = {.address = SPEAR300_MODE_CONFIG_REG, .mask = 0x0000000f},
 };
 
@@ -773,7 +773,8 @@ void sdhci_i2s_mem_enable(u8 mask)
 }
 
 /* spear300 routines */
-void __init spear300_init(void)
+void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	int ret = 0;
 
@@ -788,10 +789,13 @@ void __init spear300_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ\n");
 	}
 
+	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	/* This fixes addresses of all pmx devices for spear300 */
 	spear3xx_pmx_init_addr(&pmx_driver, SPEAR300_PAD_MUX_CONFIG_REG);
-
-	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		pr_err("padmux: registeration failed. err no: %d\n", ret);
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 1bcbd95..d8a22fd 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -28,17 +28,17 @@
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp_cs,
-	&pmx_ssp,
-	&pmx_mii,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp_cs,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_mii,
+	&spear3xx_pmx_uart0,
 
 	/* spear300 specific devices */
-	&pmx_fsmc_2_chips,
-	&pmx_clcd,
-	&pmx_telecom_sdhci_4bit,
-	&pmx_gpio1,
+	&spear300_pmx_fsmc_2_chips,
+	&spear300_pmx_clcd,
+	&spear300_pmx_telecom_sdhci_4bit,
+	&spear300_pmx_gpio1,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -130,11 +130,6 @@ static void __init spi_init(void)
 
 static void __init spear300_evb_init(void)
 {
-	/* padmux initialization, must be done before spear300_init */
-	pmx_driver.mode = &photo_frame_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
@@ -149,7 +144,7 @@ static void __init spear300_evb_init(void)
 	sdhci_i2s_mem_enable(SDHCI_MEM_ENB);
 
 	/* call spear300 machine init function */
-	spear300_init();
+	spear300_init(&photo_frame_mode, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 7a3903a..71f1148 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -38,7 +38,7 @@ static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_emi_cs_0_1_4_5 = {
+struct pmx_dev spear310_pmx_emi_cs_0_1_4_5 = {
 	.name = "emi_cs_0_1_4_5",
 	.modes = pmx_emi_cs_0_1_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
@@ -59,7 +59,7 @@ static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_emi_cs_2_3 = {
+struct pmx_dev spear310_pmx_emi_cs_2_3 = {
 	.name = "emi_cs_2_3",
 	.modes = pmx_emi_cs_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
@@ -80,7 +80,7 @@ static struct pmx_dev_mode pmx_uart1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart1 = {
+struct pmx_dev spear310_pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
@@ -101,7 +101,7 @@ static struct pmx_dev_mode pmx_uart2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart2 = {
+struct pmx_dev spear310_pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
@@ -122,7 +122,7 @@ static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart3_4_5 = {
+struct pmx_dev spear310_pmx_uart3_4_5 = {
 	.name = "uart3_4_5",
 	.modes = pmx_uart3_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
@@ -143,7 +143,7 @@ static struct pmx_dev_mode pmx_fsmc_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_fsmc = {
+struct pmx_dev spear310_pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
@@ -164,7 +164,7 @@ static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_rs485_0_1 = {
+struct pmx_dev spear310_pmx_rs485_0_1 = {
 	.name = "rs485_0_1",
 	.modes = pmx_rs485_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
@@ -185,14 +185,14 @@ static struct pmx_dev_mode pmx_tdm0_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_tdm0 = {
+struct pmx_dev spear310_pmx_tdm0 = {
 	.name = "tdm0",
 	.modes = pmx_tdm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_tdm0_modes),
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver;
+static struct pmx_driver pmx_driver;
 
 /* Add spear310 specific devices here */
 /* uart1 device registeration */
@@ -490,7 +490,8 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* spear310 routines */
-void __init spear310_init(void)
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	void __iomem *base;
 	int ret = 0;
@@ -526,10 +527,13 @@ void __init spear310_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
 
+	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	/* This fixes addresses of all pmx devices for spear310 */
 	spear3xx_pmx_init_addr(&pmx_driver, SPEAR310_PAD_MUX_CONFIG_REG);
-
-	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		pr_err("padmux: registeration failed. err no: %d\n", ret);
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 64d06f1..a306647 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -36,25 +36,25 @@ static struct mtd_partition partition_info[] = {
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp,
-	&pmx_gpio_pin0,
-	&pmx_gpio_pin1,
-	&pmx_gpio_pin2,
-	&pmx_gpio_pin3,
-	&pmx_gpio_pin4,
-	&pmx_gpio_pin5,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_gpio_pin0,
+	&spear3xx_pmx_gpio_pin1,
+	&spear3xx_pmx_gpio_pin2,
+	&spear3xx_pmx_gpio_pin3,
+	&spear3xx_pmx_gpio_pin4,
+	&spear3xx_pmx_gpio_pin5,
+	&spear3xx_pmx_uart0,
 
 	/* spear310 specific devices */
-	&pmx_emi_cs_0_1_4_5,
-	&pmx_emi_cs_2_3,
-	&pmx_uart1,
-	&pmx_uart2,
-	&pmx_uart3_4_5,
-	&pmx_fsmc,
-	&pmx_rs485_0_1,
-	&pmx_tdm0,
+	&spear310_pmx_emi_cs_0_1_4_5,
+	&spear310_pmx_emi_cs_2_3,
+	&spear310_pmx_uart1,
+	&spear310_pmx_uart2,
+	&spear310_pmx_uart3_4_5,
+	&spear310_pmx_fsmc,
+	&spear310_pmx_rs485_0_1,
+	&spear310_pmx_tdm0,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -119,17 +119,12 @@ static void __init spi_init(void)
 
 static void __init spear310_evb_init(void)
 {
-	/* padmux initialization, must be done before spear310_init */
-	pmx_driver.mode = NULL;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* set nand device's plat data */
 	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
 	/* call spear310 machine init function */
-	spear310_init();
+	spear310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 7470870..bd1d12a 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -71,7 +71,7 @@ static struct pmx_dev_mode pmx_clcd_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_clcd = {
+struct pmx_dev spear320_pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
@@ -93,7 +93,7 @@ static struct pmx_dev_mode pmx_emi_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_emi = {
+struct pmx_dev spear320_pmx_emi = {
 	.name = "emi",
 	.modes = pmx_emi_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_modes),
@@ -115,7 +115,7 @@ static struct pmx_dev_mode pmx_fsmc_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_fsmc = {
+struct pmx_dev spear320_pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
@@ -137,7 +137,7 @@ static struct pmx_dev_mode pmx_spp_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_spp = {
+struct pmx_dev spear320_pmx_spp = {
 	.name = "spp",
 	.modes = pmx_spp_modes,
 	.mode_count = ARRAY_SIZE(pmx_spp_modes),
@@ -160,7 +160,7 @@ static struct pmx_dev_mode pmx_sdhci_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_sdhci = {
+struct pmx_dev spear320_pmx_sdhci = {
 	.name = "sdhci",
 	.modes = pmx_sdhci_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_modes),
@@ -182,7 +182,7 @@ static struct pmx_dev_mode pmx_i2s_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_i2s = {
+struct pmx_dev spear320_pmx_i2s = {
 	.name = "i2s",
 	.modes = pmx_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2s_modes),
@@ -204,7 +204,7 @@ static struct pmx_dev_mode pmx_uart1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart1 = {
+struct pmx_dev spear320_pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
@@ -239,7 +239,7 @@ static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart1_modem = {
+struct pmx_dev spear320_pmx_uart1_modem = {
 	.name = "uart1_modem",
 	.modes = pmx_uart1_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
@@ -261,7 +261,7 @@ static struct pmx_dev_mode pmx_uart2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart2 = {
+struct pmx_dev spear320_pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
@@ -283,7 +283,7 @@ static struct pmx_dev_mode pmx_touchscreen_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_touchscreen = {
+struct pmx_dev spear320_pmx_touchscreen = {
 	.name = "touchscreen",
 	.modes = pmx_touchscreen_modes,
 	.mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
@@ -306,7 +306,7 @@ static struct pmx_dev_mode pmx_can_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_can = {
+struct pmx_dev spear320_pmx_can = {
 	.name = "can",
 	.modes = pmx_can_modes,
 	.mode_count = ARRAY_SIZE(pmx_can_modes),
@@ -328,7 +328,7 @@ static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_sdhci_led = {
+struct pmx_dev spear320_pmx_sdhci_led = {
 	.name = "sdhci_led",
 	.modes = pmx_sdhci_led_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
@@ -361,7 +361,7 @@ static struct pmx_dev_mode pmx_pwm0_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_pwm0 = {
+struct pmx_dev spear320_pmx_pwm0 = {
 	.name = "pwm0",
 	.modes = pmx_pwm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm0_modes),
@@ -394,7 +394,7 @@ static struct pmx_dev_mode pmx_pwm1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_pwm1 = {
+struct pmx_dev spear320_pmx_pwm1 = {
 	.name = "pwm1",
 	.modes = pmx_pwm1_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm1_modes),
@@ -427,7 +427,7 @@ static struct pmx_dev_mode pmx_pwm2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_pwm2 = {
+struct pmx_dev spear320_pmx_pwm2 = {
 	.name = "pwm2",
 	.modes = pmx_pwm2_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm2_modes),
@@ -449,7 +449,7 @@ static struct pmx_dev_mode pmx_pwm3_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_pwm3 = {
+struct pmx_dev spear320_pmx_pwm3 = {
 	.name = "pwm3",
 	.modes = pmx_pwm3_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm3_modes),
@@ -471,7 +471,7 @@ static struct pmx_dev_mode pmx_ssp1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_ssp1 = {
+struct pmx_dev spear320_pmx_ssp1 = {
 	.name = "ssp1",
 	.modes = pmx_ssp1_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp1_modes),
@@ -493,7 +493,7 @@ static struct pmx_dev_mode pmx_ssp2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_ssp2 = {
+struct pmx_dev spear320_pmx_ssp2 = {
 	.name = "ssp2",
 	.modes = pmx_ssp2_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp2_modes),
@@ -515,7 +515,7 @@ static struct pmx_dev_mode pmx_mii1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_mii1 = {
+struct pmx_dev spear320_pmx_mii1 = {
 	.name = "mii1",
 	.modes = pmx_mii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii1_modes),
@@ -537,7 +537,7 @@ static struct pmx_dev_mode pmx_smii0_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_smii0 = {
+struct pmx_dev spear320_pmx_smii0 = {
 	.name = "smii0",
 	.modes = pmx_smii0_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii0_modes),
@@ -559,7 +559,7 @@ static struct pmx_dev_mode pmx_smii1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_smii1 = {
+struct pmx_dev spear320_pmx_smii1 = {
 	.name = "smii1",
 	.modes = pmx_smii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii1_modes),
@@ -581,14 +581,14 @@ static struct pmx_dev_mode pmx_i2c1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_i2c1 = {
+struct pmx_dev spear320_pmx_i2c1 = {
 	.name = "i2c1",
 	.modes = pmx_i2c1_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
+static struct pmx_driver pmx_driver = {
 	.mode_reg = {.address = SPEAR320_MODE_CONFIG_REG, .mask = 0x00000007},
 };
 
@@ -970,7 +970,8 @@ static struct spear_shirq shirq_intrcomm_ras = {
 };
 
 /* spear320 routines */
-void __init spear320_init(void)
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	void __iomem *base;
 	int ret = 0;
@@ -1000,10 +1001,13 @@ void __init spear320_init(void)
 			printk(KERN_ERR "Error registering Shared IRQ 4\n");
 	}
 
+	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	/* This fixes addresses of all pmx devices for spear320 */
 	spear3xx_pmx_init_addr(&pmx_driver, SPEAR320_PAD_MUX_CONFIG_REG);
-
-	/* pmx initialization */
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		pr_err("padmux: registeration failed. err no: %d\n", ret);
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index da57e97..7c94abf 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -37,22 +37,22 @@ static struct mtd_partition partition_info[] = {
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp,
-	&pmx_mii,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_mii,
+	&spear3xx_pmx_uart0,
 
 	/* spear320 specific devices */
-	&pmx_fsmc,
-	&pmx_sdhci,
-	&pmx_i2s,
-	&pmx_uart1,
-	&pmx_uart2,
-	&pmx_can,
-	&pmx_pwm0,
-	&pmx_pwm1,
-	&pmx_pwm2,
-	&pmx_mii1,
+	&spear320_pmx_fsmc,
+	&spear320_pmx_sdhci,
+	&spear320_pmx_i2s,
+	&spear320_pmx_uart1,
+	&spear320_pmx_uart2,
+	&spear320_pmx_can,
+	&spear320_pmx_pwm0,
+	&spear320_pmx_pwm1,
+	&spear320_pmx_pwm2,
+	&spear320_pmx_mii1,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -137,17 +137,12 @@ static void __init spear320_evb_init(void)
 	/* set sdhci device platform data */
 	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
 
-	/* padmux initialization, must be done before spear320_init */
-	pmx_driver.mode = &auto_net_mii_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* set nand device's plat data */
 	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
 	/* call spear320 machine init function */
-	spear320_init();
+	spear320_init(&auto_net_mii_mode, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* initialize serial nor related data in smi plat data */
 	smi_init_board_info(&smi_device);
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 46093e2..184c9de 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -310,7 +310,7 @@ static struct pmx_dev_mode pmx_firda_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_firda = {
+struct pmx_dev spear3xx_pmx_firda = {
 	.name = "firda",
 	.modes = pmx_firda_modes,
 	.mode_count = ARRAY_SIZE(pmx_firda_modes),
@@ -332,7 +332,7 @@ static struct pmx_dev_mode pmx_i2c_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_i2c = {
+struct pmx_dev spear3xx_pmx_i2c = {
 	.name = "i2c",
 	.modes = pmx_i2c_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
@@ -354,7 +354,7 @@ static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_ssp_cs = {
+struct pmx_dev spear3xx_pmx_ssp_cs = {
 	.name = "ssp_chip_selects",
 	.modes = pmx_ssp_cs_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
@@ -376,7 +376,7 @@ static struct pmx_dev_mode pmx_ssp_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_ssp = {
+struct pmx_dev spear3xx_pmx_ssp = {
 	.name = "ssp",
 	.modes = pmx_ssp_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
@@ -398,7 +398,7 @@ static struct pmx_dev_mode pmx_mii_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_mii = {
+struct pmx_dev spear3xx_pmx_mii = {
 	.name = "mii",
 	.modes = pmx_mii_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii_modes),
@@ -420,7 +420,7 @@ static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin0 = {
+struct pmx_dev spear3xx_pmx_gpio_pin0 = {
 	.name = "gpio_pin0",
 	.modes = pmx_gpio_pin0_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
@@ -442,7 +442,7 @@ static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin1 = {
+struct pmx_dev spear3xx_pmx_gpio_pin1 = {
 	.name = "gpio_pin1",
 	.modes = pmx_gpio_pin1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
@@ -464,7 +464,7 @@ static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin2 = {
+struct pmx_dev spear3xx_pmx_gpio_pin2 = {
 	.name = "gpio_pin2",
 	.modes = pmx_gpio_pin2_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
@@ -486,7 +486,7 @@ static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin3 = {
+struct pmx_dev spear3xx_pmx_gpio_pin3 = {
 	.name = "gpio_pin3",
 	.modes = pmx_gpio_pin3_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
@@ -508,7 +508,7 @@ static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin4 = {
+struct pmx_dev spear3xx_pmx_gpio_pin4 = {
 	.name = "gpio_pin4",
 	.modes = pmx_gpio_pin4_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
@@ -530,7 +530,7 @@ static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_gpio_pin5 = {
+struct pmx_dev spear3xx_pmx_gpio_pin5 = {
 	.name = "gpio_pin5",
 	.modes = pmx_gpio_pin5_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
@@ -552,7 +552,7 @@ static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart0_modem = {
+struct pmx_dev spear3xx_pmx_uart0_modem = {
 	.name = "uart0_modem",
 	.modes = pmx_uart0_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
@@ -574,7 +574,7 @@ static struct pmx_dev_mode pmx_uart0_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_uart0 = {
+struct pmx_dev spear3xx_pmx_uart0 = {
 	.name = "uart0",
 	.modes = pmx_uart0_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
@@ -596,7 +596,7 @@ static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_timer_3_4 = {
+struct pmx_dev spear3xx_pmx_timer_3_4 = {
 	.name = "timer_3_4",
 	.modes = pmx_timer_3_4_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
@@ -618,7 +618,7 @@ static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_timer_1_2 = {
+struct pmx_dev spear3xx_pmx_timer_1_2 = {
 	.name = "timer_1_2",
 	.modes = pmx_timer_1_2_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
@@ -641,7 +641,7 @@ static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_0_1 = {
+struct pmx_dev spear3xx_pmx_plgpio_0_1 = {
 	.name = "plgpio 0 and 1",
 	.modes = pmx_plgpio_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
@@ -663,7 +663,7 @@ static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_2_3 = {
+struct pmx_dev spear3xx_pmx_plgpio_2_3 = {
 	.name = "plgpio 2 and 3",
 	.modes = pmx_plgpio_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
@@ -685,7 +685,7 @@ static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_4_5 = {
+struct pmx_dev spear3xx_pmx_plgpio_4_5 = {
 	.name = "plgpio 4 and 5",
 	.modes = pmx_plgpio_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
@@ -707,7 +707,7 @@ static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_6_9 = {
+struct pmx_dev spear3xx_pmx_plgpio_6_9 = {
 	.name = "plgpio 6 to 9",
 	.modes = pmx_plgpio_6_9_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
@@ -729,7 +729,7 @@ static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_10_27 = {
+struct pmx_dev spear3xx_pmx_plgpio_10_27 = {
 	.name = "plgpio 10 to 27",
 	.modes = pmx_plgpio_10_27_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
@@ -751,7 +751,7 @@ static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_28 = {
+struct pmx_dev spear3xx_pmx_plgpio_28 = {
 	.name = "plgpio 28",
 	.modes = pmx_plgpio_28_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
@@ -773,7 +773,7 @@ static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_29 = {
+struct pmx_dev spear3xx_pmx_plgpio_29 = {
 	.name = "plgpio 29",
 	.modes = pmx_plgpio_29_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
@@ -795,7 +795,7 @@ static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_30 = {
+struct pmx_dev spear3xx_pmx_plgpio_30 = {
 	.name = "plgpio 30",
 	.modes = pmx_plgpio_30_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
@@ -817,7 +817,7 @@ static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_31 = {
+struct pmx_dev spear3xx_pmx_plgpio_31 = {
 	.name = "plgpio 31",
 	.modes = pmx_plgpio_31_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
@@ -839,7 +839,7 @@ static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_32 = {
+struct pmx_dev spear3xx_pmx_plgpio_32 = {
 	.name = "plgpio 32",
 	.modes = pmx_plgpio_32_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
@@ -861,7 +861,7 @@ static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_33 = {
+struct pmx_dev spear3xx_pmx_plgpio_33 = {
 	.name = "plgpio 33",
 	.modes = pmx_plgpio_33_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
@@ -883,7 +883,7 @@ static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_34_36 = {
+struct pmx_dev spear3xx_pmx_plgpio_34_36 = {
 	.name = "plgpio 34 to 36",
 	.modes = pmx_plgpio_34_36_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
@@ -905,7 +905,7 @@ static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_37_42 = {
+struct pmx_dev spear3xx_pmx_plgpio_37_42 = {
 	.name = "plgpio 37 to 42",
 	.modes = pmx_plgpio_37_42_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
@@ -927,7 +927,7 @@ static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_43_44_47_48 = {
+struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48 = {
 	.name = "plgpio 43, 44, 47 and 48",
 	.modes = pmx_plgpio_43_44_47_48_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
@@ -949,7 +949,7 @@ static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
 	},
 };
 
-struct pmx_dev pmx_plgpio_45_46_49_50 = {
+struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50 = {
 	.name = "plgpio 45, 46, 49 and 50",
 	.modes = pmx_plgpio_45_46_49_50_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
-- 
1.7.2.2

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

* [PATCH 64/74] SPEAr3xx: Rework KConfig to allow all boards to be compiled in
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (54 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 63/74] SPEAr3xx: Rework pmx_dev code to remove conflicts Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 65/74] SPEAr3xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
                   ` (18 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ryan Mallon <ryan@bluewatersys.com>

Now that all three SPEAr3xx platforms can be built into one kernel,
rework KConfig to allow this. Move everything into one KConfig file
while we are here.

Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/Kconfig                |   30 ++++++++++++++++--------
 arch/arm/mach-spear3xx/Kconfig300             |   17 --------------
 arch/arm/mach-spear3xx/Kconfig310             |   17 --------------
 arch/arm/mach-spear3xx/Kconfig320             |   17 --------------
 arch/arm/mach-spear3xx/include/mach/generic.h |    6 +++-
 5 files changed, 24 insertions(+), 63 deletions(-)
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig300
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig310
 delete mode 100644 arch/arm/mach-spear3xx/Kconfig320

diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig
index 20d1317..2cee6b0 100644
--- a/arch/arm/mach-spear3xx/Kconfig
+++ b/arch/arm/mach-spear3xx/Kconfig
@@ -4,9 +4,26 @@
 
 if ARCH_SPEAR3XX
 
-choice
-	prompt "SPEAr3XX Family"
-	default MACH_SPEAR300
+menu "SPEAr3xx Implementations"
+config BOARD_SPEAR300_EVB
+	bool "SPEAr300 Evaluation Board"
+	select MACH_SPEAR300
+	help
+	  Supports ST SPEAr300 Evaluation Board
+
+config BOARD_SPEAR310_EVB
+	bool "SPEAr310 Evaluation Board"
+	select MACH_SPEAR310
+	help
+	  Supports ST SPEAr310 Evaluation Board
+
+config BOARD_SPEAR320_EVB
+	bool "SPEAr320 Evaluation Board"
+	select MACH_SPEAR320
+	help
+	  Supports ST SPEAr320 Evaluation Board
+
+endmenu
 
 config MACH_SPEAR300
 	bool "SPEAr300"
@@ -23,11 +40,4 @@ config MACH_SPEAR320
 	help
 	  Supports ST SPEAr320 Machine
 
-endchoice
-
-# Adding SPEAr3XX machine specific configuration files
-source "arch/arm/mach-spear3xx/Kconfig300"
-source "arch/arm/mach-spear3xx/Kconfig310"
-source "arch/arm/mach-spear3xx/Kconfig320"
-
 endif #ARCH_SPEAR3XX
diff --git a/arch/arm/mach-spear3xx/Kconfig300 b/arch/arm/mach-spear3xx/Kconfig300
deleted file mode 100644
index c519a05..0000000
--- a/arch/arm/mach-spear3xx/Kconfig300
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr300 machine configuration file
-#
-
-if MACH_SPEAR300
-
-choice
-	prompt "SPEAr300 Boards"
-	default BOARD_SPEAR300_EVB
-
-config BOARD_SPEAR300_EVB
-	bool "SPEAr300 Evaluation Board"
-	help
-	  Supports ST SPEAr300 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR300
diff --git a/arch/arm/mach-spear3xx/Kconfig310 b/arch/arm/mach-spear3xx/Kconfig310
deleted file mode 100644
index 60e7442..0000000
--- a/arch/arm/mach-spear3xx/Kconfig310
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr310 machine configuration file
-#
-
-if MACH_SPEAR310
-
-choice
-	prompt "SPEAr310 Boards"
-	default BOARD_SPEAR310_EVB
-
-config BOARD_SPEAR310_EVB
-	bool "SPEAr310 Evaluation Board"
-	help
-	  Supports ST SPEAr310 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR310
diff --git a/arch/arm/mach-spear3xx/Kconfig320 b/arch/arm/mach-spear3xx/Kconfig320
deleted file mode 100644
index 1c1d438..0000000
--- a/arch/arm/mach-spear3xx/Kconfig320
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr320 machine configuration file
-#
-
-if MACH_SPEAR320
-
-choice
-	prompt "SPEAr320 Boards"
-	default BOARD_SPEAR320_EVB
-
-config BOARD_SPEAR320_EVB
-	bool "SPEAr320 Evaluation Board"
-	help
-	  Supports ST SPEAr320 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR320
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 6f4b90d..d70f515 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -162,9 +162,10 @@ void sdhci_i2s_mem_enable(u8 mask);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
+#endif
 
 /* spear310 declarations */
-#elif defined(CONFIG_MACH_SPEAR310)
+#if defined(CONFIG_MACH_SPEAR310)
 /* Add spear310 machine device structure declarations here */
 extern struct amba_device uart1_device;
 extern struct amba_device uart2_device;
@@ -189,9 +190,10 @@ extern struct pmx_dev spear310_pmx_tdm0;
 /* Add spear310 machine function declarations here */
 void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count);
+#endif
 
 /* spear320 declarations */
-#elif defined(CONFIG_MACH_SPEAR320)
+#if defined(CONFIG_MACH_SPEAR320)
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct amba_device ssp_device[];
-- 
1.7.2.2

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

* [PATCH 65/74] SPEAr3xx: Replace defconfigs with single unfied defconfig
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (55 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 64/74] SPEAr3xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 66/74] ST SPEAr: Appending spear3** with global structures Viresh KUMAR
                   ` (17 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ryan Mallon <ryan@bluewatersys.com>

We only need one defconfig for SPEAr3xx now since we can build all
three boards into one kernel.

Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/configs/spear300_defconfig |   51 -----------
 arch/arm/configs/spear310_defconfig |   52 -----------
 arch/arm/configs/spear320_defconfig |   52 -----------
 arch/arm/configs/spear3xx_defconfig |  163 +++++++++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+), 155 deletions(-)
 delete mode 100644 arch/arm/configs/spear300_defconfig
 delete mode 100644 arch/arm/configs/spear310_defconfig
 delete mode 100644 arch/arm/configs/spear320_defconfig
 create mode 100644 arch/arm/configs/spear3xx_defconfig

diff --git a/arch/arm/configs/spear300_defconfig b/arch/arm/configs/spear300_defconfig
deleted file mode 100644
index cf29f3e..0000000
--- a/arch/arm/configs/spear300_defconfig
+++ /dev/null
@@ -1,51 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear310_defconfig b/arch/arm/configs/spear310_defconfig
deleted file mode 100644
index 824e444..0000000
--- a/arch/arm/configs/spear310_defconfig
+++ /dev/null
@@ -1,52 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_MACH_SPEAR310=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear320_defconfig b/arch/arm/configs/spear320_defconfig
deleted file mode 100644
index 842f7f3..0000000
--- a/arch/arm/configs/spear320_defconfig
+++ /dev/null
@@ -1,52 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_MACH_SPEAR320=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
new file mode 100644
index 0000000..3b0e955
--- /dev/null
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -0,0 +1,163 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+CONFIG_MACH_SPEAR300=y
+CONFIG_MACH_SPEAR310=y
+CONFIG_MACH_SPEAR320=y
+CONFIG_BOARD_SPEAR300_EVB=y
+CONFIG_BOARD_SPEAR310_EVB=y
+CONFIG_BOARD_SPEAR320_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_CRC32 is not set
-- 
1.7.2.2

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

* [PATCH 66/74] ST SPEAr: Appending spear3** with global structures
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (56 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 65/74] SPEAr3xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 67/74] ST SPEAr3xx: Updating plgpio and emi source to make it compliant with single image strategy Viresh KUMAR
                   ` (16 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/include/mach/generic.h |  140 ++++++++++++------------
 arch/arm/mach-spear3xx/spear300.c             |   42 ++++----
 arch/arm/mach-spear3xx/spear300_evb.c         |   41 ++++----
 arch/arm/mach-spear3xx/spear310.c             |   16 ++--
 arch/arm/mach-spear3xx/spear310_evb.c         |   35 +++---
 arch/arm/mach-spear3xx/spear320.c             |   32 +++---
 arch/arm/mach-spear3xx/spear320_evb.c         |   48 +++++----
 arch/arm/mach-spear3xx/spear3xx.c             |   20 ++--
 arch/arm/plat-spear/include/plat/spi.h        |    2 +-
 9 files changed, 190 insertions(+), 186 deletions(-)

diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index d70f515..f00cc24 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -32,16 +32,16 @@
 #define SPEAR_GPT0_CHAN1_IRQ	SPEAR3XX_IRQ_CPU_GPT1_2
 
 /* Add spear3xx family device structure declarations here */
-extern struct amba_device gpio_device;
-extern struct amba_device ssp0_device;
-extern struct amba_device uart_device;
-extern struct amba_device wdt_device;
-extern struct platform_device ehci_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 platform_device smi_device;
+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;
+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 platform_device spear3xx_smi_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
@@ -89,49 +89,49 @@ extern struct pmx_dev spear3xx_pmx_timer_1_2;
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 /* padmux plgpio devices */
-extern struct pmx_dev pmx_plgpio_0_1;
-extern struct pmx_dev pmx_plgpio_2_3;
-extern struct pmx_dev pmx_plgpio_4_5;
-extern struct pmx_dev pmx_plgpio_6_9;
-extern struct pmx_dev pmx_plgpio_10_27;
-extern struct pmx_dev pmx_plgpio_28;
-extern struct pmx_dev pmx_plgpio_29;
-extern struct pmx_dev pmx_plgpio_30;
-extern struct pmx_dev pmx_plgpio_31;
-extern struct pmx_dev pmx_plgpio_32;
-extern struct pmx_dev pmx_plgpio_33;
-extern struct pmx_dev pmx_plgpio_34_36;
-extern struct pmx_dev pmx_plgpio_37_42;
-extern struct pmx_dev pmx_plgpio_43_44_47_48;
-extern struct pmx_dev pmx_plgpio_45_46_49_50;
+extern struct pmx_dev spear3xx_pmx_plgpio_0_1;
+extern struct pmx_dev spear3xx_pmx_plgpio_2_3;
+extern struct pmx_dev spear3xx_pmx_plgpio_4_5;
+extern struct pmx_dev spear3xx_pmx_plgpio_6_9;
+extern struct pmx_dev spear3xx_pmx_plgpio_10_27;
+extern struct pmx_dev spear3xx_pmx_plgpio_28;
+extern struct pmx_dev spear3xx_pmx_plgpio_29;
+extern struct pmx_dev spear3xx_pmx_plgpio_30;
+extern struct pmx_dev spear3xx_pmx_plgpio_31;
+extern struct pmx_dev spear3xx_pmx_plgpio_32;
+extern struct pmx_dev spear3xx_pmx_plgpio_33;
+extern struct pmx_dev spear3xx_pmx_plgpio_34_36;
+extern struct pmx_dev spear3xx_pmx_plgpio_37_42;
+extern struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48;
+extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
 #endif
 
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
 /* Add spear300 machine device structure declarations here */
-extern struct amba_device clcd_device;
-extern struct amba_device gpio1_device;
-extern struct platform_device kbd_device;
-extern struct platform_device nand0_device;
-extern struct platform_device nand1_device;
-extern struct platform_device nand2_device;
-extern struct platform_device nand3_device;
-extern struct platform_device sdhci_device;
+extern struct amba_device spear300_clcd_device;
+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;
+extern struct platform_device spear300_sdhci_device;
 
 /* pad mux modes */
-extern struct pmx_mode nand_mode;
-extern struct pmx_mode nor_mode;
-extern struct pmx_mode photo_frame_mode;
-extern struct pmx_mode lend_ip_phone_mode;
-extern struct pmx_mode hend_ip_phone_mode;
-extern struct pmx_mode lend_wifi_phone_mode;
-extern struct pmx_mode hend_wifi_phone_mode;
-extern struct pmx_mode ata_pabx_wi2s_mode;
-extern struct pmx_mode ata_pabx_i2s_mode;
-extern struct pmx_mode caml_lcdw_mode;
-extern struct pmx_mode camu_lcd_mode;
-extern struct pmx_mode camu_wlcd_mode;
-extern struct pmx_mode caml_lcd_mode;
+extern struct pmx_mode spear300_nand_mode;
+extern struct pmx_mode spear300_nor_mode;
+extern struct pmx_mode spear300_photo_frame_mode;
+extern struct pmx_mode spear300_lend_ip_phone_mode;
+extern struct pmx_mode spear300_hend_ip_phone_mode;
+extern struct pmx_mode spear300_lend_wifi_phone_mode;
+extern struct pmx_mode spear300_hend_wifi_phone_mode;
+extern struct pmx_mode spear300_ata_pabx_wi2s_mode;
+extern struct pmx_mode spear300_ata_pabx_i2s_mode;
+extern struct pmx_mode spear300_caml_lcdw_mode;
+extern struct pmx_mode spear300_camu_lcd_mode;
+extern struct pmx_mode spear300_camu_wlcd_mode;
+extern struct pmx_mode spear300_caml_lcd_mode;
 
 /* pad mux devices */
 extern struct pmx_dev spear300_pmx_fsmc_2_chips;
@@ -167,14 +167,14 @@ extern struct clcd_board clcd_plat_data;
 /* spear310 declarations */
 #if defined(CONFIG_MACH_SPEAR310)
 /* Add spear310 machine device structure declarations here */
-extern struct amba_device uart1_device;
-extern struct amba_device uart2_device;
-extern struct amba_device uart3_device;
-extern struct amba_device uart4_device;
-extern struct amba_device uart5_device;
-extern struct platform_device emi_nor_device;
-extern struct platform_device plgpio_device;
-extern struct platform_device nand_device;
+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_emi_nor_device;
+extern struct platform_device spear310_plgpio_device;
+extern struct platform_device spear310_nand_device;
 
 /* pad mux devices */
 extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
@@ -195,24 +195,24 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear320 declarations */
 #if defined(CONFIG_MACH_SPEAR320)
 /* Add spear320 machine device structure declarations here */
-extern struct amba_device clcd_device;
-extern struct amba_device ssp_device[];
-extern struct amba_device uart1_device;
-extern struct amba_device uart2_device;
-extern struct platform_device can0_device;
-extern struct platform_device can1_device;
-extern struct platform_device emi_nor_device;
-extern struct platform_device i2c1_device;
-extern struct platform_device nand_device;
-extern struct platform_device plgpio_device;
-extern struct platform_device pwm_device;
-extern struct platform_device sdhci_device;
+extern struct amba_device spear320_clcd_device;
+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;
+extern struct platform_device spear320_can1_device;
+extern struct platform_device spear320_emi_nor_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;
+extern struct platform_device spear320_sdhci_device;
 
 /* pad mux modes */
-extern struct pmx_mode auto_net_smii_mode;
-extern struct pmx_mode auto_net_mii_mode;
-extern struct pmx_mode auto_exp_mode;
-extern struct pmx_mode small_printers_mode;
+extern struct pmx_mode spear320_auto_net_smii_mode;
+extern struct pmx_mode spear320_auto_net_mii_mode;
+extern struct pmx_mode spear320_auto_exp_mode;
+extern struct pmx_mode spear320_small_printers_mode;
 
 /* pad mux devices */
 extern struct pmx_dev spear320_pmx_clcd;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 272cd80..b931f8e 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -36,79 +36,79 @@
 #define CAML_LCD_MODE			(1 << 12)
 #define ALL_MODES			0x1FFF
 
-struct pmx_mode nand_mode = {
+struct pmx_mode spear300_nand_mode = {
 	.id = NAND_MODE,
 	.name = "nand mode",
 	.value = 0x00,
 };
 
-struct pmx_mode nor_mode = {
+struct pmx_mode spear300_nor_mode = {
 	.id = NOR_MODE,
 	.name = "nor mode",
 	.value = 0x01,
 };
 
-struct pmx_mode photo_frame_mode = {
+struct pmx_mode spear300_photo_frame_mode = {
 	.id = PHOTO_FRAME_MODE,
 	.name = "photo frame mode",
 	.value = 0x02,
 };
 
-struct pmx_mode lend_ip_phone_mode = {
+struct pmx_mode spear300_lend_ip_phone_mode = {
 	.id = LEND_IP_PHONE_MODE,
 	.name = "lend ip phone mode",
 	.value = 0x03,
 };
 
-struct pmx_mode hend_ip_phone_mode = {
+struct pmx_mode spear300_hend_ip_phone_mode = {
 	.id = HEND_IP_PHONE_MODE,
 	.name = "hend ip phone mode",
 	.value = 0x04,
 };
 
-struct pmx_mode lend_wifi_phone_mode = {
+struct pmx_mode spear300_lend_wifi_phone_mode = {
 	.id = LEND_WIFI_PHONE_MODE,
 	.name = "lend wifi phone mode",
 	.value = 0x05,
 };
 
-struct pmx_mode hend_wifi_phone_mode = {
+struct pmx_mode spear300_hend_wifi_phone_mode = {
 	.id = HEND_WIFI_PHONE_MODE,
 	.name = "hend wifi phone mode",
 	.value = 0x06,
 };
 
-struct pmx_mode ata_pabx_wi2s_mode = {
+struct pmx_mode spear300_ata_pabx_wi2s_mode = {
 	.id = ATA_PABX_WI2S_MODE,
 	.name = "ata pabx wi2s mode",
 	.value = 0x07,
 };
 
-struct pmx_mode ata_pabx_i2s_mode = {
+struct pmx_mode spear300_ata_pabx_i2s_mode = {
 	.id = ATA_PABX_I2S_MODE,
 	.name = "ata pabx i2s mode",
 	.value = 0x08,
 };
 
-struct pmx_mode caml_lcdw_mode = {
+struct pmx_mode spear300_caml_lcdw_mode = {
 	.id = CAML_LCDW_MODE,
 	.name = "caml lcdw mode",
 	.value = 0x0C,
 };
 
-struct pmx_mode camu_lcd_mode = {
+struct pmx_mode spear300_camu_lcd_mode = {
 	.id = CAMU_LCD_MODE,
 	.name = "camu lcd mode",
 	.value = 0x0D,
 };
 
-struct pmx_mode camu_wlcd_mode = {
+struct pmx_mode spear300_camu_wlcd_mode = {
 	.id = CAMU_WLCD_MODE,
 	.name = "camu wlcd mode",
 	.value = 0x0E,
 };
 
-struct pmx_mode caml_lcd_mode = {
+struct pmx_mode spear300_caml_lcd_mode = {
 	.id = CAML_LCD_MODE,
 	.name = "caml lcd mode",
 	.value = 0x0F,
@@ -526,7 +526,7 @@ static struct pmx_driver pmx_driver = {
 /* Add spear300 specific devices here */
 
 /* CLCD device registration */
-struct amba_device clcd_device = {
+struct amba_device spear300_clcd_device = {
 	.dev = {
 		.init_name = "clcd",
 		.coherent_dma_mask = ~0,
@@ -547,7 +547,7 @@ static struct pl061_platform_data gpio1_plat_data = {
 	.irq_base	= SPEAR300_GPIO1_INT_BASE,
 };
 
-struct amba_device gpio1_device = {
+struct amba_device spear300_gpio1_device = {
 	.dev = {
 		.init_name = "gpio1",
 		.platform_data = &gpio1_plat_data,
@@ -572,7 +572,7 @@ static struct resource kbd_resources[] = {
 	},
 };
 
-struct platform_device kbd_device = {
+struct platform_device spear300_kbd_device = {
 	.name = "keyboard",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(kbd_resources),
@@ -596,7 +596,7 @@ static struct resource nand0_resources[] = {
 	},
 };
 
-struct platform_device nand0_device = {
+struct platform_device spear300_nand0_device = {
 	.name = "nand",
 	.id = 0,
 	.resource = nand0_resources,
@@ -620,7 +620,7 @@ static struct resource nand1_resources[] = {
 	},
 };
 
-struct platform_device nand1_device = {
+struct platform_device spear300_nand1_device = {
 	.name = "nand",
 	.id = 1,
 	.resource = nand1_resources,
@@ -644,7 +644,7 @@ static struct resource nand2_resources[] = {
 	},
 };
 
-struct platform_device nand2_device = {
+struct platform_device spear300_nand2_device = {
 	.name = "nand",
 	.id = 2,
 	.resource = nand2_resources,
@@ -668,7 +668,7 @@ static struct resource nand3_resources[] = {
 	},
 };
 
-struct platform_device nand3_device = {
+struct platform_device spear300_nand3_device = {
 	.name = "nand",
 	.id = 3,
 	.resource = nand3_resources,
@@ -688,7 +688,7 @@ static struct resource sdhci_resources[] = {
 	}
 };
 
-struct platform_device sdhci_device = {
+struct platform_device spear300_sdhci_device = {
 	.dev = {
 		.coherent_dma_mask = ~0,
 	},
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index d8a22fd..a1ec55d 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -43,29 +43,29 @@ static struct pmx_dev *pmx_devs[] = {
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&ssp0_device,
-	&uart_device,
-	&wdt_device,
+	&spear3xx_gpio_device,
+	&spear3xx_ssp0_device,
+	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear300 specific devices */
-	&clcd_device,
-	&gpio1_device,
+	&spear300_clcd_device,
+	&spear300_gpio1_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&ehci_device,
-	&i2c_device,
-	&nand0_device,
-	&ohci0_device,
-	&ohci1_device,
-	&rtc_device,
-	&smi_device,
+	&spear3xx_ehci_device,
+	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
+	&spear3xx_rtc_device,
+	&spear3xx_smi_device,
 
 	/* spear300 specific devices */
-	&kbd_device,
-	&sdhci_device,
+	&spear300_kbd_device,
+	&spear300_nand0_device,
+	&spear300_sdhci_device,
 };
 
 /* sdhci board specific information */
@@ -131,26 +131,27 @@ static void __init spi_init(void)
 static void __init spear300_evb_init(void)
 {
 	/* set keyboard plat data */
-	kbd_set_plat_data(&kbd_device, &kbd_data);
+	kbd_set_plat_data(&spear300_kbd_device, &kbd_data);
 
 	/* set nand0 device's plat data */
-	nand_set_plat_data(&nand0_device, NULL, 0, NAND_SKIP_BBTSCAN,
+	nand_set_plat_data(&spear300_nand0_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
 	/* set sdhci device platform data */
-	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
+	sdhci_set_plat_data(&spear300_sdhci_device, &sdhci_plat_data);
 
 	/* Enable sdhci memory */
 	sdhci_i2s_mem_enable(SDHCI_MEM_ENB);
 
 	/* call spear300 machine init function */
-	spear300_init(&photo_frame_mode, pmx_devs, ARRAY_SIZE(pmx_devs));
+	spear300_init(&spear300_photo_frame_mode, pmx_devs,
+			ARRAY_SIZE(pmx_devs));
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
 	/* initialize serial nor related data in smi plat data */
-	smi_init_board_info(&smi_device);
+	smi_init_board_info(&spear3xx_smi_device);
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 71f1148..25316d1 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -196,7 +196,7 @@ static struct pmx_driver pmx_driver;
 
 /* Add spear310 specific devices here */
 /* uart1 device registeration */
-struct amba_device uart1_device = {
+struct amba_device spear310_uart1_device = {
 	.dev = {
 		.init_name = "uart1",
 	},
@@ -209,7 +209,7 @@ struct amba_device uart1_device = {
 };
 
 /* uart2 device registeration */
-struct amba_device uart2_device = {
+struct amba_device spear310_uart2_device = {
 	.dev = {
 		.init_name = "uart2",
 	},
@@ -222,7 +222,7 @@ struct amba_device uart2_device = {
 };
 
 /* uart3 device registeration */
-struct amba_device uart3_device = {
+struct amba_device spear310_uart3_device = {
 	.dev = {
 		.init_name = "uart3",
 	},
@@ -235,7 +235,7 @@ struct amba_device uart3_device = {
 };
 
 /* uart4 device registeration */
-struct amba_device uart4_device = {
+struct amba_device spear310_uart4_device = {
 	.dev = {
 		.init_name = "uart4",
 	},
@@ -248,7 +248,7 @@ struct amba_device uart4_device = {
 };
 
 /* uart5 device registeration */
-struct amba_device uart5_device = {
+struct amba_device spear310_uart5_device = {
 	.dev = {
 		.init_name = "uart5",
 	},
@@ -277,7 +277,7 @@ static struct resource nand_resources[] = {
 	},
 };
 
-struct platform_device nand_device = {
+struct platform_device spear310_nand_device = {
 	.name = "nand",
 	.id = -1,
 	.resource = nand_resources,
@@ -332,7 +332,7 @@ static struct resource emi_nor_resources[] = {
 	},
 };
 
-struct platform_device emi_nor_device = {
+struct platform_device spear310_emi_nor_device = {
 	.name	= "physmap-flash",
 	.id	= -1,
 	.resource = emi_nor_resources,
@@ -362,7 +362,7 @@ static struct resource plgpio_resources[] = {
 	},
 };
 
-struct platform_device plgpio_device = {
+struct platform_device spear310_plgpio_device = {
 	.name = "plgpio",
 	.id = -1,
 	.dev = {
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index a306647..70e473d 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -59,27 +59,27 @@ static struct pmx_dev *pmx_devs[] = {
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&ssp0_device,
-	&uart_device,
-	&wdt_device,
+	&spear3xx_gpio_device,
+	&spear3xx_ssp0_device,
+	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear310 specific devices */
 };
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&ehci_device,
-	&emi_nor_device,
-	&i2c_device,
-	&nand_device,
-	&ohci0_device,
-	&ohci1_device,
-	&rtc_device,
-	&smi_device,
+	&spear3xx_ehci_device,
+	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
+	&spear3xx_rtc_device,
+	&spear3xx_smi_device,
 
 	/* spear310 specific devices */
-	&plgpio_device,
+	&spear310_emi_nor_device,
+	&spear310_nand_device,
+	&spear310_plgpio_device,
 };
 
 /* spi board information */
@@ -120,7 +120,7 @@ static void __init spi_init(void)
 static void __init spear310_evb_init(void)
 {
 	/* set nand device's plat data */
-	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+	nand_set_plat_data(&spear310_nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
 	/* call spear310 machine init function */
@@ -130,10 +130,10 @@ static void __init spear310_evb_init(void)
 	i2c_register_board_devices();
 
 	/* initialize serial nor related data in smi plat data */
-	smi_init_board_info(&smi_device);
+	smi_init_board_info(&spear3xx_smi_device);
 
 	/* initialize emi related data in emi plat data */
-	emi_init_board_info(&emi_nor_device, partition_info,
+	emi_init_board_info(&spear310_emi_nor_device, partition_info,
 			ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH32);
 
 	/* Add Platform Devices */
@@ -143,7 +143,8 @@ static void __init spear310_evb_init(void)
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	/* Initialize emi regiters */
-	emi_init(&emi_nor_device, SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32);
+	emi_init(&spear310_emi_nor_device, SPEAR310_EMI_REG_BASE, 0,
+			EMI_FLASH_WIDTH32);
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index bd1d12a..9e35fbc 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -30,25 +30,25 @@
 #define SMALL_PRINTERS_MODE	(1 << 3)
 #define ALL_MODES		0xF
 
-struct pmx_mode auto_net_smii_mode = {
+struct pmx_mode spear320_auto_net_smii_mode = {
 	.id = AUTO_NET_SMII_MODE,
 	.name = "Automation Networking SMII Mode",
 	.value = 0x00,
 };
 
-struct pmx_mode auto_net_mii_mode = {
+struct pmx_mode spear320_auto_net_mii_mode = {
 	.id = AUTO_NET_MII_MODE,
 	.name = "Automation Networking MII Mode",
 	.value = 0x01,
 };
 
-struct pmx_mode auto_exp_mode = {
+struct pmx_mode spear320_auto_exp_mode = {
 	.id = AUTO_EXP_MODE,
 	.name = "Automation Expanded Mode",
 	.value = 0x02,
 };
 
-struct pmx_mode small_printers_mode = {
+struct pmx_mode spear320_small_printers_mode = {
 	.id = SMALL_PRINTERS_MODE,
 	.name = "Small Printers Mode",
 	.value = 0x03,
@@ -594,7 +594,7 @@ static struct pmx_driver pmx_driver = {
 
 /* Add spear320 specific devices here */
 /* CLCD device registration */
-struct amba_device clcd_device = {
+struct amba_device spear320_clcd_device = {
 	.dev = {
 		.init_name = "clcd",
 		.coherent_dma_mask = ~0,
@@ -622,7 +622,7 @@ static struct pl022_ssp_controller ssp_platform_data[] = {
 	}
 };
 
-struct amba_device ssp_device[] = {
+struct amba_device spear320_ssp_device[] = {
 	{
 		.dev = {
 			.coherent_dma_mask = ~0,
@@ -651,7 +651,7 @@ struct amba_device ssp_device[] = {
 };
 
 /* uart1 device registeration */
-struct amba_device uart1_device = {
+struct amba_device spear320_uart1_device = {
 	.dev = {
 		.init_name = "uart1",
 	},
@@ -664,7 +664,7 @@ struct amba_device uart1_device = {
 };
 
 /* uart2 device registeration */
-struct amba_device uart2_device = {
+struct amba_device spear320_uart2_device = {
 	.dev = {
 		.init_name = "uart2",
 	},
@@ -687,7 +687,7 @@ static struct resource emi_nor_resources[] = {
 	},
 };
 
-struct platform_device emi_nor_device = {
+struct platform_device spear320_emi_nor_device = {
 	.name	= "physmap-flash",
 	.id	= -1,
 	.resource = emi_nor_resources,
@@ -714,7 +714,7 @@ static struct resource can0_resources[] = {
 	},
 };
 
-struct platform_device can0_device = {
+struct platform_device spear320_can0_device = {
 	.name = "spear_can",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(can0_resources),
@@ -732,7 +732,7 @@ static struct resource can1_resources[] = {
 	},
 };
 
-struct platform_device can1_device = {
+struct platform_device spear320_can1_device = {
 	.name = "spear_can",
 	.id = 1,
 	.num_resources = ARRAY_SIZE(can1_resources),
@@ -751,7 +751,7 @@ static struct resource i2c1_resources[] = {
 	},
 };
 
-struct platform_device i2c1_device = {
+struct platform_device spear320_i2c1_device = {
 	.name = "i2c_designware",
 	.id = 1,
 	.dev = {
@@ -778,7 +778,7 @@ static struct resource nand_resources[] = {
 	},
 };
 
-struct platform_device nand_device = {
+struct platform_device spear320_nand_device = {
 	.name = "nand",
 	.id = -1,
 	.resource = nand_resources,
@@ -797,7 +797,7 @@ static struct resource plgpio_resources[] = {
 	},
 };
 
-struct platform_device plgpio_device = {
+struct platform_device spear320_plgpio_device = {
 	.name = "plgpio",
 	.id = -1,
 	.dev = {
@@ -816,7 +816,7 @@ static struct resource pwm_resources[] = {
 	},
 };
 
-struct platform_device pwm_device = {
+struct platform_device spear320_pwm_device = {
 	.name = "pwm",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(pwm_resources),
@@ -835,7 +835,7 @@ static struct resource sdhci_resources[] = {
 	}
 };
 
-struct platform_device sdhci_device = {
+struct platform_device spear320_sdhci_device = {
 	.dev = {
 		.coherent_dma_mask = ~0,
 	},
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 7c94abf..de161c8 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -57,31 +57,31 @@ static struct pmx_dev *pmx_devs[] = {
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&uart_device,
-	&wdt_device,
+	&spear3xx_gpio_device,
+	&spear3xx_uart_device,
+	&spear3xx_wdt_device,
 
 	/* spear320 specific devices */
-	&clcd_device,
+	&spear320_clcd_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&ehci_device,
-	&i2c_device,
-	&nand_device,
-	&ohci0_device,
-	&ohci1_device,
-	&rtc_device,
-	&smi_device,
+	&spear3xx_ehci_device,
+	&spear3xx_i2c_device,
+	&spear3xx_ohci0_device,
+	&spear3xx_ohci1_device,
+	&spear3xx_rtc_device,
+	&spear3xx_smi_device,
 
 	/* spear320 specific devices */
-	&can0_device,
-	&can1_device,
-	&i2c1_device,
-	&plgpio_device,
-	&pwm_device,
-	&sdhci_device,
+	&spear320_can0_device,
+	&spear320_can1_device,
+	&spear320_i2c1_device,
+	&spear320_nand_device,
+	&spear320_plgpio_device,
+	&spear320_pwm_device,
+	&spear320_sdhci_device,
 };
 
 /* sdhci board specific information */
@@ -135,23 +135,24 @@ static void __init spi_init(void)
 static void __init spear320_evb_init(void)
 {
 	/* set sdhci device platform data */
-	sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data);
+	sdhci_set_plat_data(&spear320_sdhci_device, &sdhci_plat_data);
 
 	/* set nand device's plat data */
-	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+	nand_set_plat_data(&spear320_nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 
 	/* call spear320 machine init function */
-	spear320_init(&auto_net_mii_mode, pmx_devs, ARRAY_SIZE(pmx_devs));
+	spear320_init(&spear320_auto_net_mii_mode, pmx_devs,
+			ARRAY_SIZE(pmx_devs));
 
 	/* initialize serial nor related data in smi plat data */
-	smi_init_board_info(&smi_device);
+	smi_init_board_info(&spear3xx_smi_device);
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
 	/* initialize emi related data in emi plat data */
-	emi_init_board_info(&emi_nor_device, partition_info,
+	emi_init_board_info(&spear320_emi_nor_device, partition_info,
 			ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH16);
 
 	/* Add Platform Devices */
@@ -161,7 +162,8 @@ static void __init spear320_evb_init(void)
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	/* Initialize emi regiters */
-	emi_init(&emi_nor_device, SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16);
+	emi_init(&spear320_emi_nor_device, SPEAR320_EMI_CTRL_BASE, 0,
+			EMI_FLASH_WIDTH16);
 
 	spi_init();
 }
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 184c9de..31fc69a 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -32,7 +32,7 @@ static struct pl061_platform_data gpio_plat_data = {
 	.irq_base	= SPEAR3XX_GPIO_INT_BASE,
 };
 
-struct amba_device gpio_device = {
+struct amba_device spear3xx_gpio_device = {
 	.dev = {
 		.init_name = "gpio",
 		.platform_data = &gpio_plat_data,
@@ -61,7 +61,7 @@ static struct pl022_ssp_controller ssp_platform_data = {
 	.num_chipselect = 2,
 };
 
-struct amba_device ssp0_device = {
+struct amba_device spear3xx_ssp0_device = {
 	.dev = {
 		.coherent_dma_mask = ~0,
 		.init_name = "ssp-pl022.0",
@@ -76,7 +76,7 @@ struct amba_device ssp0_device = {
 };
 
 /* uart device registeration */
-struct amba_device uart_device = {
+struct amba_device spear3xx_uart_device = {
 	.dev = {
 		.init_name = "uart",
 	},
@@ -89,7 +89,7 @@ struct amba_device uart_device = {
 };
 
 /* watchdog device registeration */
-struct amba_device wdt_device = {
+struct amba_device spear3xx_wdt_device = {
 	.dev = {
 		.init_name = "wdt",
 	},
@@ -112,7 +112,7 @@ static struct resource i2c_resources[] = {
 	},
 };
 
-struct platform_device i2c_device = {
+struct platform_device spear3xx_i2c_device = {
 	.name = "i2c_designware",
 	.id = 0,
 	.dev = {
@@ -162,7 +162,7 @@ static struct resource ohci1_resources[] = {
 static u64 ehci_dmamask = ~0;
 static int usbh_id = -1;
 
-struct platform_device ehci_device = {
+struct platform_device spear3xx_ehci_device = {
 	.name = "spear-ehci",
 	.id = -1,
 	.dev = {
@@ -176,7 +176,7 @@ struct platform_device ehci_device = {
 
 static u64 ohci0_dmamask = ~0;
 
-struct platform_device ohci0_device = {
+struct platform_device spear3xx_ohci0_device = {
 	.name = "spear-ohci",
 	.id = 0,
 	.dev = {
@@ -190,7 +190,7 @@ struct platform_device ohci0_device = {
 
 static u64 ohci1_dmamask = ~0;
 
-struct platform_device ohci1_device = {
+struct platform_device spear3xx_ohci1_device = {
 	.name = "spear-ohci",
 	.id = 1,
 	.dev = {
@@ -214,7 +214,7 @@ static struct resource rtc_resources[] = {
 	},
 };
 
-struct platform_device rtc_device = {
+struct platform_device spear3xx_rtc_device = {
 	.name = "rtc-spear",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(rtc_resources),
@@ -233,7 +233,7 @@ static struct resource smi_resources[] = {
 	},
 };
 
-struct platform_device smi_device = {
+struct platform_device spear3xx_smi_device = {
 	.name = "smi",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(smi_resources),
diff --git a/arch/arm/plat-spear/include/plat/spi.h b/arch/arm/plat-spear/include/plat/spi.h
index a2c53f3..c53410a 100644
--- a/arch/arm/plat-spear/include/plat/spi.h
+++ b/arch/arm/plat-spear/include/plat/spi.h
@@ -55,7 +55,7 @@ static void spi##id##_##type##_cs_control(u32 control)	\
 
 /* This will define CHIP_INFO structure for a specific spi slave */
 #define DECLARE_SPI_CHIP_INFO(id, type, chip_select_control)	\
-struct pl022_config_chip spi##id##_##type##_chip_info = {	\
+static struct pl022_config_chip spi##id##_##type##_chip_info = {\
 	.lbm = LOOPBACK_DISABLED,			\
 	.iface = SSP_INTERFACE_MOTOROLA_SPI,		\
 	.hierarchy = SSP_MASTER,			\
-- 
1.7.2.2

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

* [PATCH 67/74] ST SPEAr3xx: Updating plgpio and emi source to make it compliant with single image strategy
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (57 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 66/74] ST SPEAr: Appending spear3** with global structures Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 68/74] SPEAr6xx: Rework Kconfig for single image solution Viresh KUMAR
                   ` (15 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/mach-spear3xx/emi.c               |   20 +++++++++++-
 arch/arm/mach-spear3xx/include/mach/emi.h  |   19 ++++++-----
 arch/arm/mach-spear3xx/include/mach/gpio.h |   27 ++++++++--------
 arch/arm/plat-spear/plgpio.c               |   46 ++++++++++++++++++++-------
 4 files changed, 76 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c
index dd5cb8e..f0de4e0 100644
--- a/arch/arm/mach-spear3xx/emi.c
+++ b/arch/arm/mach-spear3xx/emi.c
@@ -15,6 +15,7 @@
 #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(struct platform_device *pdev, unsigned long base,
@@ -23,8 +24,23 @@ int __init emi_init(struct platform_device *pdev, unsigned long base,
 	void __iomem *emi_reg_base;
 	struct clk *clk;
 	int ret;
+	u32 ack_reg, max_banks;
+	/* u32 timeout_reg, irq_reg; */
 
-	if (bank > (EMI_MAX_BANKS - 1))
+	/* 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);
@@ -71,7 +87,7 @@ int __init emi_init(struct platform_device *pdev, unsigned long base,
 		emi_reg_base + (EMI_BANK_REG_SIZE * bank) + CTRL_REG);
 
 	/* disable all the acks */
-	writel(0x3f << bank, emi_reg_base + ACK_REG);
+	writel(0x3f << bank, emi_reg_base + ack_reg);
 
 	iounmap(emi_reg_base);
 
diff --git a/arch/arm/mach-spear3xx/include/mach/emi.h b/arch/arm/mach-spear3xx/include/mach/emi.h
index f3cbfbc..53b8cf8 100644
--- a/arch/arm/mach-spear3xx/include/mach/emi.h
+++ b/arch/arm/mach-spear3xx/include/mach/emi.h
@@ -33,18 +33,19 @@
 #define CTRL_REG		(0x14)
 
 #if defined(CONFIG_MACH_SPEAR310)
-#define TIMEOUT_REG		(0x90)
-#define ACK_REG			(0x94)
-#define IRQ_REG			(0x98)
+#define SPEAR310_TIMEOUT_REG	(0x90)
+#define SPEAR310_ACK_REG	(0x94)
+#define SPEAR310_IRQ_REG	(0x98)
 
-#define EMI_MAX_BANKS		6
+#define SPEAR310_EMI_MAX_BANKS	6
+#endif
 
-#elif defined(CONFIG_MACH_SPEAR320)
-#define TIMEOUT_REG		(0x60)
-#define ACK_REG			(0x64)
-#define IRQ_REG			(0x68)
+#if defined(CONFIG_MACH_SPEAR320)
+#define SPEAR320_TIMEOUT_REG	(0x60)
+#define SPEAR320_ACK_REG	(0x64)
+#define SPEAR320_IRQ_REG	(0x68)
 
-#define EMI_MAX_BANKS		4
+#define SPEAR320_EMI_MAX_BANKS	4
 
 #endif
 
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
index f15248c..0c13d8c 100644
--- a/arch/arm/mach-spear3xx/include/mach/gpio.h
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -17,20 +17,21 @@
 #include <plat/gpio.h>
 
 #ifdef CONFIG_MACH_SPEAR310
-#define PLGPIO_ENB		0x0010
-#define PLGPIO_WDATA		0x0020
-#define PLGPIO_DIR		0x0030
-#define PLGPIO_IE		0x0040
-#define PLGPIO_RDATA		0x0050
-#define PLGPIO_MIS		0x0060
+#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
 
-#elif defined(CONFIG_MACH_SPEAR320)
-#define PLGPIO_ENB		0x0024
-#define PLGPIO_WDATA		0x0034
-#define PLGPIO_DIR		0x0044
-#define PLGPIO_RDATA		0x0054
-#define PLGPIO_IE		0x0064
-#define PLGPIO_MIS		0x0074
+#if defined(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
 
 #define BASIC_GPIO_0		0
diff --git a/arch/arm/plat-spear/plgpio.c b/arch/arm/plat-spear/plgpio.c
index 847ff9c..d5631a8 100644
--- a/arch/arm/plat-spear/plgpio.c
+++ b/arch/arm/plat-spear/plgpio.c
@@ -22,6 +22,7 @@
 #include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <asm/mach-types.h>
 #include <mach/gpio.h>
 
 #define MAX_GPIO_PER_REG		32
@@ -29,6 +30,9 @@
 #define REG_OFFSET(base, reg, pin)	(base + reg + (pin / MAX_GPIO_PER_REG)\
 		* sizeof(int *))
 
+static u32 plgpio_enb, plgpio_wdata, plgpio_dir, plgpio_rdata, plgpio_ie,
+	   plgpio_mis;
+
 /*
  * struct plgpio: plgpio driver specific structure
  *
@@ -97,7 +101,7 @@ static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_set(plgpio->base, offset, PLGPIO_DIR);
+	plgpio_reg_set(plgpio->base, offset, plgpio_dir);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 
 	return 0;
@@ -126,11 +130,11 @@ static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_reset(plgpio->base, dir_offset, PLGPIO_DIR);
+	plgpio_reg_reset(plgpio->base, dir_offset, plgpio_dir);
 	if (value)
-		plgpio_reg_set(plgpio->base, wdata_offset, PLGPIO_WDATA);
+		plgpio_reg_set(plgpio->base, wdata_offset, plgpio_wdata);
 	else
-		plgpio_reg_reset(plgpio->base, wdata_offset, PLGPIO_WDATA);
+		plgpio_reg_reset(plgpio->base, wdata_offset, plgpio_wdata);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 
 	return 0;
@@ -150,7 +154,7 @@ static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
 			return -EINVAL;
 	}
 
-	return is_plgpio_set(plgpio->base, offset, PLGPIO_RDATA);
+	return is_plgpio_set(plgpio->base, offset, plgpio_rdata);
 }
 
 static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
@@ -168,9 +172,9 @@ static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
 	}
 
 	if (value)
-		plgpio_reg_set(plgpio->base, offset, PLGPIO_WDATA);
+		plgpio_reg_set(plgpio->base, offset, plgpio_wdata);
 	else
-		plgpio_reg_reset(plgpio->base, offset, PLGPIO_WDATA);
+		plgpio_reg_reset(plgpio->base, offset, plgpio_wdata);
 }
 
 static int plgpio_request(struct gpio_chip *chip, unsigned offset)
@@ -197,7 +201,7 @@ static int plgpio_request(struct gpio_chip *chip, unsigned offset)
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_set(plgpio->base, offset, PLGPIO_ENB);
+	plgpio_reg_set(plgpio->base, offset, plgpio_enb);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 
 	return 0;
@@ -219,7 +223,7 @@ static void plgpio_free(struct gpio_chip *chip, unsigned offset)
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_reset(plgpio->base, offset, PLGPIO_ENB);
+	plgpio_reg_reset(plgpio->base, offset, plgpio_enb);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 }
 
@@ -248,7 +252,7 @@ static void plgpio_irq_mask(unsigned irq)
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_set(plgpio->base, offset, PLGPIO_IE);
+	plgpio_reg_set(plgpio->base, offset, plgpio_ie);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 }
 
@@ -266,7 +270,7 @@ static void plgpio_irq_unmask(unsigned irq)
 	}
 
 	spin_lock_irqsave(&plgpio->lock, flags);
-	plgpio_reg_reset(plgpio->base, offset, PLGPIO_IE);
+	plgpio_reg_reset(plgpio->base, offset, plgpio_ie);
 	spin_unlock_irqrestore(&plgpio->lock, flags);
 }
 
@@ -299,7 +303,7 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 	/* check all plgpio MIS registers for a possible interrupt */
 	for (; i < regs_count; i++) {
-		pending = readl(plgpio->base + PLGPIO_MIS + i * sizeof(int *));
+		pending = readl(plgpio->base + plgpio_mis + i * sizeof(int *));
 		if (!pending)
 			continue;
 
@@ -444,6 +448,24 @@ static struct platform_driver plgpio_driver = {
 
 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 0;
+	}
+
 	return platform_driver_register(&plgpio_driver);
 }
 subsys_initcall(plgpio_init);
-- 
1.7.2.2

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

* [PATCH 68/74] SPEAr6xx: Rework Kconfig for single image solution
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (58 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 67/74] ST SPEAr3xx: Updating plgpio and emi source to make it compliant with single image strategy Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 69/74] ST SPEAR6xx: renaming spear600_defconfig as spear6xx_defconfig Viresh KUMAR
                   ` (14 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/mach-spear6xx/Kconfig    |   15 ++++++++-------
 arch/arm/mach-spear6xx/Kconfig600 |   17 -----------------
 2 files changed, 8 insertions(+), 24 deletions(-)
 delete mode 100644 arch/arm/mach-spear6xx/Kconfig600

diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig
index bddba03..ff4ae5b 100644
--- a/arch/arm/mach-spear6xx/Kconfig
+++ b/arch/arm/mach-spear6xx/Kconfig
@@ -4,17 +4,18 @@
 
 if ARCH_SPEAR6XX
 
-choice
-	prompt "SPEAr6XX Family"
-	default MACH_SPEAR600
+menu "SPEAr6xx Implementations"
+config BOARD_SPEAR600_EVB
+	bool "SPEAr600 Evaluation Board"
+	select MACH_SPEAR600
+	help
+	  Supports ST SPEAr600 Evaluation Board
+
+endmenu
 
 config MACH_SPEAR600
 	bool "SPEAr600"
 	help
 	  Supports ST SPEAr600 Machine
-endchoice
-
-# Adding SPEAr6XX machine specific configuration files
-source "arch/arm/mach-spear6xx/Kconfig600"
 
 endif #ARCH_SPEAR6XX
diff --git a/arch/arm/mach-spear6xx/Kconfig600 b/arch/arm/mach-spear6xx/Kconfig600
deleted file mode 100644
index 9e19f65..0000000
--- a/arch/arm/mach-spear6xx/Kconfig600
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr600 machine configuration file
-#
-
-if MACH_SPEAR600
-
-choice
-	prompt "SPEAr600 Boards"
-	default BOARD_SPEAR600_EVB
-
-config	BOARD_SPEAR600_EVB
-	bool "SPEAr600 Evaluation Board"
-	help
-	  Supports ST SPEAr600 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR600
-- 
1.7.2.2

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

* [PATCH 69/74] ST SPEAR6xx: renaming spear600_defconfig as spear6xx_defconfig
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (59 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 68/74] SPEAr6xx: Rework Kconfig for single image solution Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 70/74] SPEAr13XX: Update register/macros/devices/routine names and pmx dev registration to implement single image for multiple boards Viresh KUMAR
                   ` (13 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
---
 arch/arm/configs/spear600_defconfig |   49 -----
 arch/arm/configs/spear6xx_defconfig |  358 +++++++++++++++++++++++++++++++++++
 2 files changed, 358 insertions(+), 49 deletions(-)
 delete mode 100644 arch/arm/configs/spear600_defconfig
 create mode 100644 arch/arm/configs/spear6xx_defconfig

diff --git a/arch/arm/configs/spear600_defconfig b/arch/arm/configs/spear600_defconfig
deleted file mode 100644
index 6777c11..0000000
--- a/arch/arm/configs/spear600_defconfig
+++ /dev/null
@@ -1,49 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX 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_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
new file mode 100644
index 0000000..3dfc6bb
--- /dev/null
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -0,0 +1,358 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Thu Aug 19 15:23:42 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR13XX is not set
+# CONFIG_ARCH_SPEAR3XX is not set
+CONFIG_ARCH_SPEAR6XX=y
+
+#
+# SPEAr6xx Implementations
+#
+CONFIG_BOARD_SPEAR600_EVB=y
+CONFIG_MACH_SPEAR600=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_SPEAR is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_CRC32 is not set
-- 
1.7.2.2

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

* [PATCH 70/74] SPEAr13XX: Update register/macros/devices/routine names and pmx dev registration to implement single image for multiple boards.
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (60 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 69/74] ST SPEAR6xx: renaming spear600_defconfig as spear6xx_defconfig Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 71/74] SPEAr13xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
                   ` (12 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/clock.c                  |   12 +++---
 arch/arm/mach-spear13xx/include/mach/generic.h   |   47 ++++++++++-----------
 arch/arm/mach-spear13xx/include/mach/irqs.h      |    1 -
 arch/arm/mach-spear13xx/include/mach/spear1310.h |    6 +-
 arch/arm/mach-spear13xx/spear1300.c              |    9 +++-
 arch/arm/mach-spear13xx/spear1300_evb.c          |   47 +++++++++-----------
 arch/arm/mach-spear13xx/spear1310.c              |   13 ++++--
 arch/arm/mach-spear13xx/spear1310_evb.c          |   49 ++++++++++------------
 arch/arm/mach-spear13xx/spear13xx.c              |   34 ++++++++--------
 9 files changed, 108 insertions(+), 110 deletions(-)

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index cad2bbb..044319b 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -988,15 +988,15 @@ static struct pclk_info phy_pclk_info[] = {
 static struct pclk_sel phy_pclk_sel = {
 	.pclk_info = phy_pclk_info,
 	.pclk_count = ARRAY_SIZE(phy_pclk_info),
-	.pclk_sel_reg = (unsigned int *)(IO_ADDRESS(RAS_CTRL_REG1)),
-	.pclk_sel_mask = PHY_CLK_MASK,
+	.pclk_sel_reg = (unsigned int *)(IO_ADDRESS(SPEAR1310_RAS_CTRL_REG1)),
+	.pclk_sel_mask = SPEAR1310_PHY_CLK_MASK,
 };
 
 /* Phy 1 Clock */
 struct clk gmac_phy1_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk_sel = &phy_pclk_sel,
-	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.pclk_sel_shift = SPEAR1310_PHY_CLK_SHIFT,
 	.recalc = &follow_parent,
 };
 
@@ -1004,7 +1004,7 @@ struct clk gmac_phy1_clk = {
 static struct clk gmac_phy2_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk_sel = &phy_pclk_sel,
-	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.pclk_sel_shift = SPEAR1310_PHY_CLK_SHIFT,
 	.recalc = &follow_parent,
 };
 
@@ -1012,7 +1012,7 @@ static struct clk gmac_phy2_clk = {
 static struct clk gmac_phy3_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk_sel = &phy_pclk_sel,
-	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.pclk_sel_shift = SPEAR1310_PHY_CLK_SHIFT,
 	.recalc = &follow_parent,
 };
 
@@ -1020,7 +1020,7 @@ static struct clk gmac_phy3_clk = {
 static struct clk gmac_phy4_clk = {
 	.flags = ALWAYS_ENABLED,
 	.pclk_sel = &phy_pclk_sel,
-	.pclk_sel_shift = PHY_CLK_SHIFT,
+	.pclk_sel_shift = SPEAR1310_PHY_CLK_SHIFT,
 	.recalc = &follow_parent,
 };
 
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index d453b60..75e9b82 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -35,7 +35,6 @@
 
 #if defined(CONFIG_MACH_SPEAR1310)
 #define SPEAR1310_FUNC_CNTL_0	UL(0x6C800000)
-
 #define PMX_SMII_MASK		(1 << 24)	/* Func cntl reg0 */
 #endif
 
@@ -217,26 +216,24 @@ extern struct pmx_dev pmx_uart1_modem;
 #define SPEAR_GPT0_CHAN0_IRQ	IRQ_GPT0_TMR0
 #define SPEAR_GPT0_CHAN1_IRQ	IRQ_GPT0_TMR1
 
-extern struct pmx_driver pmx_driver;
-
 /* Add spear13xx 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 platform_device ehci0_device;
-extern struct platform_device ehci1_device;
-extern struct platform_device i2c_device;
-extern struct platform_device kbd_device;
-extern struct platform_device nand_device;
-extern struct platform_device fsmc_nor_device;
-extern struct platform_device ohci0_device;
-extern struct platform_device ohci1_device;
-extern struct platform_device rtc_device;
-extern struct platform_device sdhci_device;
-extern struct platform_device smi_device;
-extern struct platform_device pcie_gadget0_device;
-extern struct platform_device pcie_gadget1_device;
-extern struct platform_device pcie_gadget2_device;
+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;
+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_fsmc_nor_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 platform_device spear13xx_smi_device;
+extern struct platform_device spear13xx_pcie_gadget0_device;
+extern struct platform_device spear13xx_pcie_gadget1_device;
+extern struct platform_device spear13xx_pcie_gadget2_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
@@ -252,18 +249,20 @@ void spear13xx_secondary_startup(void);
 /* spear1300 declarations */
 #ifdef CONFIG_MACH_SPEAR1300
 /* Add spear1300 machine function declarations here */
-void __init spear1300_init(void);
+void __init spear1300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 #endif /* CONFIG_MACH_SPEAR1300 */
 
 /* spear1310 declarations */
 #ifdef CONFIG_MACH_SPEAR1310
 /* Add spear1310 machine device structure declarations here */
-extern struct platform_device can0_device;
-extern struct platform_device can1_device;
+extern struct platform_device spear1310_can0_device;
+extern struct platform_device spear1310_can1_device;
 
 /* Add spear1310 machine function declarations here */
-void __init spear1310_init(void);
+void __init spear1310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 #endif /* CONFIG_MACH_SPEAR1310 */
 
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index 1ca70a6..19ebdf0 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -122,7 +122,6 @@
 #endif /* CONFIG_MACH_SPEAR1310 */
 
 #define IRQ_GIC_END		(IRQ_SHPI_START + 128)
-
 #define VIRQ_START		IRQ_GIC_END
 
 /* GPIO pins virtual irqs */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310.h b/arch/arm/mach-spear13xx/include/mach/spear1310.h
index fd97c64..5fa69bb 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear1310.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310.h
@@ -21,9 +21,9 @@
 #define SPEAR1310_RAS_BASE		UL(0x6C800000)
 
 /* RAS Area Control Register */
-#define RAS_CTRL_REG1		(SPEAR1310_RAS_BASE + 0x4)
-#define PHY_CLK_MASK		0xF
-#define PHY_CLK_SHIFT		0
+#define SPEAR1310_RAS_CTRL_REG1		(SPEAR1310_RAS_BASE + 0x4)
+#define SPEAR1310_PHY_CLK_MASK		0xF
+#define SPEAR1310_PHY_CLK_SHIFT		0
 
 #endif /* __MACH_SPEAR1310_H */
 
diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
index 28822a3..b10f7a0 100644
--- a/arch/arm/mach-spear13xx/spear1300.c
+++ b/arch/arm/mach-spear13xx/spear1300.c
@@ -15,11 +15,12 @@
 #include <mach/spear.h>
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver;
+static struct pmx_driver pmx_driver;
 
 /* Add spear1300 specific devices here */
 
-void __init spear1300_init(void)
+void __init spear1300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	int ret;
 
@@ -27,6 +28,10 @@ void __init spear1300_init(void)
 	spear13xx_init();
 
 	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		pr_err("padmux: registeration failed. err no: %d\n", ret);
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index e297981..9d7229f 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -58,24 +58,24 @@ static struct pmx_dev *pmx_devs[] = {
 };
 
 static struct amba_device *amba_devs[] __initdata = {
-	&gpio_device[0],
-	&gpio_device[1],
-	&ssp_device,
-	&uart_device,
+	&spear13xx_gpio_device[0],
+	&spear13xx_gpio_device[1],
+	&spear13xx_ssp_device,
+	&spear13xx_uart_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
-	&ehci0_device,
-	&ehci1_device,
-	&i2c_device,
-	&kbd_device,
-	&nand_device,
-	&ohci0_device,
-	&ohci1_device,
-	&rtc_device,
-	&sdhci_device,
-	&smi_device,
-	&pcie_gadget0_device,
+	&spear13xx_ehci0_device,
+	&spear13xx_ehci1_device,
+	&spear13xx_i2c_device,
+	&spear13xx_kbd_device,
+	&spear13xx_nand_device,
+	&spear13xx_ohci0_device,
+	&spear13xx_ohci1_device,
+	&spear13xx_rtc_device,
+	&spear13xx_sdhci_device,
+	&spear13xx_smi_device,
+	&spear13xx_pcie_gadget0_device,
 };
 
 /* keyboard specific platform data */
@@ -153,11 +153,6 @@ static int spear1300_pcie_port_is_host(int port)
 
 static void __init spear1300_evb_init(void)
 {
-	/* padmux initialization, must be done before spear1300_init */
-	pmx_driver.mode = NULL;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 #ifdef CONFIG_CACHE_L2X0
 	/*
 	 * 256KB (16KB/way), 16-way associativity, parity not
@@ -170,21 +165,21 @@ static void __init spear1300_evb_init(void)
 #endif
 
 	/* set keyboard plat data */
-	kbd_set_plat_data(&kbd_device, &kbd_data);
+	kbd_set_plat_data(&spear13xx_kbd_device, &kbd_data);
 
 	/* set nand device's plat data */
-	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+	nand_set_plat_data(&spear13xx_nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 	nand_mach_init(SPEAR_NAND_BW8);
 
 	/* call spear1300 machine init function */
-	spear1300_init();
+	spear1300_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
 	/* initialize serial nor related data in smi plat data */
-	smi_init_board_info(&smi_device);
+	smi_init_board_info(&spear13xx_smi_device);
 
 #ifdef CONFIG_PCIEPORTBUS
 	/* Enable PCIE0 clk */
@@ -192,7 +187,7 @@ static void __init spear1300_evb_init(void)
 	pcie_init(&spear1300_pcie_port_is_host);
 #endif
 	/* initialize fsmc related data in fsmc plat data */
-	fsmc_init_board_info(&fsmc_nor_device, partition_info,
+	fsmc_init_board_info(&spear13xx_fsmc_nor_device, partition_info,
 			ARRAY_SIZE(partition_info), FSMC_FLASH_WIDTH8);
 
 	/* Add Platform Devices */
@@ -202,7 +197,7 @@ static void __init spear1300_evb_init(void)
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	/* Initialize fsmc regiters */
-	fsmc_nor_init(&fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
+	fsmc_nor_init(&spear13xx_fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
 			FSMC_FLASH_WIDTH8);
 
 	spi_init();
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 3b38a4c..5cadea8 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -17,7 +17,7 @@
 #include <mach/hardware.h>
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver;
+static struct pmx_driver pmx_driver;
 
 /* Pad multiplexing for uart1_modem device */
 static struct pmx_mux_reg pmx_uart1_modem_mux[] = {
@@ -338,7 +338,7 @@ static struct resource can0_resources[] = {
 	},
 };
 
-struct platform_device can0_device = {
+struct platform_device spear1310_can0_device = {
 	.name = "spear_can",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(can0_resources),
@@ -356,14 +356,15 @@ static struct resource can1_resources[] = {
 	},
 };
 
-struct platform_device can1_device = {
+struct platform_device spear1310_can1_device = {
 	.name = "spear_can",
 	.id = 1,
 	.num_resources = ARRAY_SIZE(can1_resources),
 	.resource = can1_resources,
 };
 
-void __init spear1310_init(void)
+void __init spear1310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	int ret;
 
@@ -371,6 +372,10 @@ void __init spear1310_init(void)
 	spear13xx_init();
 
 	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		pr_err("padmux: registeration failed. err no: %d\n", ret);
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index dec9ceb..6335b88 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -62,28 +62,28 @@ static struct pmx_dev *pmx_devs[] = {
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear13xx specific devices */
-	&gpio_device[0],
-	&gpio_device[1],
-	&uart_device,
+	&spear13xx_gpio_device[0],
+	&spear13xx_gpio_device[1],
+	&spear13xx_uart_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear13xx specific devices */
-	&ehci0_device,
-	&ehci1_device,
-	&i2c_device,
-	&kbd_device,
-	&nand_device,
-	&ohci0_device,
-	&ohci1_device,
-	&rtc_device,
-	&sdhci_device,
-	&smi_device,
-	&pcie_gadget0_device,
+	&spear13xx_ehci0_device,
+	&spear13xx_ehci1_device,
+	&spear13xx_i2c_device,
+	&spear13xx_kbd_device,
+	&spear13xx_nand_device,
+	&spear13xx_ohci0_device,
+	&spear13xx_ohci1_device,
+	&spear13xx_rtc_device,
+	&spear13xx_sdhci_device,
+	&spear13xx_smi_device,
+	&spear13xx_pcie_gadget0_device,
 
 	/* spear1310 specific devices */
-	&can0_device,
-	&can1_device,
+	&spear1310_can0_device,
+	&spear1310_can1_device,
 };
 
 /* keyboard specific platform data */
@@ -160,29 +160,24 @@ int spear1310_pcie_port_is_host(int port)
 
 static void __init spear1310_evb_init(void)
 {
-	/* padmux initialization, must be done before spear1300_init */
-	pmx_driver.mode = NULL;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* set keyboard plat data */
-	kbd_set_plat_data(&kbd_device, &kbd_data);
+	kbd_set_plat_data(&spear13xx_kbd_device, &kbd_data);
 
 	/* set nand device's plat data */
-	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+	nand_set_plat_data(&spear13xx_nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
 			SPEAR_NAND_BW8);
 	nand_mach_init(SPEAR_NAND_BW8);
 
 	/* call spear1310 machine init function */
-	spear1310_init();
+	spear1310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* Register slave devices on the I2C buses */
 	i2c_register_board_devices();
 
 	/* initialize serial nor related data in smi plat data */
-	smi_init_board_info(&smi_device);
+	smi_init_board_info(&spear13xx_smi_device);
 	/* initialize fsmc related data in fsmc plat data */
-	fsmc_init_board_info(&fsmc_nor_device, partition_info,
+	fsmc_init_board_info(&spear13xx_fsmc_nor_device, partition_info,
 			ARRAY_SIZE(partition_info), FSMC_FLASH_WIDTH8);
 
 #ifdef CONFIG_PCIEPORTBUS
@@ -198,7 +193,7 @@ static void __init spear1310_evb_init(void)
 	spear_amba_device_register(amba_devs, ARRAY_SIZE(amba_devs));
 
 	/* Initialize fsmc regiters */
-	fsmc_nor_init(&fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
+	fsmc_nor_init(&spear13xx_fsmc_nor_device, SPEAR13XX_FSMC_BASE, 0,
 			FSMC_FLASH_WIDTH8);
 
 	spi_init();
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index c02073f..d183e5a 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -40,7 +40,7 @@ static struct pl061_platform_data gpio_plat_data[] = {
 	},
 };
 
-struct amba_device gpio_device[] = {
+struct amba_device spear13xx_gpio_device[] = {
 	{
 		.dev = {
 			.init_name = "gpio0",
@@ -82,7 +82,7 @@ static struct pl022_ssp_controller ssp_platform_data = {
 	.num_chipselect = 2,
 };
 
-struct amba_device ssp_device = {
+struct amba_device spear13xx_ssp_device = {
 	.dev = {
 		.coherent_dma_mask = ~0,
 		.init_name = "ssp-pl022",
@@ -97,7 +97,7 @@ struct amba_device ssp_device = {
 };
 
 /* uart device registeration */
-struct amba_device uart_device = {
+struct amba_device spear13xx_uart_device = {
 	.dev = {
 		.init_name = "uart",
 	},
@@ -121,7 +121,7 @@ static struct resource i2c_resources[] = {
 	},
 };
 
-struct platform_device i2c_device = {
+struct platform_device spear13xx_i2c_device = {
 	.name = "i2c_designware",
 	.id = 0,
 	.dev = {
@@ -142,7 +142,7 @@ static struct resource fsmc_nor_resources[] = {
 	},
 };
 
-struct platform_device fsmc_nor_device = {
+struct platform_device spear13xx_fsmc_nor_device = {
 	.name	= "physmap-flash",
 	.id	= -1,
 	.resource = fsmc_nor_resources,
@@ -198,7 +198,7 @@ static struct resource nand_resources[] = {
 	},
 };
 
-struct platform_device nand_device = {
+struct platform_device spear13xx_nand_device = {
 	.name = "nand",
 	.id = -1,
 	.resource = nand_resources,
@@ -259,7 +259,7 @@ static int usbh0_id;
 static int usbh1_id = 1;
 static u64 ehci0_dmamask = ~0;
 
-struct platform_device ehci0_device = {
+struct platform_device spear13xx_ehci0_device = {
 	.name = "spear-ehci",
 	.id = 0,
 	.dev = {
@@ -273,7 +273,7 @@ struct platform_device ehci0_device = {
 
 static u64 ehci1_dmamask = ~0;
 
-struct platform_device ehci1_device = {
+struct platform_device spear13xx_ehci1_device = {
 	.name = "spear-ehci",
 	.id = 1,
 	.dev = {
@@ -287,7 +287,7 @@ struct platform_device ehci1_device = {
 
 static u64 ohci0_dmamask = ~0;
 
-struct platform_device ohci0_device = {
+struct platform_device spear13xx_ohci0_device = {
 	.name = "spear-ohci",
 	.id = 0,
 	.dev = {
@@ -300,7 +300,7 @@ struct platform_device ohci0_device = {
 };
 
 static u64 ohci1_dmamask = ~0;
-struct platform_device ohci1_device = {
+struct platform_device spear13xx_ohci1_device = {
 	.name = "spear-ohci",
 	.id = 1,
 	.dev = {
@@ -324,7 +324,7 @@ static struct resource kbd_resources[] = {
 	},
 };
 
-struct platform_device kbd_device = {
+struct platform_device spear13xx_kbd_device = {
 	.name = "keyboard",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(kbd_resources),
@@ -343,7 +343,7 @@ static struct resource rtc_resources[] = {
 	},
 };
 
-struct platform_device rtc_device = {
+struct platform_device spear13xx_rtc_device = {
 	.name = "rtc-spear",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(rtc_resources),
@@ -362,7 +362,7 @@ static struct resource smi_resources[] = {
 	},
 };
 
-struct platform_device smi_device = {
+struct platform_device spear13xx_smi_device = {
 	.name = "smi",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(smi_resources),
@@ -419,7 +419,7 @@ static struct resource sdhci_resources[] = {
 	}
 };
 
-struct platform_device sdhci_device = {
+struct platform_device spear13xx_sdhci_device = {
 	.dev = {
 		.coherent_dma_mask = ~0,
 	},
@@ -449,7 +449,7 @@ static struct resource pcie_gadget0_resources[] = {
 static int pcie_gadget0_id;
 static u64 pcie_gadget0_dmamask = ~0;
 
-struct platform_device pcie_gadget0_device = {
+struct platform_device spear13xx_pcie_gadget0_device = {
 	.name = "pcie-gadget-spear",
 	.id = 0,
 	.dev = {
@@ -480,7 +480,7 @@ static struct resource pcie_gadget1_resources[] = {
 static int pcie_gadget1_id;
 static u64 pcie_gadget1_dmamask = ~0;
 
-struct platform_device pcie_gadget1_device = {
+struct platform_device spear13xx_pcie_gadget1_device = {
 	.name = "pcie-gadget-spear",
 	.id = 1,
 	.dev = {
@@ -511,7 +511,7 @@ static struct resource pcie_gadget2_resources[] = {
 static int pcie_gadget2_id;
 static u64 pcie_gadget2_dmamask = ~0;
 
-struct platform_device pcie_gadget2_device = {
+struct platform_device spear13xx_pcie_gadget2_device = {
 	.name = "pcie-gadget-spear",
 	.id = 2,
 	.dev = {
-- 
1.7.2.2

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

* [PATCH 71/74] SPEAr13xx: Rework KConfig to allow all boards to be compiled in
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (61 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 70/74] SPEAr13XX: Update register/macros/devices/routine names and pmx dev registration to implement single image for multiple boards Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
                   ` (11 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Now that all three SPEAr13xx platforms can be built into one kernel,
rework KConfig to allow this. Move everything into one KConfig file
while we are here.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/mach-spear13xx/Kconfig     |   23 ++++++++++++++---------
 arch/arm/mach-spear13xx/Kconfig1300 |   17 -----------------
 arch/arm/mach-spear13xx/Kconfig1310 |   17 -----------------
 3 files changed, 14 insertions(+), 43 deletions(-)
 delete mode 100644 arch/arm/mach-spear13xx/Kconfig1300
 delete mode 100644 arch/arm/mach-spear13xx/Kconfig1310

diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
index cc8faa4..229ef93 100644
--- a/arch/arm/mach-spear13xx/Kconfig
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -4,9 +4,20 @@
 
 if ARCH_SPEAR13XX
 
-choice
-	prompt "SPEAr13XX Family"
-	default MACH_SPEAR1300
+menu "SPEAr13xx Implementations"
+config BOARD_SPEAR1300_EVB
+	bool "SPEAr1300 Evaluation Board"
+	select MACH_SPEAR1300
+	help
+	  Supports ST SPEAr1300 Evaluation Board
+
+config BOARD_SPEAR1310_EVB
+	bool "SPEAr1310 Evaluation Board"
+	select MACH_SPEAR1310
+	help
+	  Supports ST SPEAr1310 Evaluation Board
+
+endmenu
 
 config MACH_SPEAR1300
 	bool "SPEAr1300"
@@ -18,10 +29,4 @@ config MACH_SPEAR1310
 	help
 	  Supports ST SPEAr1310 Machine
 
-endchoice
-
-# Adding SPEAr13XX machine specific configuration files
-source "arch/arm/mach-spear13xx/Kconfig1300"
-source "arch/arm/mach-spear13xx/Kconfig1310"
-
 endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Kconfig1300 b/arch/arm/mach-spear13xx/Kconfig1300
deleted file mode 100644
index 5d6feb1..0000000
--- a/arch/arm/mach-spear13xx/Kconfig1300
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr1300 machine configuration file
-#
-
-if MACH_SPEAR1300
-
-choice
-	prompt "SPEAr1300 Boards"
-	default BOARD_SPEAR1300_EVB
-
-config BOARD_SPEAR1300_EVB
-	bool "SPEAr1300 Evaluation Board"
-	help
-	  Supports ST SPEAr1300 Evaluation Board
-endchoice
-
-endif #MACH_SPEAR1300
diff --git a/arch/arm/mach-spear13xx/Kconfig1310 b/arch/arm/mach-spear13xx/Kconfig1310
deleted file mode 100644
index ad61820..0000000
--- a/arch/arm/mach-spear13xx/Kconfig1310
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SPEAr1310 machine configuration file
-#
-
-if MACH_SPEAR1310
-
-choice
-	prompt "SPEAr1310 Boards"
-	default BOARD_SPEAR1310_EVB
-
-config BOARD_SPEAR1310_EVB
-	bool "SPEAr1310 Evaluation Board"
-	help
-	  Supports ST SPEAr1310 Evaluation Board
-endchoice
-
-endif #MACH_SPEAR1310
-- 
1.7.2.2

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

* [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (62 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 71/74] SPEAr13xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-09-02 15:40   ` Russell King - ARM Linux
  2010-08-30 10:39 ` [PATCH 73/74] ST SPEAr: Updating defconfigs Viresh KUMAR
                   ` (10 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

We only need one defconfig for SPEAr13xx now since we can build all
boards into one kernel.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
---
 arch/arm/configs/spear1310-smp_defconfig           |  875 --------------------
 ...spear1300-smp_defconfig => spear13xx_defconfig} |   21 +-
 2 files changed, 17 insertions(+), 879 deletions(-)
 delete mode 100644 arch/arm/configs/spear1310-smp_defconfig
 rename arch/arm/configs/{spear1300-smp_defconfig => spear13xx_defconfig} (98%)

diff --git a/arch/arm/configs/spear1310-smp_defconfig b/arch/arm/configs/spear1310-smp_defconfig
deleted file mode 100644
index 2ca577b..0000000
--- a/arch/arm/configs/spear1310-smp_defconfig
+++ /dev/null
@@ -1,875 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32
-# Tue May 25 16:10:10 2010
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_TREE_RCU=y
-# CONFIG_TREE_PREEMPT_RCU is not set
-# CONFIG_RCU_TRACE is not set
-CONFIG_RCU_FANOUT=32
-# CONFIG_RCU_FANOUT_EXACT is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_RELAY is not set
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-# CONFIG_EMBEDDED is not set
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_COMPAT_BRK=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-CONFIG_HAVE_CLK=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-CONFIG_MMU=y
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_STMP3XXX is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5PC1XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
-CONFIG_PLAT_SPEAR=y
-# CONFIG_ARCH_SPEAR3XX is not set
-# CONFIG_ARCH_SPEAR6XX is not set
-CONFIG_ARCH_SPEAR13XX=y
-CONFIG_MACH_SPEAR1310=y
-CONFIG_BOARD_SPEAR1310_EVB=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_V7=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_ARM_THUMBEE is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_HAS_TLS_REG=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
-# CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-CONFIG_ARM_GIC=y
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-CONFIG_ARM_AMBA=y
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_SMP=y
-CONFIG_HAVE_ARM_SCU=y
-CONFIG_HAVE_ARM_TWD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_NR_CPUS=2
-# CONFIG_HOTPLUG_CPU is not set
-CONFIG_LOCAL_TIMERS=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_HZ=100
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_FPE_NWFPE is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_NET is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_TESTS is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_MG_DISK is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_AMBAKMI is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_AMBA_PL010 is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-# CONFIG_GPIO_PL061 is not set
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-
-#
-# AC97 GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_MEDIA_SUPPORT is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
-
-#
-# TI VLYNQ
-#
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-# CONFIG_INOTIFY is not set
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-# CONFIG_JFFS2_SUMMARY is not set
-# CONFIG_JFFS2_FS_XATTR is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-CONFIG_DEBUG_SPINLOCK=y
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-CONFIG_DEBUG_MEMORY_INIT=y
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_RCU_CPU_STALL_DETECTOR=y
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_PAGE_POISONING is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-# CONFIG_BOOT_TRACER is not set
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear1300-smp_defconfig b/arch/arm/configs/spear13xx_defconfig
similarity index 98%
rename from arch/arm/configs/spear1300-smp_defconfig
rename to arch/arm/configs/spear13xx_defconfig
index 98502da..908880f 100644
--- a/arch/arm/configs/spear1300-smp_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.32
-# Mon Apr 19 15:37:56 2010
+# Thu Aug 19 16:11:33 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -15,6 +15,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -184,11 +185,17 @@ CONFIG_MMU=y
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_BCMRING is not set
 CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR13XX=y
 # CONFIG_ARCH_SPEAR3XX is not set
 # CONFIG_ARCH_SPEAR6XX is not set
-CONFIG_ARCH_SPEAR13XX=y
-CONFIG_MACH_SPEAR1300=y
+
+#
+# SPEAr13xx Implementations
+#
 CONFIG_BOARD_SPEAR1300_EVB=y
+CONFIG_BOARD_SPEAR1310_EVB=y
+CONFIG_MACH_SPEAR1300=y
+CONFIG_MACH_SPEAR1310=y
 
 #
 # Processor Type
@@ -216,6 +223,8 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
@@ -227,8 +236,9 @@ CONFIG_COMMON_CLKDEV=y
 # Bus support
 #
 CONFIG_ARM_AMBA=y
+# CONFIG_PCI is not set
 # CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCCARD is not set
 
 #
@@ -287,6 +297,7 @@ CONFIG_CMDLINE=""
 #
 # CPU Power Management
 #
+# CONFIG_CPU_FREQ is not set
 # CONFIG_CPU_IDLE is not set
 
 #
@@ -384,6 +395,7 @@ CONFIG_MTD_CFI_I2=y
 #
 # Self-contained MTD device drivers
 #
+CONFIG_MTD_SPEAR_SMI=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -419,6 +431,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_SPEAR13XX_PCIE_GADGET is not set
 # CONFIG_C2PORT is not set
 
 #
-- 
1.7.2.2

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

* [PATCH 73/74] ST SPEAr: Updating defconfigs
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (63 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:39 ` [PATCH 74/74] ST SPEAr: Enabling devices in various evb.c files Viresh KUMAR
                   ` (9 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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 | 1015 ++++++++++++++++++++++--
 arch/arm/configs/spear3xx_defconfig  | 1480 +++++++++++++++++++++++++++++++++-
 arch/arm/configs/spear6xx_defconfig  | 1290 +++++++++++++++++++++++++++++-
 3 files changed, 3683 insertions(+), 102 deletions(-)

diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index 908880f..ed05cbc 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -1,13 +1,15 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32
-# Thu Aug 19 16:11:33 2010
+# Linux kernel version: 2.6.36-rc2
+# Thu Aug 26 15:45:55 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -18,6 +20,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -29,26 +32,35 @@ CONFIG_CONSTRUCTORS=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
 
 #
 # RCU Subsystem
 #
 CONFIG_TREE_RCU=y
-# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -57,11 +69,13 @@ CONFIG_NAMESPACES=y
 # CONFIG_IPC_NS is not set
 # CONFIG_USER_NS is not set
 # CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -83,29 +97,33 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
-# CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_CLK=y
 
 #
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -126,15 +144,42 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_FREEZER is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -144,8 +189,11 @@ CONFIG_MMU=y
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
 # CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
@@ -154,36 +202,44 @@ CONFIG_MMU=y
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
 # CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_LPC32XX is not set
 # CONFIG_ARCH_MV78XX0 is not set
 # CONFIG_ARCH_ORION5X is not set
 # CONFIG_ARCH_MMP is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_TEGRA is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_S5PV310 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR13XX=y
 # CONFIG_ARCH_SPEAR3XX is not set
@@ -200,7 +256,6 @@ CONFIG_MACH_SPEAR1310=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
@@ -222,13 +277,14 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_HAS_TLS_REG=y
-CONFIG_OUTER_CACHE=y
-CONFIG_CACHE_L2X0=y
+# CONFIG_CACHE_L2X0 is not set
 CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
 # CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
 CONFIG_ARM_GIC=y
 CONFIG_COMMON_CLKDEV=y
 
@@ -236,9 +292,17 @@ CONFIG_COMMON_CLKDEV=y
 # Bus support
 #
 CONFIG_ARM_AMBA=y
-# CONFIG_PCI is not set
-# CONFIG_PCI_SYSCALL is not set
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCIEAER is not set
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEBUG is not set
 # CONFIG_PCCARD is not set
 
 #
@@ -255,7 +319,7 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_NR_CPUS=2
-# CONFIG_HOTPLUG_CPU is not set
+CONFIG_HOTPLUG_CPU=y
 CONFIG_LOCAL_TIMERS=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
@@ -267,23 +331,24 @@ CONFIG_OABI_COMPAT=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
+# CONFIG_SPARSE_IRQ is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_ALIGNMENT_TRAP=y
 # CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
 
 #
 # Boot options
@@ -293,11 +358,26 @@ CONFIG_ZBOOT_ROM_BSS=0
 CONFIG_CMDLINE=""
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
+# CONFIG_AUTO_ZRELADDR is not set
+CONFIG_ZRELADDR=0x00008000
 
 #
 # CPU Power Management
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=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_CPU_IDLE is not set
 
 #
@@ -323,9 +403,99 @@ CONFIG_BINFMT_MISC=y
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_NVS=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_NET is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_RPS=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
 
 #
 # Device Drivers
@@ -335,7 +505,8 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -344,6 +515,7 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_TESTS is not set
@@ -365,13 +537,16 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
 # CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -382,6 +557,10 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -390,12 +569,21 @@ CONFIG_MTD_CFI_I2=y
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
 CONFIG_MTD_SPEAR_SMI=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -407,7 +595,22 @@ CONFIG_MTD_SPEAR_SMI=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_SPEAR=y
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -421,35 +624,251 @@ CONFIG_MTD_SPEAR_SMI=y
 # CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 # CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_SPEAR13XX_PCIE_GADGET is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
 # CONFIG_C2PORT is not set
 
 #
 # EEPROM support
 #
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
+CONFIG_CHELSIO_T4VF_DEPENDS=y
+# CONFIG_CHELSIO_T4VF is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+# CONFIG_TR is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
 #
@@ -458,6 +877,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -467,13 +887,28 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
 
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -486,7 +921,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -499,6 +936,8 @@ CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -511,8 +950,15 @@ CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_AMBA_PL010 is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+# CONFIG_SERIAL_MFD_HSU is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -520,11 +966,83 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_HW_RANDOM=m
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
 # CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DESIGNWARE=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PL022=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
 
 #
 # PPS support
@@ -533,28 +1051,47 @@ CONFIG_MAX_RAW_DEVS=8192
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
+CONFIG_GPIO_SYSFS=y
 
 #
 # Memory mapped GPIO expanders:
 #
-# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_IT8761E is not set
+CONFIG_GPIO_PL061=y
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_RDC321X is not set
 
 #
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
 
 #
 # AC97 GPIO expanders:
 #
+
+#
+# MODULbus GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -566,25 +1103,50 @@ CONFIG_SSB_POSSIBLE=y
 # Sonics Silicon Backplane
 #
 # CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
+CONFIG_MFD_SUPPORT=y
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC35892 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_TPS6586X is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
@@ -598,24 +1160,224 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=y
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+# CONFIG_MMC_SDHCI_PLTFM is not set
+CONFIG_MMC_SDHCI_SPEAR=y
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# TI VLYNQ
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
 #
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_SPEAR=y
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
 #
@@ -640,13 +1402,14 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
-# CONFIG_INOTIFY is not set
 CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=m
@@ -666,9 +1429,9 @@ CONFIG_AUTOFS4_FS=m
 #
 # DOS/FAT/NT Filesystems
 #
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 # CONFIG_NTFS_FS is not set
@@ -703,6 +1466,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -713,6 +1477,23 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -760,7 +1541,7 @@ CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
+CONFIG_NLS_ASCII=y
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -775,6 +1556,7 @@ CONFIG_NLS_ASCII=m
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
@@ -790,9 +1572,8 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
 CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
@@ -815,6 +1596,7 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 CONFIG_DEBUG_MEMORY_INIT=y
@@ -822,12 +1604,15 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
@@ -838,23 +1623,22 @@ CONFIG_FTRACE=y
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_ENABLE_DEFAULT_TRACERS is not set
-# CONFIG_BOOT_TRACER is not set
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
+# CONFIG_ARM_UNWIND is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -862,8 +1646,102 @@ CONFIG_ARM_UNWIND=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
@@ -880,9 +1758,12 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
index 3b0e955..a928329 100644
--- a/arch/arm/configs/spear3xx_defconfig
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -1,25 +1,263 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35
+# Mon Aug 23 14:09:21 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
 CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
 CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR13XX is not set
 CONFIG_ARCH_SPEAR3XX=y
 # CONFIG_ARCH_SPEAR6XX is not set
-CONFIG_MACH_SPEAR300=y
-CONFIG_MACH_SPEAR310=y
-CONFIG_MACH_SPEAR320=y
+
+#
+# SPEAr3xx Implementations
+#
 CONFIG_BOARD_SPEAR300_EVB=y
 CONFIG_BOARD_SPEAR310_EVB=y
 CONFIG_BOARD_SPEAR320_EVB=y
+CONFIG_MACH_SPEAR300=y
+CONFIG_MACH_SPEAR310=y
+CONFIG_MACH_SPEAR320=y
+CONFIG_SPEAR_PWM=y
 
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
@@ -65,7 +303,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
-# CONFIG_AEABI is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
@@ -76,12 +315,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
@@ -99,6 +336,21 @@ CONFIG_CMDLINE=""
 #
 # CPU Power Management
 #
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=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_CPU_IDLE is not set
 
 #
@@ -120,44 +372,1244 @@ CONFIG_BINFMT_ELF=y
 CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_NVS=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_MTD_SPEAR_SMI=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_SPEAR=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DESIGNWARE=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PL022=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
 CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_ARM_SP805_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TC35892 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ043T1DG01 is not set
+CONFIG_FB_ARMCLCD_SAMSUNG_LMS700=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
+# CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE is not set
+# CONFIG_FB_ARMCLCD_HITACHI is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
 # CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=y
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
+CONFIG_MMC_SDHCI_SPEAR=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_SPEAR=y
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
 CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
 CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
index 3dfc6bb..cb85a99 100644
--- a/arch/arm/configs/spear6xx_defconfig
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -1,13 +1,15 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32
-# Thu Aug 19 15:23:42 2010
+# Linux kernel version: 2.6.35
+# Mon Aug 23 14:09:34 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -19,6 +21,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -28,13 +31,214 @@ CONFIG_CONSTRUCTORS=y
 # General setup
 #
 CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
 CONFIG_PLAT_SPEAR=y
 # CONFIG_ARCH_SPEAR13XX is not set
 # CONFIG_ARCH_SPEAR3XX is not set
@@ -49,7 +253,6 @@ CONFIG_MACH_SPEAR600=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
@@ -95,7 +298,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
-# CONFIG_AEABI is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
@@ -106,12 +310,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
@@ -129,7 +331,21 @@ CONFIG_CMDLINE=""
 #
 # CPU Power Management
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=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_CPU_IDLE is not set
 
 #
@@ -151,19 +367,265 @@ CONFIG_BINFMT_ELF=y
 CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_NVS=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_MTD_SPEAR_SMI=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_SPEAR=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 # CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
 # EEPROM support
 #
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -171,12 +633,80 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
 #
@@ -184,6 +714,13 @@ CONFIG_HAVE_IDE=y
 #
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
@@ -195,10 +732,14 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
 # CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
@@ -215,8 +756,11 @@ CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -230,6 +774,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_AMBAKMI is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -242,6 +787,7 @@ CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
 
 #
 # Serial drivers
@@ -254,6 +800,14 @@ CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_AMBA_PL010 is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
@@ -261,30 +815,155 @@ CONFIG_HW_RANDOM=m
 # CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DESIGNWARE=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PL022=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
 CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
 
 #
-# Sonics Silicon Backplane
+# Watchdog Device Drivers
 #
-# CONFIG_SSB is not set
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_ARM_SP805_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multifunction device drivers
+# Sonics Silicon Backplane
 #
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TC35892 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -293,7 +972,43 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ043T1DG01 is not set
+CONFIG_FB_ARMCLCD_SAMSUNG_LMS700=y
+# CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
+# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
+# CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE is not set
+# CONFIG_FB_ARMCLCD_HITACHI is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -306,18 +1021,260 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=y
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_SPEAR=y
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
 CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -330,6 +1287,18 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -340,19 +1309,298 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
-- 
1.7.2.2

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

* [PATCH 74/74] ST SPEAr: Enabling devices in various evb.c files
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (64 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 73/74] ST SPEAr: Updating defconfigs Viresh KUMAR
@ 2010-08-30 10:39 ` Viresh KUMAR
  2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
                   ` (8 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

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   |    6 ++
 arch/arm/mach-spear13xx/include/mach/irqs.h      |   10 +-
 arch/arm/mach-spear13xx/include/mach/spear1310.h |   18 ++++-
 arch/arm/mach-spear13xx/spear1310.c              |   86 ++++++++++++++++++++++
 arch/arm/mach-spear13xx/spear1310_evb.c          |    9 ++
 arch/arm/mach-spear3xx/spear310_evb.c            |    5 +
 arch/arm/mach-spear3xx/spear320_evb.c            |    6 ++
 7 files changed, 134 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 75e9b82..a9160d2 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -257,8 +257,14 @@ void __init spear1300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 /* spear1310 declarations */
 #ifdef CONFIG_MACH_SPEAR1310
 /* Add spear1310 machine device structure declarations here */
+extern struct amba_device spear1310_uart1_device;
+extern struct amba_device spear1310_uart2_device;
+extern struct amba_device spear1310_uart3_device;
+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/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
index 19ebdf0..1900a63 100644
--- a/arch/arm/mach-spear13xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -97,11 +97,11 @@
 #define IRQ_CCAN1		(IRQ_SHPI_START + 83)
 #define IRQ_TDM0		(IRQ_SHPI_START + 84)
 #define IRQ_TDM1		(IRQ_SHPI_START + 85)
-#define IRQ_UART0		(IRQ_SHPI_START + 86)
-#define IRQ_UART1		(IRQ_SHPI_START + 87)
-#define IRQ_UART2		(IRQ_SHPI_START + 88)
-#define IRQ_UART3		(IRQ_SHPI_START + 89)
-#define IRQ_UART4		(IRQ_SHPI_START + 90)
+#define IRQ_UART1		(IRQ_SHPI_START + 86)
+#define IRQ_UART2		(IRQ_SHPI_START + 87)
+#define IRQ_UART3		(IRQ_SHPI_START + 88)
+#define IRQ_UART4		(IRQ_SHPI_START + 89)
+#define IRQ_UART5		(IRQ_SHPI_START + 90)
 #define IRQ_I2C_CNTR		(IRQ_SHPI_START + 91)
 #define IRQ_GMAC0_SBD		(IRQ_SHPI_START + 92)
 #define IRQ_GMAC0_PMT		(IRQ_SHPI_START + 93)
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310.h b/arch/arm/mach-spear13xx/include/mach/spear1310.h
index 5fa69bb..a2b6e55 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear1310.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310.h
@@ -16,9 +16,25 @@
 #ifndef __MACH_SPEAR1310_H
 #define __MACH_SPEAR1310_H
 
+#define SPEAR1310_TDM_E1_0_BASE		UL(0x6C200000)
+#define SPEAR1310_TDM_E1_1_BASE		UL(0x6C300000)
+#define SPEAR1310_RS485_0_BASE		UL(0x6C400000)
+#define SPEAR1310_RS485_1_BASE		UL(0x6C500000)
+#define SPEAR1310_RAS_BASE		UL(0x6C800000)
+#define SPEAR1310_GETH1_BASE		UL(0x6D000000)
+#define SPEAR1310_GETH2_BASE		UL(0x6D100000)
+#define SPEAR1310_GETH3_BASE		UL(0x6D200000)
+#define SPEAR1310_GETH4_BASE		UL(0x6D300000)
+#define SPEAR1310_UART1_BASE		UL(0x6D400000)
+#define SPEAR1310_UART2_BASE		UL(0x6D500000)
+#define SPEAR1310_UART3_BASE		UL(0x6D600000)
+#define SPEAR1310_UART4_BASE		UL(0x6D700000)
+#define SPEAR1310_UART5_BASE		UL(0x6D800000)
+#define SPEAR1310_I2C1_BASE		UL(0x6D900000)
 #define SPEAR1310_CAN0_BASE		UL(0x6DA00000)
 #define SPEAR1310_CAN1_BASE		UL(0x6DB00000)
-#define SPEAR1310_RAS_BASE		UL(0x6C800000)
+#define SPEAR1310_FSMC1_MEM_BASE	UL(0x70000000)
+#define SPEAR1310_FSMC1_BASE		UL(0x6FF00000)
 
 /* RAS Area Control Register */
 #define SPEAR1310_RAS_CTRL_REG1		(SPEAR1310_RAS_BASE + 0x4)
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 5cadea8..2f7fabc 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -325,6 +325,70 @@ struct pmx_dev pmx_can = {
 };
 
 /* Add spear1310 specific devices here */
+/* uart1 device registeration */
+struct amba_device spear1310_uart1_device = {
+	.dev = {
+		.init_name = "uart1",
+	},
+	.res = {
+		.start = SPEAR1310_UART1_BASE,
+		.end = SPEAR1310_UART1_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART1, NO_IRQ},
+};
+
+/* uart2 device registeration */
+struct amba_device spear1310_uart2_device = {
+	.dev = {
+		.init_name = "uart2",
+	},
+	.res = {
+		.start = SPEAR1310_UART2_BASE,
+		.end = SPEAR1310_UART2_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART2, NO_IRQ},
+};
+
+/* uart3 device registeration */
+struct amba_device spear1310_uart3_device = {
+	.dev = {
+		.init_name = "uart3",
+	},
+	.res = {
+		.start = SPEAR1310_UART3_BASE,
+		.end = SPEAR1310_UART3_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART3, NO_IRQ},
+};
+
+/* uart4 device registeration */
+struct amba_device spear1310_uart4_device = {
+	.dev = {
+		.init_name = "uart4",
+	},
+	.res = {
+		.start = SPEAR1310_UART4_BASE,
+		.end = SPEAR1310_UART4_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART4, NO_IRQ},
+};
+
+/* uart5 device registeration */
+struct amba_device spear1310_uart5_device = {
+	.dev = {
+		.init_name = "uart5",
+	},
+	.res = {
+		.start = SPEAR1310_UART5_BASE,
+		.end = SPEAR1310_UART5_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART5, NO_IRQ},
+};
 
 /* CAN device registeration */
 static struct resource can0_resources[] = {
@@ -363,6 +427,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,
+};
+
 void __init spear1310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 		u8 pmx_dev_count)
 {
diff --git a/arch/arm/mach-spear13xx/spear1310_evb.c b/arch/arm/mach-spear13xx/spear1310_evb.c
index 6335b88..d1c728d 100644
--- a/arch/arm/mach-spear13xx/spear1310_evb.c
+++ b/arch/arm/mach-spear13xx/spear1310_evb.c
@@ -64,7 +64,15 @@ 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 */
+	&spear1310_uart1_device,
+	&spear1310_uart2_device,
+	&spear1310_uart3_device,
+	&spear1310_uart4_device,
+	&spear1310_uart5_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
@@ -84,6 +92,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear1310 specific devices */
 	&spear1310_can0_device,
 	&spear1310_can1_device,
+	&spear1310_i2c1_device,
 };
 
 /* keyboard specific platform data */
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 70e473d..3d87d66 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -65,6 +65,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_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index de161c8..98ab4e6 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -58,11 +58,16 @@ 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_clcd_device,
+	&spear320_ssp_device[0],
+	&spear320_ssp_device[1],
+	&spear320_uart1_device,
+	&spear320_uart2_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
@@ -77,6 +82,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear320 specific devices */
 	&spear320_can0_device,
 	&spear320_can1_device,
+	&spear320_emi_nor_device,
 	&spear320_i2c1_device,
 	&spear320_nand_device,
 	&spear320_plgpio_device,
-- 
1.7.2.2

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (65 preceding siblings ...)
  2010-08-30 10:39 ` [PATCH 74/74] ST SPEAr: Enabling devices in various evb.c files Viresh KUMAR
@ 2010-08-30 10:41 ` Viresh KUMAR
  2010-09-01  1:22   ` [rtc-linux] " Wan ZongShun
                     ` (2 more replies)
  2010-08-30 10:42 ` [PATCH 17/74] ST SPEAr: Adding USB Host support Viresh KUMAR
                   ` (7 subsequent siblings)
  74 siblings, 3 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear13xx.c            |   19 +
 arch/arm/mach-spear3xx/clock.c                 |    2 +-
 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/clock.c                 |    2 +-
 arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    1 +
 arch/arm/mach-spear6xx/spear6xx.c              |   19 +
 drivers/rtc/Kconfig                            |    7 +
 drivers/rtc/Makefile                           |    1 +
 drivers/rtc/rtc-spear.c                        |  598 ++++++++++++++++++++++++
 17 files changed, 674 insertions(+), 3 deletions(-)
 create mode 100644 drivers/rtc/rtc-spear.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index cef3b13..cc692cc 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -736,7 +736,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.con_id = "osc3_25m_clk",	.clk = &osc3_25m_clk},
 
 	/* clock derived from 32 KHz osc clk */
-	{.dev_id = "rtc",		.clk = &rtc_clk},
+	{.dev_id = "rtc-spear",		.clk = &rtc_clk},
 
 	/* clock derived from 24/25 MHz osc1/osc3 clk */
 	{.con_id = "pll1_clk",		.clk = &pll1_clk},
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 41c1a53..dc80421 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -30,6 +30,7 @@
 
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device uart_device;
+extern struct platform_device rtc_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear1300 machine device structure declarations here */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index d72c8a8..60c5fee 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -22,6 +22,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 static struct platform_device *plat_devs[] __initdata = {
+	&rtc_device,
 };
 
 static void __init spear1300_evb_init(void)
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index d11e300..bdca713 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -37,6 +37,25 @@ struct amba_device 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 rtc_device = {
+	.name = "rtc-spear",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(rtc_resources),
+	.resource = rtc_resources,
+};
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index dc19666..147d0a3 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -467,7 +467,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
 	{ .con_id = "osc_24m_clk",	.clk = &osc_24m_clk},
 	/* clock derived from 32 KHz osc clk */
-	{ .dev_id = "rtc",		.clk = &rtc_clk},
+	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
 	/* clock derived from 24 MHz osc clk */
 	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
 	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index d76ee98..408bb8d 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 gpio_device;
 extern struct amba_device uart_device;
+extern struct platform_device 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 3bb7fbc..392ee4a 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 */
+	&rtc_device,
 
 	/* spear300 specific devices */
 };
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 7dd93bd..15ca8fc 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -50,6 +50,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&rtc_device,
 
 	/* spear310 specific devices */
 	&plgpio_device,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 82f4e76..48155cc 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -48,6 +48,7 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&rtc_device,
 
 	/* spear320 specific devices */
 	&plgpio_device,
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 89cf8ea..6d8791e 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -54,6 +54,25 @@ struct amba_device uart_device = {
 	.irq = {IRQ_UART, NO_IRQ},
 };
 
+/* 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 = 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,
+};
+
 /* Do spear3xx familiy common initialization part here */
 void __init spear3xx_init(void)
 {
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 4a91991..66fc622 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -569,7 +569,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
 	{ .con_id = "osc_30m_clk",	.clk = &osc_30m_clk},
 	/* clock derived from 32 KHz os		 clk */
-	{ .dev_id = "rtc",		.clk = &rtc_clk},
+	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
 	/* clock derived from 30 MHz os		 clk */
 	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
 	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index d6a04f2..674b16c 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 clcd_device;
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_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 88e69f4..861e83d 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 d0f6b9d..1e403cb 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -121,6 +121,25 @@ struct amba_device gpio_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)
 {
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 48ca713..f099473 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -625,6 +625,13 @@ config RTC_DRV_WM8350
 	  This driver can also be built as a module. If so, the module
 	  will be called "rtc-wm8350".
 
+config RTC_DRV_SPEAR
+	tristate "SPEAR ST RTC"
+	default y
+	help
+	 If you say Y here you will get support for the RTC found on
+	 spear
+
 config RTC_DRV_PCF50633
 	depends on MFD_PCF50633
 	tristate "NXP PCF50633 RTC"
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0f207b3..44df01a 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_S35390A)	+= rtc-s35390a.o
 obj-$(CONFIG_RTC_DRV_S3C)	+= rtc-s3c.o
 obj-$(CONFIG_RTC_DRV_SA1100)	+= rtc-sa1100.o
 obj-$(CONFIG_RTC_DRV_SH)	+= rtc-sh.o
+obj-$(CONFIG_RTC_DRV_SPEAR)	+= rtc-spear.o
 obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_STMP)	+= rtc-stmp3xxx.o
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
new file mode 100644
index 0000000..5b49124
--- /dev/null
+++ b/drivers/rtc/rtc-spear.c
@@ -0,0 +1,598 @@
+/*
+ * drivers/rtc/rtc-spear.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/bcd.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/mach/time.h>
+
+/* RTC registers */
+#define TIME_REG		0x00
+#define DATE_REG		0x04
+#define ALARM_TIME_REG		0x08
+#define ALARM_DATE_REG		0x0C
+#define CTRL_REG		0x10
+#define STATUS_REG		0x14
+
+/* TIME_REG & ALARM_TIME_REG */
+#define SECONDS_UNITS		(0xf<<0)	/* seconds units position */
+#define SECONDS_TENS		(0x7<<4)	/* seconds tens position */
+#define MINUTES_UNITS		(0xf<<8)	/* minutes units position */
+#define MINUTES_TENS		(0x7<<12)	/* minutes tens position */
+#define HOURS_UNITS		(0xf<<16)	/* hours units position */
+#define HOURS_TENS		(0x3<<20)	/* hours tens position */
+
+/* DATE_REG & ALARM_DATE_REG */
+#define DAYS_UNITS		(0xf<<0)	/* days units position */
+#define DAYS_TENS		(0x3<<4)	/* days tens position */
+#define MONTHS_UNITS		(0xf<<8)	/* months units position */
+#define MONTHS_TENS		(0x1<<12)	/* months tens position */
+#define YEARS_UNITS		(0xf<<16)	/* years units position */
+#define YEARS_TENS		(0xf<<20)	/* years tens position */
+#define YEARS_HUNDREDS		(0xf<<24)	/* years hundereds position */
+#define YEARS_MILLENIUMS	(0xf<<28)	/* years millenium position */
+
+/* MASK SHIFT TIME_REG & ALARM_TIME_REG*/
+#define SECOND_SHIFT		0x00		/* seconds units */
+#define MINUTE_SHIFT		0x08		/* minutes units position */
+#define HOUR_SHIFT		0x10		/* hours units position */
+#define MDAY_SHIFT		0x00		/* Month day shift */
+#define MONTH_SHIFT		0x08		/* Month shift */
+#define YEAR_SHIFT		0x10		/* Year shift */
+
+#define SECOND_MASK		0x7F
+#define MIN_MASK		0x7F
+#define HOUR_MASK		0x3F
+#define DAY_MASK		0x3F
+#define MONTH_MASK		0x7F
+#define YEAR_MASK		0xFFFF
+
+/* date reg equal to time reg, for debug only */
+#define TIME_BYP		(1<<9)
+#define INT_ENABLE		(1<<31)		/* interrupt enable */
+
+/* STATUS_REG */
+#define CLK_UNCONNECTED		(1<<0)
+#define PEND_WR_TIME		(1<<2)
+#define PEND_WR_DATE		(1<<3)
+#define LOST_WR_TIME		(1<<4)
+#define LOST_WR_DATE		(1<<5)
+#define RTC_INT_MASK		(1<<31)
+#define STATUS_BUSY		(PEND_WR_TIME | PEND_WR_DATE)
+#define STATUS_FAIL		(LOST_WR_TIME | LOST_WR_DATE)
+
+struct spear_rtc_config {
+	struct clk *clk;
+	spinlock_t lock;
+	void __iomem *ioaddr;
+};
+
+static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&config->lock, flags);
+	val = readl(config->ioaddr + STATUS_REG);
+	val |= RTC_INT_MASK;
+	writel(val, config->ioaddr + STATUS_REG);
+	spin_unlock_irqrestore(&config->lock, flags);
+}
+
+static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+
+	val = readl(config->ioaddr + CTRL_REG);
+	if (!(val & INT_ENABLE)) {
+		spear_rtc_clear_interrupt(config);
+		val |= INT_ENABLE;
+		writel(val, config->ioaddr + CTRL_REG);
+	}
+}
+
+static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+
+	val = readl(config->ioaddr + CTRL_REG);
+	if (val & INT_ENABLE) {
+		val &= ~INT_ENABLE;
+		writel(val, config->ioaddr + CTRL_REG);
+	}
+}
+
+static inline int is_write_complete(struct spear_rtc_config *config)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&config->lock, flags);
+	if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL)
+		ret = -EIO;
+	spin_unlock_irqrestore(&config->lock, flags);
+
+	return ret;
+}
+
+static void rtc_wait_not_busy(struct spear_rtc_config *config)
+{
+	int status, count = 0;
+	unsigned long flags;
+
+	/* Assuming BUSY may stay active for 80 msec) */
+	for (count = 0; count < 80; count++) {
+		spin_lock_irqsave(&config->lock, flags);
+		status = readl(config->ioaddr + STATUS_REG);
+		spin_unlock_irqrestore(&config->lock, flags);
+		if ((status & STATUS_BUSY) == 0)
+			break;
+		/* check status busy, after each msec */
+		msleep(1);
+	}
+}
+
+static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
+{
+	struct rtc_device *rtc = (struct rtc_device *)dev_id;
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned long flags, events = 0;
+	unsigned int irq_data;
+
+	spin_lock_irqsave(&config->lock, flags);
+	irq_data = readl(config->ioaddr + STATUS_REG);
+	spin_unlock_irqrestore(&config->lock, flags);
+
+	if ((irq_data & RTC_INT_MASK)) {
+		spear_rtc_clear_interrupt(config);
+		events = RTC_IRQF | RTC_AF;
+		rtc_update_irq(rtc, 1, events);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+
+}
+
+static int tm2bcd(struct rtc_time *tm)
+{
+	if (rtc_valid_tm(tm) != 0)
+		return -EINVAL;
+	tm->tm_sec = bin2bcd(tm->tm_sec);
+	tm->tm_min = bin2bcd(tm->tm_min);
+	tm->tm_hour = bin2bcd(tm->tm_hour);
+	tm->tm_mday = bin2bcd(tm->tm_mday);
+	tm->tm_mon = bin2bcd(tm->tm_mon + 1);
+	tm->tm_year = bin2bcd(tm->tm_year);
+
+	return 0;
+}
+
+static void bcd2tm(struct rtc_time *tm)
+{
+	tm->tm_sec = bcd2bin(tm->tm_sec);
+	tm->tm_min = bcd2bin(tm->tm_min);
+	tm->tm_hour = bcd2bin(tm->tm_hour);
+	tm->tm_mday = bcd2bin(tm->tm_mday);
+	tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
+	/* epoch == 1900 */
+	tm->tm_year = bcd2bin(tm->tm_year);
+}
+
+/*
+ * spear_rtc_read_time - set the time
+ * @dev: rtc device in use
+ * @tm: holds date and time
+ *
+ * This function read time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date;
+
+	/* we don't report wday/yday/isdst ... */
+	rtc_wait_not_busy(config);
+
+	time = readl(config->ioaddr + TIME_REG);
+	date = readl(config->ioaddr + DATE_REG);
+	tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
+	tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
+	tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
+	tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
+	tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
+	tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
+
+	bcd2tm(tm);
+	return 0;
+}
+
+/*
+ * spear_rtc_set_time - set the time
+ * @dev: rtc device in use
+ * @tm: holds date and time
+ *
+ * This function set time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date, err = 0;
+
+	if (tm2bcd(tm) < 0)
+		return -EINVAL;
+
+	rtc_wait_not_busy(config);
+	time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) |
+		(tm->tm_hour << HOUR_SHIFT);
+	date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) |
+		(tm->tm_year << YEAR_SHIFT);
+	writel(time, config->ioaddr + TIME_REG);
+	writel(date, config->ioaddr + DATE_REG);
+	err = is_write_complete(config);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+ * spear_rtc_read_alarm - read the alarm time
+ * @dev: rtc device in use
+ * @alm: holds alarm date and time
+ *
+ * This function read alarm time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date;
+
+	rtc_wait_not_busy(config);
+
+	time = readl(config->ioaddr + ALARM_TIME_REG);
+	date = readl(config->ioaddr + ALARM_DATE_REG);
+	alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
+	alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
+	alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
+	alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
+	alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
+	alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
+
+	bcd2tm(&alm->time);
+	alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE;
+
+	return 0;
+}
+
+/*
+ * spear_rtc_set_alarm - set the alarm time
+ * @dev: rtc device in use
+ * @alm: holds alarm date and time
+ *
+ * This function set alarm time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date, err = 0;
+
+	if (tm2bcd(&alm->time) < 0)
+		return -EINVAL;
+
+	rtc_wait_not_busy(config);
+
+	time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min <<
+			MINUTE_SHIFT) |	(alm->time.tm_hour << HOUR_SHIFT);
+	date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon <<
+			MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT);
+
+	writel(time, config->ioaddr + ALARM_TIME_REG);
+	writel(date, config->ioaddr + ALARM_DATE_REG);
+	err = is_write_complete(config);
+	if (err < 0)
+		return err;
+
+	if (alm->enabled)
+		spear_rtc_enable_interrupt(config);
+	else
+		spear_rtc_disable_interrupt(config);
+
+	return 0;
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+static int
+spear_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct rtc_time tm;
+	struct rtc_wkalrm alm;
+	void __user *uarg = (void __user *)arg;
+	int err = 0;
+
+	switch (cmd) {
+		/* AIE = Alarm Interrupt Enable */
+	case RTC_AIE_OFF:
+		spear_rtc_disable_interrupt(config);
+		break;
+	case RTC_AIE_ON:
+		spear_rtc_enable_interrupt(config);
+		break;
+	case RTC_SET_TIME:
+		if (copy_from_user(&tm, uarg, sizeof(tm)))
+			return -EFAULT;
+		return spear_rtc_set_time(dev, &tm);
+	case RTC_RD_TIME:
+		err = spear_rtc_read_time(dev, &tm);
+		if (err < 0)
+			return err;
+
+		if (copy_to_user(uarg, &tm, sizeof(tm)))
+			return -EFAULT;
+		break;
+	case RTC_ALM_SET:
+		if (copy_from_user(&alm.time, uarg, sizeof(tm)))
+			return -EFAULT;
+		alm.enabled = 0;
+		alm.pending = 0;
+		spear_rtc_set_alarm(dev, &alm);
+		break;
+	case RTC_ALM_READ:
+		err = spear_rtc_read_alarm(dev, &alm);
+		if (err < 0)
+			return err;
+
+		if (copy_to_user(uarg, &alm.time, sizeof(tm)))
+			return -EFAULT;
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+#else
+#define spear_rtc_ioctl	NULL
+#endif
+
+static struct rtc_class_ops spear_rtc_ops = {
+	.ioctl = spear_rtc_ioctl,
+	.read_time = spear_rtc_read_time,
+	.set_time = spear_rtc_set_time,
+	.read_alarm = spear_rtc_read_alarm,
+	.set_alarm = spear_rtc_set_alarm,
+};
+
+static int __devinit spear_rtc_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct rtc_device *rtc;
+	struct spear_rtc_config *config;
+	unsigned int status = 0;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		return -EBUSY;
+	}
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "rtc region already claimed\n");
+		return -EBUSY;
+	}
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(&pdev->dev, "out of memory\n");
+		status = -ENOMEM;
+		goto err_release_region;
+	}
+
+	config->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(config->clk)) {
+		status = PTR_ERR(config->clk);
+		goto err_kfree;
+	}
+
+	status = clk_enable(config->clk);
+	if (status < 0)
+		goto err_clk_put;
+
+	config->ioaddr = ioremap(res->start, resource_size(res));
+	if (!config->ioaddr) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_disable_clock;
+	}
+
+	rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops,
+			THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+				PTR_ERR(rtc));
+		status = PTR_ERR(rtc);
+		goto err_iounmap;
+	}
+	platform_set_drvdata(pdev, rtc);
+	dev_set_drvdata(&rtc->dev, config);
+
+	spin_lock_init(&config->lock);
+
+	/* alarm irqs */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no update irq?\n");
+		status = irq;
+		goto err_clear_platdata;
+	}
+
+	status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc);
+	if (status) {
+		dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
+				claimed\n", irq);
+		goto err_clear_platdata;
+	}
+
+	if (!device_can_wakeup(&pdev->dev))
+		device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+err_clear_platdata:
+	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&rtc->dev, NULL);
+	rtc_device_unregister(rtc);
+err_iounmap:
+	iounmap(config->ioaddr);
+err_disable_clock:
+	clk_disable(config->clk);
+err_clk_put:
+	clk_put(config->clk);
+err_kfree:
+	kfree(config);
+err_release_region:
+	release_mem_region(res->start, resource_size(res));
+
+	return status;
+}
+
+static int __devexit spear_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+	struct resource *res;
+
+	/* leave rtc running, but disable irqs */
+	spear_rtc_disable_interrupt(config);
+	device_init_wakeup(&pdev->dev, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (irq)
+		free_irq(irq, pdev);
+	clk_disable(config->clk);
+	clk_put(config->clk);
+	iounmap(config->ioaddr);
+	kfree(config);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&rtc->dev, NULL);
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(irq);
+	else {
+		spear_rtc_disable_interrupt(config);
+		clk_disable(config->clk);
+	}
+
+	return 0;
+}
+
+static int spear_rtc_resume(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(irq);
+	else {
+		clk_enable(config->clk);
+		spear_rtc_enable_interrupt(config);
+	}
+
+	return 0;
+}
+
+#else
+#define spear_rtc_suspend	NULL
+#define spear_rtc_resume	NULL
+#endif
+
+static void spear_rtc_shutdown(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+
+	spear_rtc_disable_interrupt(config);
+	clk_disable(config->clk);
+}
+
+static struct platform_driver spear_rtc_driver = {
+	.probe = spear_rtc_probe,
+	.remove = __devexit_p(spear_rtc_remove),
+	.suspend = spear_rtc_suspend,
+	.resume = spear_rtc_resume,
+	.shutdown = spear_rtc_shutdown,
+	.driver = {
+		.name = "rtc-spear",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init rtc_init(void)
+{
+	return platform_driver_register(&spear_rtc_driver);
+}
+module_init(rtc_init);
+
+static void __exit rtc_exit(void)
+{
+	platform_driver_unregister(&spear_rtc_driver);
+}
+module_exit(rtc_exit);
+
+MODULE_ALIAS("rtc-spear");
+MODULE_AUTHOR("Rajeev Kumar");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* [PATCH 17/74] ST SPEAr: Adding USB Host support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (66 preceding siblings ...)
  2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
@ 2010-08-30 10:42 ` Viresh KUMAR
  2010-08-30 14:10   ` Alan Stern
  2010-08-30 10:43   ` Viresh KUMAR
                   ` (6 subsequent siblings)
  74 siblings, 1 reply; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Deepak Sikri <deepak.sikri@st.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/clock.c                |    4 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    4 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |    4 +
 arch/arm/mach-spear13xx/spear13xx.c            |  106 +++++++++++
 arch/arm/mach-spear3xx/clock.c                 |    2 +-
 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              |   80 ++++++++
 arch/arm/mach-spear6xx/clock.c                 |    4 +-
 arch/arm/mach-spear6xx/include/mach/generic.h  |    4 +
 arch/arm/mach-spear6xx/spear600_evb.c          |    4 +
 arch/arm/mach-spear6xx/spear6xx.c              |  108 +++++++++++
 drivers/usb/Kconfig                            |    2 +
 drivers/usb/host/ehci-hcd.c                    |    5 +
 drivers/usb/host/ehci-spear.c                  |  210 +++++++++++++++++++++
 drivers/usb/host/ohci-hcd.c                    |    5 +
 drivers/usb/host/ohci-spear.c                  |  240 ++++++++++++++++++++++++
 19 files changed, 789 insertions(+), 5 deletions(-)
 create mode 100644 drivers/usb/host/ehci-spear.c
 create mode 100644 drivers/usb/host/ohci-spear.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 7f7330c..9d97c69 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -774,8 +774,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 
 	/* clock derived from ahb clk */
 	{.dev_id = "smi",		.clk = &smi_clk},
-	{.dev_id = "uhci0",		.clk = &uhci0_clk},
-	{.dev_id = "uhci1",		.clk = &uhci1_clk},
+	{.con_id = "usbh.0_clk",	.clk = &uhci0_clk},
+	{.con_id = "usbh.1_clk",	.clk = &uhci1_clk},
 	{.dev_id = "usbd",		.clk = &usbd_clk},
 	{.dev_id = "i2c_designware.0",	.clk = &i2c_clk},
 	{.dev_id = "dma0",		.clk = &dma0_clk},
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 0ba99de..7e5d7e1 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -30,7 +30,11 @@
 
 /* Add spear13xx family device structure declarations here */
 extern struct amba_device uart_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 spear13xx_timer;
 
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 4bf908f..0a6d26f 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -22,7 +22,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-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 5abdae8..c8f1aff 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -60,6 +60,112 @@ struct platform_device 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 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[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index ae6c244..5eb6ff6 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -495,7 +495,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "gpt1",		.clk = &gpt1_clk},
 	{ .dev_id = "gpt2",		.clk = &gpt2_clk},
 	/* clock derived from pll3 clk */
-	{ .dev_id = "usbh",		.clk = &usbh_clk},
+	{ .con_id = "usbh_clk",		.clk = &usbh_clk},
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
 	{ .dev_id = "clcd",		.clk = &clcd_clk},
 	/* clock derived from ahb clk */
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 162f33b..3eb2737 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -33,7 +33,10 @@
 /* Add spear3xx family device structure declarations here */
 extern struct amba_device gpio_device;
 extern struct amba_device uart_device;
+extern struct platform_device ehci_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 spear3xx_timer;
 
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 083f65c..3b3c6ce 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 */
+	&ehci_device,
 	&i2c_device,
+	&ohci0_device,
+	&ohci1_device,
 	&rtc_device,
 
 	/* spear300 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index 208a68ce1..d523040 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -50,7 +50,10 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&ehci_device,
 	&i2c_device,
+	&ohci0_device,
+	&ohci1_device,
 	&rtc_device,
 
 	/* spear310 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 90d685e..f90a9b8 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -48,7 +48,10 @@ static struct amba_device *amba_devs[] __initdata = {
 
 static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
+	&ehci_device,
 	&i2c_device,
+	&ohci0_device,
+	&ohci1_device,
 	&rtc_device,
 
 	/* spear320 specific devices */
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 34d22a5..780d83e 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -76,6 +76,86 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* usb host device registeration */
+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 = 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 = 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 = IRQ_USB_H_OHCI_1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = ~0;
+static int usbh_id = -1;
+
+struct platform_device 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 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 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/clock.c b/arch/arm/mach-spear6xx/clock.c
index 0972b8f..3caf91a 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -591,8 +591,8 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "gpt2",		.clk = &gpt2_clk},
 	{ .dev_id = "gpt3",		.clk = &gpt3_clk},
 	/* clock derived from pll3 clk */
-	{ .dev_id = "usbh0",		.clk = &usbh0_clk},
-	{ .dev_id = "usbh1",		.clk = &usbh1_clk},
+	{ .con_id = "usbh.0_clk",	.clk = &usbh0_clk},
+	{ .con_id = "usbh.1_clk",	.clk = &usbh1_clk},
 	{ .dev_id = "usbd",		.clk = &usbd_clk},
 	/* clock derived from ahb clk */
 	{ .con_id = "apb_clk",		.clk = &apb_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 44a2f99..3b15289 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 clcd_device;
 extern struct amba_device gpio_device[];
 extern struct amba_device uart_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 6b0cf23..b4dfd25 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 787de46..5a5195b 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -143,6 +143,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[] = {
 	{
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 4aa00e6..108f69d 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -41,6 +41,7 @@ config USB_ARCH_HAS_OHCI
 	default y if MFD_TC6393XB
 	default y if ARCH_W90X900
 	default y if ARCH_DAVINCI_DA8XX
+	default y if PLAT_SPEAR
 	# PPC:
 	default y if STB03xxx
 	default y if PPC_MPC52xx
@@ -65,6 +66,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_AT91SAM9G45
 	default y if ARCH_MXC
 	default y if ARCH_OMAP3
+	default y if PLAT_SPEAR
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 34a928d..2101725 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1197,6 +1197,11 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ehci_atmel_driver
 #endif
 
+#ifdef CONFIG_PLAT_SPEAR
+#include "ehci-spear.c"
+#define PLATFORM_DRIVER		spear_ehci_hcd_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
new file mode 100644
index 0000000..caac843
--- /dev/null
+++ b/drivers/usb/host/ehci-spear.c
@@ -0,0 +1,210 @@
+/*
+* Driver for EHCI HCD on SPEAR SOC
+*
+* Copyright (C) 2010 ST Micro Electronics,
+* Deepak Sikri <deepak.sikri@st.com>
+*
+* Based on various ehci-*.c drivers
+*
+* This file is subject to the terms and conditions of the GNU General Public
+* License. See the file COPYING in the main directory of this archive for
+* more details.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+struct spear_ehci {
+	struct ehci_hcd ehci;
+	struct clk *clk;
+};
+
+#define to_spear_ehci(hcd)	(struct spear_ehci *)hcd_to_ehci(hcd)
+
+static void spear_start_ehci(struct spear_ehci *ehci)
+{
+	clk_enable(ehci->clk);
+}
+
+static void spear_stop_ehci(struct spear_ehci *ehci)
+{
+	clk_disable(ehci->clk);
+}
+
+static int ehci_spear_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval = 0;
+
+	/* registers start at offset 0x0 */
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci,
+				&ehci->caps->hc_capbase));
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	ehci_reset(ehci);
+	ehci_port_power(ehci, 0);
+
+	return retval;
+}
+
+static const struct hc_driver ehci_spear_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "SPEAr EHCI",
+	.hcd_priv_size		= sizeof(struct spear_ehci),
+
+	/* generic hardware linkage */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/* basic lifecycle operations */
+	.reset			= ehci_spear_setup,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/* managing i/o requests and associated device resources */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+
+	/* scheduling support */
+	.get_frame_number	= ehci_get_frame,
+
+	/* root hub support */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+};
+
+static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd ;
+	struct spear_ehci *ehci;
+	struct resource *res;
+	struct clk *usbh_clk;
+	const struct hc_driver *driver = &ehci_spear_hc_driver;
+	int *pdata = pdev->dev.platform_data;
+	int irq, retval;
+	char clk_name[20] = "usbh_clk";
+
+	if (pdata == NULL)
+		return -EFAULT;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		retval = irq;
+		goto fail_irq_get;
+	}
+
+	if (*pdata >= 0)
+		sprintf(clk_name, "usbh.%01d_clk", *pdata);
+
+	usbh_clk = clk_get(NULL, clk_name);
+	if (IS_ERR(usbh_clk)) {
+		dev_err(&pdev->dev, "Error getting interface clock\n");
+		retval = PTR_ERR(usbh_clk);
+		goto fail_get_usbh_clk;
+	}
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		retval = -ENOMEM;
+		goto fail_create_hcd;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		retval = -ENODEV;
+		goto fail_request_resource;
+	}
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+				driver->description)) {
+		retval = -EBUSY;
+		goto fail_request_resource;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (hcd->regs == NULL) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		retval = -ENOMEM;
+		goto fail_ioremap;
+	}
+
+	ehci = (struct spear_ehci *)hcd_to_ehci(hcd);
+	ehci->clk = usbh_clk;
+
+	spear_start_ehci(ehci);
+	retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
+	if (retval)
+		goto fail_add_hcd;
+
+	return retval;
+
+fail_add_hcd:
+	spear_stop_ehci(ehci);
+	iounmap(hcd->regs);
+fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+fail_request_resource:
+	usb_put_hcd(hcd);
+fail_create_hcd:
+	clk_put(usbh_clk);
+fail_get_usbh_clk:
+fail_irq_get:
+	dev_err(&pdev->dev, "init fail, %d\n", retval);
+
+	return retval ;
+}
+
+static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct spear_ehci *ehci_p = to_spear_ehci(hcd);
+
+	if (!hcd)
+		return 0;
+	if (in_interrupt())
+		BUG();
+	usb_remove_hcd(hcd);
+
+	if (ehci_p->clk)
+		spear_stop_ehci(ehci_p);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	if (ehci_p->clk)
+		clk_put(ehci_p->clk);
+
+	return 0;
+}
+
+static struct platform_driver spear_ehci_hcd_driver = {
+	.probe		= spear_ehci_hcd_drv_probe,
+	.remove		= spear_ehci_hcd_drv_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name = "spear-ehci",
+		.bus = &platform_bus_type
+	}
+};
+
+MODULE_ALIAS("platform:spear-ehci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c3b4ccc..8104fd3 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1075,6 +1075,11 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
+#ifdef CONFIG_PLAT_SPEAR
+#include "ohci-spear.c"
+#define PLATFORM_DRIVER		spear_ohci_hcd_driver
+#endif
+
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
new file mode 100644
index 0000000..4fd4bea
--- /dev/null
+++ b/drivers/usb/host/ohci-spear.c
@@ -0,0 +1,240 @@
+/*
+* OHCI HCD (Host Controller Driver) for USB.
+*
+* Copyright (C) 2010 ST Microelectronics.
+* Deepak Sikri<deepak.sikri@st.com>
+*
+* Based on various ohci-*.c drivers
+*
+* 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/signal.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+struct spear_ohci {
+	struct ohci_hcd ohci;
+	struct clk *clk;
+};
+
+#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
+
+static void spear_start_ohci(struct spear_ohci *ohci)
+{
+	clk_enable(ohci->clk);
+}
+
+static void spear_stop_ohci(struct spear_ohci *ohci)
+{
+	clk_disable(ohci->clk);
+}
+
+static int __devinit ohci_spear_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	ret = ohci_init(ohci);
+	if (ret < 0)
+		return ret;
+	ohci->regs = hcd->regs;
+
+	ret = ohci_run(ohci);
+	if (ret < 0) {
+		dev_err(hcd->self.controller, "can't start\n");
+		ohci_stop(hcd);
+		return ret;
+	}
+
+	create_debug_files(ohci);
+
+#ifdef DEBUG
+	ohci_dump(ohci, 1);
+#endif
+	return 0;
+}
+
+static const struct hc_driver ohci_spear_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "SPEAr OHCI",
+	.hcd_priv_size		= sizeof(struct spear_ohci),
+
+	/* generic hardware linkage */
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+
+	/* basic lifecycle operations */
+	.start			= ohci_spear_start,
+	.stop			= ohci_stop,
+	.shutdown		= ohci_shutdown,
+#ifdef	CONFIG_PM
+	.bus_suspend		= ohci_bus_suspend,
+	.bus_resume		= ohci_bus_resume,
+#endif
+
+	/* managing i/o requests and associated device resources */
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+
+	/* scheduling support */
+	.get_frame_number	= ohci_get_frame,
+
+	/* root hub support */
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
+{
+	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct usb_hcd *hcd = NULL;
+	struct clk *usbh_clk;
+	struct spear_ohci *ohci_p;
+	struct resource *res;
+	int retval, irq;
+	int *pdata = pdev->dev.platform_data;
+	char clk_name[20] = "usbh_clk";
+
+	if (pdata == NULL)
+		return -EFAULT;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		retval = irq;
+		goto fail_irq_get;
+	}
+
+	if (*pdata >= 0)
+		sprintf(clk_name, "usbh.%01d_clk", *pdata);
+
+	usbh_clk = clk_get(NULL, clk_name);
+	if (IS_ERR(usbh_clk)) {
+		dev_err(&pdev->dev, "Error getting interface clock\n");
+		retval = PTR_ERR(usbh_clk);
+		goto fail_get_usbh_clk;
+	}
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		retval = -ENOMEM;
+		goto fail_create_hcd;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		retval = -ENODEV;
+		goto fail_request_resource;
+	}
+
+	hcd->rsrc_start = pdev->resource[0].start;
+	hcd->rsrc_len = resource_size(res);
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "request_mem_region failed\n");
+		retval = -EBUSY;
+		goto fail_request_resource;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		retval = -ENOMEM;
+		goto fail_ioremap;
+	}
+
+	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
+	ohci_p->clk = usbh_clk;
+	spear_start_ohci(ohci_p);
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), IRQF_DISABLED);
+	if (retval == 0)
+		return retval;
+
+	spear_stop_ohci(ohci_p);
+	iounmap(hcd->regs);
+fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+fail_request_resource:
+	usb_put_hcd(hcd);
+fail_create_hcd:
+	clk_put(usbh_clk);
+fail_get_usbh_clk:
+fail_irq_get:
+	dev_err(&pdev->dev, "init fail, %d\n", retval);
+
+	return retval;
+}
+
+static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+
+	usb_remove_hcd(hcd);
+	if (ohci_p->clk)
+		spear_stop_ohci(ohci_p);
+
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	if (ohci_p->clk)
+		clk_put(ohci_p->clk);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#if defined(CONFIG_PM)
+static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
+		pm_message_t message)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	spear_stop_ohci(ohci_p);
+	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
+	return 0;
+}
+
+static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(dev);
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	spear_start_ohci(ohci_p);
+	ohci_finish_controller_resume(hcd);
+	return 0;
+}
+#endif
+
+/* Driver definition to register with the platform bus */
+static struct platform_driver spear_ohci_hcd_driver = {
+	.probe =	spear_ohci_hcd_drv_probe,
+	.remove =	spear_ohci_hcd_drv_remove,
+#ifdef CONFIG_PM
+	.suspend =	spear_ohci_hcd_drv_suspend,
+	.resume =	spear_ohci_hcd_drv_resume,
+#endif
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "spear-ohci",
+	},
+};
+
+MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.2.2

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
@ 2010-08-30 10:43   ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
                     ` (73 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel, dmitry.torokhov, linux-input
  Cc: pratyush.anand, Viresh Kumar, Rajeev Kumar, bhupesh.sharma,
	armando.visconti, vipin.kumar, shiraz.hashim, vipulkumar.samar,
	deepak.sikri

From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   14 +
 arch/arm/mach-spear13xx/spear13xx.c            |   19 ++
 arch/arm/mach-spear3xx/clock.c                 |   12 +
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300.c              |   19 ++
 arch/arm/mach-spear3xx/spear300_evb.c          |   14 +
 arch/arm/plat-spear/include/plat/keyboard.h    |  154 +++++++++++
 drivers/input/keyboard/Kconfig                 |    8 +
 drivers/input/keyboard/Makefile                |    1 +
 drivers/input/keyboard/spear-keyboard.c        |  335 ++++++++++++++++++++++++
 12 files changed, 579 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/keyboard.h
 create mode 100644 drivers/input/keyboard/spear-keyboard.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 9252940..c48b779 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -801,7 +801,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "ssp",		.clk = &ssp_clk},
 	{.dev_id = "gpio0",		.clk = &gpio0_clk},
 	{.dev_id = "gpio1",		.clk = &gpio1_clk},
-	{.dev_id = "kbd",		.clk = &kbd_clk},
+	{.dev_id = "keyboard",		.clk = &kbd_clk},
 	{.dev_id = "wdt",		.clk = &wdt_clk},
 };
 
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 7e5d7e1..19c5de0 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -33,6 +33,7 @@ extern struct amba_device uart_device;
 extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
+extern struct platform_device kbd_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-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 0a6d26f..0cdad7a 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/spear.h>
+#include <plat/keyboard.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart_device,
@@ -25,15 +26,28 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ehci0_device,
 	&ehci1_device,
 	&i2c_device,
+	&kbd_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
 };
 
+/* keyboard specific platform data */
+static DECLARE_KEYMAP(spear_keymap);
+
+static struct kbd_platform_data kbd_data = {
+	.keymap = spear_keymap,
+	.keymapsize = ARRAY_SIZE(spear_keymap),
+	.rep = 1,
+};
+
 static void __init spear1300_evb_init(void)
 {
 	unsigned int i;
 
+	/* set keyboard plat data */
+	kbd_set_plat_data(&kbd_device, &kbd_data);
+
 	/* call spear1300 machine init function */
 	spear1300_init();
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index c8f1aff..342fcd9 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -166,6 +166,25 @@ struct platform_device 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 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/clock.c b/arch/arm/mach-spear3xx/clock.c
index 79f0159..3a26622 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -470,6 +470,15 @@ static struct clk i2c1_clk = {
 };
 #endif
 
+#ifdef CONFIG_MACH_SPEAR300
+/* keyboard clock */
+static struct clk kbd_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
@@ -511,6 +520,9 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#ifdef CONFIG_MACH_SPEAR300
+	{ .dev_id = "keyboard",		.clk = &kbd_clk},
+#endif
 #ifdef CONFIG_MACH_SPEAR320
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 #endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 3eb2737..70f7ee2 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -108,6 +108,7 @@ extern struct pmx_driver pmx_driver;
 /* Add spear300 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct amba_device gpio1_device;
+extern struct platform_device kbd_device;
 
 /* pad mux modes */
 extern struct pmx_mode nand_mode;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 5d8df00..fa314e9 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -407,6 +407,25 @@ struct amba_device gpio1_device = {
 	.irq = {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 = VIRQ_KEYBOARD,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device kbd_device = {
+	.name = "keyboard",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(kbd_resources),
+	.resource = kbd_resources,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 3b3c6ce..afb773e 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/keyboard.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -51,6 +52,16 @@ static struct platform_device *plat_devs[] __initdata = {
 	&rtc_device,
 
 	/* spear300 specific devices */
+	&kbd_device,
+};
+
+/* keyboard specific platform data */
+static DECLARE_KEYMAP(spear_keymap);
+
+static struct kbd_platform_data kbd_data = {
+	.keymap = spear_keymap,
+	.keymapsize = ARRAY_SIZE(spear_keymap),
+	.rep = 1,
 };
 
 static void __init spear300_evb_init(void)
@@ -62,6 +73,9 @@ static void __init spear300_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set keyboard plat data */
+	kbd_set_plat_data(&kbd_device, &kbd_data);
+
 	/* call spear300 machine init function */
 	spear300_init();
 
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
new file mode 100644
index 0000000..8345770
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/plat-spear/include/plat/keyboard.h
+ *
+ * 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.
+ */
+
+#ifndef __PLAT_KEYBOARD_H
+#define __PLAT_KEYBOARD_H
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <mach/misc_regs.h>
+
+#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
+
+#define DECLARE_KEYMAP(name) \
+int name[] = {\
+	KEY(0, 0, KEY_ESC), \
+	KEY(0, 1, KEY_1), \
+	KEY(0, 2, KEY_2), \
+	KEY(0, 3, KEY_3), \
+	KEY(0, 4, KEY_4), \
+	KEY(0, 5, KEY_5), \
+	KEY(0, 6, KEY_6), \
+	KEY(0, 7, KEY_7), \
+	KEY(0, 8, KEY_8), \
+	KEY(1, 0, KEY_9), \
+	KEY(1, 1, KEY_MINUS), \
+	KEY(1, 2, KEY_EQUAL), \
+	KEY(1, 3, KEY_BACKSPACE), \
+	KEY(1, 4, KEY_TAB), \
+	KEY(1, 5, KEY_Q), \
+	KEY(1, 6, KEY_W), \
+	KEY(1, 7, KEY_E), \
+	KEY(1, 8, KEY_R), \
+	KEY(2, 0, KEY_T), \
+	KEY(2, 1, KEY_Y), \
+	KEY(2, 2, KEY_U), \
+	KEY(2, 3, KEY_I), \
+	KEY(2, 4, KEY_O), \
+	KEY(2, 5, KEY_P), \
+	KEY(2, 6, KEY_LEFTBRACE), \
+	KEY(2, 7, KEY_RIGHTBRACE), \
+	KEY(2, 8, KEY_ENTER), \
+	KEY(3, 0, KEY_LEFTCTRL), \
+	KEY(3, 1, KEY_A), \
+	KEY(3, 2, KEY_S), \
+	KEY(3, 3, KEY_D), \
+	KEY(3, 4, KEY_F), \
+	KEY(3, 5, KEY_G), \
+	KEY(3, 6, KEY_H), \
+	KEY(3, 7, KEY_J), \
+	KEY(3, 8, KEY_K), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(5, 0, KEY_V), \
+	KEY(5, 1, KEY_B), \
+	KEY(5, 2, KEY_N), \
+	KEY(5, 3, KEY_M), \
+	KEY(5, 4, KEY_COMMA), \
+	KEY(5, 5, KEY_DOT), \
+	KEY(5, 6, KEY_SLASH), \
+	KEY(5, 7, KEY_RIGHTSHIFT), \
+	KEY(5, 8, KEY_KPASTERISK), \
+	KEY(6, 0, KEY_LEFTALT), \
+	KEY(6, 1, KEY_SPACE), \
+	KEY(6, 2, KEY_CAPSLOCK), \
+	KEY(6, 3, KEY_F1), \
+	KEY(6, 4, KEY_F2), \
+	KEY(6, 5, KEY_F3), \
+	KEY(6, 6, KEY_F4), \
+	KEY(6, 7, KEY_F5), \
+	KEY(6, 8, KEY_F6), \
+	KEY(7, 0, KEY_F7), \
+	KEY(7, 1, KEY_F8), \
+	KEY(7, 2, KEY_F9), \
+	KEY(7, 3, KEY_F10), \
+	KEY(7, 4, KEY_NUMLOCK), \
+	KEY(7, 5, KEY_SCROLLLOCK), \
+	KEY(7, 6, KEY_KP7), \
+	KEY(7, 7, KEY_KP8), \
+	KEY(7, 8, KEY_KP9), \
+	KEY(8, 0, KEY_KPMINUS), \
+	KEY(8, 1, KEY_KP4), \
+	KEY(8, 2, KEY_KP5), \
+	KEY(8, 3, KEY_KP6), \
+	KEY(8, 4, KEY_KPPLUS), \
+	KEY(8, 5, KEY_KP1), \
+	KEY(8, 6, KEY_KP2), \
+	KEY(8, 7, KEY_KP3), \
+	KEY(8, 8, KEY_KP0), \
+};
+/**
+ * struct kbd_platform_data - keymap for spear keyboards
+ * keymap: pointer to array of values encoded with KEY() macro representing
+ * keymap
+ * keymapsize: number of entries (initialized) in this keymap
+ * rep: current values for autorepeat parameters
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement keyboards.
+ */
+struct kbd_platform_data {
+	int *keymap;
+	unsigned int keymapsize;
+	unsigned int rep:1;
+};
+
+/* 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)
+{
+#ifdef CONFIG_ARCH_SPEAR13XX
+#define KBD_PAD_SEL	(BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
+
+	u32 val;
+	/* Workaround:Setting bit for routing it to the IP */
+	val = readl(PAD_FUNCTION_EN_2);
+	val &= ~KBD_PAD_SEL;
+	writel(val, PAD_FUNCTION_EN_2);
+#endif
+	pdev->dev.platform_data = data;
+}
+#endif /* __PLAT_KEYBOARD_H */
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9cc488d..2d7e3a8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -424,6 +424,14 @@ config KEYBOARD_OMAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called omap-keypad.
 
+config KEYBOARD_SPEAR
+	tristate "ST SPEAR keyboard support"
+	help
+	  Say Y here if you want to use the SPEAR keyboard.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called spear-keboard.
+
 config KEYBOARD_TWL4030
 	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
 	depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 504b591..b21c54d 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT2160)		+= qt2160.o
 obj-$(CONFIG_KEYBOARD_SAMSUNG)		+= samsung-keypad.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)		+= sh_keysc.o
+obj-$(CONFIG_KEYBOARD_SPEAR)		+= spear-keyboard.o
 obj-$(CONFIG_KEYBOARD_STMPE)		+= stmpe-keypad.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
new file mode 100644
index 0000000..4f5c734
--- /dev/null
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -0,0 +1,335 @@
+/*
+ * drivers/input/keyboard/keyboard-spear.c
+ *
+ * SPEAr Keyboard Driver
+ * Based on omap-keypad driver
+ *
+ * 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/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <plat/keyboard.h>
+
+/* Keyboard Regsiters */
+#define MODE_REG	0x00	/* 16 bit reg */
+#define STATUS_REG	0x0C	/* 2 bit reg */
+#define DATA_REG	0x10	/* 8 bit reg */
+#define INTR_MASK	0x54
+
+/* Register Values */
+/*
+ * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
+ * control register as 1010010(82MHZ)
+ */
+#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
+#define START_SCAN	0x0100
+#define SCAN_RATE_10	0x0000
+#define SCAN_RATE_20	0x0004
+#define SCAN_RATE_40	0x0008
+#define SCAN_RATE_80	0x000C
+#define MODE_KEYBOARD	0x0002
+#define DATA_AVAIL	0x2
+
+#define KEY_MASK	0xFF000000
+#define KEY_VALUE	0x00FFFFFF
+#define ROW_MASK	0xF0
+#define COLUMN_MASK	0x0F
+#define ROW_SHIFT	4
+
+struct spear_kbd {
+	struct input_dev *input;
+	void __iomem *io_base;		/* Keyboard Base Address */
+	struct clk *clk;
+	int *keymap;
+};
+/* TODO: Need to optimize this function */
+static inline int get_key_value(struct spear_kbd *dev, int row, int col)
+{
+	int i, key;
+	int *keymap = dev->keymap;
+
+	key = KEY(row, col, 0);
+	for (i = 0; keymap[i] != 0; i++)
+		if ((keymap[i] & KEY_MASK) == key)
+			return keymap[i] & KEY_VALUE;
+	return -ENOKEY;
+}
+
+static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
+{
+	struct spear_kbd *dev = dev_id;
+	static u8 last_key ;
+	static u8 last_event;
+	int key;
+	u8 sts, val = 0;
+
+	if (dev == NULL) {
+		pr_err("Keyboard: Invalid dev_id in irq handler\n");
+		return IRQ_NONE;
+	}
+
+	sts = readb(dev->io_base + STATUS_REG);
+	if (sts & DATA_AVAIL) {
+		/* following reads active (row, col) pair */
+		val = readb(dev->io_base + DATA_REG);
+		key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
+					& COLUMN_MASK));
+
+		/* valid key press event */
+		if (key >= 0) {
+			if (last_event == 1) {
+				/* check if we missed a release event */
+				input_report_key(dev->input, last_key,
+						!last_event);
+			}
+			/* notify key press */
+			last_event = 1;
+			last_key = key;
+			input_report_key(dev->input, key, last_event);
+		} else {
+			/* notify key release */
+			last_event = 0;
+			input_report_key(dev->input, last_key, last_event);
+		}
+	} else
+		return IRQ_NONE;
+
+	/* clear interrupt */
+	writeb(0, dev->io_base + STATUS_REG);
+
+	return IRQ_HANDLED;
+}
+
+static int __init spear_kbd_probe(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd;
+	struct kbd_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *res;
+	int i, ret, irq;
+	u16 val = 0;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Invalid platform data\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no keyboard resource defined\n");
+		return -EBUSY;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "keyboard region already claimed\n");
+		return -EBUSY;
+	}
+
+	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+	if (!kbd) {
+		dev_err(&pdev->dev, "out of memory\n");
+		ret = -ENOMEM;
+		goto err_release_mem_region;
+	}
+
+	kbd->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(kbd->clk)) {
+		ret = PTR_ERR(kbd->clk);
+		goto err_kfree;
+	}
+
+	ret = clk_enable(kbd->clk);
+	if (ret < 0)
+		goto err_clk_put;
+
+	platform_set_drvdata(pdev, kbd);
+	kbd->keymap = pdata->keymap; /* key mappings */
+
+	kbd->io_base = ioremap(res->start, resource_size(res));
+	if (!kbd->io_base) {
+		dev_err(&pdev->dev, "ioremap fail for kbd_region\n");
+		ret = -ENOMEM;
+		goto err_clear_plat_data;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "not able to get irq for the device\n");
+		ret = irq;
+		goto err_iounmap;
+	}
+
+	ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
+			kbd);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq fail\n");
+		goto err_iounmap;
+	}
+
+	kbd->input = input_allocate_device();
+	if (!kbd->input) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "input device allocation fail\n");
+		goto err_free_irq;
+	}
+
+	if (pdata->rep)
+		__set_bit(EV_REP, kbd->input->evbit);
+
+	/* setup input device */
+	__set_bit(EV_KEY, kbd->input->evbit);
+
+	for (i = 0; kbd->keymap[i] != 0; i++)
+		__set_bit(kbd->keymap[i] & KEY_MAX, kbd->input->keybit);
+
+	kbd->input->name = "keyboard";
+	kbd->input->phys = "keyboard/input0";
+	kbd->input->dev.parent = &pdev->dev;
+	kbd->input->id.bustype = BUS_HOST;
+	kbd->input->id.vendor = 0x0001;
+	kbd->input->id.product = 0x0001;
+	kbd->input->id.version = 0x0100;
+
+	ret = input_register_device(kbd->input);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to register keyboard device\n");
+		goto err_free_dev;
+	}
+
+	/* program keyboard */
+	val |= SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
+	writew(val, kbd->io_base + MODE_REG);
+
+	writeb(1, kbd->io_base + STATUS_REG);
+
+	/* start key scan */
+	val |= START_SCAN;
+	writew(val, kbd->io_base + MODE_REG);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+err_free_dev:
+	input_free_device(kbd->input);
+err_free_irq:
+	free_irq(irq, pdev);
+err_iounmap:
+	iounmap(kbd->io_base);
+err_clear_plat_data:
+	platform_set_drvdata(pdev, NULL);
+	clk_disable(kbd->clk);
+err_clk_put:
+	clk_put(kbd->clk);
+err_kfree:
+	kfree(kbd);
+err_release_mem_region:
+	release_mem_region(res->start, resource_size(res));
+
+	return ret;
+}
+
+static int spear_kbd_remove(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	struct resource *res;
+	u16 val;
+	int irq;
+
+	val = readw(kbd->io_base + MODE_REG);
+	val &= ~START_SCAN;
+	writew(val, kbd->io_base + MODE_REG);
+
+	/* unregister input device */
+	input_unregister_device(kbd->input);
+	input_free_device(kbd->input);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq)
+		free_irq(irq, pdev);
+
+	iounmap(kbd->io_base);
+	platform_set_drvdata(pdev, NULL);
+	clk_disable(kbd->clk);
+	clk_put(kbd->clk);
+	kfree(kbd);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int spear_kbd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	clk_disable(kbd->clk);
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(irq);
+
+	return 0;
+}
+
+static int spear_kbd_resume(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(irq);
+	clk_enable(kbd->clk);
+
+	return 0;
+}
+#else
+#define spear_kbd_suspend	NULL
+#define spear_kbd_resume	NULL
+#endif
+
+static struct platform_driver spear_kbd_driver = {
+	.probe		= spear_kbd_probe,
+	.remove		= spear_kbd_remove,
+	.suspend	= spear_kbd_suspend,
+	.resume		= spear_kbd_resume,
+	.driver		= {
+		.name	= "keyboard",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __devinit spear_kbd_init(void)
+{
+	return platform_driver_register(&spear_kbd_driver);
+}
+module_init(spear_kbd_init);
+
+static void __exit spear_kbd_exit(void)
+{
+	platform_driver_unregister(&spear_kbd_driver);
+}
+module_exit(spear_kbd_exit);
+
+MODULE_AUTHOR("Rajeev Kumar");
+MODULE_DESCRIPTION("SPEAr Keyboard Driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-08-30 10:43   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
 arch/arm/mach-spear13xx/spear1300_evb.c        |   14 +
 arch/arm/mach-spear13xx/spear13xx.c            |   19 ++
 arch/arm/mach-spear3xx/clock.c                 |   12 +
 arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
 arch/arm/mach-spear3xx/spear300.c              |   19 ++
 arch/arm/mach-spear3xx/spear300_evb.c          |   14 +
 arch/arm/plat-spear/include/plat/keyboard.h    |  154 +++++++++++
 drivers/input/keyboard/Kconfig                 |    8 +
 drivers/input/keyboard/Makefile                |    1 +
 drivers/input/keyboard/spear-keyboard.c        |  335 ++++++++++++++++++++++++
 12 files changed, 579 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/keyboard.h
 create mode 100644 drivers/input/keyboard/spear-keyboard.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 9252940..c48b779 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -801,7 +801,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "ssp",		.clk = &ssp_clk},
 	{.dev_id = "gpio0",		.clk = &gpio0_clk},
 	{.dev_id = "gpio1",		.clk = &gpio1_clk},
-	{.dev_id = "kbd",		.clk = &kbd_clk},
+	{.dev_id = "keyboard",		.clk = &kbd_clk},
 	{.dev_id = "wdt",		.clk = &wdt_clk},
 };
 
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 7e5d7e1..19c5de0 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -33,6 +33,7 @@ extern struct amba_device uart_device;
 extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
+extern struct platform_device kbd_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-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 0a6d26f..0cdad7a 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/spear.h>
+#include <plat/keyboard.h>
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart_device,
@@ -25,15 +26,28 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ehci0_device,
 	&ehci1_device,
 	&i2c_device,
+	&kbd_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
 };
 
+/* keyboard specific platform data */
+static DECLARE_KEYMAP(spear_keymap);
+
+static struct kbd_platform_data kbd_data = {
+	.keymap = spear_keymap,
+	.keymapsize = ARRAY_SIZE(spear_keymap),
+	.rep = 1,
+};
+
 static void __init spear1300_evb_init(void)
 {
 	unsigned int i;
 
+	/* set keyboard plat data */
+	kbd_set_plat_data(&kbd_device, &kbd_data);
+
 	/* call spear1300 machine init function */
 	spear1300_init();
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index c8f1aff..342fcd9 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -166,6 +166,25 @@ struct platform_device 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 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/clock.c b/arch/arm/mach-spear3xx/clock.c
index 79f0159..3a26622 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -470,6 +470,15 @@ static struct clk i2c1_clk = {
 };
 #endif
 
+#ifdef CONFIG_MACH_SPEAR300
+/* keyboard clock */
+static struct clk kbd_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
 	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
@@ -511,6 +520,9 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#ifdef CONFIG_MACH_SPEAR300
+	{ .dev_id = "keyboard",		.clk = &kbd_clk},
+#endif
 #ifdef CONFIG_MACH_SPEAR320
 	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 #endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 3eb2737..70f7ee2 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -108,6 +108,7 @@ extern struct pmx_driver pmx_driver;
 /* Add spear300 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct amba_device gpio1_device;
+extern struct platform_device kbd_device;
 
 /* pad mux modes */
 extern struct pmx_mode nand_mode;
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 5d8df00..fa314e9 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -407,6 +407,25 @@ struct amba_device gpio1_device = {
 	.irq = {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 = VIRQ_KEYBOARD,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device kbd_device = {
+	.name = "keyboard",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(kbd_resources),
+	.resource = kbd_resources,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 3b3c6ce..afb773e 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -15,6 +15,7 @@
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/keyboard.h>
 
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
@@ -51,6 +52,16 @@ static struct platform_device *plat_devs[] __initdata = {
 	&rtc_device,
 
 	/* spear300 specific devices */
+	&kbd_device,
+};
+
+/* keyboard specific platform data */
+static DECLARE_KEYMAP(spear_keymap);
+
+static struct kbd_platform_data kbd_data = {
+	.keymap = spear_keymap,
+	.keymapsize = ARRAY_SIZE(spear_keymap),
+	.rep = 1,
 };
 
 static void __init spear300_evb_init(void)
@@ -62,6 +73,9 @@ static void __init spear300_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set keyboard plat data */
+	kbd_set_plat_data(&kbd_device, &kbd_data);
+
 	/* call spear300 machine init function */
 	spear300_init();
 
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
new file mode 100644
index 0000000..8345770
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/plat-spear/include/plat/keyboard.h
+ *
+ * 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.
+ */
+
+#ifndef __PLAT_KEYBOARD_H
+#define __PLAT_KEYBOARD_H
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <mach/misc_regs.h>
+
+#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
+
+#define DECLARE_KEYMAP(name) \
+int name[] = {\
+	KEY(0, 0, KEY_ESC), \
+	KEY(0, 1, KEY_1), \
+	KEY(0, 2, KEY_2), \
+	KEY(0, 3, KEY_3), \
+	KEY(0, 4, KEY_4), \
+	KEY(0, 5, KEY_5), \
+	KEY(0, 6, KEY_6), \
+	KEY(0, 7, KEY_7), \
+	KEY(0, 8, KEY_8), \
+	KEY(1, 0, KEY_9), \
+	KEY(1, 1, KEY_MINUS), \
+	KEY(1, 2, KEY_EQUAL), \
+	KEY(1, 3, KEY_BACKSPACE), \
+	KEY(1, 4, KEY_TAB), \
+	KEY(1, 5, KEY_Q), \
+	KEY(1, 6, KEY_W), \
+	KEY(1, 7, KEY_E), \
+	KEY(1, 8, KEY_R), \
+	KEY(2, 0, KEY_T), \
+	KEY(2, 1, KEY_Y), \
+	KEY(2, 2, KEY_U), \
+	KEY(2, 3, KEY_I), \
+	KEY(2, 4, KEY_O), \
+	KEY(2, 5, KEY_P), \
+	KEY(2, 6, KEY_LEFTBRACE), \
+	KEY(2, 7, KEY_RIGHTBRACE), \
+	KEY(2, 8, KEY_ENTER), \
+	KEY(3, 0, KEY_LEFTCTRL), \
+	KEY(3, 1, KEY_A), \
+	KEY(3, 2, KEY_S), \
+	KEY(3, 3, KEY_D), \
+	KEY(3, 4, KEY_F), \
+	KEY(3, 5, KEY_G), \
+	KEY(3, 6, KEY_H), \
+	KEY(3, 7, KEY_J), \
+	KEY(3, 8, KEY_K), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(4, 0, KEY_L), \
+	KEY(4, 1, KEY_SEMICOLON), \
+	KEY(4, 2, KEY_APOSTROPHE), \
+	KEY(4, 3, KEY_GRAVE), \
+	KEY(4, 4, KEY_LEFTSHIFT), \
+	KEY(4, 5, KEY_BACKSLASH), \
+	KEY(4, 6, KEY_Z), \
+	KEY(4, 7, KEY_X), \
+	KEY(4, 8, KEY_C), \
+	KEY(5, 0, KEY_V), \
+	KEY(5, 1, KEY_B), \
+	KEY(5, 2, KEY_N), \
+	KEY(5, 3, KEY_M), \
+	KEY(5, 4, KEY_COMMA), \
+	KEY(5, 5, KEY_DOT), \
+	KEY(5, 6, KEY_SLASH), \
+	KEY(5, 7, KEY_RIGHTSHIFT), \
+	KEY(5, 8, KEY_KPASTERISK), \
+	KEY(6, 0, KEY_LEFTALT), \
+	KEY(6, 1, KEY_SPACE), \
+	KEY(6, 2, KEY_CAPSLOCK), \
+	KEY(6, 3, KEY_F1), \
+	KEY(6, 4, KEY_F2), \
+	KEY(6, 5, KEY_F3), \
+	KEY(6, 6, KEY_F4), \
+	KEY(6, 7, KEY_F5), \
+	KEY(6, 8, KEY_F6), \
+	KEY(7, 0, KEY_F7), \
+	KEY(7, 1, KEY_F8), \
+	KEY(7, 2, KEY_F9), \
+	KEY(7, 3, KEY_F10), \
+	KEY(7, 4, KEY_NUMLOCK), \
+	KEY(7, 5, KEY_SCROLLLOCK), \
+	KEY(7, 6, KEY_KP7), \
+	KEY(7, 7, KEY_KP8), \
+	KEY(7, 8, KEY_KP9), \
+	KEY(8, 0, KEY_KPMINUS), \
+	KEY(8, 1, KEY_KP4), \
+	KEY(8, 2, KEY_KP5), \
+	KEY(8, 3, KEY_KP6), \
+	KEY(8, 4, KEY_KPPLUS), \
+	KEY(8, 5, KEY_KP1), \
+	KEY(8, 6, KEY_KP2), \
+	KEY(8, 7, KEY_KP3), \
+	KEY(8, 8, KEY_KP0), \
+};
+/**
+ * struct kbd_platform_data - keymap for spear keyboards
+ * keymap: pointer to array of values encoded with KEY() macro representing
+ * keymap
+ * keymapsize: number of entries (initialized) in this keymap
+ * rep: current values for autorepeat parameters
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement keyboards.
+ */
+struct kbd_platform_data {
+	int *keymap;
+	unsigned int keymapsize;
+	unsigned int rep:1;
+};
+
+/* 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)
+{
+#ifdef CONFIG_ARCH_SPEAR13XX
+#define KBD_PAD_SEL	(BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
+
+	u32 val;
+	/* Workaround:Setting bit for routing it to the IP */
+	val = readl(PAD_FUNCTION_EN_2);
+	val &= ~KBD_PAD_SEL;
+	writel(val, PAD_FUNCTION_EN_2);
+#endif
+	pdev->dev.platform_data = data;
+}
+#endif /* __PLAT_KEYBOARD_H */
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9cc488d..2d7e3a8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -424,6 +424,14 @@ config KEYBOARD_OMAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called omap-keypad.
 
+config KEYBOARD_SPEAR
+	tristate "ST SPEAR keyboard support"
+	help
+	  Say Y here if you want to use the SPEAR keyboard.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called spear-keboard.
+
 config KEYBOARD_TWL4030
 	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
 	depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 504b591..b21c54d 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT2160)		+= qt2160.o
 obj-$(CONFIG_KEYBOARD_SAMSUNG)		+= samsung-keypad.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)		+= sh_keysc.o
+obj-$(CONFIG_KEYBOARD_SPEAR)		+= spear-keyboard.o
 obj-$(CONFIG_KEYBOARD_STMPE)		+= stmpe-keypad.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
new file mode 100644
index 0000000..4f5c734
--- /dev/null
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -0,0 +1,335 @@
+/*
+ * drivers/input/keyboard/keyboard-spear.c
+ *
+ * SPEAr Keyboard Driver
+ * Based on omap-keypad driver
+ *
+ * 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/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <plat/keyboard.h>
+
+/* Keyboard Regsiters */
+#define MODE_REG	0x00	/* 16 bit reg */
+#define STATUS_REG	0x0C	/* 2 bit reg */
+#define DATA_REG	0x10	/* 8 bit reg */
+#define INTR_MASK	0x54
+
+/* Register Values */
+/*
+ * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
+ * control register as 1010010(82MHZ)
+ */
+#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
+#define START_SCAN	0x0100
+#define SCAN_RATE_10	0x0000
+#define SCAN_RATE_20	0x0004
+#define SCAN_RATE_40	0x0008
+#define SCAN_RATE_80	0x000C
+#define MODE_KEYBOARD	0x0002
+#define DATA_AVAIL	0x2
+
+#define KEY_MASK	0xFF000000
+#define KEY_VALUE	0x00FFFFFF
+#define ROW_MASK	0xF0
+#define COLUMN_MASK	0x0F
+#define ROW_SHIFT	4
+
+struct spear_kbd {
+	struct input_dev *input;
+	void __iomem *io_base;		/* Keyboard Base Address */
+	struct clk *clk;
+	int *keymap;
+};
+/* TODO: Need to optimize this function */
+static inline int get_key_value(struct spear_kbd *dev, int row, int col)
+{
+	int i, key;
+	int *keymap = dev->keymap;
+
+	key = KEY(row, col, 0);
+	for (i = 0; keymap[i] != 0; i++)
+		if ((keymap[i] & KEY_MASK) == key)
+			return keymap[i] & KEY_VALUE;
+	return -ENOKEY;
+}
+
+static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
+{
+	struct spear_kbd *dev = dev_id;
+	static u8 last_key ;
+	static u8 last_event;
+	int key;
+	u8 sts, val = 0;
+
+	if (dev == NULL) {
+		pr_err("Keyboard: Invalid dev_id in irq handler\n");
+		return IRQ_NONE;
+	}
+
+	sts = readb(dev->io_base + STATUS_REG);
+	if (sts & DATA_AVAIL) {
+		/* following reads active (row, col) pair */
+		val = readb(dev->io_base + DATA_REG);
+		key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
+					& COLUMN_MASK));
+
+		/* valid key press event */
+		if (key >= 0) {
+			if (last_event == 1) {
+				/* check if we missed a release event */
+				input_report_key(dev->input, last_key,
+						!last_event);
+			}
+			/* notify key press */
+			last_event = 1;
+			last_key = key;
+			input_report_key(dev->input, key, last_event);
+		} else {
+			/* notify key release */
+			last_event = 0;
+			input_report_key(dev->input, last_key, last_event);
+		}
+	} else
+		return IRQ_NONE;
+
+	/* clear interrupt */
+	writeb(0, dev->io_base + STATUS_REG);
+
+	return IRQ_HANDLED;
+}
+
+static int __init spear_kbd_probe(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd;
+	struct kbd_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *res;
+	int i, ret, irq;
+	u16 val = 0;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Invalid platform data\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no keyboard resource defined\n");
+		return -EBUSY;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "keyboard region already claimed\n");
+		return -EBUSY;
+	}
+
+	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+	if (!kbd) {
+		dev_err(&pdev->dev, "out of memory\n");
+		ret = -ENOMEM;
+		goto err_release_mem_region;
+	}
+
+	kbd->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(kbd->clk)) {
+		ret = PTR_ERR(kbd->clk);
+		goto err_kfree;
+	}
+
+	ret = clk_enable(kbd->clk);
+	if (ret < 0)
+		goto err_clk_put;
+
+	platform_set_drvdata(pdev, kbd);
+	kbd->keymap = pdata->keymap; /* key mappings */
+
+	kbd->io_base = ioremap(res->start, resource_size(res));
+	if (!kbd->io_base) {
+		dev_err(&pdev->dev, "ioremap fail for kbd_region\n");
+		ret = -ENOMEM;
+		goto err_clear_plat_data;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "not able to get irq for the device\n");
+		ret = irq;
+		goto err_iounmap;
+	}
+
+	ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
+			kbd);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq fail\n");
+		goto err_iounmap;
+	}
+
+	kbd->input = input_allocate_device();
+	if (!kbd->input) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "input device allocation fail\n");
+		goto err_free_irq;
+	}
+
+	if (pdata->rep)
+		__set_bit(EV_REP, kbd->input->evbit);
+
+	/* setup input device */
+	__set_bit(EV_KEY, kbd->input->evbit);
+
+	for (i = 0; kbd->keymap[i] != 0; i++)
+		__set_bit(kbd->keymap[i] & KEY_MAX, kbd->input->keybit);
+
+	kbd->input->name = "keyboard";
+	kbd->input->phys = "keyboard/input0";
+	kbd->input->dev.parent = &pdev->dev;
+	kbd->input->id.bustype = BUS_HOST;
+	kbd->input->id.vendor = 0x0001;
+	kbd->input->id.product = 0x0001;
+	kbd->input->id.version = 0x0100;
+
+	ret = input_register_device(kbd->input);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to register keyboard device\n");
+		goto err_free_dev;
+	}
+
+	/* program keyboard */
+	val |= SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
+	writew(val, kbd->io_base + MODE_REG);
+
+	writeb(1, kbd->io_base + STATUS_REG);
+
+	/* start key scan */
+	val |= START_SCAN;
+	writew(val, kbd->io_base + MODE_REG);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+err_free_dev:
+	input_free_device(kbd->input);
+err_free_irq:
+	free_irq(irq, pdev);
+err_iounmap:
+	iounmap(kbd->io_base);
+err_clear_plat_data:
+	platform_set_drvdata(pdev, NULL);
+	clk_disable(kbd->clk);
+err_clk_put:
+	clk_put(kbd->clk);
+err_kfree:
+	kfree(kbd);
+err_release_mem_region:
+	release_mem_region(res->start, resource_size(res));
+
+	return ret;
+}
+
+static int spear_kbd_remove(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	struct resource *res;
+	u16 val;
+	int irq;
+
+	val = readw(kbd->io_base + MODE_REG);
+	val &= ~START_SCAN;
+	writew(val, kbd->io_base + MODE_REG);
+
+	/* unregister input device */
+	input_unregister_device(kbd->input);
+	input_free_device(kbd->input);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq)
+		free_irq(irq, pdev);
+
+	iounmap(kbd->io_base);
+	platform_set_drvdata(pdev, NULL);
+	clk_disable(kbd->clk);
+	clk_put(kbd->clk);
+	kfree(kbd);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int spear_kbd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	clk_disable(kbd->clk);
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(irq);
+
+	return 0;
+}
+
+static int spear_kbd_resume(struct platform_device *pdev)
+{
+	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(irq);
+	clk_enable(kbd->clk);
+
+	return 0;
+}
+#else
+#define spear_kbd_suspend	NULL
+#define spear_kbd_resume	NULL
+#endif
+
+static struct platform_driver spear_kbd_driver = {
+	.probe		= spear_kbd_probe,
+	.remove		= spear_kbd_remove,
+	.suspend	= spear_kbd_suspend,
+	.resume		= spear_kbd_resume,
+	.driver		= {
+		.name	= "keyboard",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __devinit spear_kbd_init(void)
+{
+	return platform_driver_register(&spear_kbd_driver);
+}
+module_init(spear_kbd_init);
+
+static void __exit spear_kbd_exit(void)
+{
+	platform_driver_unregister(&spear_kbd_driver);
+}
+module_exit(spear_kbd_exit);
+
+MODULE_AUTHOR("Rajeev Kumar");
+MODULE_DESCRIPTION("SPEAr Keyboard Driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* [PATCH 24/74] ST SPEAr: Add smi driver for serial NOR flash
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
@ 2010-08-30 10:43   ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
                     ` (73 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mtd, dwmw2
  Cc: pratyush.anand, Viresh Kumar, vipulkumar.samar, bhupesh.sharma,
	armando.visconti, vipin.kumar, Shiraz Hashim, rajeev-dlh.kumar,
	deepak.sikri

From: Shiraz Hashim <shiraz.hashim@st.com>

SPEAr platforms(spear3xx/spear6xx/spear13xx) provide SMI(Serial Memory
Interface) controller to access serial NOR flash. SMI provides a simple
interface for SPI/serial NOR flashes and has certain inbuilt commands
and features to support these flashes easily. It also makes it possible
to map an address range in order to directly access (read/write) the SNOR
over address bus. This patch intends to provide serial nor driver support
for spear platforms which are accessed through SMI.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/include/plat/smi.h |   68 ++
 drivers/mtd/devices/Kconfig            |    7 +
 drivers/mtd/devices/Makefile           |    1 +
 drivers/mtd/devices/spear_smi.c        | 1122 ++++++++++++++++++++++++++++++++
 4 files changed, 1198 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/smi.h
 create mode 100644 drivers/mtd/devices/spear_smi.c

diff --git a/arch/arm/plat-spear/include/plat/smi.h b/arch/arm/plat-spear/include/plat/smi.h
new file mode 100644
index 0000000..4c74df7
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/smi.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/plat-spear/include/plat/smi.h
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_SMI_H
+#define __PLAT_SMI_H
+
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+
+/* macro to define partitions for flash devices */
+#define DEFINE_PARTS(n, of, s)		\
+{					\
+	.name = n,			\
+	.offset = of,			\
+	.size = s,			\
+}
+
+/**
+ * struct spear_smi_flash_info - platform structure for passing flash
+ * information
+ *
+ * name: name of the serial nor flash for identification
+ * mem_base: the memory base on which the flash is mapped
+ * size: size of the flash in bytes
+ * num_parts: number of partitions
+ * parts: parition details
+ * fast_mode: whether flash supports fast mode
+ */
+
+struct spear_smi_flash_info {
+	char *name;
+	unsigned long mem_base;
+	unsigned long size;
+	int num_parts;
+	struct mtd_partition *parts;
+	u8 fast_mode;
+};
+
+/**
+ * struct spear_smi_plat_data - platform structure for configuring smi
+ *
+ * clk_rate: clk rate at which SMI must operate
+ * num_flashes: number of flashes present on board
+ * board_flash_info: specific details of each flash present on board
+ */
+struct spear_smi_plat_data {
+	unsigned long clk_rate;
+	int num_flashes;
+	struct spear_smi_flash_info *board_flash_info;
+};
+
+static inline void smi_set_plat_data(struct platform_device *pdev,
+		struct spear_smi_plat_data *pdata)
+{
+	pdev->dev.platform_data = pdata;
+}
+
+#endif /* __PLAT_SMI_H */
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 35081ce..83daf23 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -102,6 +102,13 @@ config M25PXX_USE_FAST_READ
 	help
 	  This option enables FAST_READ access supported by ST M25Pxx.
 
+config MTD_SPEAR_SMI
+	tristate "SPEAR MTD NOR Support through SMI controller"
+	depends on PLAT_SPEAR
+	default y
+	help
+	  This enable SNOR support on SPEAR platforms using SMI controller
+
 config MTD_SST25L
 	tristate "Support SST25L (non JEDEC) SPI Flash chips"
 	depends on SPI_MASTER
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index f3226b1..6e9063b 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
+obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
new file mode 100644
index 0000000..6dd7de1
--- /dev/null
+++ b/drivers/mtd/devices/spear_smi.c
@@ -0,0 +1,1122 @@
+/*
+ * linux/drivers/mtd/devices/spear_smi.c
+ *
+ * SMI (Serial Memory Controller) device driver for Serial NOR Flash on
+ * SPEAr platform
+ * The serial nor interface is largely based on drivers/mtd/m25p80.c,
+ * however the SPI interface has been replaced by SMI.
+ *
+ * Copyright (C) 2010 STMicroelectronics.
+ * Ashish Priyadarshi
+ * Shiraz Hashim <shiraz.hashim@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/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <plat/smi.h>
+
+/* max possible slots for serial-nor flash chip in the SMI controller */
+#define MAX_NUM_FLASH_CHIP	4
+
+/* SMI clock rate */
+#define SMI_MAX_CLOCK_FREQ	50000000 /* 50 MHz */
+
+/* MAX time out to safely come out of a erase or write busy conditions */
+#define SMI_PROBE_TIMEOUT	(HZ / 10)
+#define SMI_MAX_TIME_OUT	(3 * HZ)
+
+/* timeout for command completion */
+#define SMI_CMD_TIMEOUT		(HZ / 10)
+
+/* registers of smi */
+#define SMI_CR1		0x0	/* SMI control register 1 */
+#define SMI_CR2		0x4	/* SMI control register 2 */
+#define SMI_SR		0x8	/* SMI status register */
+#define SMI_TR		0xC	/* SMI transmit register */
+#define SMI_RR		0x10	/* SMI receive register */
+
+/* defines for control_reg 1 */
+#define BANK_EN		(0xF << 0)	/* enables all banks */
+#define DSEL_TIME	(0x6 << 4)	/* Deselect time 6 + 1 SMI_CK periods */
+#define SW_MODE		(0x1 << 28)	/* enables SW Mode */
+#define WB_MODE		(0x1 << 29)	/* Write Burst Mode */
+#define FAST_MODE	(0x1 << 15)	/* Fast Mode */
+#define HOLD1		(0x1 << 16)	/* Clock Hold period selection */
+
+/* defines for control_reg 2 */
+#define SEND		(0x1 << 7)	/* Send data */
+#define TFIE		(0x1 << 8)	/* Transmission Flag Interrupt Enable */
+#define WCIE		(0x1 << 9)	/* Write Complete Interrupt Enable */
+#define RD_STATUS_REG	(0x1 << 10)	/* reads status reg */
+#define WE		(0x1 << 11)	/* Write Enable */
+
+#define TX_LEN_SHIFT	0
+#define RX_LEN_SHIFT	4
+#define BANK_SHIFT	12
+
+/* defines for status register */
+#define SR_WIP		0x1	/* Write in progress */
+#define SR_WEL		0x2	/* Write enable latch */
+#define SR_BP0		0x4	/* Block protect 0 */
+#define SR_BP1		0x8	/* Block protect 1 */
+#define SR_BP2		0x10	/* Block protect 2 */
+#define SR_SRWD		0x80	/* SR write protect */
+#define TFF		0x100	/* Transfer Finished Flag */
+#define WCF		0x200	/* Transfer Finished Flag */
+#define ERF1		0x400	/* Forbidden Write Request */
+#define ERF2		0x800	/* Forbidden Access */
+
+#define WM_SHIFT	12
+
+/* flash opcodes */
+#define OPCODE_RDID	0x9f	/* Read JEDEC ID */
+
+/* Flash Device Ids maintenance section */
+
+/* data structure to maintain flash ids from different vendors */
+struct flash_device {
+	char *name;
+	u8 erase_cmd;
+	u32 device_id;
+	u32 pagesize;
+	unsigned long sectorsize;
+	unsigned long size_in_bytes;
+};
+
+#define FLASH_ID(n, es, id, psize, ssize, size)	\
+{				\
+	.name = n,		\
+	.erase_cmd = es,	\
+	.device_id = id,	\
+	.pagesize = psize,	\
+	.sectorsize = ssize,	\
+	.size_in_bytes = size	\
+}
+
+static struct flash_device flash_devices[] = {
+	FLASH_ID("st m25p16"     , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
+	FLASH_ID("st m25p32"     , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
+	FLASH_ID("st m25p64"     , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
+	FLASH_ID("st m25p128"    , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
+	FLASH_ID("st m25p05"     , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("st m25p10"     , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),
+	FLASH_ID("st m25p20"     , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m25p40"     , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m25p80"     , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("st m45pe10"    , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
+	FLASH_ID("st m45pe20"    , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m45pe40"    , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m45pe80"    , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl004"   , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
+	FLASH_ID("sp s25fl008"   , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl016"   , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
+	FLASH_ID("sp s25fl032"   , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
+	FLASH_ID("sp s25fl064"   , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
+	FLASH_ID("atmel 25f512"  , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000),
+	FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000),
+	FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("mac 25l512"    , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),
+	FLASH_ID("mac 25l1005"   , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),
+	FLASH_ID("mac 25l2005"   , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),
+	FLASH_ID("mac 25l4005"   , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l4005a"  , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l8005"   , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),
+	FLASH_ID("mac 25l1605"   , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),
+	FLASH_ID("mac 25l1605a"  , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),
+	FLASH_ID("mac 25l3205"   , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l3205a"  , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l6405"   , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),
+};
+
+/* These partitions would be used if platform doesn't pass one */
+static struct mtd_partition part_info_8M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x10000),
+	DEFINE_PARTS("UBoot", 0x10000, 0x40000),
+	DEFINE_PARTS("Kernel", 0x50000, 0x2C0000),
+	DEFINE_PARTS("Root File System", 0x310000, 0x4F0000),
+};
+
+static struct mtd_partition part_info_16M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x40000),
+	DEFINE_PARTS("UBoot", 0x40000, 0x100000),
+	DEFINE_PARTS("Kernel", 0x140000, 0x300000),
+	DEFINE_PARTS("Root File System", 0x440000, 0xBC0000),
+};
+
+/* Define spear specific structures */
+
+struct spear_snor_flash;
+
+/**
+ * struct spear_smi - Structure for SMI Device
+ *
+ * @clk: functional clock
+ * @status: current status register of SMI.
+ * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)
+ * @lock: lock to prevent parallel access of SMI.
+ * @io_base: base address for registers of SMI.
+ * @pdev: platform device
+ * @cmd_complete: queue to wait for command completion of NOR-flash.
+ * @num_flashes: number of flashes actually present on board.
+ * @flash: separate structure for each Serial NOR-flash attached to SMI.
+ */
+struct spear_smi {
+	struct clk *clk;
+	u32 status;
+	unsigned long clk_rate;
+	struct mutex lock;
+	void __iomem *io_base;
+	struct platform_device *pdev;
+	wait_queue_head_t cmd_complete;
+	u32 num_flashes;
+	struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];
+};
+
+/**
+ * struct spear_snor_flash - Structure for Serial NOR Flash
+ *
+ * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.
+ * @dev_id: Device ID of NOR-flash.
+ * @lock: lock to manage flash read, write and erase operations
+ * @mtd: MTD info for each NOR-flash.
+ * @num_parts: Total number of partition in each bank of NOR-flash.
+ * @parts: Partition info for each bank of NOR-flash.
+ * @page_size: Page size of NOR-flash.
+ * @base_addr: Base address of NOR-flash.
+ * @erase_cmd: erase command may vary on different flash types
+ * @fast_mode: flash supports read in fast mode
+ */
+struct spear_snor_flash {
+	u32 bank;
+	u32 dev_id;
+	struct mutex lock;
+	struct mtd_info mtd;
+	u32 num_parts;
+	struct mtd_partition *parts;
+	u32 page_size;
+	void __iomem *base_addr;
+	u8 erase_cmd;
+	u8 fast_mode;
+};
+
+static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct spear_snor_flash, mtd);
+}
+
+/**
+ * spear_smi_read_sr - Read status register of flash through SMI
+ * @dev: structure of SMI information.
+ * @bank: bank to which flash is connected
+ *
+ * This routine will return the status register of the flash chip present at the
+ * given bank.
+ */
+static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in hw mode */
+	writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);
+
+	/* performing a rsr instruction in hw mode */
+	writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,
+			dev->io_base + SMI_CR2);
+
+	/* wait for tff */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* copy dev->status (lower 16 bits) in order to release lock */
+	if (ret > 0)
+		ret = dev->status & 0xffff;
+	else
+		ret = -EIO;
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_wait_till_ready - wait till flash is ready
+ * @dev: structure of SMI information.
+ * @bank: flash corresponding to this bank
+ * @timeout: timeout for busy wait condition
+ *
+ * This routine checks for WIP (write in progress) bit in Status register
+ * If successful the routine returns 0 else -EBUSY
+ */
+static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
+		unsigned long timeout)
+{
+	unsigned long finish;
+	int status;
+
+	finish = jiffies + timeout;
+	do {
+		status = spear_smi_read_sr(dev, bank);
+		if (status < 0)
+			continue; /* try till timeout */
+		else if (!(status & SR_WIP))
+			return 0;
+
+		cond_resched();
+	} while (!time_after_eq(jiffies, finish));
+
+	dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
+	return status;
+}
+
+/**
+ * spear_smi_int_handler - SMI Interrupt Handler.
+ * @irq: irq number
+ * @dev_id: structure of SMI device, embedded in dev_id.
+ *
+ * The handler clears all interrupt conditions and records the status in
+ * dev->status which is used by the driver later.
+ */
+static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)
+{
+	u32 status = 0;
+	struct spear_smi *dev = dev_id;
+
+	status = readl(dev->io_base + SMI_SR);
+
+	if (unlikely(!status))
+		return IRQ_NONE;
+
+	/* clear all interrupt conditions */
+	writel(0, dev->io_base + SMI_SR);
+
+	/* copy the status register in dev->status */
+	dev->status |= status;
+
+	/* send the completion */
+	wake_up_interruptible(&dev->cmd_complete);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * spear_smi_hw_init - initializes the smi controller.
+ * @dev: structure of smi device
+ *
+ * this routine initializes the smi controller wit the default values
+ */
+static void spear_smi_hw_init(struct spear_smi *dev)
+{
+	unsigned long rate = 0;
+	u32 prescale = 0;
+	u32 val;
+
+	rate = clk_get_rate(dev->clk);
+
+	/* functional clock of smi */
+	prescale = DIV_ROUND_UP(rate, dev->clk_rate);
+
+	/*
+	 * setting the standard values, fast mode, prescaler for
+	 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable
+	 */
+	val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
+
+	mutex_lock(&dev->lock);
+	writel(val, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+}
+
+/**
+ * get_flash_index - match chip id from a flash list.
+ * @flash_id: a valid nor flash chip id obtained from board.
+ *
+ * try to validate the chip id by matching from a list, if not found then simply
+ * returns negative. In case of success returns index in to the flash devices
+ * array.
+ */
+static int get_flash_index(u32 flash_id)
+{
+	int index;
+
+	/* Matches chip-id to entire list of 'serial-nor flash' ids */
+	for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {
+		if (flash_devices[index].device_id == flash_id)
+			return index;
+	}
+
+	/* Memory chip is not listed and not supported */
+	return -ENODEV;
+}
+
+/**
+ * spear_smi_write_enable - Enable the flash to do write operation
+ * @dev: structure of SMI device
+ * @bank: enable write for flash connected to this bank
+ *
+ * Set write enable latch with Write Enable command.
+ * Returns 0 on success.
+ */
+static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in h/w mode */
+	writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	/* give the flash, write enable command */
+	writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev,
+			"smi controller failed on write enable\n");
+	} else {
+		/* check whether write mode status is set for required bank */
+		if (dev->status & (1 << (bank + WM_SHIFT)))
+			ret = 0;
+		else {
+			dev_err(&dev->pdev->dev, "couldn't enable write\n");
+			ret = -EIO;
+		}
+	}
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static inline u32
+get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)
+{
+	u32 cmd;
+	u8 *x = (u8 *)&cmd;
+
+	x[0] = flash->erase_cmd;
+	x[1] = offset >> 16;
+	x[2] = offset >> 8;
+	x[3] = offset;
+
+	return cmd;
+}
+
+/**
+ * spear_smi_erase_sector - erase one sector of flash
+ * @dev: structure of SMI information
+ * @command: erase command to be send
+ * @bank: bank to which this command needs to be send
+ * @bytes: size of command
+ *
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int spear_smi_erase_sector(struct spear_smi *dev,
+		u32 bank, u32 command, u32 bytes)
+{
+	u32 ctrlreg1 = 0;
+	int ret;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);
+
+	/* send command in sw mode */
+	writel(command, dev->io_base + SMI_TR);
+
+	writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),
+			dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev, "sector erase failed\n");
+	} else
+		ret = 0; /* success */
+
+	/* restore ctrl regs */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+/**
+ * spear_mtd_erase - perform flash erase operation as requested by user
+ * @mtd: Provides the memory characteristics
+ * @e_info: Provides the erase information
+ *
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	u32 addr, command, bank;
+	int len, ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	/* do not allow erase past end of device */
+	if (e_info->addr + e_info->len > flash->mtd.size)
+		return -EINVAL;
+
+	bank = flash->bank;
+	if (bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	addr = e_info->addr;
+	len = e_info->len;
+
+	mutex_lock(&flash->lock);
+
+	/* now erase sectors in loop */
+	while (len) {
+		command = get_sector_erase_cmd(flash, addr);
+		/* preparing the command for flash */
+		ret = spear_smi_erase_sector(dev, bank, command, 4);
+		if (ret) {
+			e_info->state = MTD_ERASE_FAILED;
+			mutex_unlock(&flash->lock);
+			return ret;
+		}
+		addr += mtd->erasesize;
+		len -= mtd->erasesize;
+	}
+
+	mutex_unlock(&flash->lock);
+	e_info->state = MTD_ERASE_DONE;
+	mtd_erase_callback(e_info);
+
+	return 0;
+}
+
+/**
+ * spear_mtd_read - performs flash read operation as requested by the user
+ * @mtd: MTD information of the memory bank
+ * @from: Address from which to start read
+ * @len: Number of bytes to be read
+ * @retlen: Fills the Number of bytes actually read
+ * @buf: Fills this after reading
+ *
+ * Read an address range from the flash chip. The address range
+ * may be any size provided it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *src;
+	u32 ctrlreg1, val;
+	int ret;
+
+	if (!len)
+		return 0;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	/* do not allow reads past end of device */
+	if (from + len > flash->mtd.size)
+		return -EINVAL;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	if (!retlen)
+		return -EINVAL;
+	else
+		*retlen = 0;
+
+	/* select address as per bank number */
+	src = flash->base_addr + from;
+
+	mutex_lock(&flash->lock);
+
+	/* wait till previous write/erase is done. */
+	ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);
+	if (ret) {
+		mutex_unlock(&flash->lock);
+		return ret;
+	}
+
+	mutex_lock(&dev->lock);
+	/* put smi in hw mode not wbt mode */
+	ctrlreg1 = val = readl(dev->io_base + SMI_CR1);
+	val &= ~(SW_MODE | WB_MODE);
+	if (flash->fast_mode)
+		val |= FAST_MODE;
+
+	writel(val, dev->io_base + SMI_CR1);
+
+	memcpy_fromio(buf, (u8 *)src, len);
+
+	/* restore ctrl reg1 */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+
+	*retlen = len;
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
+static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
+		void *dest, const void *src, size_t len)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	/* wait until finished previous write command. */
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	/* put smi in write enable */
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	/* put smi in hw, write burst mode */
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	memcpy_toio(dest, src, len);
+
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+/**
+ * spear_mtd_write - performs write operation as requested by the user.
+ * @mtd: MTD information of the memory bank.
+ * @to:	Address to write.
+ * @len: Number of bytes to be written.
+ * @retlen: Number of bytes actually wrote.
+ * @buf: Buffer from which the data to be taken.
+ *
+ * Write an address range to the flash chip. Data must be written in
+ * flash_page_size chunks. The address range may be any size provided
+ * it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *dest;
+	u32 page_offset, page_size;
+	int ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	if (!len)
+		return 0;
+
+	/* do not allow write past end of page */
+	if (to + len > flash->mtd.size)
+		return -EINVAL;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	if (!retlen)
+		return -EINVAL;
+	else
+		*retlen = 0;
+
+	/* select address as per bank number */
+	dest = flash->base_addr + to;
+	mutex_lock(&flash->lock);
+
+	page_offset = (u32)to % flash->page_size;
+
+	/* do if all the bytes fit onto one page */
+	if (page_offset + len <= flash->page_size) {
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);
+		if (!ret)
+			*retlen += len;
+	} else {
+		u32 i;
+
+		/* the size of data remaining on the first page */
+		page_size = flash->page_size - page_offset;
+
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,
+				page_size);
+		if (ret)
+			goto err_write;
+		else
+			*retlen += page_size;
+
+		/* write everything in pagesize chunks */
+		for (i = page_size; i < len; i += page_size) {
+			page_size = len - i;
+			if (page_size > flash->page_size)
+				page_size = flash->page_size;
+
+			ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,
+					buf + i, page_size);
+			if (ret)
+				break;
+			else
+				*retlen += page_size;
+		}
+	}
+
+err_write:
+	mutex_unlock(&flash->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_probe_flash - Detects the NOR Flash chip.
+ * @dev: structure of SMI information.
+ * @bank: bank on which flash must be probed
+ *
+ * This routine will check whether there exists a flash chip on a given memory
+ * bank ID.
+ * Return index of the probed flash in flash devices structure
+ */
+static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 val = 0;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	dev->status = 0; /* Will be set in interrupt handler */
+	/* put smi in sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val | SW_MODE, dev->io_base + SMI_CR1);
+
+	/* send readid command in sw mode */
+	writel(OPCODE_RDID, dev->io_base + SMI_TR);
+
+	val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |
+		(3 << RX_LEN_SHIFT) | TFIE;
+	writel(val, dev->io_base + SMI_CR2);
+
+	/* wait for TFF */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+	if (ret <= 0) {
+		ret = -ENODEV;
+		goto err_probe;
+	}
+
+	/* get memory chip id */
+	val = readl(dev->io_base + SMI_RR);
+	val &= 0x00ffffff;
+	ret = get_flash_index(val);
+
+err_probe:
+	/* clear sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank)
+{
+	const char *part_probes[] = {"cmdlinepart", NULL};
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	struct spear_smi_flash_info *flash_info;
+	struct spear_smi_plat_data *pdata;
+	struct spear_snor_flash *flash;
+	int flash_index;
+	int ret = 0;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (bank > pdata->num_flashes - 1)
+		return -EINVAL;
+
+	flash_info = &pdata->board_flash_info[bank];
+	if (!flash_info)
+		return -ENODEV;
+
+	flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
+	if (!flash)
+		return -ENOMEM;
+	flash->bank = bank;
+	flash->fast_mode = flash_info->fast_mode ? 1 : 0;
+	mutex_init(&flash->lock);
+
+	/* verify whether nor flash is really present on board */
+	flash_index = spear_smi_probe_flash(dev, bank);
+	if (flash_index < 0) {
+		dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
+		kfree(flash);
+		return flash_index;
+	}
+	/* map the memory for nor flash chip */
+	flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
+	if (!flash->base_addr) {
+		kfree(flash);
+		return -EIO;
+	}
+
+	dev->flash[bank] = flash;
+	flash->mtd.priv = dev;
+
+	if (flash_info->name)
+		flash->mtd.name = flash_info->name;
+	else
+		flash->mtd.name = flash_devices[flash_index].name;
+
+	flash->mtd.type = MTD_NORFLASH;
+	flash->mtd.writesize = 1;
+	flash->mtd.flags = MTD_CAP_NORFLASH;
+	flash->mtd.size = flash_info->size;
+	flash->mtd.erasesize = flash_devices[flash_index].sectorsize;
+	flash->page_size = flash_devices[flash_index].pagesize;
+	flash->erase_cmd = flash_devices[flash_index].erase_cmd;
+	flash->mtd.erase = spear_mtd_erase;
+	flash->mtd.read = spear_mtd_read;
+	flash->mtd.write = spear_mtd_write;
+	flash->dev_id = flash_devices[flash_index].device_id;
+
+	dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",
+			flash->mtd.name, flash->mtd.size,
+			flash->mtd.size / (1024 * 1024));
+
+	dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
+			flash->mtd.erasesize, flash->mtd.erasesize / 1024);
+
+	if (!mtd_has_partitions()) {
+		ret = add_mtd_device(&flash->mtd);
+		return ret;
+	}
+
+	flash->num_parts = 0;
+	if (mtd_has_cmdlinepart()) {
+		flash->num_parts = parse_mtd_partitions(&flash->mtd,
+				part_probes, &flash->parts, 0);
+	}
+
+	if (flash->num_parts <= 0) {
+		if (flash_info->parts) {
+			flash->parts = flash_info->parts;
+			flash->num_parts = flash_info->num_parts;
+		} else {
+			/* choose from default ones */
+			switch (flash->mtd.size) {
+			case 0x800000:/* 8MB */
+				flash->parts = part_info_8M;
+				flash->num_parts =
+					ARRAY_SIZE(part_info_8M);
+				break;
+			case 0x1000000:/* 16MB */
+				flash->parts = part_info_16M;
+				flash->num_parts =
+					ARRAY_SIZE(part_info_16M);
+				break;
+			default:
+				dev_err(&pdev->dev, "undefined partition\n");
+			}
+		}
+	}
+
+	/* Register the partitions */
+	ret = add_mtd_partitions(&flash->mtd, flash->parts, flash->num_parts);
+	if (ret)
+		dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
+
+	return ret;
+}
+
+/**
+ * spear_smi_probe - Entry routine
+ * @pdev: platform device structure
+ *
+ * This is the first routine which gets invoked during booting and does all
+ * initialization/allocation work. The routine looks for available memory banks,
+ * and do proper init for any found one.
+ * Returns 0 on success, non zero otherwise
+ */
+static int __devinit spear_smi_probe(struct platform_device *pdev)
+{
+	struct spear_smi_plat_data *pdata;
+	struct spear_smi *dev;
+	struct resource *smi_base;
+	int irq, ret = 0;
+	int i;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (pdata < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "no platform data\n");
+		goto err;
+	}
+
+	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!smi_base) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi base address\n");
+		goto err;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi irq\n");
+		goto err;
+	}
+
+	dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
+	if (!dev) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "mem alloc fail\n");
+		goto err;
+	}
+
+	smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
+			pdev->name);
+	if (!smi_base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "request mem region fail\n");
+		goto err_mem;
+	}
+
+	dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
+	if (!dev->io_base) {
+		ret = -EIO;
+		dev_err(&pdev->dev, "ioremap fail\n");
+		goto err_ioremap;
+	}
+
+	dev->pdev = pdev;
+	dev->clk_rate = pdata->clk_rate;
+
+	if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
+		dev->clk_rate = SMI_MAX_CLOCK_FREQ;
+
+	dev->num_flashes = pdata->num_flashes;
+
+	if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {
+		dev_err(&pdev->dev, "exceeding max number of flashes\n");
+		dev->num_flashes = MAX_NUM_FLASH_CHIP;
+	}
+
+	dev->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(dev->clk)) {
+		ret = PTR_ERR(dev->clk);
+		goto err_clk;
+	}
+
+	ret = clk_enable(dev->clk);
+	if (ret)
+		goto err_clk_enable;
+
+	ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
+		goto err_irq;
+	}
+
+	mutex_init(&dev->lock);
+	init_waitqueue_head(&dev->cmd_complete);
+	spear_smi_hw_init(dev);
+	platform_set_drvdata(pdev, dev);
+
+	/* loop for each serial nor-flash which is connected to smi */
+	for (i = 0; i < dev->num_flashes; i++) {
+		ret = spear_smi_setup_banks(pdev, i);
+		if (ret) {
+			dev_err(&dev->pdev->dev, "bank setup failed\n");
+			goto err_bank_setup;
+		}
+	}
+
+	return 0;
+
+err_bank_setup:
+	free_irq(irq, dev);
+	platform_set_drvdata(pdev, NULL);
+err_irq:
+	clk_disable(dev->clk);
+err_clk_enable:
+	clk_put(dev->clk);
+err_clk:
+	iounmap(dev->io_base);
+err_ioremap:
+	release_mem_region(smi_base->start, resource_size(smi_base));
+err_mem:
+	kfree(dev);
+err:
+	return ret;
+}
+
+/**
+ * spear_smi_remove - Exit routine
+ * @pdev: platform device structure
+ *
+ * free all allocations and delete the partitions.
+ */
+static int __devexit spear_smi_remove(struct platform_device *pdev)
+{
+	struct spear_smi *dev;
+	struct spear_snor_flash *flash;
+	int ret;
+	int i, irq;
+
+	dev = platform_get_drvdata(pdev);
+	if (!dev) {
+		dev_err(&pdev->dev, "dev is null\n");
+		return -ENODEV;
+	}
+
+	/* clean up for all nor flash */
+	for (i = 0; i < dev->num_flashes; i++) {
+		flash = dev->flash[i];
+		if (!flash)
+			continue;
+
+		/* clean up mtd stuff */
+		if (mtd_has_partitions())
+			ret = del_mtd_partitions(&flash->mtd);
+		else
+			ret = del_mtd_device(&flash->mtd);
+
+		if (ret)
+			dev_err(&pdev->dev, "error removing mtd\n");
+
+		iounmap(flash->base_addr);
+		kfree(flash);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	free_irq(irq, dev);
+
+	clk_disable(dev->clk);
+	clk_put(dev->clk);
+	iounmap(dev->io_base);
+	kfree(dev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+
+	if (dev && dev->clk)
+		clk_disable(dev->clk);
+
+	return 0;
+}
+
+int spear_smi_resume(struct platform_device *pdev)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	int ret = -EPERM;
+
+	if (dev && dev->clk)
+		ret = clk_enable(dev->clk);
+
+	return ret;
+}
+
+static struct platform_driver spear_smi_driver = {
+	.driver = {
+		.name = "smi",
+		.bus = &platform_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = spear_smi_probe,
+	.remove = __devexit_p(spear_smi_remove),
+	.suspend = spear_smi_suspend,
+	.resume = spear_smi_resume,
+};
+
+static int spear_smi_init(void)
+{
+	return platform_driver_register(&spear_smi_driver);
+}
+module_init(spear_smi_init);
+
+static void spear_smi_exit(void)
+{
+	platform_driver_unregister(&spear_smi_driver);
+}
+module_exit(spear_smi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
-- 
1.7.2.2

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

* [PATCH 24/74] ST SPEAr: Add smi driver for serial NOR flash
@ 2010-08-30 10:43   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shiraz Hashim <shiraz.hashim@st.com>

SPEAr platforms(spear3xx/spear6xx/spear13xx) provide SMI(Serial Memory
Interface) controller to access serial NOR flash. SMI provides a simple
interface for SPI/serial NOR flashes and has certain inbuilt commands
and features to support these flashes easily. It also makes it possible
to map an address range in order to directly access (read/write) the SNOR
over address bus. This patch intends to provide serial nor driver support
for spear platforms which are accessed through SMI.

Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/include/plat/smi.h |   68 ++
 drivers/mtd/devices/Kconfig            |    7 +
 drivers/mtd/devices/Makefile           |    1 +
 drivers/mtd/devices/spear_smi.c        | 1122 ++++++++++++++++++++++++++++++++
 4 files changed, 1198 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/smi.h
 create mode 100644 drivers/mtd/devices/spear_smi.c

diff --git a/arch/arm/plat-spear/include/plat/smi.h b/arch/arm/plat-spear/include/plat/smi.h
new file mode 100644
index 0000000..4c74df7
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/smi.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/plat-spear/include/plat/smi.h
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@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_SMI_H
+#define __PLAT_SMI_H
+
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+
+/* macro to define partitions for flash devices */
+#define DEFINE_PARTS(n, of, s)		\
+{					\
+	.name = n,			\
+	.offset = of,			\
+	.size = s,			\
+}
+
+/**
+ * struct spear_smi_flash_info - platform structure for passing flash
+ * information
+ *
+ * name: name of the serial nor flash for identification
+ * mem_base: the memory base on which the flash is mapped
+ * size: size of the flash in bytes
+ * num_parts: number of partitions
+ * parts: parition details
+ * fast_mode: whether flash supports fast mode
+ */
+
+struct spear_smi_flash_info {
+	char *name;
+	unsigned long mem_base;
+	unsigned long size;
+	int num_parts;
+	struct mtd_partition *parts;
+	u8 fast_mode;
+};
+
+/**
+ * struct spear_smi_plat_data - platform structure for configuring smi
+ *
+ * clk_rate: clk rate at which SMI must operate
+ * num_flashes: number of flashes present on board
+ * board_flash_info: specific details of each flash present on board
+ */
+struct spear_smi_plat_data {
+	unsigned long clk_rate;
+	int num_flashes;
+	struct spear_smi_flash_info *board_flash_info;
+};
+
+static inline void smi_set_plat_data(struct platform_device *pdev,
+		struct spear_smi_plat_data *pdata)
+{
+	pdev->dev.platform_data = pdata;
+}
+
+#endif /* __PLAT_SMI_H */
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 35081ce..83daf23 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -102,6 +102,13 @@ config M25PXX_USE_FAST_READ
 	help
 	  This option enables FAST_READ access supported by ST M25Pxx.
 
+config MTD_SPEAR_SMI
+	tristate "SPEAR MTD NOR Support through SMI controller"
+	depends on PLAT_SPEAR
+	default y
+	help
+	  This enable SNOR support on SPEAR platforms using SMI controller
+
 config MTD_SST25L
 	tristate "Support SST25L (non JEDEC) SPI Flash chips"
 	depends on SPI_MASTER
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index f3226b1..6e9063b 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
+obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
new file mode 100644
index 0000000..6dd7de1
--- /dev/null
+++ b/drivers/mtd/devices/spear_smi.c
@@ -0,0 +1,1122 @@
+/*
+ * linux/drivers/mtd/devices/spear_smi.c
+ *
+ * SMI (Serial Memory Controller) device driver for Serial NOR Flash on
+ * SPEAr platform
+ * The serial nor interface is largely based on drivers/mtd/m25p80.c,
+ * however the SPI interface has been replaced by SMI.
+ *
+ * Copyright (C) 2010 STMicroelectronics.
+ * Ashish Priyadarshi
+ * Shiraz Hashim <shiraz.hashim@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/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <plat/smi.h>
+
+/* max possible slots for serial-nor flash chip in the SMI controller */
+#define MAX_NUM_FLASH_CHIP	4
+
+/* SMI clock rate */
+#define SMI_MAX_CLOCK_FREQ	50000000 /* 50 MHz */
+
+/* MAX time out to safely come out of a erase or write busy conditions */
+#define SMI_PROBE_TIMEOUT	(HZ / 10)
+#define SMI_MAX_TIME_OUT	(3 * HZ)
+
+/* timeout for command completion */
+#define SMI_CMD_TIMEOUT		(HZ / 10)
+
+/* registers of smi */
+#define SMI_CR1		0x0	/* SMI control register 1 */
+#define SMI_CR2		0x4	/* SMI control register 2 */
+#define SMI_SR		0x8	/* SMI status register */
+#define SMI_TR		0xC	/* SMI transmit register */
+#define SMI_RR		0x10	/* SMI receive register */
+
+/* defines for control_reg 1 */
+#define BANK_EN		(0xF << 0)	/* enables all banks */
+#define DSEL_TIME	(0x6 << 4)	/* Deselect time 6 + 1 SMI_CK periods */
+#define SW_MODE		(0x1 << 28)	/* enables SW Mode */
+#define WB_MODE		(0x1 << 29)	/* Write Burst Mode */
+#define FAST_MODE	(0x1 << 15)	/* Fast Mode */
+#define HOLD1		(0x1 << 16)	/* Clock Hold period selection */
+
+/* defines for control_reg 2 */
+#define SEND		(0x1 << 7)	/* Send data */
+#define TFIE		(0x1 << 8)	/* Transmission Flag Interrupt Enable */
+#define WCIE		(0x1 << 9)	/* Write Complete Interrupt Enable */
+#define RD_STATUS_REG	(0x1 << 10)	/* reads status reg */
+#define WE		(0x1 << 11)	/* Write Enable */
+
+#define TX_LEN_SHIFT	0
+#define RX_LEN_SHIFT	4
+#define BANK_SHIFT	12
+
+/* defines for status register */
+#define SR_WIP		0x1	/* Write in progress */
+#define SR_WEL		0x2	/* Write enable latch */
+#define SR_BP0		0x4	/* Block protect 0 */
+#define SR_BP1		0x8	/* Block protect 1 */
+#define SR_BP2		0x10	/* Block protect 2 */
+#define SR_SRWD		0x80	/* SR write protect */
+#define TFF		0x100	/* Transfer Finished Flag */
+#define WCF		0x200	/* Transfer Finished Flag */
+#define ERF1		0x400	/* Forbidden Write Request */
+#define ERF2		0x800	/* Forbidden Access */
+
+#define WM_SHIFT	12
+
+/* flash opcodes */
+#define OPCODE_RDID	0x9f	/* Read JEDEC ID */
+
+/* Flash Device Ids maintenance section */
+
+/* data structure to maintain flash ids from different vendors */
+struct flash_device {
+	char *name;
+	u8 erase_cmd;
+	u32 device_id;
+	u32 pagesize;
+	unsigned long sectorsize;
+	unsigned long size_in_bytes;
+};
+
+#define FLASH_ID(n, es, id, psize, ssize, size)	\
+{				\
+	.name = n,		\
+	.erase_cmd = es,	\
+	.device_id = id,	\
+	.pagesize = psize,	\
+	.sectorsize = ssize,	\
+	.size_in_bytes = size	\
+}
+
+static struct flash_device flash_devices[] = {
+	FLASH_ID("st m25p16"     , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
+	FLASH_ID("st m25p32"     , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
+	FLASH_ID("st m25p64"     , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
+	FLASH_ID("st m25p128"    , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
+	FLASH_ID("st m25p05"     , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("st m25p10"     , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),
+	FLASH_ID("st m25p20"     , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m25p40"     , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m25p80"     , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("st m45pe10"    , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
+	FLASH_ID("st m45pe20"    , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m45pe40"    , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m45pe80"    , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl004"   , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
+	FLASH_ID("sp s25fl008"   , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl016"   , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
+	FLASH_ID("sp s25fl032"   , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
+	FLASH_ID("sp s25fl064"   , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
+	FLASH_ID("atmel 25f512"  , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000),
+	FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000),
+	FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("mac 25l512"    , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),
+	FLASH_ID("mac 25l1005"   , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),
+	FLASH_ID("mac 25l2005"   , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),
+	FLASH_ID("mac 25l4005"   , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l4005a"  , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l8005"   , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),
+	FLASH_ID("mac 25l1605"   , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),
+	FLASH_ID("mac 25l1605a"  , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),
+	FLASH_ID("mac 25l3205"   , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l3205a"  , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l6405"   , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),
+};
+
+/* These partitions would be used if platform doesn't pass one */
+static struct mtd_partition part_info_8M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x10000),
+	DEFINE_PARTS("UBoot", 0x10000, 0x40000),
+	DEFINE_PARTS("Kernel", 0x50000, 0x2C0000),
+	DEFINE_PARTS("Root File System", 0x310000, 0x4F0000),
+};
+
+static struct mtd_partition part_info_16M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x40000),
+	DEFINE_PARTS("UBoot", 0x40000, 0x100000),
+	DEFINE_PARTS("Kernel", 0x140000, 0x300000),
+	DEFINE_PARTS("Root File System", 0x440000, 0xBC0000),
+};
+
+/* Define spear specific structures */
+
+struct spear_snor_flash;
+
+/**
+ * struct spear_smi - Structure for SMI Device
+ *
+ * @clk: functional clock
+ * @status: current status register of SMI.
+ * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)
+ * @lock: lock to prevent parallel access of SMI.
+ * @io_base: base address for registers of SMI.
+ * @pdev: platform device
+ * @cmd_complete: queue to wait for command completion of NOR-flash.
+ * @num_flashes: number of flashes actually present on board.
+ * @flash: separate structure for each Serial NOR-flash attached to SMI.
+ */
+struct spear_smi {
+	struct clk *clk;
+	u32 status;
+	unsigned long clk_rate;
+	struct mutex lock;
+	void __iomem *io_base;
+	struct platform_device *pdev;
+	wait_queue_head_t cmd_complete;
+	u32 num_flashes;
+	struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];
+};
+
+/**
+ * struct spear_snor_flash - Structure for Serial NOR Flash
+ *
+ * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.
+ * @dev_id: Device ID of NOR-flash.
+ * @lock: lock to manage flash read, write and erase operations
+ * @mtd: MTD info for each NOR-flash.
+ * @num_parts: Total number of partition in each bank of NOR-flash.
+ * @parts: Partition info for each bank of NOR-flash.
+ * @page_size: Page size of NOR-flash.
+ * @base_addr: Base address of NOR-flash.
+ * @erase_cmd: erase command may vary on different flash types
+ * @fast_mode: flash supports read in fast mode
+ */
+struct spear_snor_flash {
+	u32 bank;
+	u32 dev_id;
+	struct mutex lock;
+	struct mtd_info mtd;
+	u32 num_parts;
+	struct mtd_partition *parts;
+	u32 page_size;
+	void __iomem *base_addr;
+	u8 erase_cmd;
+	u8 fast_mode;
+};
+
+static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct spear_snor_flash, mtd);
+}
+
+/**
+ * spear_smi_read_sr - Read status register of flash through SMI
+ * @dev: structure of SMI information.
+ * @bank: bank to which flash is connected
+ *
+ * This routine will return the status register of the flash chip present@the
+ * given bank.
+ */
+static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in hw mode */
+	writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);
+
+	/* performing a rsr instruction in hw mode */
+	writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,
+			dev->io_base + SMI_CR2);
+
+	/* wait for tff */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* copy dev->status (lower 16 bits) in order to release lock */
+	if (ret > 0)
+		ret = dev->status & 0xffff;
+	else
+		ret = -EIO;
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_wait_till_ready - wait till flash is ready
+ * @dev: structure of SMI information.
+ * @bank: flash corresponding to this bank
+ * @timeout: timeout for busy wait condition
+ *
+ * This routine checks for WIP (write in progress) bit in Status register
+ * If successful the routine returns 0 else -EBUSY
+ */
+static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
+		unsigned long timeout)
+{
+	unsigned long finish;
+	int status;
+
+	finish = jiffies + timeout;
+	do {
+		status = spear_smi_read_sr(dev, bank);
+		if (status < 0)
+			continue; /* try till timeout */
+		else if (!(status & SR_WIP))
+			return 0;
+
+		cond_resched();
+	} while (!time_after_eq(jiffies, finish));
+
+	dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
+	return status;
+}
+
+/**
+ * spear_smi_int_handler - SMI Interrupt Handler.
+ * @irq: irq number
+ * @dev_id: structure of SMI device, embedded in dev_id.
+ *
+ * The handler clears all interrupt conditions and records the status in
+ * dev->status which is used by the driver later.
+ */
+static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)
+{
+	u32 status = 0;
+	struct spear_smi *dev = dev_id;
+
+	status = readl(dev->io_base + SMI_SR);
+
+	if (unlikely(!status))
+		return IRQ_NONE;
+
+	/* clear all interrupt conditions */
+	writel(0, dev->io_base + SMI_SR);
+
+	/* copy the status register in dev->status */
+	dev->status |= status;
+
+	/* send the completion */
+	wake_up_interruptible(&dev->cmd_complete);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * spear_smi_hw_init - initializes the smi controller.
+ * @dev: structure of smi device
+ *
+ * this routine initializes the smi controller wit the default values
+ */
+static void spear_smi_hw_init(struct spear_smi *dev)
+{
+	unsigned long rate = 0;
+	u32 prescale = 0;
+	u32 val;
+
+	rate = clk_get_rate(dev->clk);
+
+	/* functional clock of smi */
+	prescale = DIV_ROUND_UP(rate, dev->clk_rate);
+
+	/*
+	 * setting the standard values, fast mode, prescaler for
+	 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable
+	 */
+	val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
+
+	mutex_lock(&dev->lock);
+	writel(val, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+}
+
+/**
+ * get_flash_index - match chip id from a flash list.
+ * @flash_id: a valid nor flash chip id obtained from board.
+ *
+ * try to validate the chip id by matching from a list, if not found then simply
+ * returns negative. In case of success returns index in to the flash devices
+ * array.
+ */
+static int get_flash_index(u32 flash_id)
+{
+	int index;
+
+	/* Matches chip-id to entire list of 'serial-nor flash' ids */
+	for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {
+		if (flash_devices[index].device_id == flash_id)
+			return index;
+	}
+
+	/* Memory chip is not listed and not supported */
+	return -ENODEV;
+}
+
+/**
+ * spear_smi_write_enable - Enable the flash to do write operation
+ * @dev: structure of SMI device
+ * @bank: enable write for flash connected to this bank
+ *
+ * Set write enable latch with Write Enable command.
+ * Returns 0 on success.
+ */
+static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in h/w mode */
+	writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	/* give the flash, write enable command */
+	writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev,
+			"smi controller failed on write enable\n");
+	} else {
+		/* check whether write mode status is set for required bank */
+		if (dev->status & (1 << (bank + WM_SHIFT)))
+			ret = 0;
+		else {
+			dev_err(&dev->pdev->dev, "couldn't enable write\n");
+			ret = -EIO;
+		}
+	}
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static inline u32
+get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)
+{
+	u32 cmd;
+	u8 *x = (u8 *)&cmd;
+
+	x[0] = flash->erase_cmd;
+	x[1] = offset >> 16;
+	x[2] = offset >> 8;
+	x[3] = offset;
+
+	return cmd;
+}
+
+/**
+ * spear_smi_erase_sector - erase one sector of flash
+ * @dev: structure of SMI information
+ * @command: erase command to be send
+ * @bank: bank to which this command needs to be send
+ * @bytes: size of command
+ *
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int spear_smi_erase_sector(struct spear_smi *dev,
+		u32 bank, u32 command, u32 bytes)
+{
+	u32 ctrlreg1 = 0;
+	int ret;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);
+
+	/* send command in sw mode */
+	writel(command, dev->io_base + SMI_TR);
+
+	writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),
+			dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev, "sector erase failed\n");
+	} else
+		ret = 0; /* success */
+
+	/* restore ctrl regs */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+/**
+ * spear_mtd_erase - perform flash erase operation as requested by user
+ * @mtd: Provides the memory characteristics
+ * @e_info: Provides the erase information
+ *
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	u32 addr, command, bank;
+	int len, ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	/* do not allow erase past end of device */
+	if (e_info->addr + e_info->len > flash->mtd.size)
+		return -EINVAL;
+
+	bank = flash->bank;
+	if (bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	addr = e_info->addr;
+	len = e_info->len;
+
+	mutex_lock(&flash->lock);
+
+	/* now erase sectors in loop */
+	while (len) {
+		command = get_sector_erase_cmd(flash, addr);
+		/* preparing the command for flash */
+		ret = spear_smi_erase_sector(dev, bank, command, 4);
+		if (ret) {
+			e_info->state = MTD_ERASE_FAILED;
+			mutex_unlock(&flash->lock);
+			return ret;
+		}
+		addr += mtd->erasesize;
+		len -= mtd->erasesize;
+	}
+
+	mutex_unlock(&flash->lock);
+	e_info->state = MTD_ERASE_DONE;
+	mtd_erase_callback(e_info);
+
+	return 0;
+}
+
+/**
+ * spear_mtd_read - performs flash read operation as requested by the user
+ * @mtd: MTD information of the memory bank
+ * @from: Address from which to start read
+ * @len: Number of bytes to be read
+ * @retlen: Fills the Number of bytes actually read
+ * @buf: Fills this after reading
+ *
+ * Read an address range from the flash chip. The address range
+ * may be any size provided it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *src;
+	u32 ctrlreg1, val;
+	int ret;
+
+	if (!len)
+		return 0;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	/* do not allow reads past end of device */
+	if (from + len > flash->mtd.size)
+		return -EINVAL;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	if (!retlen)
+		return -EINVAL;
+	else
+		*retlen = 0;
+
+	/* select address as per bank number */
+	src = flash->base_addr + from;
+
+	mutex_lock(&flash->lock);
+
+	/* wait till previous write/erase is done. */
+	ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);
+	if (ret) {
+		mutex_unlock(&flash->lock);
+		return ret;
+	}
+
+	mutex_lock(&dev->lock);
+	/* put smi in hw mode not wbt mode */
+	ctrlreg1 = val = readl(dev->io_base + SMI_CR1);
+	val &= ~(SW_MODE | WB_MODE);
+	if (flash->fast_mode)
+		val |= FAST_MODE;
+
+	writel(val, dev->io_base + SMI_CR1);
+
+	memcpy_fromio(buf, (u8 *)src, len);
+
+	/* restore ctrl reg1 */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+
+	*retlen = len;
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
+static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
+		void *dest, const void *src, size_t len)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	/* wait until finished previous write command. */
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	/* put smi in write enable */
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	/* put smi in hw, write burst mode */
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	memcpy_toio(dest, src, len);
+
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+/**
+ * spear_mtd_write - performs write operation as requested by the user.
+ * @mtd: MTD information of the memory bank.
+ * @to:	Address to write.
+ * @len: Number of bytes to be written.
+ * @retlen: Number of bytes actually wrote.
+ * @buf: Buffer from which the data to be taken.
+ *
+ * Write an address range to the flash chip. Data must be written in
+ * flash_page_size chunks. The address range may be any size provided
+ * it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *dest;
+	u32 page_offset, page_size;
+	int ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	if (!len)
+		return 0;
+
+	/* do not allow write past end of page */
+	if (to + len > flash->mtd.size)
+		return -EINVAL;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	if (!retlen)
+		return -EINVAL;
+	else
+		*retlen = 0;
+
+	/* select address as per bank number */
+	dest = flash->base_addr + to;
+	mutex_lock(&flash->lock);
+
+	page_offset = (u32)to % flash->page_size;
+
+	/* do if all the bytes fit onto one page */
+	if (page_offset + len <= flash->page_size) {
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);
+		if (!ret)
+			*retlen += len;
+	} else {
+		u32 i;
+
+		/* the size of data remaining on the first page */
+		page_size = flash->page_size - page_offset;
+
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,
+				page_size);
+		if (ret)
+			goto err_write;
+		else
+			*retlen += page_size;
+
+		/* write everything in pagesize chunks */
+		for (i = page_size; i < len; i += page_size) {
+			page_size = len - i;
+			if (page_size > flash->page_size)
+				page_size = flash->page_size;
+
+			ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,
+					buf + i, page_size);
+			if (ret)
+				break;
+			else
+				*retlen += page_size;
+		}
+	}
+
+err_write:
+	mutex_unlock(&flash->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_probe_flash - Detects the NOR Flash chip.
+ * @dev: structure of SMI information.
+ * @bank: bank on which flash must be probed
+ *
+ * This routine will check whether there exists a flash chip on a given memory
+ * bank ID.
+ * Return index of the probed flash in flash devices structure
+ */
+static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 val = 0;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	dev->status = 0; /* Will be set in interrupt handler */
+	/* put smi in sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val | SW_MODE, dev->io_base + SMI_CR1);
+
+	/* send readid command in sw mode */
+	writel(OPCODE_RDID, dev->io_base + SMI_TR);
+
+	val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |
+		(3 << RX_LEN_SHIFT) | TFIE;
+	writel(val, dev->io_base + SMI_CR2);
+
+	/* wait for TFF */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+	if (ret <= 0) {
+		ret = -ENODEV;
+		goto err_probe;
+	}
+
+	/* get memory chip id */
+	val = readl(dev->io_base + SMI_RR);
+	val &= 0x00ffffff;
+	ret = get_flash_index(val);
+
+err_probe:
+	/* clear sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank)
+{
+	const char *part_probes[] = {"cmdlinepart", NULL};
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	struct spear_smi_flash_info *flash_info;
+	struct spear_smi_plat_data *pdata;
+	struct spear_snor_flash *flash;
+	int flash_index;
+	int ret = 0;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (bank > pdata->num_flashes - 1)
+		return -EINVAL;
+
+	flash_info = &pdata->board_flash_info[bank];
+	if (!flash_info)
+		return -ENODEV;
+
+	flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
+	if (!flash)
+		return -ENOMEM;
+	flash->bank = bank;
+	flash->fast_mode = flash_info->fast_mode ? 1 : 0;
+	mutex_init(&flash->lock);
+
+	/* verify whether nor flash is really present on board */
+	flash_index = spear_smi_probe_flash(dev, bank);
+	if (flash_index < 0) {
+		dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
+		kfree(flash);
+		return flash_index;
+	}
+	/* map the memory for nor flash chip */
+	flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
+	if (!flash->base_addr) {
+		kfree(flash);
+		return -EIO;
+	}
+
+	dev->flash[bank] = flash;
+	flash->mtd.priv = dev;
+
+	if (flash_info->name)
+		flash->mtd.name = flash_info->name;
+	else
+		flash->mtd.name = flash_devices[flash_index].name;
+
+	flash->mtd.type = MTD_NORFLASH;
+	flash->mtd.writesize = 1;
+	flash->mtd.flags = MTD_CAP_NORFLASH;
+	flash->mtd.size = flash_info->size;
+	flash->mtd.erasesize = flash_devices[flash_index].sectorsize;
+	flash->page_size = flash_devices[flash_index].pagesize;
+	flash->erase_cmd = flash_devices[flash_index].erase_cmd;
+	flash->mtd.erase = spear_mtd_erase;
+	flash->mtd.read = spear_mtd_read;
+	flash->mtd.write = spear_mtd_write;
+	flash->dev_id = flash_devices[flash_index].device_id;
+
+	dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",
+			flash->mtd.name, flash->mtd.size,
+			flash->mtd.size / (1024 * 1024));
+
+	dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
+			flash->mtd.erasesize, flash->mtd.erasesize / 1024);
+
+	if (!mtd_has_partitions()) {
+		ret = add_mtd_device(&flash->mtd);
+		return ret;
+	}
+
+	flash->num_parts = 0;
+	if (mtd_has_cmdlinepart()) {
+		flash->num_parts = parse_mtd_partitions(&flash->mtd,
+				part_probes, &flash->parts, 0);
+	}
+
+	if (flash->num_parts <= 0) {
+		if (flash_info->parts) {
+			flash->parts = flash_info->parts;
+			flash->num_parts = flash_info->num_parts;
+		} else {
+			/* choose from default ones */
+			switch (flash->mtd.size) {
+			case 0x800000:/* 8MB */
+				flash->parts = part_info_8M;
+				flash->num_parts =
+					ARRAY_SIZE(part_info_8M);
+				break;
+			case 0x1000000:/* 16MB */
+				flash->parts = part_info_16M;
+				flash->num_parts =
+					ARRAY_SIZE(part_info_16M);
+				break;
+			default:
+				dev_err(&pdev->dev, "undefined partition\n");
+			}
+		}
+	}
+
+	/* Register the partitions */
+	ret = add_mtd_partitions(&flash->mtd, flash->parts, flash->num_parts);
+	if (ret)
+		dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
+
+	return ret;
+}
+
+/**
+ * spear_smi_probe - Entry routine
+ * @pdev: platform device structure
+ *
+ * This is the first routine which gets invoked during booting and does all
+ * initialization/allocation work. The routine looks for available memory banks,
+ * and do proper init for any found one.
+ * Returns 0 on success, non zero otherwise
+ */
+static int __devinit spear_smi_probe(struct platform_device *pdev)
+{
+	struct spear_smi_plat_data *pdata;
+	struct spear_smi *dev;
+	struct resource *smi_base;
+	int irq, ret = 0;
+	int i;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (pdata < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "no platform data\n");
+		goto err;
+	}
+
+	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!smi_base) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi base address\n");
+		goto err;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi irq\n");
+		goto err;
+	}
+
+	dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
+	if (!dev) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "mem alloc fail\n");
+		goto err;
+	}
+
+	smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
+			pdev->name);
+	if (!smi_base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "request mem region fail\n");
+		goto err_mem;
+	}
+
+	dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
+	if (!dev->io_base) {
+		ret = -EIO;
+		dev_err(&pdev->dev, "ioremap fail\n");
+		goto err_ioremap;
+	}
+
+	dev->pdev = pdev;
+	dev->clk_rate = pdata->clk_rate;
+
+	if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
+		dev->clk_rate = SMI_MAX_CLOCK_FREQ;
+
+	dev->num_flashes = pdata->num_flashes;
+
+	if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {
+		dev_err(&pdev->dev, "exceeding max number of flashes\n");
+		dev->num_flashes = MAX_NUM_FLASH_CHIP;
+	}
+
+	dev->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(dev->clk)) {
+		ret = PTR_ERR(dev->clk);
+		goto err_clk;
+	}
+
+	ret = clk_enable(dev->clk);
+	if (ret)
+		goto err_clk_enable;
+
+	ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
+		goto err_irq;
+	}
+
+	mutex_init(&dev->lock);
+	init_waitqueue_head(&dev->cmd_complete);
+	spear_smi_hw_init(dev);
+	platform_set_drvdata(pdev, dev);
+
+	/* loop for each serial nor-flash which is connected to smi */
+	for (i = 0; i < dev->num_flashes; i++) {
+		ret = spear_smi_setup_banks(pdev, i);
+		if (ret) {
+			dev_err(&dev->pdev->dev, "bank setup failed\n");
+			goto err_bank_setup;
+		}
+	}
+
+	return 0;
+
+err_bank_setup:
+	free_irq(irq, dev);
+	platform_set_drvdata(pdev, NULL);
+err_irq:
+	clk_disable(dev->clk);
+err_clk_enable:
+	clk_put(dev->clk);
+err_clk:
+	iounmap(dev->io_base);
+err_ioremap:
+	release_mem_region(smi_base->start, resource_size(smi_base));
+err_mem:
+	kfree(dev);
+err:
+	return ret;
+}
+
+/**
+ * spear_smi_remove - Exit routine
+ * @pdev: platform device structure
+ *
+ * free all allocations and delete the partitions.
+ */
+static int __devexit spear_smi_remove(struct platform_device *pdev)
+{
+	struct spear_smi *dev;
+	struct spear_snor_flash *flash;
+	int ret;
+	int i, irq;
+
+	dev = platform_get_drvdata(pdev);
+	if (!dev) {
+		dev_err(&pdev->dev, "dev is null\n");
+		return -ENODEV;
+	}
+
+	/* clean up for all nor flash */
+	for (i = 0; i < dev->num_flashes; i++) {
+		flash = dev->flash[i];
+		if (!flash)
+			continue;
+
+		/* clean up mtd stuff */
+		if (mtd_has_partitions())
+			ret = del_mtd_partitions(&flash->mtd);
+		else
+			ret = del_mtd_device(&flash->mtd);
+
+		if (ret)
+			dev_err(&pdev->dev, "error removing mtd\n");
+
+		iounmap(flash->base_addr);
+		kfree(flash);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	free_irq(irq, dev);
+
+	clk_disable(dev->clk);
+	clk_put(dev->clk);
+	iounmap(dev->io_base);
+	kfree(dev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+
+	if (dev && dev->clk)
+		clk_disable(dev->clk);
+
+	return 0;
+}
+
+int spear_smi_resume(struct platform_device *pdev)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	int ret = -EPERM;
+
+	if (dev && dev->clk)
+		ret = clk_enable(dev->clk);
+
+	return ret;
+}
+
+static struct platform_driver spear_smi_driver = {
+	.driver = {
+		.name = "smi",
+		.bus = &platform_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = spear_smi_probe,
+	.remove = __devexit_p(spear_smi_remove),
+	.suspend = spear_smi_suspend,
+	.resume = spear_smi_resume,
+};
+
+static int spear_smi_init(void)
+{
+	return platform_driver_register(&spear_smi_driver);
+}
+module_init(spear_smi_init);
+
+static void spear_smi_exit(void)
+{
+	platform_driver_unregister(&spear_smi_driver);
+}
+module_exit(spear_smi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
-- 
1.7.2.2

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-08-30 10:43   ` Viresh KUMAR
  -1 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mtd, dwmw2
  Cc: pratyush.anand, Viresh Kumar, vipulkumar.samar, bhupesh.sharma,
	armando.visconti, Vipin Kumar, shiraz.hashim, rajeev-dlh.kumar,
	deepak.sikri

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

SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
interfacing with NAND devices.
This patch adds the support for glue logic for NAND flash on SPEAr boards

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/clock.c                  |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h   |    2 +
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |   10 +
 arch/arm/mach-spear13xx/spear1300_evb.c          |    8 +
 arch/arm/mach-spear13xx/spear13xx.c              |   58 ++
 arch/arm/mach-spear3xx/clock.c                   |   14 +
 arch/arm/mach-spear3xx/include/mach/generic.h    |   15 +-
 arch/arm/mach-spear3xx/include/mach/spear320.h   |    3 +
 arch/arm/mach-spear3xx/spear300.c                |   98 +++
 arch/arm/mach-spear3xx/spear300_evb.c            |    7 +
 arch/arm/mach-spear3xx/spear310.c                |   26 +
 arch/arm/mach-spear3xx/spear310_evb.c            |    7 +
 arch/arm/mach-spear3xx/spear320.c                |   26 +
 arch/arm/mach-spear3xx/spear320_evb.c            |    7 +
 arch/arm/mach-spear6xx/clock.c                   |    2 +-
 arch/arm/mach-spear6xx/include/mach/generic.h    |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c            |    7 +
 arch/arm/mach-spear6xx/spear6xx.c                |   26 +
 arch/arm/plat-spear/include/plat/fsmc.h          |  109 +++
 arch/arm/plat-spear/include/plat/nand.h          |   76 ++
 drivers/mtd/nand/Kconfig                         |    6 +
 drivers/mtd/nand/Makefile                        |    1 +
 drivers/mtd/nand/spear_nand.c                    |  860 ++++++++++++++++++++++
 23 files changed, 1363 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
 create mode 100644 arch/arm/plat-spear/include/plat/nand.h
 create mode 100644 drivers/mtd/nand/spear_nand.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 5280657..8658d48 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -791,7 +791,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "pcie2",		.clk = &pcie2_clk},
 	{.dev_id = "cfxd",		.clk = &cfxd_clk},
 	{.dev_id = "sd",		.clk = &sd_clk},
-	{.dev_id = "fsmc",		.clk = &fsmc_clk},
+	{.con_id = "fsmc",		.clk = &fsmc_clk},
 	{.dev_id = "sysram0",		.clk = &sysram0_clk},
 	{.dev_id = "sysram1",		.clk = &sysram1_clk},
 
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 186a8be..b884359 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -35,6 +35,7 @@ extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
 extern struct platform_device kbd_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;
@@ -51,6 +52,7 @@ void __init spear1300_init(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 spear13xx_secondary_startup(void);
 
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index c4dcab2..05815fa 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -205,6 +205,16 @@
 #define PCIE_MIPHY_CFG		((unsigned int *)(MISC_BASE + 0x328))
 #define PERIP_CFG		((unsigned int *)(MISC_BASE + 0x32c))
 #define FSMC_CFG		((unsigned int *)(MISC_BASE + 0x330))
+	/* FSMC_CFG register masks */
+	#define FSMC_MEMSEL_MASK	0x3
+	#define FSMC_MEMSEL_SHIFT	0
+	#define FSMC_MEM_NOR		0
+	#define FSMC_MEM_NAND		1
+	#define FSMC_MEM_SRAM		2
+	#define NAND_BANK_MASK		0x3
+	#define NAND_BANK_SHIFT		2
+	#define NAND_DEV_WIDTH16	4
+
 #define MPMC_CTR_STS		((unsigned int *)(MISC_BASE + 0x334))
 
 /* Inter-Processor Communication Registers */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 5b74f05..4267b46 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -12,11 +12,13 @@
  */
 
 #include <linux/types.h>
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -30,6 +32,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ehci1_device,
 	&i2c_device,
 	&kbd_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -52,6 +55,11 @@ static void __init spear1300_evb_init(void)
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+	nand_mach_init(SPEAR_NAND_BW8);
+
 	/* call spear1300 machine init function */
 	spear1300_init();
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index b6bddff..4810652 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -23,6 +23,8 @@
 #include <mach/irqs.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
+#include <mach/misc_regs.h>
+#include <plat/nand.h>
 
 /* Add spear13xx machines common devices here */
 /* gpio device registeration */
@@ -97,6 +99,62 @@ struct platform_device 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 == SPEAR_NAND_BW16)
+		fsmc_cfg |= 1 << NAND_DEV_WIDTH16;
+	else
+		fsmc_cfg &= ~(1 << NAND_DEV_WIDTH16);
+
+	writel(fsmc_cfg, FSMC_CFG);
+}
+
+static 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 nand_platform_data nand_platform_data = {
+	.select_bank = nand_select_bank,
+};
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 39835e8..93c5fd9 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -461,6 +461,16 @@ static struct clk gpio_clk = {
 
 static struct clk dummy_apb_pclk;
 
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
+	defined(CONFIG_MACH_SPEAR320)
+/* fsmc clock */
+static struct clk fsmc_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
 /* keyboard clock */
@@ -535,6 +545,10 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
+	defined(CONFIG_MACH_SPEAR320)
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
+#endif
 
 	/* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 91c0c09..6aac229 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -111,6 +111,10 @@ extern struct pmx_driver pmx_driver;
 extern struct amba_device clcd_device;
 extern struct amba_device gpio1_device;
 extern struct platform_device kbd_device;
+extern struct platform_device nand0_device;
+extern struct platform_device nand1_device;
+extern struct platform_device nand2_device;
+extern struct platform_device nand3_device;
 
 /* pad mux modes */
 extern struct pmx_mode nand_mode;
@@ -148,12 +152,12 @@ void __init spear300_init(void);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
-#endif /* CONFIG_MACH_SPEAR300 */
 
 /* spear310 declarations */
-#ifdef CONFIG_MACH_SPEAR310
+#elif defined(CONFIG_MACH_SPEAR310)
 /* Add spear310 machine device structure declarations here */
 extern struct platform_device plgpio_device;
+extern struct platform_device nand_device;
 
 /* pad mux devices */
 extern struct pmx_dev pmx_emi_cs_0_1_4_5;
@@ -168,13 +172,12 @@ extern struct pmx_dev pmx_tdm0;
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
 
-#endif /* CONFIG_MACH_SPEAR310 */
-
 /* spear320 declarations */
-#ifdef CONFIG_MACH_SPEAR320
+#elif defined(CONFIG_MACH_SPEAR320)
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct platform_device i2c1_device;
+extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
 extern struct platform_device pwm_device;
 
@@ -213,6 +216,6 @@ void __init spear320_init(void);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
-#endif /* CONFIG_MACH_SPEAR320 */
+#endif
 
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index 53677e4..aa6727c 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -22,6 +22,9 @@
 #define SPEAR320_FSMC_BASE		0x4C000000
 #define SPEAR320_FSMC_SIZE		0x01000000
 
+#define SPEAR320_NAND_BASE		0x50000000
+#define SPEAR320_NAND_SIZE		0x04000000
+
 #define SPEAR320_I2S_BASE		0x60000000
 #define SPEAR320_I2S_SIZE		0x10000000
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index cf010cc..3a86868 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -17,6 +17,7 @@
 #include <asm/irq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -426,6 +427,103 @@ struct platform_device kbd_device = {
 	.resource = kbd_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand0_platform_data;
+
+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 nand0_device = {
+	.name = "nand",
+	.id = 0,
+	.resource = nand0_resources,
+	.num_resources = ARRAY_SIZE(nand0_resources),
+	.dev.platform_data = &nand0_platform_data,
+};
+
+static struct nand_platform_data nand1_platform_data;
+
+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 nand1_device = {
+	.name = "nand",
+	.id = 1,
+	.resource = nand1_resources,
+	.num_resources = ARRAY_SIZE(nand1_resources),
+	.dev.platform_data = &nand1_platform_data,
+};
+
+static struct nand_platform_data nand2_platform_data;
+
+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 nand2_device = {
+	.name = "nand",
+	.id = 2,
+	.resource = nand2_resources,
+	.num_resources = ARRAY_SIZE(nand2_resources),
+	.dev.platform_data = &nand2_platform_data,
+};
+
+static struct nand_platform_data nand3_platform_data;
+
+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 nand3_device = {
+	.name = "nand",
+	.id = 3,
+	.resource = nand3_resources,
+	.num_resources = ARRAY_SIZE(nand3_resources),
+	.dev.platform_data = &nand3_platform_data,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 7bd8963..895f7b7 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -11,11 +11,13 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -49,6 +51,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand0_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -79,6 +82,10 @@ static void __init spear300_evb_init(void)
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
+	/* set nand0 device's plat data */
+	nand_set_plat_data(&nand0_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear300 machine init function */
 	spear300_init();
 
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 88b55b5..69350b7 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -16,6 +16,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/gpio.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -177,6 +178,31 @@ int spear300_o2p(int offset)
 		return offset + 2;
 }
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
 	.irq_base = SPEAR_PLGPIO_INT_BASE,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index cd076c9..8f17362 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -54,6 +56,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -72,6 +75,10 @@ static void __init spear310_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear310 machine init function */
 	spear310_init();
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 75e7890..2ac838b 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -16,6 +16,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/gpio.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -431,6 +432,31 @@ struct platform_device i2c1_device = {
 	.resource = i2c1_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 static struct resource plgpio_resources[] = {
 	{
 		.start = SPEAR320_SOC_CONFIG_BASE,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 7f7b5dd..d693877 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -52,6 +54,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -72,6 +75,10 @@ static void __init spear320_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear320 machine init function */
 	spear320_init();
 
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index fb05ec8..91f1f3f 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -602,7 +602,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
 	{ .dev_id = "gmac",		.clk = &gmac_clk},
 	{ .dev_id = "smi",		.clk = &smi_clk},
-	{ .dev_id = "fsmc",		.clk = &fsmc_clk},
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 	/* clock derived from apb clk */
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp0",		.clk = &ssp0_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index f885898..ff90419 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -36,6 +36,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 0eb5f50..cf86efc 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -33,6 +35,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&i2c_device,
 	&ohci0_device,
 	&ohci1_device,
+	&nand_device,
 	&rtc_device,
 	&smi_device,
 };
@@ -41,6 +44,10 @@ static void __init spear600_evb_init(void)
 {
 	unsigned int i;
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear600 machine init function */
 	spear600_init();
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 4987597..2296d0f 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -21,6 +21,7 @@
 #include <mach/irqs.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 
 /* Add spear6xx machines common devices here */
 
@@ -152,6 +153,31 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h
new file mode 100644
index 0000000..c0fdcd3
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/fsmc.h
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/plat-spear/include/plat/fsmc.h
+ *
+ * SPEAr platform nand interface header 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.
+ */
+
+#ifndef __PLAT_FSMC_H
+#define __PLAT_FSMC_H
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <asm/param.h>
+
+#define FSMC_MAX_NAND_BANKS	4
+
+struct nand_bank_regs {
+	u32 pc;
+	u32 sts;
+	u32 comm;
+	u32 attrib;
+	u32 ioata;
+	u32 ecc1;
+	u32 ecc2;
+	u32 ecc3;
+};
+
+struct fsmc_regs {
+	u8 reserved_1[0x40];
+	struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
+	u8 reserved_2[0xfe0 - 0xc0];
+	u32 peripid0;			/* 0xfe0 */
+	u32 peripid1;			/* 0xfe4 */
+	u32 peripid2;			/* 0xfe8 */
+	u32 peripid3;			/* 0xfec */
+	u32 pcellid0;			/* 0xff0 */
+	u32 pcellid1;			/* 0xff4 */
+	u32 pcellid2;			/* 0xff8 */
+	u32 pcellid3;			/* 0xffc */
+};
+
+#define FSMC_BUSY_WAIT_TIMEOUT	(1 * HZ)
+
+/* pc register definitions */
+#define FSMC_RESET		(1 << 0)
+#define FSMC_WAITON		(1 << 1)
+#define FSMC_ENABLE		(1 << 2)
+#define FSMC_DEVTYPE_NAND	(1 << 3)
+#define FSMC_DEVWID_8		(0 << 4)
+#define FSMC_DEVWID_16		(1 << 4)
+#define FSMC_ECCEN		(1 << 6)
+#define FSMC_ECCPLEN_512	(0 << 7)
+#define FSMC_ECCPLEN_256	(1 << 7)
+#define FSMC_TCLR_1		(1 << 9)
+#define FSMC_TAR_1		(1 << 13)
+
+/* sts register definitions */
+#define FSMC_CODE_RDY		(1 << 15)
+
+/* comm register definitions */
+#define FSMC_TSET_0		(0 << 0)
+#define FSMC_TWAIT_6		(6 << 8)
+#define FSMC_THOLD_4		(4 << 16)
+#define FSMC_THIZ_1		(1 << 24)
+
+/* peripid2 register definitions */
+#define FSMC_REVISION_MSK	(0xf)
+#define FSMC_REVISION_SHFT	(0x4)
+
+#define FSMC_VER1		1
+#define FSMC_VER2		2
+#define FSMC_VER3		3
+#define FSMC_VER4		4
+#define FSMC_VER5		5
+#define FSMC_VER6		6
+#define FSMC_VER7		7
+#define FSMC_VER8		8
+
+static inline u32 get_fsmc_version(struct fsmc_regs *regs)
+{
+	return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
+				FSMC_REVISION_MSK;
+}
+
+/*
+ * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
+ * and it has to be read consecutively and immediately after the 512
+ * byte data block for hardware to generate the error bit offsets
+ * Managing the ecc bytes in the following way is easier. This way is
+ * similar to oobfree structure maintained already in u-boot nand driver
+ */
+#define MAX_ECCPLACE_ENTRIES	32
+
+struct fsmc_nand_eccplace {
+	u8 offset;
+	u8 length;
+};
+
+struct fsmc_eccplace {
+	struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
+};
+
+#endif /* __PLAT_FSMC_H */
diff --git a/arch/arm/plat-spear/include/plat/nand.h b/arch/arm/plat-spear/include/plat/nand.h
new file mode 100644
index 0000000..712b4b0
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/nand.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/plat-spear/include/plat/nand.h
+ *
+ * NAND 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 __PLAT_NAND_H
+#define __PLAT_NAND_H
+
+#include <linux/mtd/partitions.h>
+
+#define SPEAR_NAND_BW8		1
+#define SPEAR_NAND_BW16		2
+
+#if defined(CONFIG_MACH_SPEAR310)
+#define PLAT_NAND_CLE		(1 << 17)
+#define PLAT_NAND_ALE		(1 << 16)
+#else
+#define PLAT_NAND_CLE		(1 << 16)
+#define PLAT_NAND_ALE		(1 << 17)
+#endif
+
+struct nand_platform_data {
+	/*
+	 * Board specific information
+	 * Set from arch/arm/mach-spear<mach>/spear<mach>_evb.c
+	 */
+
+	/*
+	 * Use the default partition table present in the NAND driver if
+	 * partitions is set to NULL.
+	 */
+	struct mtd_partition	*partitions;
+	unsigned int		nr_partitions;
+	unsigned int		options;
+	unsigned int		width;
+
+	/*
+	 * Machine specific information
+	 * Set from arch/arm/mach-spear<mach>/spear<mach>.c
+	 */
+
+	unsigned int		bank;
+	/*
+	 * Set to NULL if bank selection is not supported by machine
+	 * architecture
+	 * -> eg. when controller supports only one bank
+	 */
+	void			(*select_bank)(u32 bank, u32 busw);
+};
+
+/* This function is used to set platform data field of pdev->dev */
+static inline void nand_set_plat_data(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int options, unsigned int width)
+{
+	struct nand_platform_data *nand_plat_data;
+	nand_plat_data = dev_get_platdata(&pdev->dev);
+
+	if (partitions) {
+		nand_plat_data->partitions = partitions;
+		nand_plat_data->nr_partitions = nr_partitions;
+	}
+
+	nand_plat_data->options = options;
+	nand_plat_data->width = width;
+}
+
+#endif /* __PLAT_NAND_H */
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8b4b67c..89d35d1 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -531,4 +531,10 @@ config MTD_NAND_JZ4740
 	help
 		Enables support for NAND Flash on JZ4740 SoC based boards.
 
+config MTD_NAND_SPEAR
+	tristate "Support for NAND on SPEAr platforms"
+	depends on MTD_NAND && PLAT_SPEAR
+	help
+	  Enables support for NAND Flash chips wired onto SPEAr boards.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index ac83dcd..d1749af 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
 obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
+obj-$(CONFIG_MTD_NAND_SPEAR)		+= spear_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
 obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
new file mode 100644
index 0000000..da9661b
--- /dev/null
+++ b/drivers/mtd/nand/spear_nand.c
@@ -0,0 +1,860 @@
+/*
+ * drivers/mtd/nand/spear_nand.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Vipin Kumar <vipin.kumar@st.com>
+ * Ashish Priyadarshi
+ *
+ * Based on drivers/mtd/nand/nomadik_nand.c
+ *
+ * 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/module.h>
+#include <linux/resource.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <plat/fsmc.h>
+#include <plat/nand.h>
+#include <mtd/mtd-abi.h>
+
+static struct nand_ecclayout fsmc_ecc1_layout = {
+	.eccbytes = 24,
+	.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
+		66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
+	.oobfree = {
+		{.offset = 8, .length = 8},
+		{.offset = 24, .length = 8},
+		{.offset = 40, .length = 8},
+		{.offset = 56, .length = 8},
+		{.offset = 72, .length = 8},
+		{.offset = 88, .length = 8},
+		{.offset = 104, .length = 8},
+		{.offset = 120, .length = 8}
+	}
+};
+
+static struct nand_ecclayout fsmc_ecc4_lp_layout = {
+	.eccbytes = 104,
+	.eccpos = {  2,   3,   4,   5,   6,   7,   8,
+		9,  10,  11,  12,  13,  14,
+		18,  19,  20,  21,  22,  23,  24,
+		25,  26,  27,  28,  29,  30,
+		34,  35,  36,  37,  38,  39,  40,
+		41,  42,  43,  44,  45,  46,
+		50,  51,  52,  53,  54,  55,  56,
+		57,  58,  59,  60,  61,  62,
+		66,  67,  68,  69,  70,  71,  72,
+		73,  74,  75,  76,  77,  78,
+		82,  83,  84,  85,  86,  87,  88,
+		89,  90,  91,  92,  93,  94,
+		98,  99, 100, 101, 102, 103, 104,
+		105, 106, 107, 108, 109, 110,
+		114, 115, 116, 117, 118, 119, 120,
+		121, 122, 123, 124, 125, 126
+	},
+	.oobfree = {
+		{.offset = 15, .length = 3},
+		{.offset = 31, .length = 3},
+		{.offset = 47, .length = 3},
+		{.offset = 63, .length = 3},
+		{.offset = 79, .length = 3},
+		{.offset = 95, .length = 3},
+		{.offset = 111, .length = 3},
+		{.offset = 127, .length = 1}
+	}
+};
+
+/*
+ * ECC placement definitions in oobfree type format.
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data.
+ * Managing the ecc bytes in the following way makes it easier for software to
+ * read ecc bytes consecutive to data bytes. This way is similar to
+ * oobfree structure maintained already in generic nand driver
+ */
+static struct fsmc_eccplace fsmc_ecc4_lp_place = {
+	.eccplace = {
+		{.offset = 2, .length = 13},
+		{.offset = 18, .length = 13},
+		{.offset = 34, .length = 13},
+		{.offset = 50, .length = 13},
+		{.offset = 66, .length = 13},
+		{.offset = 82, .length = 13},
+		{.offset = 98, .length = 13},
+		{.offset = 114, .length = 13}
+	}
+};
+
+static struct nand_ecclayout fsmc_ecc4_sp_layout = {
+	.eccbytes = 13,
+	.eccpos = { 0,  1,  2,  3,  6,  7, 8,
+		9, 10, 11, 12, 13, 14
+	},
+	.oobfree = {
+		{.offset = 15, .length = 1},
+	}
+};
+
+static struct fsmc_eccplace fsmc_ecc4_sp_place = {
+	.eccplace = {
+		{.offset = 0, .length = 4},
+		{.offset = 6, .length = 9}
+	}
+};
+
+/*
+ * Default partition tables to be used if the partition information not provided
+ * through platform data
+ */
+#define PARTITION(n, off, sz)	{.name = n, .offset = off, .size = sz}
+
+/*
+ * Default partition layout for small page(= 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_16KB_blk[] = {
+	PARTITION("X-loader", 0, 4 * 0x4000),
+	PARTITION("U-Boot", 0x10000, 20 * 0x4000),
+	PARTITION("Kernel", 0x60000, 256 * 0x4000),
+	PARTITION("Root File System", 0x460000, 0),
+};
+
+/*
+ * Default partition layout for large page(> 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_128KB_blk[] = {
+	PARTITION("X-loader", 0, 4 * 0x20000),
+	PARTITION("U-Boot", 0x80000, 12 * 0x20000),
+	PARTITION("Kernel", 0x200000, 48 * 0x20000),
+	PARTITION("Root File System", 0x800000, 0),
+};
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/**
+ * struct spear_nand_dev - Structure for SPEAr NAND Device
+ *
+ * @mtd:		MTD info for a NAND flash.
+ * @nand:		Chip related info for a NAND flash.
+ * @partitions:		Partition info for a NAND Flash.
+ * @nr_partitions:	Total number of partition of a NAND flash.
+ *
+ * @ecc_place:		ECC placing locations in oobfree type format.
+ * @bank:		Bank number for probed device.
+ * @clk:		Clock structure for FSMC.
+ *
+ * @data_va:		NAND port for Data.
+ * @cmd_va:		NAND port for Command.
+ * @addr_va:		NAND port for Address.
+ * @regs_va:		FSMC regs base address.
+ */
+struct spear_nand_data {
+	struct mtd_info		mtd;
+	struct nand_chip	nand;
+	struct mtd_partition	*partitions;
+	unsigned int		nr_partitions;
+
+	struct fsmc_eccplace	*ecc_place;
+	unsigned int		bank;
+	struct clk		*clk;
+
+	struct resource		*resregs;
+	struct resource		*rescmd;
+	struct resource		*resaddr;
+	struct resource		*resdata;
+
+	void __iomem		*data_va;
+	void __iomem		*cmd_va;
+	void __iomem		*addr_va;
+	void __iomem		*regs_va;
+
+	void			(*select_chip)(u32 bank, u32 busw);
+};
+
+/* Assert CS signal based on chipnr */
+static void spear_select_chip(struct mtd_info *mtd, int chipnr)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct spear_nand_data *host;
+
+	host = container_of(mtd, struct spear_nand_data, mtd);
+
+	switch (chipnr) {
+	case -1:
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+		break;
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+		if (host->select_chip)
+			host->select_chip(chipnr,
+					chip->options & NAND_BUSWIDTH_16);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+/*
+ * spear_cmd_ctrl - For facilitaing Hardware access
+ * This routine allows hardware specific access to control-lines(ALE,CLE)
+ */
+static void spear_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	unsigned int bank = host->bank;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE) {
+			this->IO_ADDR_R = (void __iomem *)host->cmd_va;
+			this->IO_ADDR_W = (void __iomem *)host->cmd_va;
+		} else if (ctrl & NAND_ALE) {
+			this->IO_ADDR_R = (void __iomem *)host->addr_va;
+			this->IO_ADDR_W = (void __iomem *)host->addr_va;
+		} else {
+			this->IO_ADDR_R = (void __iomem *)host->data_va;
+			this->IO_ADDR_W = (void __iomem *)host->data_va;
+		}
+
+		if (ctrl & NAND_NCE) {
+			writel(readl(&regs->bank_regs[bank].pc) | FSMC_ENABLE,
+					&regs->bank_regs[bank].pc);
+		} else {
+			writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ENABLE,
+				       &regs->bank_regs[bank].pc);
+		}
+	}
+
+	mb();
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+/*
+ * fsmc_nand_init - FSMC (Flexible Static Memory Controller) init routine
+ *
+ * This routine initializes timing parameters related to NAND memory access in
+ * FSMC registers
+ */
+static void fsmc_nand_init(struct fsmc_regs *regs, u32 bank, u32 busw)
+{
+	u32 value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
+
+	if (busw)
+		writel(value | FSMC_DEVWID_16, &regs->bank_regs[bank].pc);
+	else
+		writel(value | FSMC_DEVWID_8, &regs->bank_regs[bank].pc);
+
+	writel(readl(&regs->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1,
+	       &regs->bank_regs[bank].pc);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &regs->bank_regs[bank].comm);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &regs->bank_regs[bank].attrib);
+}
+
+/*
+ * fsmc_enable_hwecc - Enables Hardware ECC through FSMC registers
+ */
+static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+
+	writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCPLEN_256,
+		       &regs->bank_regs[bank].pc);
+	writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCEN,
+			&regs->bank_regs[bank].pc);
+	writel(readl(&regs->bank_regs[bank].pc) | FSMC_ECCEN,
+			&regs->bank_regs[bank].pc);
+}
+
+/*
+ * fsmc_read_hwecc_ecc4 - Hardware ECC calculator for ecc4 option supported by
+ * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction upto
+ * max of 8-bits)
+ */
+static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const u8 *data, u8 *ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+	u32 ecc_tmp;
+	unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
+
+	do {
+		if (readl(&regs->bank_regs[bank].sts) & FSMC_CODE_RDY)
+			break;
+		else
+			cond_resched();
+	} while (!time_after_eq(jiffies, deadline));
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+	ecc[0] = (u8) (ecc_tmp >> 0);
+	ecc[1] = (u8) (ecc_tmp >> 8);
+	ecc[2] = (u8) (ecc_tmp >> 16);
+	ecc[3] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc2);
+	ecc[4] = (u8) (ecc_tmp >> 0);
+	ecc[5] = (u8) (ecc_tmp >> 8);
+	ecc[6] = (u8) (ecc_tmp >> 16);
+	ecc[7] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc3);
+	ecc[8] = (u8) (ecc_tmp >> 0);
+	ecc[9] = (u8) (ecc_tmp >> 8);
+	ecc[10] = (u8) (ecc_tmp >> 16);
+	ecc[11] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].sts);
+	ecc[12] = (u8) (ecc_tmp >> 16);
+
+	return 0;
+}
+
+/*
+ * fsmc_read_hwecc_ecc1 - Hardware ECC calculator for ecc1 option supported by
+ * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction upto
+ * max of 1-bit)
+ */
+static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const u8 *data, u8 *ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+	u32 ecc_tmp;
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+	ecc[0] = (u8) (ecc_tmp >> 0);
+	ecc[1] = (u8) (ecc_tmp >> 8);
+	ecc[2] = (u8) (ecc_tmp >> 16);
+
+	return 0;
+}
+
+/*
+ * fsmc_read_page_hwecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
+ * performed in a strict sequence as follows:
+ * data(512 byte) -> ecc(13 byte)
+ * After this read, fsmc hardware generates and reports error data bits(upto a
+ * max of 8 bits)
+ */
+static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				 u8 *buf, int page)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_eccplace *ecc_place = host->ecc_place;
+	int i, j, s, stat, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	u8 *p = buf;
+	u8 *ecc_calc = chip->buffers->ecccalc;
+	u8 *ecc_code = chip->buffers->ecccode;
+	int off, len, group = 0;
+	/*
+	 * ecc_oob is intentionally taken as u16. In 16bit devices, we end up
+	 * reading 14 bytes (7 words) from oob. The local array is to maintain
+	 * word alignment
+	 */
+	u16 ecc_oob[7];
+	u8 *oob = (u8 *)&ecc_oob[0];
+
+	for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
+
+		chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+
+		for (j = 0; j < eccbytes;) {
+			off = ecc_place->eccplace[group].offset;
+			len = ecc_place->eccplace[group].length;
+			group++;
+
+			/*
+			* length is intentionally kept a higher multiple of 2
+			* to read at least 13 bytes even in case of 16 bit NAND
+			* devices
+			*/
+			len = roundup(len, 2);
+			chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
+			chip->read_buf(mtd, oob + j, len);
+			j += len;
+		}
+
+		memcpy(&ecc_code[i], oob, 13);
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+
+	return 0;
+}
+
+/*
+ * fsmc_correct_data
+ * @mtd:	mtd info structure
+ * @dat:	buffer of read data
+ * @read_ecc:	ecc read from device spare area
+ * @calc_ecc:	ecc calculated from read data
+ *
+ * calc_ecc is a 104 bit information containing maximum of 8 error
+ * offset informations of 13 bits each in 512 bytes of read data.
+ */
+static int fsmc_correct_data(struct mtd_info *mtd, u8 *dat, u8 *read_ecc,
+		u8 *calc_ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	unsigned int bank = host->bank;
+	u16 err_idx[8];
+	u64 ecc_data[2];
+	u32 num_err, i;
+
+	/* The calculated ecc is actually the correction index in data */
+	memcpy(ecc_data, calc_ecc, 13);
+
+	/*
+	 * ------------------- calc_ecc[] bit wise -----------|--13 bits--|
+	 * |---idx[7]--|--.....-----|---idx[2]--||---idx[1]--||---idx[0]--|
+	 *
+	 * calc_ecc is a 104 bit information containing maximum of 8 error
+	 * offset informations of 13 bits each. calc_ecc is copied into a u64
+	 * array and error offset indexes are populated in err_idx array
+	 */
+	for (i = 0; i < 8; i++) {
+		if (i == 4) {
+			err_idx[4] = ((ecc_data[1] & 0x1) << 12) | ecc_data[0];
+			ecc_data[1] >>= 1;
+			continue;
+		}
+		err_idx[i] = (ecc_data[i/4] & 0x1FFF);
+		ecc_data[i/4] >>= 13;
+	}
+
+	num_err = (readl(&regs->bank_regs[bank].sts) >> 10) & 0xF;
+
+	if (num_err == 0xF)
+		return -EBADMSG;
+
+	i = 0;
+	while (num_err--) {
+		change_bit(0, (unsigned long *)&err_idx[i]);
+		change_bit(1, (unsigned long *)&err_idx[i]);
+
+		if (err_idx[i] <= 512 * 8) {
+			change_bit(err_idx[i], (unsigned long *)dat);
+			i++;
+		}
+	}
+	return i;
+}
+
+/*
+ * spear_nand_probe - Probe function
+ * @pdev:       platform device structure
+ */
+static int spear_nand_probe(struct platform_device *pdev)
+{
+	struct nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct spear_nand_data *host;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	struct fsmc_regs *regs;
+	struct resource *res;
+	int nr_parts, ret = 0;
+
+	if (!pdata) {
+		pr_err("Platform data is NULL\n");
+		return -EINVAL;
+	}
+
+	/* Allocate memory for the device structure (and zero it) */
+	host = kzalloc(sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
+	if (!res) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resdata = request_mem_region(res->start, resource_size(res),
+			pdev->name);
+	if (!host->resdata) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->data_va = ioremap(res->start, resource_size(res));
+	if (!host->data_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resaddr = request_mem_region(res->start + PLAT_NAND_ALE,
+			resource_size(res), pdev->name);
+	if (!host->resaddr) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->addr_va = ioremap(res->start + PLAT_NAND_ALE, resource_size(res));
+	if (!host->addr_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->rescmd = request_mem_region(res->start + PLAT_NAND_CLE,
+			resource_size(res), pdev->name);
+	if (!host->rescmd) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->cmd_va = ioremap(res->start + PLAT_NAND_CLE, resource_size(res));
+	if (!host->cmd_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
+	if (!res) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resregs = request_mem_region(res->start, resource_size(res),
+			pdev->name);
+	if (!host->resregs) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->regs_va = ioremap(res->start, resource_size(res));
+	if (!host->regs_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->clk = clk_get(NULL, "fsmc");
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		host->clk = NULL;
+		goto err_probe1;
+	}
+
+	ret = clk_enable(host->clk);
+	if (ret)
+		goto err_probe1;
+
+	host->bank = pdata->bank;
+	host->select_chip = pdata->select_bank;
+	regs = host->regs_va;
+
+	/* Link all private pointers */
+	mtd = &host->mtd;
+	nand = &host->nand;
+	mtd->priv = nand;
+	nand->priv = host;
+
+	host->mtd.owner = THIS_MODULE;
+	nand->IO_ADDR_R = host->data_va;
+	nand->IO_ADDR_W = host->data_va;
+	nand->cmd_ctrl = spear_cmd_ctrl;
+	nand->chip_delay = 30;
+
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.hwctl = fsmc_enable_hwecc;
+	nand->ecc.size = 512;
+	nand->options = pdata->options;
+	nand->select_chip = spear_select_chip;
+
+	if (pdata->width == SPEAR_NAND_BW16)
+		nand->options |= NAND_BUSWIDTH_16;
+
+	fsmc_nand_init(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
+
+	if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+		nand->ecc.read_page = fsmc_read_page_hwecc;
+		nand->ecc.calculate = fsmc_read_hwecc_ecc4;
+		nand->ecc.correct = fsmc_correct_data;
+		nand->ecc.bytes = 13;
+	} else {
+		nand->ecc.calculate = fsmc_read_hwecc_ecc1;
+		nand->ecc.correct = nand_correct_data;
+		nand->ecc.bytes = 3;
+	}
+
+	/*
+	 * Scan to find existance of the device
+	 */
+	if (nand_scan_ident(&host->mtd, 1, NULL)) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "No NAND Device found!\n");
+		goto err_probe;
+	}
+
+	if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+		if (host->mtd.writesize == 512) {
+			nand->ecc.layout = &fsmc_ecc4_sp_layout;
+			host->ecc_place = &fsmc_ecc4_sp_place;
+		} else {
+			nand->ecc.layout = &fsmc_ecc4_lp_layout;
+			host->ecc_place = &fsmc_ecc4_lp_place;
+		}
+	} else {
+		nand->ecc.layout = &fsmc_ecc1_layout;
+	}
+
+	/* Second stage of scan to fill MTD data-structures */
+	if (nand_scan_tail(&host->mtd)) {
+		ret = -ENXIO;
+		goto err_probe;
+	}
+
+	/*
+	 * The partition information can is accessed by (in the same precedence)
+	 *
+	 * command line through Bootloader,
+	 * platform data,
+	 * default partition information present in driver.
+	 */
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	/*
+	 * Check if partition info passed via command line
+	 */
+	host->mtd.name = "nand";
+	nr_parts = parse_mtd_partitions(&host->mtd, part_probes,
+			&host->partitions, 0);
+	if (nr_parts > 0) {
+		host->nr_partitions = nr_parts;
+	} else {
+#endif
+		/*
+		 * Check if partition info passed via command line
+		 */
+		if (pdata->partitions) {
+			host->partitions = pdata->partitions;
+			host->nr_partitions = pdata->nr_partitions;
+		} else {
+			struct mtd_partition *partition;
+			int i;
+
+			/* Select the default partitions info */
+			switch (host->mtd.size) {
+			case 0x01000000:
+			case 0x02000000:
+			case 0x04000000:
+				host->partitions = partition_info_16KB_blk;
+				host->nr_partitions =
+					sizeof(partition_info_16KB_blk) /
+					sizeof(struct mtd_partition);
+				break;
+			case 0x08000000:
+			case 0x10000000:
+			case 0x20000000:
+			case 0x40000000:
+				host->partitions = partition_info_128KB_blk;
+				host->nr_partitions =
+					sizeof(partition_info_128KB_blk) /
+					sizeof(struct mtd_partition);
+				break;
+			default:
+				ret = -ENXIO;
+				pr_err("Unsupported NAND size\n");
+				goto err_probe;
+			}
+
+			partition = host->partitions;
+			for (i = 0; i < host->nr_partitions; i++, partition++) {
+				if (partition->size == 0) {
+					partition->size = host->mtd.size -
+						partition->offset;
+					break;
+				}
+			}
+		}
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	}
+#endif
+
+	if (host->partitions) {
+		ret = add_mtd_partitions(&host->mtd, host->partitions,
+				host->nr_partitions);
+		if (ret)
+			goto err_probe;
+	}
+#else
+	dev_info(&pdev->dev, "Registering %s as whole device\n", mtd->name);
+	if (!add_mtd_device(mtd)) {
+		ret = -ENXIO;
+		goto err_probe;
+	}
+#endif
+
+	platform_set_drvdata(pdev, host);
+	dev_info(&pdev->dev, "SPEAr NAND driver registration successful\n");
+	return 0;
+
+err_probe:
+	clk_disable(host->clk);
+err_probe1:
+	if (host->clk)
+		clk_put(host->clk);
+	if (host->regs_va)
+		iounmap(host->regs_va);
+	if (host->resregs)
+		release_mem_region(host->resregs->start,
+				resource_size(host->resregs));
+	if (host->cmd_va)
+		iounmap(host->cmd_va);
+	if (host->rescmd)
+		release_mem_region(host->rescmd->start,
+				resource_size(host->rescmd));
+	if (host->addr_va)
+		iounmap(host->addr_va);
+	if (host->resaddr)
+		release_mem_region(host->resaddr->start,
+				resource_size(host->resaddr));
+	if (host->data_va)
+		iounmap(host->data_va);
+	if (host->resdata)
+		release_mem_region(host->resdata->start,
+				resource_size(host->resdata));
+
+	kfree(host);
+	return ret;
+}
+
+/*
+ * Clean up routine
+ */
+static int spear_nand_remove(struct platform_device *pdev)
+{
+	struct spear_nand_data *host = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (host) {
+#ifdef CONFIG_MTD_PARTITIONS
+		del_mtd_partitions(&host->mtd);
+#else
+		del_mtd_device(&host->mtd);
+#endif
+		clk_disable(host->clk);
+		clk_put(host->clk);
+
+		iounmap(host->regs_va);
+		release_mem_region(host->resregs->start,
+				resource_size(host->resregs));
+		iounmap(host->cmd_va);
+		release_mem_region(host->rescmd->start,
+				resource_size(host->rescmd));
+		iounmap(host->addr_va);
+		release_mem_region(host->resaddr->start,
+				resource_size(host->resaddr));
+		iounmap(host->data_va);
+		release_mem_region(host->resdata->start,
+				resource_size(host->resdata));
+
+		kfree(host);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int spear_nand_suspend(struct device *dev)
+{
+	struct spear_nand_data *host = dev_get_drvdata(dev);
+	if (host)
+		clk_disable(host->clk);
+	return 0;
+}
+
+static int spear_nand_resume(struct device *dev)
+{
+	struct spear_nand_data *host = dev_get_drvdata(dev);
+	if (host)
+		clk_enable(host->clk);
+	return 0;
+}
+
+static const struct dev_pm_ops spear_nand_pm_ops = {
+	.suspend = spear_nand_suspend,
+	.resume = spear_nand_resume,
+};
+#endif
+
+static struct platform_driver spear_nand_driver = {
+	.probe = spear_nand_probe,
+	.remove = spear_nand_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "nand",
+#ifdef CONFIG_PM
+		.pm = &spear_nand_pm_ops,
+#endif
+	},
+};
+
+static int __init spear_nand_init(void)
+{
+	return platform_driver_register(&spear_nand_driver);
+}
+module_init(spear_nand_init);
+
+static void __exit spear_nand_exit(void)
+{
+	platform_driver_unregister(&spear_nand_driver);
+}
+module_exit(spear_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi");
+MODULE_DESCRIPTION("NAND driver for SPEAr Platforms");
-- 
1.7.2.2

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-08-30 10:43   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

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

SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
interfacing with NAND devices.
This patch adds the support for glue logic for NAND flash on SPEAr boards

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/clock.c                  |    2 +-
 arch/arm/mach-spear13xx/include/mach/generic.h   |    2 +
 arch/arm/mach-spear13xx/include/mach/misc_regs.h |   10 +
 arch/arm/mach-spear13xx/spear1300_evb.c          |    8 +
 arch/arm/mach-spear13xx/spear13xx.c              |   58 ++
 arch/arm/mach-spear3xx/clock.c                   |   14 +
 arch/arm/mach-spear3xx/include/mach/generic.h    |   15 +-
 arch/arm/mach-spear3xx/include/mach/spear320.h   |    3 +
 arch/arm/mach-spear3xx/spear300.c                |   98 +++
 arch/arm/mach-spear3xx/spear300_evb.c            |    7 +
 arch/arm/mach-spear3xx/spear310.c                |   26 +
 arch/arm/mach-spear3xx/spear310_evb.c            |    7 +
 arch/arm/mach-spear3xx/spear320.c                |   26 +
 arch/arm/mach-spear3xx/spear320_evb.c            |    7 +
 arch/arm/mach-spear6xx/clock.c                   |    2 +-
 arch/arm/mach-spear6xx/include/mach/generic.h    |    1 +
 arch/arm/mach-spear6xx/spear600_evb.c            |    7 +
 arch/arm/mach-spear6xx/spear6xx.c                |   26 +
 arch/arm/plat-spear/include/plat/fsmc.h          |  109 +++
 arch/arm/plat-spear/include/plat/nand.h          |   76 ++
 drivers/mtd/nand/Kconfig                         |    6 +
 drivers/mtd/nand/Makefile                        |    1 +
 drivers/mtd/nand/spear_nand.c                    |  860 ++++++++++++++++++++++
 23 files changed, 1363 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
 create mode 100644 arch/arm/plat-spear/include/plat/nand.h
 create mode 100644 drivers/mtd/nand/spear_nand.c

diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
index 5280657..8658d48 100644
--- a/arch/arm/mach-spear13xx/clock.c
+++ b/arch/arm/mach-spear13xx/clock.c
@@ -791,7 +791,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{.dev_id = "pcie2",		.clk = &pcie2_clk},
 	{.dev_id = "cfxd",		.clk = &cfxd_clk},
 	{.dev_id = "sd",		.clk = &sd_clk},
-	{.dev_id = "fsmc",		.clk = &fsmc_clk},
+	{.con_id = "fsmc",		.clk = &fsmc_clk},
 	{.dev_id = "sysram0",		.clk = &sysram0_clk},
 	{.dev_id = "sysram1",		.clk = &sysram1_clk},
 
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index 186a8be..b884359 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -35,6 +35,7 @@ extern struct platform_device ehci0_device;
 extern struct platform_device ehci1_device;
 extern struct platform_device i2c_device;
 extern struct platform_device kbd_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;
@@ -51,6 +52,7 @@ void __init spear1300_init(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 spear13xx_secondary_startup(void);
 
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
index c4dcab2..05815fa 100644
--- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
@@ -205,6 +205,16 @@
 #define PCIE_MIPHY_CFG		((unsigned int *)(MISC_BASE + 0x328))
 #define PERIP_CFG		((unsigned int *)(MISC_BASE + 0x32c))
 #define FSMC_CFG		((unsigned int *)(MISC_BASE + 0x330))
+	/* FSMC_CFG register masks */
+	#define FSMC_MEMSEL_MASK	0x3
+	#define FSMC_MEMSEL_SHIFT	0
+	#define FSMC_MEM_NOR		0
+	#define FSMC_MEM_NAND		1
+	#define FSMC_MEM_SRAM		2
+	#define NAND_BANK_MASK		0x3
+	#define NAND_BANK_SHIFT		2
+	#define NAND_DEV_WIDTH16	4
+
 #define MPMC_CTR_STS		((unsigned int *)(MISC_BASE + 0x334))
 
 /* Inter-Processor Communication Registers */
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index 5b74f05..4267b46 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -12,11 +12,13 @@
  */
 
 #include <linux/types.h>
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -30,6 +32,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&ehci1_device,
 	&i2c_device,
 	&kbd_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -52,6 +55,11 @@ static void __init spear1300_evb_init(void)
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+	nand_mach_init(SPEAR_NAND_BW8);
+
 	/* call spear1300 machine init function */
 	spear1300_init();
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index b6bddff..4810652 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -23,6 +23,8 @@
 #include <mach/irqs.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
+#include <mach/misc_regs.h>
+#include <plat/nand.h>
 
 /* Add spear13xx machines common devices here */
 /* gpio device registeration */
@@ -97,6 +99,62 @@ struct platform_device 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 == SPEAR_NAND_BW16)
+		fsmc_cfg |= 1 << NAND_DEV_WIDTH16;
+	else
+		fsmc_cfg &= ~(1 << NAND_DEV_WIDTH16);
+
+	writel(fsmc_cfg, FSMC_CFG);
+}
+
+static 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 nand_platform_data nand_platform_data = {
+	.select_bank = nand_select_bank,
+};
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 39835e8..93c5fd9 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -461,6 +461,16 @@ static struct clk gpio_clk = {
 
 static struct clk dummy_apb_pclk;
 
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
+	defined(CONFIG_MACH_SPEAR320)
+/* fsmc clock */
+static struct clk fsmc_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &follow_parent,
+};
+#endif
+
 /* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
 /* keyboard clock */
@@ -535,6 +545,10 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp",		.clk = &ssp_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
+	defined(CONFIG_MACH_SPEAR320)
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
+#endif
 
 	/* spear300 machine specific clock structures */
 #ifdef CONFIG_MACH_SPEAR300
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 91c0c09..6aac229 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -111,6 +111,10 @@ extern struct pmx_driver pmx_driver;
 extern struct amba_device clcd_device;
 extern struct amba_device gpio1_device;
 extern struct platform_device kbd_device;
+extern struct platform_device nand0_device;
+extern struct platform_device nand1_device;
+extern struct platform_device nand2_device;
+extern struct platform_device nand3_device;
 
 /* pad mux modes */
 extern struct pmx_mode nand_mode;
@@ -148,12 +152,12 @@ void __init spear300_init(void);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
-#endif /* CONFIG_MACH_SPEAR300 */
 
 /* spear310 declarations */
-#ifdef CONFIG_MACH_SPEAR310
+#elif defined(CONFIG_MACH_SPEAR310)
 /* Add spear310 machine device structure declarations here */
 extern struct platform_device plgpio_device;
+extern struct platform_device nand_device;
 
 /* pad mux devices */
 extern struct pmx_dev pmx_emi_cs_0_1_4_5;
@@ -168,13 +172,12 @@ extern struct pmx_dev pmx_tdm0;
 /* Add spear310 machine function declarations here */
 void __init spear310_init(void);
 
-#endif /* CONFIG_MACH_SPEAR310 */
-
 /* spear320 declarations */
-#ifdef CONFIG_MACH_SPEAR320
+#elif defined(CONFIG_MACH_SPEAR320)
 /* Add spear320 machine device structure declarations here */
 extern struct amba_device clcd_device;
 extern struct platform_device i2c1_device;
+extern struct platform_device nand_device;
 extern struct platform_device plgpio_device;
 extern struct platform_device pwm_device;
 
@@ -213,6 +216,6 @@ void __init spear320_init(void);
 
 /* Add misc structure declarations here */
 extern struct clcd_board clcd_plat_data;
-#endif /* CONFIG_MACH_SPEAR320 */
+#endif
 
 #endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index 53677e4..aa6727c 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -22,6 +22,9 @@
 #define SPEAR320_FSMC_BASE		0x4C000000
 #define SPEAR320_FSMC_SIZE		0x01000000
 
+#define SPEAR320_NAND_BASE		0x50000000
+#define SPEAR320_NAND_SIZE		0x04000000
+
 #define SPEAR320_I2S_BASE		0x60000000
 #define SPEAR320_I2S_SIZE		0x10000000
 
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index cf010cc..3a86868 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -17,6 +17,7 @@
 #include <asm/irq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -426,6 +427,103 @@ struct platform_device kbd_device = {
 	.resource = kbd_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand0_platform_data;
+
+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 nand0_device = {
+	.name = "nand",
+	.id = 0,
+	.resource = nand0_resources,
+	.num_resources = ARRAY_SIZE(nand0_resources),
+	.dev.platform_data = &nand0_platform_data,
+};
+
+static struct nand_platform_data nand1_platform_data;
+
+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 nand1_device = {
+	.name = "nand",
+	.id = 1,
+	.resource = nand1_resources,
+	.num_resources = ARRAY_SIZE(nand1_resources),
+	.dev.platform_data = &nand1_platform_data,
+};
+
+static struct nand_platform_data nand2_platform_data;
+
+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 nand2_device = {
+	.name = "nand",
+	.id = 2,
+	.resource = nand2_resources,
+	.num_resources = ARRAY_SIZE(nand2_resources),
+	.dev.platform_data = &nand2_platform_data,
+};
+
+static struct nand_platform_data nand3_platform_data;
+
+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 nand3_device = {
+	.name = "nand",
+	.id = 3,
+	.resource = nand3_resources,
+	.num_resources = ARRAY_SIZE(nand3_resources),
+	.dev.platform_data = &nand3_platform_data,
+};
+
 /* spear3xx shared irq */
 struct shirq_dev_config shirq_ras1_config[] = {
 	{
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
index 7bd8963..895f7b7 100644
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -11,11 +11,13 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/keyboard.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -49,6 +51,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand0_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -79,6 +82,10 @@ static void __init spear300_evb_init(void)
 	/* set keyboard plat data */
 	kbd_set_plat_data(&kbd_device, &kbd_data);
 
+	/* set nand0 device's plat data */
+	nand_set_plat_data(&nand0_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear300 machine init function */
 	spear300_init();
 
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 88b55b5..69350b7 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -16,6 +16,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/gpio.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -177,6 +178,31 @@ int spear300_o2p(int offset)
 		return offset + 2;
 }
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 static struct plgpio_platform_data plgpio_plat_data = {
 	.gpio_base = 8,
 	.irq_base = SPEAR_PLGPIO_INT_BASE,
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
index cd076c9..8f17362 100644
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -54,6 +56,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -72,6 +75,10 @@ static void __init spear310_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear310 machine init function */
 	spear310_init();
 
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 75e7890..2ac838b 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -16,6 +16,7 @@
 #include <mach/generic.h>
 #include <mach/spear.h>
 #include <plat/gpio.h>
+#include <plat/nand.h>
 #include <plat/shirq.h>
 
 /* pad multiplexing support */
@@ -431,6 +432,31 @@ struct platform_device i2c1_device = {
 	.resource = i2c1_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 nand_device = {
+	.name = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 static struct resource plgpio_resources[] = {
 	{
 		.start = SPEAR320_SOC_CONFIG_BASE,
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
index 7f7b5dd..d693877 100644
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 /* padmux devices to enable */
@@ -52,6 +54,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	/* spear3xx specific devices */
 	&ehci_device,
 	&i2c_device,
+	&nand_device,
 	&ohci0_device,
 	&ohci1_device,
 	&rtc_device,
@@ -72,6 +75,10 @@ static void __init spear320_evb_init(void)
 	pmx_driver.devs = pmx_devs;
 	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear320 machine init function */
 	spear320_init();
 
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index fb05ec8..91f1f3f 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -602,7 +602,7 @@ static struct clk_lookup spear_clk_lookups[] = {
 	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
 	{ .dev_id = "gmac",		.clk = &gmac_clk},
 	{ .dev_id = "smi",		.clk = &smi_clk},
-	{ .dev_id = "fsmc",		.clk = &fsmc_clk},
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 	/* clock derived from apb clk */
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp0",		.clk = &ssp0_clk},
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index f885898..ff90419 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -36,6 +36,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 0eb5f50..cf86efc 100644
--- a/arch/arm/mach-spear6xx/spear600_evb.c
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -11,10 +11,12 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/mtd/nand.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 #include <plat/smi.h>
 
 static struct amba_device *amba_devs[] __initdata = {
@@ -33,6 +35,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&i2c_device,
 	&ohci0_device,
 	&ohci1_device,
+	&nand_device,
 	&rtc_device,
 	&smi_device,
 };
@@ -41,6 +44,10 @@ static void __init spear600_evb_init(void)
 {
 	unsigned int i;
 
+	/* set nand device's plat data */
+	nand_set_plat_data(&nand_device, NULL, 0, NAND_SKIP_BBTSCAN,
+			SPEAR_NAND_BW8);
+
 	/* call spear600 machine init function */
 	spear600_init();
 
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 4987597..2296d0f 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -21,6 +21,7 @@
 #include <mach/irqs.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
+#include <plat/nand.h>
 
 /* Add spear6xx machines common devices here */
 
@@ -152,6 +153,31 @@ struct platform_device i2c_device = {
 	.resource = i2c_resources,
 };
 
+/* nand device registeration */
+static struct nand_platform_data nand_platform_data;
+
+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 = "nand",
+	.id = -1,
+	.resource = nand_resources,
+	.num_resources = ARRAY_SIZE(nand_resources),
+	.dev.platform_data = &nand_platform_data,
+};
+
 /* usb host device registeration */
 static struct resource ehci0_resources[] = {
 	[0] = {
diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h
new file mode 100644
index 0000000..c0fdcd3
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/fsmc.h
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/plat-spear/include/plat/fsmc.h
+ *
+ * SPEAr platform nand interface header 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.
+ */
+
+#ifndef __PLAT_FSMC_H
+#define __PLAT_FSMC_H
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <asm/param.h>
+
+#define FSMC_MAX_NAND_BANKS	4
+
+struct nand_bank_regs {
+	u32 pc;
+	u32 sts;
+	u32 comm;
+	u32 attrib;
+	u32 ioata;
+	u32 ecc1;
+	u32 ecc2;
+	u32 ecc3;
+};
+
+struct fsmc_regs {
+	u8 reserved_1[0x40];
+	struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
+	u8 reserved_2[0xfe0 - 0xc0];
+	u32 peripid0;			/* 0xfe0 */
+	u32 peripid1;			/* 0xfe4 */
+	u32 peripid2;			/* 0xfe8 */
+	u32 peripid3;			/* 0xfec */
+	u32 pcellid0;			/* 0xff0 */
+	u32 pcellid1;			/* 0xff4 */
+	u32 pcellid2;			/* 0xff8 */
+	u32 pcellid3;			/* 0xffc */
+};
+
+#define FSMC_BUSY_WAIT_TIMEOUT	(1 * HZ)
+
+/* pc register definitions */
+#define FSMC_RESET		(1 << 0)
+#define FSMC_WAITON		(1 << 1)
+#define FSMC_ENABLE		(1 << 2)
+#define FSMC_DEVTYPE_NAND	(1 << 3)
+#define FSMC_DEVWID_8		(0 << 4)
+#define FSMC_DEVWID_16		(1 << 4)
+#define FSMC_ECCEN		(1 << 6)
+#define FSMC_ECCPLEN_512	(0 << 7)
+#define FSMC_ECCPLEN_256	(1 << 7)
+#define FSMC_TCLR_1		(1 << 9)
+#define FSMC_TAR_1		(1 << 13)
+
+/* sts register definitions */
+#define FSMC_CODE_RDY		(1 << 15)
+
+/* comm register definitions */
+#define FSMC_TSET_0		(0 << 0)
+#define FSMC_TWAIT_6		(6 << 8)
+#define FSMC_THOLD_4		(4 << 16)
+#define FSMC_THIZ_1		(1 << 24)
+
+/* peripid2 register definitions */
+#define FSMC_REVISION_MSK	(0xf)
+#define FSMC_REVISION_SHFT	(0x4)
+
+#define FSMC_VER1		1
+#define FSMC_VER2		2
+#define FSMC_VER3		3
+#define FSMC_VER4		4
+#define FSMC_VER5		5
+#define FSMC_VER6		6
+#define FSMC_VER7		7
+#define FSMC_VER8		8
+
+static inline u32 get_fsmc_version(struct fsmc_regs *regs)
+{
+	return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
+				FSMC_REVISION_MSK;
+}
+
+/*
+ * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
+ * and it has to be read consecutively and immediately after the 512
+ * byte data block for hardware to generate the error bit offsets
+ * Managing the ecc bytes in the following way is easier. This way is
+ * similar to oobfree structure maintained already in u-boot nand driver
+ */
+#define MAX_ECCPLACE_ENTRIES	32
+
+struct fsmc_nand_eccplace {
+	u8 offset;
+	u8 length;
+};
+
+struct fsmc_eccplace {
+	struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
+};
+
+#endif /* __PLAT_FSMC_H */
diff --git a/arch/arm/plat-spear/include/plat/nand.h b/arch/arm/plat-spear/include/plat/nand.h
new file mode 100644
index 0000000..712b4b0
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/nand.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/plat-spear/include/plat/nand.h
+ *
+ * NAND 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 __PLAT_NAND_H
+#define __PLAT_NAND_H
+
+#include <linux/mtd/partitions.h>
+
+#define SPEAR_NAND_BW8		1
+#define SPEAR_NAND_BW16		2
+
+#if defined(CONFIG_MACH_SPEAR310)
+#define PLAT_NAND_CLE		(1 << 17)
+#define PLAT_NAND_ALE		(1 << 16)
+#else
+#define PLAT_NAND_CLE		(1 << 16)
+#define PLAT_NAND_ALE		(1 << 17)
+#endif
+
+struct nand_platform_data {
+	/*
+	 * Board specific information
+	 * Set from arch/arm/mach-spear<mach>/spear<mach>_evb.c
+	 */
+
+	/*
+	 * Use the default partition table present in the NAND driver if
+	 * partitions is set to NULL.
+	 */
+	struct mtd_partition	*partitions;
+	unsigned int		nr_partitions;
+	unsigned int		options;
+	unsigned int		width;
+
+	/*
+	 * Machine specific information
+	 * Set from arch/arm/mach-spear<mach>/spear<mach>.c
+	 */
+
+	unsigned int		bank;
+	/*
+	 * Set to NULL if bank selection is not supported by machine
+	 * architecture
+	 * -> eg. when controller supports only one bank
+	 */
+	void			(*select_bank)(u32 bank, u32 busw);
+};
+
+/* This function is used to set platform data field of pdev->dev */
+static inline void nand_set_plat_data(struct platform_device *pdev,
+		struct mtd_partition *partitions, unsigned int nr_partitions,
+		unsigned int options, unsigned int width)
+{
+	struct nand_platform_data *nand_plat_data;
+	nand_plat_data = dev_get_platdata(&pdev->dev);
+
+	if (partitions) {
+		nand_plat_data->partitions = partitions;
+		nand_plat_data->nr_partitions = nr_partitions;
+	}
+
+	nand_plat_data->options = options;
+	nand_plat_data->width = width;
+}
+
+#endif /* __PLAT_NAND_H */
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8b4b67c..89d35d1 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -531,4 +531,10 @@ config MTD_NAND_JZ4740
 	help
 		Enables support for NAND Flash on JZ4740 SoC based boards.
 
+config MTD_NAND_SPEAR
+	tristate "Support for NAND on SPEAr platforms"
+	depends on MTD_NAND && PLAT_SPEAR
+	help
+	  Enables support for NAND Flash chips wired onto SPEAr boards.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index ac83dcd..d1749af 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
 obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
+obj-$(CONFIG_MTD_NAND_SPEAR)		+= spear_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
 obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
new file mode 100644
index 0000000..da9661b
--- /dev/null
+++ b/drivers/mtd/nand/spear_nand.c
@@ -0,0 +1,860 @@
+/*
+ * drivers/mtd/nand/spear_nand.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Vipin Kumar <vipin.kumar@st.com>
+ * Ashish Priyadarshi
+ *
+ * Based on drivers/mtd/nand/nomadik_nand.c
+ *
+ * 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/module.h>
+#include <linux/resource.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <plat/fsmc.h>
+#include <plat/nand.h>
+#include <mtd/mtd-abi.h>
+
+static struct nand_ecclayout fsmc_ecc1_layout = {
+	.eccbytes = 24,
+	.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
+		66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
+	.oobfree = {
+		{.offset = 8, .length = 8},
+		{.offset = 24, .length = 8},
+		{.offset = 40, .length = 8},
+		{.offset = 56, .length = 8},
+		{.offset = 72, .length = 8},
+		{.offset = 88, .length = 8},
+		{.offset = 104, .length = 8},
+		{.offset = 120, .length = 8}
+	}
+};
+
+static struct nand_ecclayout fsmc_ecc4_lp_layout = {
+	.eccbytes = 104,
+	.eccpos = {  2,   3,   4,   5,   6,   7,   8,
+		9,  10,  11,  12,  13,  14,
+		18,  19,  20,  21,  22,  23,  24,
+		25,  26,  27,  28,  29,  30,
+		34,  35,  36,  37,  38,  39,  40,
+		41,  42,  43,  44,  45,  46,
+		50,  51,  52,  53,  54,  55,  56,
+		57,  58,  59,  60,  61,  62,
+		66,  67,  68,  69,  70,  71,  72,
+		73,  74,  75,  76,  77,  78,
+		82,  83,  84,  85,  86,  87,  88,
+		89,  90,  91,  92,  93,  94,
+		98,  99, 100, 101, 102, 103, 104,
+		105, 106, 107, 108, 109, 110,
+		114, 115, 116, 117, 118, 119, 120,
+		121, 122, 123, 124, 125, 126
+	},
+	.oobfree = {
+		{.offset = 15, .length = 3},
+		{.offset = 31, .length = 3},
+		{.offset = 47, .length = 3},
+		{.offset = 63, .length = 3},
+		{.offset = 79, .length = 3},
+		{.offset = 95, .length = 3},
+		{.offset = 111, .length = 3},
+		{.offset = 127, .length = 1}
+	}
+};
+
+/*
+ * ECC placement definitions in oobfree type format.
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data.
+ * Managing the ecc bytes in the following way makes it easier for software to
+ * read ecc bytes consecutive to data bytes. This way is similar to
+ * oobfree structure maintained already in generic nand driver
+ */
+static struct fsmc_eccplace fsmc_ecc4_lp_place = {
+	.eccplace = {
+		{.offset = 2, .length = 13},
+		{.offset = 18, .length = 13},
+		{.offset = 34, .length = 13},
+		{.offset = 50, .length = 13},
+		{.offset = 66, .length = 13},
+		{.offset = 82, .length = 13},
+		{.offset = 98, .length = 13},
+		{.offset = 114, .length = 13}
+	}
+};
+
+static struct nand_ecclayout fsmc_ecc4_sp_layout = {
+	.eccbytes = 13,
+	.eccpos = { 0,  1,  2,  3,  6,  7, 8,
+		9, 10, 11, 12, 13, 14
+	},
+	.oobfree = {
+		{.offset = 15, .length = 1},
+	}
+};
+
+static struct fsmc_eccplace fsmc_ecc4_sp_place = {
+	.eccplace = {
+		{.offset = 0, .length = 4},
+		{.offset = 6, .length = 9}
+	}
+};
+
+/*
+ * Default partition tables to be used if the partition information not provided
+ * through platform data
+ */
+#define PARTITION(n, off, sz)	{.name = n, .offset = off, .size = sz}
+
+/*
+ * Default partition layout for small page(= 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_16KB_blk[] = {
+	PARTITION("X-loader", 0, 4 * 0x4000),
+	PARTITION("U-Boot", 0x10000, 20 * 0x4000),
+	PARTITION("Kernel", 0x60000, 256 * 0x4000),
+	PARTITION("Root File System", 0x460000, 0),
+};
+
+/*
+ * Default partition layout for large page(> 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_128KB_blk[] = {
+	PARTITION("X-loader", 0, 4 * 0x20000),
+	PARTITION("U-Boot", 0x80000, 12 * 0x20000),
+	PARTITION("Kernel", 0x200000, 48 * 0x20000),
+	PARTITION("Root File System", 0x800000, 0),
+};
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/**
+ * struct spear_nand_dev - Structure for SPEAr NAND Device
+ *
+ * @mtd:		MTD info for a NAND flash.
+ * @nand:		Chip related info for a NAND flash.
+ * @partitions:		Partition info for a NAND Flash.
+ * @nr_partitions:	Total number of partition of a NAND flash.
+ *
+ * @ecc_place:		ECC placing locations in oobfree type format.
+ * @bank:		Bank number for probed device.
+ * @clk:		Clock structure for FSMC.
+ *
+ * @data_va:		NAND port for Data.
+ * @cmd_va:		NAND port for Command.
+ * @addr_va:		NAND port for Address.
+ * @regs_va:		FSMC regs base address.
+ */
+struct spear_nand_data {
+	struct mtd_info		mtd;
+	struct nand_chip	nand;
+	struct mtd_partition	*partitions;
+	unsigned int		nr_partitions;
+
+	struct fsmc_eccplace	*ecc_place;
+	unsigned int		bank;
+	struct clk		*clk;
+
+	struct resource		*resregs;
+	struct resource		*rescmd;
+	struct resource		*resaddr;
+	struct resource		*resdata;
+
+	void __iomem		*data_va;
+	void __iomem		*cmd_va;
+	void __iomem		*addr_va;
+	void __iomem		*regs_va;
+
+	void			(*select_chip)(u32 bank, u32 busw);
+};
+
+/* Assert CS signal based on chipnr */
+static void spear_select_chip(struct mtd_info *mtd, int chipnr)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct spear_nand_data *host;
+
+	host = container_of(mtd, struct spear_nand_data, mtd);
+
+	switch (chipnr) {
+	case -1:
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+		break;
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+		if (host->select_chip)
+			host->select_chip(chipnr,
+					chip->options & NAND_BUSWIDTH_16);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+/*
+ * spear_cmd_ctrl - For facilitaing Hardware access
+ * This routine allows hardware specific access to control-lines(ALE,CLE)
+ */
+static void spear_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	unsigned int bank = host->bank;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE) {
+			this->IO_ADDR_R = (void __iomem *)host->cmd_va;
+			this->IO_ADDR_W = (void __iomem *)host->cmd_va;
+		} else if (ctrl & NAND_ALE) {
+			this->IO_ADDR_R = (void __iomem *)host->addr_va;
+			this->IO_ADDR_W = (void __iomem *)host->addr_va;
+		} else {
+			this->IO_ADDR_R = (void __iomem *)host->data_va;
+			this->IO_ADDR_W = (void __iomem *)host->data_va;
+		}
+
+		if (ctrl & NAND_NCE) {
+			writel(readl(&regs->bank_regs[bank].pc) | FSMC_ENABLE,
+					&regs->bank_regs[bank].pc);
+		} else {
+			writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ENABLE,
+				       &regs->bank_regs[bank].pc);
+		}
+	}
+
+	mb();
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+/*
+ * fsmc_nand_init - FSMC (Flexible Static Memory Controller) init routine
+ *
+ * This routine initializes timing parameters related to NAND memory access in
+ * FSMC registers
+ */
+static void fsmc_nand_init(struct fsmc_regs *regs, u32 bank, u32 busw)
+{
+	u32 value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
+
+	if (busw)
+		writel(value | FSMC_DEVWID_16, &regs->bank_regs[bank].pc);
+	else
+		writel(value | FSMC_DEVWID_8, &regs->bank_regs[bank].pc);
+
+	writel(readl(&regs->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1,
+	       &regs->bank_regs[bank].pc);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &regs->bank_regs[bank].comm);
+	writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+	       &regs->bank_regs[bank].attrib);
+}
+
+/*
+ * fsmc_enable_hwecc - Enables Hardware ECC through FSMC registers
+ */
+static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+
+	writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCPLEN_256,
+		       &regs->bank_regs[bank].pc);
+	writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCEN,
+			&regs->bank_regs[bank].pc);
+	writel(readl(&regs->bank_regs[bank].pc) | FSMC_ECCEN,
+			&regs->bank_regs[bank].pc);
+}
+
+/*
+ * fsmc_read_hwecc_ecc4 - Hardware ECC calculator for ecc4 option supported by
+ * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction upto
+ * max of 8-bits)
+ */
+static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const u8 *data, u8 *ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+	u32 ecc_tmp;
+	unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
+
+	do {
+		if (readl(&regs->bank_regs[bank].sts) & FSMC_CODE_RDY)
+			break;
+		else
+			cond_resched();
+	} while (!time_after_eq(jiffies, deadline));
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+	ecc[0] = (u8) (ecc_tmp >> 0);
+	ecc[1] = (u8) (ecc_tmp >> 8);
+	ecc[2] = (u8) (ecc_tmp >> 16);
+	ecc[3] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc2);
+	ecc[4] = (u8) (ecc_tmp >> 0);
+	ecc[5] = (u8) (ecc_tmp >> 8);
+	ecc[6] = (u8) (ecc_tmp >> 16);
+	ecc[7] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc3);
+	ecc[8] = (u8) (ecc_tmp >> 0);
+	ecc[9] = (u8) (ecc_tmp >> 8);
+	ecc[10] = (u8) (ecc_tmp >> 16);
+	ecc[11] = (u8) (ecc_tmp >> 24);
+
+	ecc_tmp = readl(&regs->bank_regs[bank].sts);
+	ecc[12] = (u8) (ecc_tmp >> 16);
+
+	return 0;
+}
+
+/*
+ * fsmc_read_hwecc_ecc1 - Hardware ECC calculator for ecc1 option supported by
+ * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction upto
+ * max of 1-bit)
+ */
+static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const u8 *data, u8 *ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	u32 bank = host->bank;
+	u32 ecc_tmp;
+
+	ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+	ecc[0] = (u8) (ecc_tmp >> 0);
+	ecc[1] = (u8) (ecc_tmp >> 8);
+	ecc[2] = (u8) (ecc_tmp >> 16);
+
+	return 0;
+}
+
+/*
+ * fsmc_read_page_hwecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
+ * performed in a strict sequence as follows:
+ * data(512 byte) -> ecc(13 byte)
+ * After this read, fsmc hardware generates and reports error data bits(upto a
+ * max of 8 bits)
+ */
+static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				 u8 *buf, int page)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_eccplace *ecc_place = host->ecc_place;
+	int i, j, s, stat, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	u8 *p = buf;
+	u8 *ecc_calc = chip->buffers->ecccalc;
+	u8 *ecc_code = chip->buffers->ecccode;
+	int off, len, group = 0;
+	/*
+	 * ecc_oob is intentionally taken as u16. In 16bit devices, we end up
+	 * reading 14 bytes (7 words) from oob. The local array is to maintain
+	 * word alignment
+	 */
+	u16 ecc_oob[7];
+	u8 *oob = (u8 *)&ecc_oob[0];
+
+	for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
+
+		chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+
+		for (j = 0; j < eccbytes;) {
+			off = ecc_place->eccplace[group].offset;
+			len = ecc_place->eccplace[group].length;
+			group++;
+
+			/*
+			* length is intentionally kept a higher multiple of 2
+			* to read at least 13 bytes even in case of 16 bit NAND
+			* devices
+			*/
+			len = roundup(len, 2);
+			chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
+			chip->read_buf(mtd, oob + j, len);
+			j += len;
+		}
+
+		memcpy(&ecc_code[i], oob, 13);
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+
+	return 0;
+}
+
+/*
+ * fsmc_correct_data
+ * @mtd:	mtd info structure
+ * @dat:	buffer of read data
+ * @read_ecc:	ecc read from device spare area
+ * @calc_ecc:	ecc calculated from read data
+ *
+ * calc_ecc is a 104 bit information containing maximum of 8 error
+ * offset informations of 13 bits each in 512 bytes of read data.
+ */
+static int fsmc_correct_data(struct mtd_info *mtd, u8 *dat, u8 *read_ecc,
+		u8 *calc_ecc)
+{
+	struct spear_nand_data *host = container_of(mtd,
+					struct spear_nand_data, mtd);
+	struct fsmc_regs *regs = host->regs_va;
+	unsigned int bank = host->bank;
+	u16 err_idx[8];
+	u64 ecc_data[2];
+	u32 num_err, i;
+
+	/* The calculated ecc is actually the correction index in data */
+	memcpy(ecc_data, calc_ecc, 13);
+
+	/*
+	 * ------------------- calc_ecc[] bit wise -----------|--13 bits--|
+	 * |---idx[7]--|--.....-----|---idx[2]--||---idx[1]--||---idx[0]--|
+	 *
+	 * calc_ecc is a 104 bit information containing maximum of 8 error
+	 * offset informations of 13 bits each. calc_ecc is copied into a u64
+	 * array and error offset indexes are populated in err_idx array
+	 */
+	for (i = 0; i < 8; i++) {
+		if (i == 4) {
+			err_idx[4] = ((ecc_data[1] & 0x1) << 12) | ecc_data[0];
+			ecc_data[1] >>= 1;
+			continue;
+		}
+		err_idx[i] = (ecc_data[i/4] & 0x1FFF);
+		ecc_data[i/4] >>= 13;
+	}
+
+	num_err = (readl(&regs->bank_regs[bank].sts) >> 10) & 0xF;
+
+	if (num_err == 0xF)
+		return -EBADMSG;
+
+	i = 0;
+	while (num_err--) {
+		change_bit(0, (unsigned long *)&err_idx[i]);
+		change_bit(1, (unsigned long *)&err_idx[i]);
+
+		if (err_idx[i] <= 512 * 8) {
+			change_bit(err_idx[i], (unsigned long *)dat);
+			i++;
+		}
+	}
+	return i;
+}
+
+/*
+ * spear_nand_probe - Probe function
+ * @pdev:       platform device structure
+ */
+static int spear_nand_probe(struct platform_device *pdev)
+{
+	struct nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct spear_nand_data *host;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	struct fsmc_regs *regs;
+	struct resource *res;
+	int nr_parts, ret = 0;
+
+	if (!pdata) {
+		pr_err("Platform data is NULL\n");
+		return -EINVAL;
+	}
+
+	/* Allocate memory for the device structure (and zero it) */
+	host = kzalloc(sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
+	if (!res) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resdata = request_mem_region(res->start, resource_size(res),
+			pdev->name);
+	if (!host->resdata) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->data_va = ioremap(res->start, resource_size(res));
+	if (!host->data_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resaddr = request_mem_region(res->start + PLAT_NAND_ALE,
+			resource_size(res), pdev->name);
+	if (!host->resaddr) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->addr_va = ioremap(res->start + PLAT_NAND_ALE, resource_size(res));
+	if (!host->addr_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->rescmd = request_mem_region(res->start + PLAT_NAND_CLE,
+			resource_size(res), pdev->name);
+	if (!host->rescmd) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->cmd_va = ioremap(res->start + PLAT_NAND_CLE, resource_size(res));
+	if (!host->cmd_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
+	if (!res) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->resregs = request_mem_region(res->start, resource_size(res),
+			pdev->name);
+	if (!host->resregs) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->regs_va = ioremap(res->start, resource_size(res));
+	if (!host->regs_va) {
+		ret = -EIO;
+		goto err_probe1;
+	}
+
+	host->clk = clk_get(NULL, "fsmc");
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		host->clk = NULL;
+		goto err_probe1;
+	}
+
+	ret = clk_enable(host->clk);
+	if (ret)
+		goto err_probe1;
+
+	host->bank = pdata->bank;
+	host->select_chip = pdata->select_bank;
+	regs = host->regs_va;
+
+	/* Link all private pointers */
+	mtd = &host->mtd;
+	nand = &host->nand;
+	mtd->priv = nand;
+	nand->priv = host;
+
+	host->mtd.owner = THIS_MODULE;
+	nand->IO_ADDR_R = host->data_va;
+	nand->IO_ADDR_W = host->data_va;
+	nand->cmd_ctrl = spear_cmd_ctrl;
+	nand->chip_delay = 30;
+
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.hwctl = fsmc_enable_hwecc;
+	nand->ecc.size = 512;
+	nand->options = pdata->options;
+	nand->select_chip = spear_select_chip;
+
+	if (pdata->width == SPEAR_NAND_BW16)
+		nand->options |= NAND_BUSWIDTH_16;
+
+	fsmc_nand_init(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
+
+	if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+		nand->ecc.read_page = fsmc_read_page_hwecc;
+		nand->ecc.calculate = fsmc_read_hwecc_ecc4;
+		nand->ecc.correct = fsmc_correct_data;
+		nand->ecc.bytes = 13;
+	} else {
+		nand->ecc.calculate = fsmc_read_hwecc_ecc1;
+		nand->ecc.correct = nand_correct_data;
+		nand->ecc.bytes = 3;
+	}
+
+	/*
+	 * Scan to find existance of the device
+	 */
+	if (nand_scan_ident(&host->mtd, 1, NULL)) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "No NAND Device found!\n");
+		goto err_probe;
+	}
+
+	if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+		if (host->mtd.writesize == 512) {
+			nand->ecc.layout = &fsmc_ecc4_sp_layout;
+			host->ecc_place = &fsmc_ecc4_sp_place;
+		} else {
+			nand->ecc.layout = &fsmc_ecc4_lp_layout;
+			host->ecc_place = &fsmc_ecc4_lp_place;
+		}
+	} else {
+		nand->ecc.layout = &fsmc_ecc1_layout;
+	}
+
+	/* Second stage of scan to fill MTD data-structures */
+	if (nand_scan_tail(&host->mtd)) {
+		ret = -ENXIO;
+		goto err_probe;
+	}
+
+	/*
+	 * The partition information can is accessed by (in the same precedence)
+	 *
+	 * command line through Bootloader,
+	 * platform data,
+	 * default partition information present in driver.
+	 */
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	/*
+	 * Check if partition info passed via command line
+	 */
+	host->mtd.name = "nand";
+	nr_parts = parse_mtd_partitions(&host->mtd, part_probes,
+			&host->partitions, 0);
+	if (nr_parts > 0) {
+		host->nr_partitions = nr_parts;
+	} else {
+#endif
+		/*
+		 * Check if partition info passed via command line
+		 */
+		if (pdata->partitions) {
+			host->partitions = pdata->partitions;
+			host->nr_partitions = pdata->nr_partitions;
+		} else {
+			struct mtd_partition *partition;
+			int i;
+
+			/* Select the default partitions info */
+			switch (host->mtd.size) {
+			case 0x01000000:
+			case 0x02000000:
+			case 0x04000000:
+				host->partitions = partition_info_16KB_blk;
+				host->nr_partitions =
+					sizeof(partition_info_16KB_blk) /
+					sizeof(struct mtd_partition);
+				break;
+			case 0x08000000:
+			case 0x10000000:
+			case 0x20000000:
+			case 0x40000000:
+				host->partitions = partition_info_128KB_blk;
+				host->nr_partitions =
+					sizeof(partition_info_128KB_blk) /
+					sizeof(struct mtd_partition);
+				break;
+			default:
+				ret = -ENXIO;
+				pr_err("Unsupported NAND size\n");
+				goto err_probe;
+			}
+
+			partition = host->partitions;
+			for (i = 0; i < host->nr_partitions; i++, partition++) {
+				if (partition->size == 0) {
+					partition->size = host->mtd.size -
+						partition->offset;
+					break;
+				}
+			}
+		}
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	}
+#endif
+
+	if (host->partitions) {
+		ret = add_mtd_partitions(&host->mtd, host->partitions,
+				host->nr_partitions);
+		if (ret)
+			goto err_probe;
+	}
+#else
+	dev_info(&pdev->dev, "Registering %s as whole device\n", mtd->name);
+	if (!add_mtd_device(mtd)) {
+		ret = -ENXIO;
+		goto err_probe;
+	}
+#endif
+
+	platform_set_drvdata(pdev, host);
+	dev_info(&pdev->dev, "SPEAr NAND driver registration successful\n");
+	return 0;
+
+err_probe:
+	clk_disable(host->clk);
+err_probe1:
+	if (host->clk)
+		clk_put(host->clk);
+	if (host->regs_va)
+		iounmap(host->regs_va);
+	if (host->resregs)
+		release_mem_region(host->resregs->start,
+				resource_size(host->resregs));
+	if (host->cmd_va)
+		iounmap(host->cmd_va);
+	if (host->rescmd)
+		release_mem_region(host->rescmd->start,
+				resource_size(host->rescmd));
+	if (host->addr_va)
+		iounmap(host->addr_va);
+	if (host->resaddr)
+		release_mem_region(host->resaddr->start,
+				resource_size(host->resaddr));
+	if (host->data_va)
+		iounmap(host->data_va);
+	if (host->resdata)
+		release_mem_region(host->resdata->start,
+				resource_size(host->resdata));
+
+	kfree(host);
+	return ret;
+}
+
+/*
+ * Clean up routine
+ */
+static int spear_nand_remove(struct platform_device *pdev)
+{
+	struct spear_nand_data *host = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (host) {
+#ifdef CONFIG_MTD_PARTITIONS
+		del_mtd_partitions(&host->mtd);
+#else
+		del_mtd_device(&host->mtd);
+#endif
+		clk_disable(host->clk);
+		clk_put(host->clk);
+
+		iounmap(host->regs_va);
+		release_mem_region(host->resregs->start,
+				resource_size(host->resregs));
+		iounmap(host->cmd_va);
+		release_mem_region(host->rescmd->start,
+				resource_size(host->rescmd));
+		iounmap(host->addr_va);
+		release_mem_region(host->resaddr->start,
+				resource_size(host->resaddr));
+		iounmap(host->data_va);
+		release_mem_region(host->resdata->start,
+				resource_size(host->resdata));
+
+		kfree(host);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int spear_nand_suspend(struct device *dev)
+{
+	struct spear_nand_data *host = dev_get_drvdata(dev);
+	if (host)
+		clk_disable(host->clk);
+	return 0;
+}
+
+static int spear_nand_resume(struct device *dev)
+{
+	struct spear_nand_data *host = dev_get_drvdata(dev);
+	if (host)
+		clk_enable(host->clk);
+	return 0;
+}
+
+static const struct dev_pm_ops spear_nand_pm_ops = {
+	.suspend = spear_nand_suspend,
+	.resume = spear_nand_resume,
+};
+#endif
+
+static struct platform_driver spear_nand_driver = {
+	.probe = spear_nand_probe,
+	.remove = spear_nand_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "nand",
+#ifdef CONFIG_PM
+		.pm = &spear_nand_pm_ops,
+#endif
+	},
+};
+
+static int __init spear_nand_init(void)
+{
+	return platform_driver_register(&spear_nand_driver);
+}
+module_init(spear_nand_init);
+
+static void __exit spear_nand_exit(void)
+{
+	platform_driver_unregister(&spear_nand_driver);
+}
+module_exit(spear_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi");
+MODULE_DESCRIPTION("NAND driver for SPEAr Platforms");
-- 
1.7.2.2

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-08-30 10:43   ` Viresh KUMAR
  -1 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mtd, dwmw2
  Cc: pratyush.anand, Viresh Kumar, vipulkumar.samar, bhupesh.sharma,
	armando.visconti, Vipin Kumar, shiraz.hashim, rajeev-dlh.kumar,
	deepak.sikri

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

For a page size of 4096, the number of oob bytes are 128 per page. This demands
for an increased ecc_pos array as well as ecc can be placed at more than 64
locations.

This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
byte page.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 include/mtd/mtd-abi.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 4debb45..ff3f30e 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -150,7 +150,7 @@ struct nand_oobfree {
  */
 struct nand_ecclayout {
 	__u32 eccbytes;
-	__u32 eccpos[64];
+	__u32 eccpos[128];
 	__u32 oobavail;
 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
 };
-- 
1.7.2.2

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-08-30 10:43   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

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

For a page size of 4096, the number of oob bytes are 128 per page. This demands
for an increased ecc_pos array as well as ecc can be placed at more than 64
locations.

This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
byte page.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 include/mtd/mtd-abi.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 4debb45..ff3f30e 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -150,7 +150,7 @@ struct nand_oobfree {
  */
 struct nand_ecclayout {
 	__u32 eccbytes;
-	__u32 eccpos[64];
+	__u32 eccpos[128];
 	__u32 oobavail;
 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
 };
-- 
1.7.2.2

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

* [PATCH 29/74] Newly erased page read workaround
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-08-30 10:43   ` Viresh KUMAR
  -1 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mtd, dwmw2
  Cc: pratyush.anand, Viresh Kumar, vipulkumar.samar, bhupesh.sharma,
	armando.visconti, Vipin Kumar, shiraz.hashim, rajeev-dlh.kumar,
	deepak.sikri

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

A newly erased page contains ff in data as well as spare area. While reading an
erased page, the read out ecc from spare area does not match the ecc generated
by fsmc ecc hardware accelarator. This is because ecc of data ff ff is not ff
ff. This leads to errors when jffs2 fs erases and reads back the pages to
ensure consistency.

This patch adds a software workaround to ensure that the ecc check is not
performed for erased pages. An erased page is checked by checking data as ff ff.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/mtd/nand/spear_nand.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
index da9661b..5a31bde 100644
--- a/drivers/mtd/nand/spear_nand.c
+++ b/drivers/mtd/nand/spear_nand.c
@@ -381,7 +381,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	struct spear_nand_data *host = container_of(mtd,
 					struct spear_nand_data, mtd);
 	struct fsmc_eccplace *ecc_place = host->ecc_place;
-	int i, j, s, stat, eccsize = chip->ecc.size;
+	int i, j, k, s, stat, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
 	u8 *p = buf;
@@ -421,11 +421,27 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		memcpy(&ecc_code[i], oob, 13);
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
-		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat < 0)
-			mtd->ecc_stats.failed++;
-		else
-			mtd->ecc_stats.corrected += stat;
+		/*
+		 * This is a temporary erase check. A newly erased page read
+		 * would result in an ecc error because the oob data is also
+		 * erased to FF and the calculated ecc for an FF data is not
+		 * FF..FF.
+		 * This is a workaround to skip performing correction in case
+		 * data is FF..FF
+		 */
+		for (k = 0; k < eccsize; k++) {
+			if (*(p + k) != 0xff)
+				break;
+		}
+
+		if (k < eccsize) {
+			stat = chip->ecc.correct(mtd, p, &ecc_code[i],
+					&ecc_calc[i]);
+			if (stat < 0)
+				mtd->ecc_stats.failed++;
+			else
+				mtd->ecc_stats.corrected += stat;
+		}
 	}
 
 	return 0;
-- 
1.7.2.2

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

* [PATCH 29/74] Newly erased page read workaround
@ 2010-08-30 10:43   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

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

A newly erased page contains ff in data as well as spare area. While reading an
erased page, the read out ecc from spare area does not match the ecc generated
by fsmc ecc hardware accelarator. This is because ecc of data ff ff is not ff
ff. This leads to errors when jffs2 fs erases and reads back the pages to
ensure consistency.

This patch adds a software workaround to ensure that the ecc check is not
performed for erased pages. An erased page is checked by checking data as ff ff.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/mtd/nand/spear_nand.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
index da9661b..5a31bde 100644
--- a/drivers/mtd/nand/spear_nand.c
+++ b/drivers/mtd/nand/spear_nand.c
@@ -381,7 +381,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	struct spear_nand_data *host = container_of(mtd,
 					struct spear_nand_data, mtd);
 	struct fsmc_eccplace *ecc_place = host->ecc_place;
-	int i, j, s, stat, eccsize = chip->ecc.size;
+	int i, j, k, s, stat, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	int eccsteps = chip->ecc.steps;
 	u8 *p = buf;
@@ -421,11 +421,27 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		memcpy(&ecc_code[i], oob, 13);
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
-		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat < 0)
-			mtd->ecc_stats.failed++;
-		else
-			mtd->ecc_stats.corrected += stat;
+		/*
+		 * This is a temporary erase check. A newly erased page read
+		 * would result in an ecc error because the oob data is also
+		 * erased to FF and the calculated ecc for an FF data is not
+		 * FF..FF.
+		 * This is a workaround to skip performing correction in case
+		 * data is FF..FF
+		 */
+		for (k = 0; k < eccsize; k++) {
+			if (*(p + k) != 0xff)
+				break;
+		}
+
+		if (k < eccsize) {
+			stat = chip->ecc.correct(mtd, p, &ecc_code[i],
+					&ecc_calc[i]);
+			if (stat < 0)
+				mtd->ecc_stats.failed++;
+			else
+				mtd->ecc_stats.corrected += stat;
+		}
 	}
 
 	return 0;
-- 
1.7.2.2

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

* [PATCH 50/74] ST SPEAr: PCIE gadget suppport
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
@ 2010-08-30 10:44   ` Viresh KUMAR
  2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
                     ` (73 subsequent siblings)
  74 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:44 UTC (permalink / raw)
  To: linux-arm-kernel, akpm, linux-kernel
  Cc: Pratyush Anand, shiraz.hashim, vipin.kumar, deepak.sikri,
	armando.visconti, vipulkumar.samar, rajeev-dlh.kumar,
	bhupesh.sharma, Viresh Kumar

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

This is a configurable gadget. can be configured by sysfs interface. Any
IP available at PCIE bus can be programmed to be used by host
controller.It supoorts both INTX and MSI.
By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
with size 0x1000

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/mach-spear13xx/include/mach/generic.h |    3 +
 arch/arm/mach-spear13xx/include/mach/spear.h   |    2 +-
 arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear13xx.c            |   94 +++
 drivers/misc/Kconfig                           |   10 +
 drivers/misc/Makefile                          |    1 +
 drivers/misc/spear13xx_pcie_gadget.c           |  888 ++++++++++++++++++++++++
 7 files changed, 998 insertions(+), 1 deletions(-)
 create mode 100644 drivers/misc/spear13xx_pcie_gadget.c

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index dfee834..3f54563 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -44,6 +44,9 @@ extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
 extern struct platform_device sdhci_device;
 extern struct platform_device smi_device;
+extern struct platform_device pcie_gadget0_device;
+extern struct platform_device pcie_gadget1_device;
+extern struct platform_device pcie_gadget2_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index cf25eb5..d043280 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -60,7 +60,7 @@
 #define SPEAR13XX_SYS_LOCATION		(SPEAR13XX_SYSRAM0_BASE + 0x600)
 
 #define SPEAR13XX_SYSRAM1_BASE		UL(0xE0800000)
-#define SPEAR13XX_SYSRAM1_SIZE		0x00800000
+#define SPEAR13XX_SYSRAM1_SIZE		0x00001000
 #define SPEAR13XX_CLCD_BASE		UL(0xE1000000)
 #define SPEAR13XX_C3_BASE		UL(0xE1800000)
 #define SPEAR13XX_GETH_BASE		UL(0xE2000000)
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index d030a85..5756a8c 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -54,6 +54,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&rtc_device,
 	&sdhci_device,
 	&smi_device,
+	&pcie_gadget0_device,
 };
 
 /* keyboard specific platform data */
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 59eaf98..01cb76c 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -419,6 +419,100 @@ struct platform_device sdhci_device = {
 	.resource = sdhci_resources,
 };
 
+/* pcie gadget registration */
+static struct resource pcie_gadget0_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE0_APP_BASE,
+		.end = SPEAR13XX_PCIE0_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE0_BASE,
+		.end = SPEAR13XX_PCIE0_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget0_id defaults to 0, being static variable */
+static int pcie_gadget0_id;
+static u64 pcie_gadget0_dmamask = ~0;
+
+struct platform_device pcie_gadget0_device = {
+	.name = "pcie-gadget-spear",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget0_dmamask,
+		.platform_data = &pcie_gadget0_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget0_resources),
+	.resource = pcie_gadget0_resources,
+};
+
+static struct resource pcie_gadget1_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE1_APP_BASE,
+		.end = SPEAR13XX_PCIE1_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE1_BASE,
+		.end = SPEAR13XX_PCIE1_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget1_id defaults to 0, being static variable */
+static int pcie_gadget1_id;
+static u64 pcie_gadget1_dmamask = ~0;
+
+struct platform_device pcie_gadget1_device = {
+	.name = "pcie-gadget-spear",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget1_dmamask,
+		.platform_data = &pcie_gadget1_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget1_resources),
+	.resource = pcie_gadget1_resources,
+};
+
+static struct resource pcie_gadget2_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE2_APP_BASE,
+		.end = SPEAR13XX_PCIE2_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE2_BASE,
+		.end = SPEAR13XX_PCIE2_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget2_id defaults to 0, being static variable */
+static int pcie_gadget2_id;
+static u64 pcie_gadget2_dmamask = ~0;
+
+struct platform_device pcie_gadget2_device = {
+	.name = "pcie-gadget-spear",
+	.id = 2,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget2_dmamask,
+		.platform_data = &pcie_gadget2_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget2_resources),
+	.resource = pcie_gadget2_resources,
+};
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b591b6..49a3d76 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -344,6 +344,16 @@ config DS1682
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1682.
 
+config SPEAR13XX_PCIE_GADGET
+	bool "PCIE gadget support for SPEAr13XX platform"
+	depends on ARCH_SPEAR13XX
+	default n
+	help
+	 This option enables gadget support for PCIE controller. If
+	 board file defines any controller as PCIE endpoint then a sysfs
+	 entry will be created for that controller. User can use these
+	 sysfs node to configure PCIE EP as per his requirements.
+
 config TI_DAC7512
 	tristate "Texas Instruments DAC7512"
 	depends on SPI && SYSFS
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 255a80d..67a9ed9 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -33,5 +33,6 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_HMC6352)		+= hmc6352.o
 obj-y				+= eeprom/
 obj-y				+= cb710/
+obj-$(CONFIG_SPEAR13XX_PCIE_GADGET)	+= spear13xx_pcie_gadget.o
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
new file mode 100644
index 0000000..dc63a28
--- /dev/null
+++ b/drivers/misc/spear13xx_pcie_gadget.c
@@ -0,0 +1,888 @@
+/*
+ * drivers/misc/spear13xx_pcie_gadget.c
+ *
+ * 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/delay.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/pci_regs.h>
+#include <mach/pcie.h>
+#include <mach/misc_regs.h>
+
+#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	(12 * 1024 * 1024 - 1)
+#define IN_CFG1_SIZE	(12 * 1024 * 1024 - 1)
+#define IN_MSG_SIZE	(12 * 1024 * 1024 - 1)
+/* Keep default BAR size as 4K*/
+/* AORAM would be mapped by default*/
+#define INBOUND_ADDR_MASK	(SPEAR13XX_SYSRAM1_SIZE - 1)
+
+#define INT_TYPE_NO_INT	0
+#define INT_TYPE_INTX	1
+#define INT_TYPE_MSI	2
+struct spear_pcie_gadget_config {
+	void __iomem *base;
+	void __iomem *va_app_base;
+	void __iomem *va_dbi_base;
+	char int_type[10];
+	u32 requested_msi;
+	u32 configured_msi;
+	u32 bar0_size;
+	u32 bar0_rw_offset;
+	u32 va_bar0_address;
+};
+
+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 spear_pcie_gadget_config *config,
+		int where, int size, u32 *val)
+{
+	struct pcie_app_reg *app_reg
+		= (struct pcie_app_reg *) config->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)config->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 spear_pcie_gadget_config *config,
+		int where, int size, u32 val)
+{
+	struct pcie_app_reg *app_reg
+		= (struct pcie_app_reg *) config->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)config->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);
+}
+
+#define PCI_FIND_CAP_TTL	48
+
+static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
+		u32 pos, int cap, int *ttl)
+{
+	u32 id;
+
+	while ((*ttl)--) {
+		spear_dbi_read_reg(config, pos, 1, &pos);
+		if (pos < 0x40)
+			break;
+		pos &= ~3;
+		spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos += PCI_CAP_LIST_NEXT;
+	}
+	return 0;
+}
+
+static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
+			u32 pos, int cap)
+{
+	int ttl = PCI_FIND_CAP_TTL;
+
+	return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
+}
+
+static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
+				u8 hdr_type)
+{
+	u32 status;
+
+	spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
+	if (!(status & PCI_STATUS_CAP_LIST))
+		return 0;
+
+	switch (hdr_type) {
+	case PCI_HEADER_TYPE_NORMAL:
+	case PCI_HEADER_TYPE_BRIDGE:
+		return PCI_CAPABILITY_LIST;
+	case PCI_HEADER_TYPE_CARDBUS:
+		return PCI_CB_CAPABILITY_LIST;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+/**
+ * Tell if a device supports a given PCI capability.
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it. Possible values for @cap:
+ *
+ * %PCI_CAP_ID_PM	Power Management
+ * %PCI_CAP_ID_AGP	Accelerated Graphics Port
+ * %PCI_CAP_ID_VPD	Vital Product Data
+ * %PCI_CAP_ID_SLOTID	Slot Identification
+ * %PCI_CAP_ID_MSI	Message Signalled Interrupts
+ * %PCI_CAP_ID_CHSWP	CompactPCI HotSwap
+ * %PCI_CAP_ID_PCIX	PCI-X
+ * %PCI_CAP_ID_EXP	PCI Express
+ */
+static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
+		int cap)
+{
+	u32 pos;
+	u32 hdr_type;
+
+	spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
+
+	pos = pci_find_own_cap_start(config, hdr_type);
+	if (pos)
+		pos = pci_find_own_next_cap(config, pos, cap);
+
+	return pos;
+}
+
+static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
+{
+	return 0;
+}
+
+static ssize_t pcie_gadget_show_link(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
+		return sprintf(buf, "UP");
+	else
+		return sprintf(buf, "DOWN");
+}
+
+static ssize_t pcie_gadget_store_link(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	char link[10];
+
+	if (sscanf(buf, "%s", link) != 1)
+		return -EINVAL;
+
+	if (!strcmp(link, "UP"))
+		writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
+			&app_reg->app_ctrl_0);
+	else
+		writel(readl(&app_reg->app_ctrl_0)
+				& ~(1 << APP_LTSSM_ENABLE_ID),
+				&app_reg->app_ctrl_0);
+	return count;
+}
+
+static DEVICE_ATTR(link, S_IWUSR | S_IRUGO, pcie_gadget_show_link,
+		pcie_gadget_store_link);
+
+static ssize_t pcie_gadget_show_int_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s", config->int_type);
+}
+
+static ssize_t pcie_gadget_store_int_type(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	char int_type[10];
+	u32 cap, vector, vec, flags;
+
+	if (sscanf(buf, "%s", int_type) != 1)
+		return -EINVAL;
+
+	if (!strcmp(int_type, "INTA"))
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+
+	else if (!strcmp(int_type, "MSI")) {
+		vector = config->requested_msi;
+		vec = 0;
+		while (vector > 1) {
+			vector /= 2;
+			vec++;
+		}
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QMASK;
+		flags |= vec << 1;
+		spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
+	}
+
+	strcpy(config->int_type, int_type);
+
+	return count;
+}
+
+static DEVICE_ATTR(int_type, S_IWUSR | S_IRUGO, pcie_gadget_show_int_type,
+		pcie_gadget_store_int_type);
+
+static ssize_t pcie_gadget_show_no_of_msi(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	u32 cap, vector, vec, flags;
+
+	if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
+			!= (1 << CFG_MSI_EN_ID))
+		vector = 0;
+	else {
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QSIZE;
+		vec = flags >> 4;
+		vector = 1;
+		while (vec--)
+			vector *= 2;
+	}
+	config->configured_msi = vector;
+
+	return sprintf(buf, "%u", vector);
+}
+
+static ssize_t pcie_gadget_store_no_of_msi(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &config->requested_msi) != 1)
+		return -EINVAL;
+	if (config->requested_msi > 32)
+		config->requested_msi = 32;
+
+	return count;
+}
+
+static DEVICE_ATTR(no_of_msi, S_IWUSR | S_IRUGO, pcie_gadget_show_no_of_msi,
+		pcie_gadget_store_no_of_msi);
+
+static ssize_t pcie_gadget_store_inta(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	int en;
+
+	if (sscanf(buf, "%d", &en) != 1)
+		return -EINVAL;
+
+	if (en)
+		writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+	else
+		writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+
+	return count;
+}
+
+static DEVICE_ATTR(inta, S_IWUSR, NULL, pcie_gadget_store_inta);
+
+static ssize_t pcie_gadget_store_send_msi(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	int vector;
+	u32 ven_msi;
+
+	if (sscanf(buf, "%d", &vector) != 1)
+		return -EINVAL;
+
+	if (!config->configured_msi)
+		return -EINVAL;
+
+	if (vector >= config->configured_msi)
+		return -EINVAL;
+
+	ven_msi = readl(&app_reg->ven_msi_1);
+	ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
+	ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
+	ven_msi &= ~VEN_MSI_TC_MASK;
+	ven_msi |= 0 << VEN_MSI_TC_ID;
+	ven_msi &= ~VEN_MSI_VECTOR_MASK;
+	ven_msi |= vector << VEN_MSI_VECTOR_ID;
+
+	/*generating interrupt for msi vector*/
+	ven_msi |= VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+	/*need to wait till this bit is cleared, it is not cleared
+	 * autometically[Bug RTL] TBD*/
+	udelay(1);
+	ven_msi &= ~VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+
+	return count;
+}
+
+static DEVICE_ATTR(send_msi, S_IWUSR, NULL, pcie_gadget_store_send_msi);
+
+static ssize_t pcie_gadget_show_vendor_id(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_vendor_id(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	if (sscanf(buf, "%x", &id) != 1)
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
+
+	return count;
+}
+
+static DEVICE_ATTR(vendor_id, S_IWUSR | S_IRUGO, pcie_gadget_show_vendor_id,
+		pcie_gadget_store_vendor_id);
+
+static ssize_t pcie_gadget_show_device_id(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_device_id(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	if (sscanf(buf, "%x", &id) != 1)
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
+
+	return count;
+}
+
+static DEVICE_ATTR(device_id, S_IWUSR | S_IRUGO, pcie_gadget_show_device_id,
+		pcie_gadget_store_device_id);
+
+static ssize_t pcie_gadget_show_bar0_size(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%x", config->bar0_size);
+}
+
+static ssize_t pcie_gadget_store_bar0_size(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 size, pos, pos1;
+	u32 no_of_bit = 0;
+
+	if (sscanf(buf, "%x", &size) != 1)
+		return -EINVAL;
+	/* as per PCIE specs, min bar size supported is 128 bytes. But
+	 * our controller supports min as 256*/
+	if (size <= 0x100)
+		size = 0x100;
+	/* max bar size is 1MB*/
+	else if (size >= 0x100000)
+		size = 0x100000;
+	else {
+		pos = 0;
+		pos1 = 0;
+		while (pos < 21) {
+			pos = find_next_bit((unsigned long *)&size, 21, pos);
+			if (pos != 21)
+				pos1 = pos + 1;
+			pos++;
+			no_of_bit++;
+		}
+		if (no_of_bit == 2)
+			pos1--;
+
+		size = 1 << pos1;
+	}
+	config->bar0_size = size;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_size, S_IWUSR | S_IRUGO, pcie_gadget_show_bar0_size,
+		pcie_gadget_store_bar0_size);
+
+static ssize_t pcie_gadget_show_bar0_address(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	u32 address = readl(&app_reg->pim0_mem_addr_start);
+
+	return sprintf(buf, "%x", address);
+}
+
+static ssize_t pcie_gadget_store_bar0_address(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	u32 address;
+
+	if (sscanf(buf, "%x", &address) != 1)
+		return -EINVAL;
+
+	address &= ~(config->bar0_size - 1);
+	if (config->va_bar0_address)
+		iounmap((void *)config->va_bar0_address);
+	config->va_bar0_address = (u32)ioremap(address, config->bar0_size);
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(address, &app_reg->pim0_mem_addr_start);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_address, S_IWUSR | S_IRUGO,
+		pcie_gadget_show_bar0_address, pcie_gadget_store_bar0_address);
+
+static ssize_t pcie_gadget_show_bar0_rw_offset(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%x", config->bar0_rw_offset);
+}
+
+static ssize_t pcie_gadget_store_bar0_rw_offset(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 offset;
+
+	if (sscanf(buf, "%x", &offset) != 1)
+		return -EINVAL;
+
+	if (offset % 4)
+		return -EINVAL;
+
+	config->bar0_rw_offset = offset;
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_rw_offset, S_IWUSR | S_IRUGO,
+	pcie_gadget_show_bar0_rw_offset, pcie_gadget_store_bar0_rw_offset);
+
+static ssize_t pcie_gadget_show_bar0_data(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 data;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	data = readl(config->va_bar0_address + config->bar0_rw_offset);
+
+	return sprintf(buf, "%x", data);
+}
+
+static ssize_t pcie_gadget_store_bar0_data(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 data;
+
+	if (sscanf(buf, "%x", &data) != 1)
+		return -EINVAL;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(data, config->va_bar0_address + config->bar0_rw_offset);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_data, S_IWUSR | S_IRUGO,
+		pcie_gadget_show_bar0_data, pcie_gadget_store_bar0_data);
+
+static ssize_t pcie_gadget_show_help(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	char text[] = "\t\tlink read->ltssm status\n \
+		link write->arg1 = UP to enable ltsmm DOWN to disable\n \
+		int_type read->type of supported interrupt\n \
+		int_type write->arg1 = interrupt type to be configured and\n \
+		can be INTA, MSI or NO_INT\n \
+		(select MSI only when you have programmed no_of_msi)\n \
+		no_of_msi read->zero if MSI is not enabled by host\n \
+		and positive value is the number of MSI vector granted\n \
+		no_of_msi write->arg1 = number of MSI vector needed\n \
+		inta write->arg1 = 1 to assert INTA and 0 to de-assert\n \
+		send_msi write->arg1 = MSI vector to be send\n \
+		vendor_id read->programmed vendor id (hex)\n\
+		vendor_id write->arg1 = vendor id(hex) to be programmed\n \
+		device_id read->programmed device id(hex)\n \
+		device_id write->arg1 = device id(hex) to be programmed\n \
+		bar0_size read->size of bar0 in hex\n \
+		bar0_size write->arg1= size of bar0 in hex\n \
+		(default bar0 size is 1000 (hex) bytes)\n \
+		bar0_address read->address of bar0 mapped area in hex\n \
+		bar0_address write->arg1 = address of bar0 mapped area in hex\n\
+		(default mapping of bar0 is SYSRAM1(E0800000)\n \
+		(always program bar size before bar address)\n \
+		(kernel might modify bar size and address to align)\n \
+		(read back bar size and address after writing to check)\n \
+		bar0_rw_offset read->offset of bar0 for which bar0_data \n \
+		will return value\n \
+		bar0_rw_offset write->arg1 = offset of bar0 for which\n \
+		bar0_data will write value\n \
+		bar0_data read->data at bar0_rw_offset\n \
+		bar0_data write->arg1 = data to be written at\n \
+		bar0_rw_offset\n";
+
+	int size = (sizeof(text) < PAGE_SIZE) ? sizeof(text) : PAGE_SIZE;
+
+	return snprintf(buf, size, "%s", text);
+}
+
+static DEVICE_ATTR(help, S_IRUGO, pcie_gadget_show_help, NULL);
+
+static struct attribute *pcie_gadget_attributes[] = {
+	&dev_attr_link.attr,
+	&dev_attr_int_type.attr,
+	&dev_attr_no_of_msi.attr,
+	&dev_attr_inta.attr,
+	&dev_attr_send_msi.attr,
+	&dev_attr_vendor_id.attr,
+	&dev_attr_device_id.attr,
+	&dev_attr_bar0_size.attr,
+	&dev_attr_bar0_address.attr,
+	&dev_attr_bar0_rw_offset.attr,
+	&dev_attr_bar0_data.attr,
+	&dev_attr_help.attr,
+	NULL
+};
+
+static const struct attribute_group pcie_gadget_attr_group = {
+	.attrs = pcie_gadget_attributes,
+};
+
+static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
+{
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	/*setup registers for outbound translation */
+
+	writel(config->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 */
+
+	/* Keep AORAM mapped at BAR0 as default */
+	config->bar0_size = INBOUND_ADDR_MASK + 1;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
+	spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
+	config->va_bar0_address = (u32)ioremap(SPEAR13XX_SYSRAM1_BASE,
+			config->bar0_size);
+
+	writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
+	writel(0, &app_reg->pim1_mem_addr_start);
+	writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
+
+	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_EP | (1 << MISCTRL_EN_ID)
+			| ((u32)1 << REG_TRANSLATION_ENABLE),
+			&app_reg->app_ctrl_0);
+	/* disable all rx interrupts */
+	writel(0, &app_reg->int_mask);
+
+	/* Select INTA as default*/
+	spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+}
+
+static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	struct spear_pcie_gadget_config *config;
+	unsigned int status = 0;
+	int irq;
+	struct clk *clk;
+
+	/* get resource for application registers*/
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		return -EBUSY;
+	}
+	if (!request_mem_region(res0->start, resource_size(res0),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		return -EBUSY;
+	}
+	/* get resource for dbi registers*/
+
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res1) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		goto err_rel_res0;
+	}
+	if (!request_mem_region(res1->start, resource_size(res1),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		goto err_rel_res0;
+	}
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(&pdev->dev, "out of memory\n");
+		status = -ENOMEM;
+		goto err_rel_res;
+	}
+
+	config->va_app_base = ioremap(res0->start, resource_size(res0));
+	if (!config->va_app_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	config->base = (void *)res1->start;
+
+	config->va_dbi_base = ioremap(res1->start, resource_size(res1));
+	if (!config->va_dbi_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_iounmap_app;
+	}
+
+	dev_set_drvdata(&pdev->dev, config);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no update irq?\n");
+		status = irq;
+		goto err_iounmap;
+	}
+
+	status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
+	if (status) {
+		dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
+				claimed\n", irq);
+		goto err_get_irq;
+	}
+	/* Register sysfs hooks */
+	status = sysfs_create_group(&pdev->dev.kobj, &pcie_gadget_attr_group);
+	if (status)
+		goto err_irq;
+
+	/* init basic pcie application registers*/
+	/* 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 (pdev->id == 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 (!clk) {
+			pr_err("%s:couldn't get clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+	} else if (pdev->id == 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 (!clk) {
+			pr_err("%s:couldn't get clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+	}
+	spear13xx_pcie_device_init(config);
+
+	return 0;
+err_irq:
+	free_irq(irq, NULL);
+err_get_irq:
+	dev_set_drvdata(&pdev->dev, NULL);
+err_iounmap:
+	iounmap(config->va_dbi_base);
+err_iounmap_app:
+	iounmap(config->va_app_base);
+err_kzalloc:
+	kfree(config);
+err_rel_res:
+	release_mem_region(res1->start, resource_size(res1));
+err_rel_res0:
+	release_mem_region(res0->start, resource_size(res0));
+	return status;
+}
+
+static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	struct spear_pcie_gadget_config *config;
+	int irq;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	irq = platform_get_irq(pdev, 0);
+	config = dev_get_drvdata(&pdev->dev);
+
+	free_irq(irq, NULL);
+	dev_set_drvdata(&pdev->dev, NULL);
+	iounmap(config->va_dbi_base);
+	iounmap(config->va_app_base);
+	kfree(config);
+	release_mem_region(res1->start, resource_size(res1));
+	release_mem_region(res0->start, resource_size(res0));
+	sysfs_remove_group(&pdev->dev.kobj, &pcie_gadget_attr_group);
+
+	return 0;
+}
+
+static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
+{
+}
+
+static struct platform_driver spear_pcie_gadget_driver = {
+	.probe = spear_pcie_gadget_probe,
+	.remove = spear_pcie_gadget_remove,
+	.shutdown = spear_pcie_gadget_shutdown,
+	.driver = {
+		.name = "pcie-gadget-spear",
+		.bus = &platform_bus_type
+	},
+};
+
+static int __init spear_pcie_gadget_init(void)
+{
+	return platform_driver_register(&spear_pcie_gadget_driver);
+}
+module_init(spear_pcie_gadget_init);
+
+static void __exit spear_pcie_gadget_exit(void)
+{
+	platform_driver_unregister(&spear_pcie_gadget_driver);
+}
+module_exit(spear_pcie_gadget_exit);
+
+MODULE_ALIAS("pcie-gadget-spear");
+MODULE_AUTHOR("Pratyush Anand");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2


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

* [PATCH 50/74] ST SPEAr: PCIE gadget suppport
@ 2010-08-30 10:44   ` Viresh KUMAR
  0 siblings, 0 replies; 245+ messages in thread
From: Viresh KUMAR @ 2010-08-30 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

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

This is a configurable gadget. can be configured by sysfs interface. Any
IP available at PCIE bus can be programmed to be used by host
controller.It supoorts both INTX and MSI.
By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
with size 0x1000

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/mach-spear13xx/include/mach/generic.h |    3 +
 arch/arm/mach-spear13xx/include/mach/spear.h   |    2 +-
 arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
 arch/arm/mach-spear13xx/spear13xx.c            |   94 +++
 drivers/misc/Kconfig                           |   10 +
 drivers/misc/Makefile                          |    1 +
 drivers/misc/spear13xx_pcie_gadget.c           |  888 ++++++++++++++++++++++++
 7 files changed, 998 insertions(+), 1 deletions(-)
 create mode 100644 drivers/misc/spear13xx_pcie_gadget.c

diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index dfee834..3f54563 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -44,6 +44,9 @@ extern struct platform_device ohci1_device;
 extern struct platform_device rtc_device;
 extern struct platform_device sdhci_device;
 extern struct platform_device smi_device;
+extern struct platform_device pcie_gadget0_device;
+extern struct platform_device pcie_gadget1_device;
+extern struct platform_device pcie_gadget2_device;
 extern struct sys_timer spear13xx_timer;
 
 /* Add spear13xx family function declarations here */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
index cf25eb5..d043280 100644
--- a/arch/arm/mach-spear13xx/include/mach/spear.h
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -60,7 +60,7 @@
 #define SPEAR13XX_SYS_LOCATION		(SPEAR13XX_SYSRAM0_BASE + 0x600)
 
 #define SPEAR13XX_SYSRAM1_BASE		UL(0xE0800000)
-#define SPEAR13XX_SYSRAM1_SIZE		0x00800000
+#define SPEAR13XX_SYSRAM1_SIZE		0x00001000
 #define SPEAR13XX_CLCD_BASE		UL(0xE1000000)
 #define SPEAR13XX_C3_BASE		UL(0xE1800000)
 #define SPEAR13XX_GETH_BASE		UL(0xE2000000)
diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
index d030a85..5756a8c 100644
--- a/arch/arm/mach-spear13xx/spear1300_evb.c
+++ b/arch/arm/mach-spear13xx/spear1300_evb.c
@@ -54,6 +54,7 @@ static struct platform_device *plat_devs[] __initdata = {
 	&rtc_device,
 	&sdhci_device,
 	&smi_device,
+	&pcie_gadget0_device,
 };
 
 /* keyboard specific platform data */
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index 59eaf98..01cb76c 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -419,6 +419,100 @@ struct platform_device sdhci_device = {
 	.resource = sdhci_resources,
 };
 
+/* pcie gadget registration */
+static struct resource pcie_gadget0_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE0_APP_BASE,
+		.end = SPEAR13XX_PCIE0_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE0_BASE,
+		.end = SPEAR13XX_PCIE0_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget0_id defaults to 0, being static variable */
+static int pcie_gadget0_id;
+static u64 pcie_gadget0_dmamask = ~0;
+
+struct platform_device pcie_gadget0_device = {
+	.name = "pcie-gadget-spear",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget0_dmamask,
+		.platform_data = &pcie_gadget0_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget0_resources),
+	.resource = pcie_gadget0_resources,
+};
+
+static struct resource pcie_gadget1_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE1_APP_BASE,
+		.end = SPEAR13XX_PCIE1_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE1_BASE,
+		.end = SPEAR13XX_PCIE1_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget1_id defaults to 0, being static variable */
+static int pcie_gadget1_id;
+static u64 pcie_gadget1_dmamask = ~0;
+
+struct platform_device pcie_gadget1_device = {
+	.name = "pcie-gadget-spear",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget1_dmamask,
+		.platform_data = &pcie_gadget1_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget1_resources),
+	.resource = pcie_gadget1_resources,
+};
+
+static struct resource pcie_gadget2_resources[] = {
+	{
+		.start = SPEAR13XX_PCIE2_APP_BASE,
+		.end = SPEAR13XX_PCIE2_APP_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = SPEAR13XX_PCIE2_BASE,
+		.end = SPEAR13XX_PCIE2_BASE + SZ_8K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PCIE2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* pcie_gadget2_id defaults to 0, being static variable */
+static int pcie_gadget2_id;
+static u64 pcie_gadget2_dmamask = ~0;
+
+struct platform_device pcie_gadget2_device = {
+	.name = "pcie-gadget-spear",
+	.id = 2,
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.dma_mask = &pcie_gadget2_dmamask,
+		.platform_data = &pcie_gadget2_id,
+	},
+	.num_resources = ARRAY_SIZE(pcie_gadget2_resources),
+	.resource = pcie_gadget2_resources,
+};
+
 /* Do spear13xx familiy common initialization part here */
 void __init spear13xx_init(void)
 {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b591b6..49a3d76 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -344,6 +344,16 @@ config DS1682
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1682.
 
+config SPEAR13XX_PCIE_GADGET
+	bool "PCIE gadget support for SPEAr13XX platform"
+	depends on ARCH_SPEAR13XX
+	default n
+	help
+	 This option enables gadget support for PCIE controller. If
+	 board file defines any controller as PCIE endpoint then a sysfs
+	 entry will be created for that controller. User can use these
+	 sysfs node to configure PCIE EP as per his requirements.
+
 config TI_DAC7512
 	tristate "Texas Instruments DAC7512"
 	depends on SPI && SYSFS
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 255a80d..67a9ed9 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -33,5 +33,6 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_HMC6352)		+= hmc6352.o
 obj-y				+= eeprom/
 obj-y				+= cb710/
+obj-$(CONFIG_SPEAR13XX_PCIE_GADGET)	+= spear13xx_pcie_gadget.o
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
new file mode 100644
index 0000000..dc63a28
--- /dev/null
+++ b/drivers/misc/spear13xx_pcie_gadget.c
@@ -0,0 +1,888 @@
+/*
+ * drivers/misc/spear13xx_pcie_gadget.c
+ *
+ * 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/delay.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/pci_regs.h>
+#include <mach/pcie.h>
+#include <mach/misc_regs.h>
+
+#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	(12 * 1024 * 1024 - 1)
+#define IN_CFG1_SIZE	(12 * 1024 * 1024 - 1)
+#define IN_MSG_SIZE	(12 * 1024 * 1024 - 1)
+/* Keep default BAR size as 4K*/
+/* AORAM would be mapped by default*/
+#define INBOUND_ADDR_MASK	(SPEAR13XX_SYSRAM1_SIZE - 1)
+
+#define INT_TYPE_NO_INT	0
+#define INT_TYPE_INTX	1
+#define INT_TYPE_MSI	2
+struct spear_pcie_gadget_config {
+	void __iomem *base;
+	void __iomem *va_app_base;
+	void __iomem *va_dbi_base;
+	char int_type[10];
+	u32 requested_msi;
+	u32 configured_msi;
+	u32 bar0_size;
+	u32 bar0_rw_offset;
+	u32 va_bar0_address;
+};
+
+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 spear_pcie_gadget_config *config,
+		int where, int size, u32 *val)
+{
+	struct pcie_app_reg *app_reg
+		= (struct pcie_app_reg *) config->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)config->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 spear_pcie_gadget_config *config,
+		int where, int size, u32 val)
+{
+	struct pcie_app_reg *app_reg
+		= (struct pcie_app_reg *) config->va_app_base;
+	u32 va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (u32)config->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);
+}
+
+#define PCI_FIND_CAP_TTL	48
+
+static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
+		u32 pos, int cap, int *ttl)
+{
+	u32 id;
+
+	while ((*ttl)--) {
+		spear_dbi_read_reg(config, pos, 1, &pos);
+		if (pos < 0x40)
+			break;
+		pos &= ~3;
+		spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos += PCI_CAP_LIST_NEXT;
+	}
+	return 0;
+}
+
+static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
+			u32 pos, int cap)
+{
+	int ttl = PCI_FIND_CAP_TTL;
+
+	return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
+}
+
+static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
+				u8 hdr_type)
+{
+	u32 status;
+
+	spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
+	if (!(status & PCI_STATUS_CAP_LIST))
+		return 0;
+
+	switch (hdr_type) {
+	case PCI_HEADER_TYPE_NORMAL:
+	case PCI_HEADER_TYPE_BRIDGE:
+		return PCI_CAPABILITY_LIST;
+	case PCI_HEADER_TYPE_CARDBUS:
+		return PCI_CB_CAPABILITY_LIST;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+/**
+ * Tell if a device supports a given PCI capability.
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it. Possible values for @cap:
+ *
+ * %PCI_CAP_ID_PM	Power Management
+ * %PCI_CAP_ID_AGP	Accelerated Graphics Port
+ * %PCI_CAP_ID_VPD	Vital Product Data
+ * %PCI_CAP_ID_SLOTID	Slot Identification
+ * %PCI_CAP_ID_MSI	Message Signalled Interrupts
+ * %PCI_CAP_ID_CHSWP	CompactPCI HotSwap
+ * %PCI_CAP_ID_PCIX	PCI-X
+ * %PCI_CAP_ID_EXP	PCI Express
+ */
+static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
+		int cap)
+{
+	u32 pos;
+	u32 hdr_type;
+
+	spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
+
+	pos = pci_find_own_cap_start(config, hdr_type);
+	if (pos)
+		pos = pci_find_own_next_cap(config, pos, cap);
+
+	return pos;
+}
+
+static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
+{
+	return 0;
+}
+
+static ssize_t pcie_gadget_show_link(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
+		return sprintf(buf, "UP");
+	else
+		return sprintf(buf, "DOWN");
+}
+
+static ssize_t pcie_gadget_store_link(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	char link[10];
+
+	if (sscanf(buf, "%s", link) != 1)
+		return -EINVAL;
+
+	if (!strcmp(link, "UP"))
+		writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
+			&app_reg->app_ctrl_0);
+	else
+		writel(readl(&app_reg->app_ctrl_0)
+				& ~(1 << APP_LTSSM_ENABLE_ID),
+				&app_reg->app_ctrl_0);
+	return count;
+}
+
+static DEVICE_ATTR(link, S_IWUSR | S_IRUGO, pcie_gadget_show_link,
+		pcie_gadget_store_link);
+
+static ssize_t pcie_gadget_show_int_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s", config->int_type);
+}
+
+static ssize_t pcie_gadget_store_int_type(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	char int_type[10];
+	u32 cap, vector, vec, flags;
+
+	if (sscanf(buf, "%s", int_type) != 1)
+		return -EINVAL;
+
+	if (!strcmp(int_type, "INTA"))
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+
+	else if (!strcmp(int_type, "MSI")) {
+		vector = config->requested_msi;
+		vec = 0;
+		while (vector > 1) {
+			vector /= 2;
+			vec++;
+		}
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QMASK;
+		flags |= vec << 1;
+		spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
+	}
+
+	strcpy(config->int_type, int_type);
+
+	return count;
+}
+
+static DEVICE_ATTR(int_type, S_IWUSR | S_IRUGO, pcie_gadget_show_int_type,
+		pcie_gadget_store_int_type);
+
+static ssize_t pcie_gadget_show_no_of_msi(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	u32 cap, vector, vec, flags;
+
+	if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
+			!= (1 << CFG_MSI_EN_ID))
+		vector = 0;
+	else {
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QSIZE;
+		vec = flags >> 4;
+		vector = 1;
+		while (vec--)
+			vector *= 2;
+	}
+	config->configured_msi = vector;
+
+	return sprintf(buf, "%u", vector);
+}
+
+static ssize_t pcie_gadget_store_no_of_msi(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &config->requested_msi) != 1)
+		return -EINVAL;
+	if (config->requested_msi > 32)
+		config->requested_msi = 32;
+
+	return count;
+}
+
+static DEVICE_ATTR(no_of_msi, S_IWUSR | S_IRUGO, pcie_gadget_show_no_of_msi,
+		pcie_gadget_store_no_of_msi);
+
+static ssize_t pcie_gadget_store_inta(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	int en;
+
+	if (sscanf(buf, "%d", &en) != 1)
+		return -EINVAL;
+
+	if (en)
+		writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+	else
+		writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+
+	return count;
+}
+
+static DEVICE_ATTR(inta, S_IWUSR, NULL, pcie_gadget_store_inta);
+
+static ssize_t pcie_gadget_store_send_msi(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	int vector;
+	u32 ven_msi;
+
+	if (sscanf(buf, "%d", &vector) != 1)
+		return -EINVAL;
+
+	if (!config->configured_msi)
+		return -EINVAL;
+
+	if (vector >= config->configured_msi)
+		return -EINVAL;
+
+	ven_msi = readl(&app_reg->ven_msi_1);
+	ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
+	ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
+	ven_msi &= ~VEN_MSI_TC_MASK;
+	ven_msi |= 0 << VEN_MSI_TC_ID;
+	ven_msi &= ~VEN_MSI_VECTOR_MASK;
+	ven_msi |= vector << VEN_MSI_VECTOR_ID;
+
+	/*generating interrupt for msi vector*/
+	ven_msi |= VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+	/*need to wait till this bit is cleared, it is not cleared
+	 * autometically[Bug RTL] TBD*/
+	udelay(1);
+	ven_msi &= ~VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+
+	return count;
+}
+
+static DEVICE_ATTR(send_msi, S_IWUSR, NULL, pcie_gadget_store_send_msi);
+
+static ssize_t pcie_gadget_show_vendor_id(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_vendor_id(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	if (sscanf(buf, "%x", &id) != 1)
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
+
+	return count;
+}
+
+static DEVICE_ATTR(vendor_id, S_IWUSR | S_IRUGO, pcie_gadget_show_vendor_id,
+		pcie_gadget_store_vendor_id);
+
+static ssize_t pcie_gadget_show_device_id(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_device_id(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 id;
+
+	if (sscanf(buf, "%x", &id) != 1)
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
+
+	return count;
+}
+
+static DEVICE_ATTR(device_id, S_IWUSR | S_IRUGO, pcie_gadget_show_device_id,
+		pcie_gadget_store_device_id);
+
+static ssize_t pcie_gadget_show_bar0_size(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%x", config->bar0_size);
+}
+
+static ssize_t pcie_gadget_store_bar0_size(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 size, pos, pos1;
+	u32 no_of_bit = 0;
+
+	if (sscanf(buf, "%x", &size) != 1)
+		return -EINVAL;
+	/* as per PCIE specs, min bar size supported is 128 bytes. But
+	 * our controller supports min as 256*/
+	if (size <= 0x100)
+		size = 0x100;
+	/* max bar size is 1MB*/
+	else if (size >= 0x100000)
+		size = 0x100000;
+	else {
+		pos = 0;
+		pos1 = 0;
+		while (pos < 21) {
+			pos = find_next_bit((unsigned long *)&size, 21, pos);
+			if (pos != 21)
+				pos1 = pos + 1;
+			pos++;
+			no_of_bit++;
+		}
+		if (no_of_bit == 2)
+			pos1--;
+
+		size = 1 << pos1;
+	}
+	config->bar0_size = size;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_size, S_IWUSR | S_IRUGO, pcie_gadget_show_bar0_size,
+		pcie_gadget_store_bar0_size);
+
+static ssize_t pcie_gadget_show_bar0_address(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	u32 address = readl(&app_reg->pim0_mem_addr_start);
+
+	return sprintf(buf, "%x", address);
+}
+
+static ssize_t pcie_gadget_store_bar0_address(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+	u32 address;
+
+	if (sscanf(buf, "%x", &address) != 1)
+		return -EINVAL;
+
+	address &= ~(config->bar0_size - 1);
+	if (config->va_bar0_address)
+		iounmap((void *)config->va_bar0_address);
+	config->va_bar0_address = (u32)ioremap(address, config->bar0_size);
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(address, &app_reg->pim0_mem_addr_start);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_address, S_IWUSR | S_IRUGO,
+		pcie_gadget_show_bar0_address, pcie_gadget_store_bar0_address);
+
+static ssize_t pcie_gadget_show_bar0_rw_offset(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%x", config->bar0_rw_offset);
+}
+
+static ssize_t pcie_gadget_store_bar0_rw_offset(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 offset;
+
+	if (sscanf(buf, "%x", &offset) != 1)
+		return -EINVAL;
+
+	if (offset % 4)
+		return -EINVAL;
+
+	config->bar0_rw_offset = offset;
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_rw_offset, S_IWUSR | S_IRUGO,
+	pcie_gadget_show_bar0_rw_offset, pcie_gadget_store_bar0_rw_offset);
+
+static ssize_t pcie_gadget_show_bar0_data(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 data;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	data = readl(config->va_bar0_address + config->bar0_rw_offset);
+
+	return sprintf(buf, "%x", data);
+}
+
+static ssize_t pcie_gadget_store_bar0_data(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct spear_pcie_gadget_config *config = dev_get_drvdata(dev);
+	u32 data;
+
+	if (sscanf(buf, "%x", &data) != 1)
+		return -EINVAL;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(data, config->va_bar0_address + config->bar0_rw_offset);
+
+	return count;
+}
+
+static DEVICE_ATTR(bar0_data, S_IWUSR | S_IRUGO,
+		pcie_gadget_show_bar0_data, pcie_gadget_store_bar0_data);
+
+static ssize_t pcie_gadget_show_help(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	char text[] = "\t\tlink read->ltssm status\n \
+		link write->arg1 = UP to enable ltsmm DOWN to disable\n \
+		int_type read->type of supported interrupt\n \
+		int_type write->arg1 = interrupt type to be configured and\n \
+		can be INTA, MSI or NO_INT\n \
+		(select MSI only when you have programmed no_of_msi)\n \
+		no_of_msi read->zero if MSI is not enabled by host\n \
+		and positive value is the number of MSI vector granted\n \
+		no_of_msi write->arg1 = number of MSI vector needed\n \
+		inta write->arg1 = 1 to assert INTA and 0 to de-assert\n \
+		send_msi write->arg1 = MSI vector to be send\n \
+		vendor_id read->programmed vendor id (hex)\n\
+		vendor_id write->arg1 = vendor id(hex) to be programmed\n \
+		device_id read->programmed device id(hex)\n \
+		device_id write->arg1 = device id(hex) to be programmed\n \
+		bar0_size read->size of bar0 in hex\n \
+		bar0_size write->arg1= size of bar0 in hex\n \
+		(default bar0 size is 1000 (hex) bytes)\n \
+		bar0_address read->address of bar0 mapped area in hex\n \
+		bar0_address write->arg1 = address of bar0 mapped area in hex\n\
+		(default mapping of bar0 is SYSRAM1(E0800000)\n \
+		(always program bar size before bar address)\n \
+		(kernel might modify bar size and address to align)\n \
+		(read back bar size and address after writing to check)\n \
+		bar0_rw_offset read->offset of bar0 for which bar0_data \n \
+		will return value\n \
+		bar0_rw_offset write->arg1 = offset of bar0 for which\n \
+		bar0_data will write value\n \
+		bar0_data read->data at bar0_rw_offset\n \
+		bar0_data write->arg1 = data to be written at\n \
+		bar0_rw_offset\n";
+
+	int size = (sizeof(text) < PAGE_SIZE) ? sizeof(text) : PAGE_SIZE;
+
+	return snprintf(buf, size, "%s", text);
+}
+
+static DEVICE_ATTR(help, S_IRUGO, pcie_gadget_show_help, NULL);
+
+static struct attribute *pcie_gadget_attributes[] = {
+	&dev_attr_link.attr,
+	&dev_attr_int_type.attr,
+	&dev_attr_no_of_msi.attr,
+	&dev_attr_inta.attr,
+	&dev_attr_send_msi.attr,
+	&dev_attr_vendor_id.attr,
+	&dev_attr_device_id.attr,
+	&dev_attr_bar0_size.attr,
+	&dev_attr_bar0_address.attr,
+	&dev_attr_bar0_rw_offset.attr,
+	&dev_attr_bar0_data.attr,
+	&dev_attr_help.attr,
+	NULL
+};
+
+static const struct attribute_group pcie_gadget_attr_group = {
+	.attrs = pcie_gadget_attributes,
+};
+
+static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
+{
+	struct pcie_app_reg *app_reg =
+		(struct pcie_app_reg *)config->va_app_base;
+
+	/*setup registers for outbound translation */
+
+	writel(config->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 */
+
+	/* Keep AORAM mapped at BAR0 as default */
+	config->bar0_size = INBOUND_ADDR_MASK + 1;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
+	spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
+	config->va_bar0_address = (u32)ioremap(SPEAR13XX_SYSRAM1_BASE,
+			config->bar0_size);
+
+	writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
+	writel(0, &app_reg->pim1_mem_addr_start);
+	writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
+
+	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_EP | (1 << MISCTRL_EN_ID)
+			| ((u32)1 << REG_TRANSLATION_ENABLE),
+			&app_reg->app_ctrl_0);
+	/* disable all rx interrupts */
+	writel(0, &app_reg->int_mask);
+
+	/* Select INTA as default*/
+	spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+}
+
+static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	struct spear_pcie_gadget_config *config;
+	unsigned int status = 0;
+	int irq;
+	struct clk *clk;
+
+	/* get resource for application registers*/
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		return -EBUSY;
+	}
+	if (!request_mem_region(res0->start, resource_size(res0),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		return -EBUSY;
+	}
+	/* get resource for dbi registers*/
+
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res1) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		goto err_rel_res0;
+	}
+	if (!request_mem_region(res1->start, resource_size(res1),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		goto err_rel_res0;
+	}
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(&pdev->dev, "out of memory\n");
+		status = -ENOMEM;
+		goto err_rel_res;
+	}
+
+	config->va_app_base = ioremap(res0->start, resource_size(res0));
+	if (!config->va_app_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	config->base = (void *)res1->start;
+
+	config->va_dbi_base = ioremap(res1->start, resource_size(res1));
+	if (!config->va_dbi_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_iounmap_app;
+	}
+
+	dev_set_drvdata(&pdev->dev, config);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no update irq?\n");
+		status = irq;
+		goto err_iounmap;
+	}
+
+	status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
+	if (status) {
+		dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
+				claimed\n", irq);
+		goto err_get_irq;
+	}
+	/* Register sysfs hooks */
+	status = sysfs_create_group(&pdev->dev.kobj, &pcie_gadget_attr_group);
+	if (status)
+		goto err_irq;
+
+	/* init basic pcie application registers*/
+	/* 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 (pdev->id == 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 (!clk) {
+			pr_err("%s:couldn't get clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+	} else if (pdev->id == 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 (!clk) {
+			pr_err("%s:couldn't get clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+	}
+	spear13xx_pcie_device_init(config);
+
+	return 0;
+err_irq:
+	free_irq(irq, NULL);
+err_get_irq:
+	dev_set_drvdata(&pdev->dev, NULL);
+err_iounmap:
+	iounmap(config->va_dbi_base);
+err_iounmap_app:
+	iounmap(config->va_app_base);
+err_kzalloc:
+	kfree(config);
+err_rel_res:
+	release_mem_region(res1->start, resource_size(res1));
+err_rel_res0:
+	release_mem_region(res0->start, resource_size(res0));
+	return status;
+}
+
+static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	struct spear_pcie_gadget_config *config;
+	int irq;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	irq = platform_get_irq(pdev, 0);
+	config = dev_get_drvdata(&pdev->dev);
+
+	free_irq(irq, NULL);
+	dev_set_drvdata(&pdev->dev, NULL);
+	iounmap(config->va_dbi_base);
+	iounmap(config->va_app_base);
+	kfree(config);
+	release_mem_region(res1->start, resource_size(res1));
+	release_mem_region(res0->start, resource_size(res0));
+	sysfs_remove_group(&pdev->dev.kobj, &pcie_gadget_attr_group);
+
+	return 0;
+}
+
+static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
+{
+}
+
+static struct platform_driver spear_pcie_gadget_driver = {
+	.probe = spear_pcie_gadget_probe,
+	.remove = spear_pcie_gadget_remove,
+	.shutdown = spear_pcie_gadget_shutdown,
+	.driver = {
+		.name = "pcie-gadget-spear",
+		.bus = &platform_bus_type
+	},
+};
+
+static int __init spear_pcie_gadget_init(void)
+{
+	return platform_driver_register(&spear_pcie_gadget_driver);
+}
+module_init(spear_pcie_gadget_init);
+
+static void __exit spear_pcie_gadget_exit(void)
+{
+	platform_driver_unregister(&spear_pcie_gadget_driver);
+}
+module_exit(spear_pcie_gadget_exit);
+
+MODULE_ALIAS("pcie-gadget-spear");
+MODULE_AUTHOR("Pratyush Anand");
+MODULE_LICENSE("GPL");
-- 
1.7.2.2

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-08-30 12:14     ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-08-30 12:14 UTC (permalink / raw)
  To: Viresh KUMAR
  Cc: pratyush.anand, vipulkumar.samar, bhupesh.sharma,
	armando.visconti, Vipin Kumar, shiraz.hashim, rajeev-dlh.kumar,
	linux-mtd, deepak.sikri, dwmw2, linux-arm-kernel

On Mon, 2010-08-30 at 16:13 +0530, Viresh KUMAR wrote:
> From: Vipin Kumar <vipin.kumar@st.com>
> 
> For a page size of 4096, the number of oob bytes are 128 per page. This demands
> for an increased ecc_pos array as well as ecc can be placed at more than 64
> locations.
> 
> This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
> for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
> byte page.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Nack, breaking ABI Is not allowed in Linux.

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-08-30 12:14     ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-08-30 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-08-30 at 16:13 +0530, Viresh KUMAR wrote:
> From: Vipin Kumar <vipin.kumar@st.com>
> 
> For a page size of 4096, the number of oob bytes are 128 per page. This demands
> for an increased ecc_pos array as well as ecc can be placed at more than 64
> locations.
> 
> This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
> for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
> byte page.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Nack, breaking ABI Is not allowed in Linux.

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* [PATCH 17/74] ST SPEAr: Adding USB Host support
  2010-08-30 10:42 ` [PATCH 17/74] ST SPEAr: Adding USB Host support Viresh KUMAR
@ 2010-08-30 14:10   ` Alan Stern
  2010-09-01  3:55     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Alan Stern @ 2010-08-30 14:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 30 Aug 2010, Viresh KUMAR wrote:

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

Missing patch description.

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


> --- /dev/null
> +++ b/drivers/usb/host/ehci-spear.c
> @@ -0,0 +1,210 @@

...

> +static const struct hc_driver ehci_spear_hc_driver = {
> +	.description		= hcd_name,
> +	.product_desc		= "SPEAr EHCI",
> +	.hcd_priv_size		= sizeof(struct spear_ehci),
> +
> +	/* generic hardware linkage */
> +	.irq			= ehci_irq,
> +	.flags			= HCD_MEMORY | HCD_USB2,
> +
> +	/* basic lifecycle operations */
> +	.reset			= ehci_spear_setup,
> +	.start			= ehci_run,
> +	.stop			= ehci_stop,
> +	.shutdown		= ehci_shutdown,
> +
> +	/* managing i/o requests and associated device resources */
> +	.urb_enqueue		= ehci_urb_enqueue,
> +	.urb_dequeue		= ehci_urb_dequeue,
> +	.endpoint_disable	= ehci_endpoint_disable,
> +

Missing .endpoint_reset.

Alan Stern

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

* Re: [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-08-30 16:48     ` Dmitry Torokhov
  -1 siblings, 0 replies; 245+ messages in thread
From: Dmitry Torokhov @ 2010-08-30 16:48 UTC (permalink / raw)
  To: Viresh KUMAR
  Cc: linux-arm-kernel, linux-input, Rajeev Kumar, shiraz.hashim,
	vipin.kumar, deepak.sikri, armando.visconti, vipulkumar.samar,
	pratyush.anand, bhupesh.sharma

Hi Rajeev,

On Mon, Aug 30, 2010 at 04:13:01PM +0530, Viresh KUMAR wrote:
> From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
>  arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
>  arch/arm/mach-spear13xx/spear1300_evb.c        |   14 +
>  arch/arm/mach-spear13xx/spear13xx.c            |   19 ++
>  arch/arm/mach-spear3xx/clock.c                 |   12 +
>  arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
>  arch/arm/mach-spear3xx/spear300.c              |   19 ++
>  arch/arm/mach-spear3xx/spear300_evb.c          |   14 +
>  arch/arm/plat-spear/include/plat/keyboard.h    |  154 +++++++++++
>  drivers/input/keyboard/Kconfig                 |    8 +
>  drivers/input/keyboard/Makefile                |    1 +
>  drivers/input/keyboard/spear-keyboard.c        |  335 ++++++++++++++++++++++++
>  12 files changed, 579 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/plat-spear/include/plat/keyboard.h
>  create mode 100644 drivers/input/keyboard/spear-keyboard.c
> 

First of all, please split platform modifications from the driver itself
(as I care about the latter but less about the former).

> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> index 9252940..c48b779 100644
> --- a/arch/arm/mach-spear13xx/clock.c
> +++ b/arch/arm/mach-spear13xx/clock.c
> @@ -801,7 +801,7 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{.dev_id = "ssp",		.clk = &ssp_clk},
>  	{.dev_id = "gpio0",		.clk = &gpio0_clk},
>  	{.dev_id = "gpio1",		.clk = &gpio1_clk},
> -	{.dev_id = "kbd",		.clk = &kbd_clk},
> +	{.dev_id = "keyboard",		.clk = &kbd_clk},
>  	{.dev_id = "wdt",		.clk = &wdt_clk},
>  };
>  
> diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
> index 7e5d7e1..19c5de0 100644
> --- a/arch/arm/mach-spear13xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear13xx/include/mach/generic.h
> @@ -33,6 +33,7 @@ extern struct amba_device uart_device;
>  extern struct platform_device ehci0_device;
>  extern struct platform_device ehci1_device;
>  extern struct platform_device i2c_device;
> +extern struct platform_device kbd_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-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> index 0a6d26f..0cdad7a 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/spear.h>
> +#include <plat/keyboard.h>
>  
>  static struct amba_device *amba_devs[] __initdata = {
>  	&uart_device,
> @@ -25,15 +26,28 @@ static struct platform_device *plat_devs[] __initdata = {
>  	&ehci0_device,
>  	&ehci1_device,
>  	&i2c_device,
> +	&kbd_device,
>  	&ohci0_device,
>  	&ohci1_device,
>  	&rtc_device,
>  };
>  
> +/* keyboard specific platform data */
> +static DECLARE_KEYMAP(spear_keymap);
> +
> +static struct kbd_platform_data kbd_data = {
> +	.keymap = spear_keymap,
> +	.keymapsize = ARRAY_SIZE(spear_keymap),
> +	.rep = 1,
> +};
> +
>  static void __init spear1300_evb_init(void)
>  {
>  	unsigned int i;
>  
> +	/* set keyboard plat data */
> +	kbd_set_plat_data(&kbd_device, &kbd_data);
> +
>  	/* call spear1300 machine init function */
>  	spear1300_init();
>  
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
> index c8f1aff..342fcd9 100644
> --- a/arch/arm/mach-spear13xx/spear13xx.c
> +++ b/arch/arm/mach-spear13xx/spear13xx.c
> @@ -166,6 +166,25 @@ struct platform_device 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 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/clock.c b/arch/arm/mach-spear3xx/clock.c
> index 79f0159..3a26622 100644
> --- a/arch/arm/mach-spear3xx/clock.c
> +++ b/arch/arm/mach-spear3xx/clock.c
> @@ -470,6 +470,15 @@ static struct clk i2c1_clk = {
>  };
>  #endif
>  
> +#ifdef CONFIG_MACH_SPEAR300
> +/* keyboard clock */
> +static struct clk kbd_clk = {
> +	.flags = ALWAYS_ENABLED,
> +	.pclk = &apb_clk,
> +	.recalc = &follow_parent,
> +};
> +#endif
> +
>  /* array of all spear 3xx clock lookups */
>  static struct clk_lookup spear_clk_lookups[] = {
>  	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
> @@ -511,6 +520,9 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{ .dev_id = "adc",		.clk = &adc_clk},
>  	{ .dev_id = "ssp",		.clk = &ssp_clk},
>  	{ .dev_id = "gpio",		.clk = &gpio_clk},
> +#ifdef CONFIG_MACH_SPEAR300
> +	{ .dev_id = "keyboard",		.clk = &kbd_clk},
> +#endif
>  #ifdef CONFIG_MACH_SPEAR320
>  	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
>  #endif
> diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
> index 3eb2737..70f7ee2 100644
> --- a/arch/arm/mach-spear3xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear3xx/include/mach/generic.h
> @@ -108,6 +108,7 @@ extern struct pmx_driver pmx_driver;
>  /* Add spear300 machine device structure declarations here */
>  extern struct amba_device clcd_device;
>  extern struct amba_device gpio1_device;
> +extern struct platform_device kbd_device;
>  
>  /* pad mux modes */
>  extern struct pmx_mode nand_mode;
> diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
> index 5d8df00..fa314e9 100644
> --- a/arch/arm/mach-spear3xx/spear300.c
> +++ b/arch/arm/mach-spear3xx/spear300.c
> @@ -407,6 +407,25 @@ struct amba_device gpio1_device = {
>  	.irq = {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 = VIRQ_KEYBOARD,
> +		.flags = IORESOURCE_IRQ,
> +	},
> +};
> +
> +struct platform_device kbd_device = {
> +	.name = "keyboard",
> +	.id = -1,
> +	.num_resources = ARRAY_SIZE(kbd_resources),
> +	.resource = kbd_resources,
> +};
> +
>  /* spear3xx shared irq */
>  struct shirq_dev_config shirq_ras1_config[] = {
>  	{
> diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
> index 3b3c6ce..afb773e 100644
> --- a/arch/arm/mach-spear3xx/spear300_evb.c
> +++ b/arch/arm/mach-spear3xx/spear300_evb.c
> @@ -15,6 +15,7 @@
>  #include <asm/mach-types.h>
>  #include <mach/generic.h>
>  #include <mach/spear.h>
> +#include <plat/keyboard.h>
>  
>  /* padmux devices to enable */
>  static struct pmx_dev *pmx_devs[] = {
> @@ -51,6 +52,16 @@ static struct platform_device *plat_devs[] __initdata = {
>  	&rtc_device,
>  
>  	/* spear300 specific devices */
> +	&kbd_device,
> +};
> +
> +/* keyboard specific platform data */
> +static DECLARE_KEYMAP(spear_keymap);
> +
> +static struct kbd_platform_data kbd_data = {
> +	.keymap = spear_keymap,
> +	.keymapsize = ARRAY_SIZE(spear_keymap),
> +	.rep = 1,
>  };
>  
>  static void __init spear300_evb_init(void)
> @@ -62,6 +73,9 @@ static void __init spear300_evb_init(void)
>  	pmx_driver.devs = pmx_devs;
>  	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
>  
> +	/* set keyboard plat data */
> +	kbd_set_plat_data(&kbd_device, &kbd_data);
> +
>  	/* call spear300 machine init function */
>  	spear300_init();
>  
> diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
> new file mode 100644
> index 0000000..8345770
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
> @@ -0,0 +1,154 @@
> +/*
> + * arch/arm/plat-spear/include/plat/keyboard.h
> + *
> + * 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.
> + */
> +
> +#ifndef __PLAT_KEYBOARD_H
> +#define __PLAT_KEYBOARD_H
> +
> +#include <linux/bitops.h>
> +#include <linux/input.h>
> +#include <mach/misc_regs.h>
> +
> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
> +

Please use definitions from include/linux/input/matrix_keypad.h

> +#define DECLARE_KEYMAP(name) \
> +int name[] = {\
> +	KEY(0, 0, KEY_ESC), \
> +	KEY(0, 1, KEY_1), \
> +	KEY(0, 2, KEY_2), \
> +	KEY(0, 3, KEY_3), \
> +	KEY(0, 4, KEY_4), \
> +	KEY(0, 5, KEY_5), \
> +	KEY(0, 6, KEY_6), \
> +	KEY(0, 7, KEY_7), \
> +	KEY(0, 8, KEY_8), \
> +	KEY(1, 0, KEY_9), \
> +	KEY(1, 1, KEY_MINUS), \
> +	KEY(1, 2, KEY_EQUAL), \
> +	KEY(1, 3, KEY_BACKSPACE), \
> +	KEY(1, 4, KEY_TAB), \
> +	KEY(1, 5, KEY_Q), \
> +	KEY(1, 6, KEY_W), \
> +	KEY(1, 7, KEY_E), \
> +	KEY(1, 8, KEY_R), \
> +	KEY(2, 0, KEY_T), \
> +	KEY(2, 1, KEY_Y), \
> +	KEY(2, 2, KEY_U), \
> +	KEY(2, 3, KEY_I), \
> +	KEY(2, 4, KEY_O), \
> +	KEY(2, 5, KEY_P), \
> +	KEY(2, 6, KEY_LEFTBRACE), \
> +	KEY(2, 7, KEY_RIGHTBRACE), \
> +	KEY(2, 8, KEY_ENTER), \
> +	KEY(3, 0, KEY_LEFTCTRL), \
> +	KEY(3, 1, KEY_A), \
> +	KEY(3, 2, KEY_S), \
> +	KEY(3, 3, KEY_D), \
> +	KEY(3, 4, KEY_F), \
> +	KEY(3, 5, KEY_G), \
> +	KEY(3, 6, KEY_H), \
> +	KEY(3, 7, KEY_J), \
> +	KEY(3, 8, KEY_K), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(5, 0, KEY_V), \
> +	KEY(5, 1, KEY_B), \
> +	KEY(5, 2, KEY_N), \
> +	KEY(5, 3, KEY_M), \
> +	KEY(5, 4, KEY_COMMA), \
> +	KEY(5, 5, KEY_DOT), \
> +	KEY(5, 6, KEY_SLASH), \
> +	KEY(5, 7, KEY_RIGHTSHIFT), \
> +	KEY(5, 8, KEY_KPASTERISK), \
> +	KEY(6, 0, KEY_LEFTALT), \
> +	KEY(6, 1, KEY_SPACE), \
> +	KEY(6, 2, KEY_CAPSLOCK), \
> +	KEY(6, 3, KEY_F1), \
> +	KEY(6, 4, KEY_F2), \
> +	KEY(6, 5, KEY_F3), \
> +	KEY(6, 6, KEY_F4), \
> +	KEY(6, 7, KEY_F5), \
> +	KEY(6, 8, KEY_F6), \
> +	KEY(7, 0, KEY_F7), \
> +	KEY(7, 1, KEY_F8), \
> +	KEY(7, 2, KEY_F9), \
> +	KEY(7, 3, KEY_F10), \
> +	KEY(7, 4, KEY_NUMLOCK), \
> +	KEY(7, 5, KEY_SCROLLLOCK), \
> +	KEY(7, 6, KEY_KP7), \
> +	KEY(7, 7, KEY_KP8), \
> +	KEY(7, 8, KEY_KP9), \
> +	KEY(8, 0, KEY_KPMINUS), \
> +	KEY(8, 1, KEY_KP4), \
> +	KEY(8, 2, KEY_KP5), \
> +	KEY(8, 3, KEY_KP6), \
> +	KEY(8, 4, KEY_KPPLUS), \
> +	KEY(8, 5, KEY_KP1), \
> +	KEY(8, 6, KEY_KP2), \
> +	KEY(8, 7, KEY_KP3), \
> +	KEY(8, 8, KEY_KP0), \
> +};

Hm, I'd expect this to be in particular board code, not in the header
file.

> +/**
> + * struct kbd_platform_data - keymap for spear keyboards
> + * keymap: pointer to array of values encoded with KEY() macro representing
> + * keymap
> + * keymapsize: number of entries (initialized) in this keymap
> + * rep: current values for autorepeat parameters
> + *
> + * This structure is supposed to be used by platform code to supply
> + * keymaps to drivers that implement keyboards.
> + */
> +struct kbd_platform_data {
> +	int *keymap;
> +	unsigned int keymapsize;
> +	unsigned int rep:1;

Bool please.

> +};
> +
> +/* 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)
> +{
> +#ifdef CONFIG_ARCH_SPEAR13XX
> +#define KBD_PAD_SEL	(BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
> +
> +	u32 val;
> +	/* Workaround:Setting bit for routing it to the IP */
> +	val = readl(PAD_FUNCTION_EN_2);
> +	val &= ~KBD_PAD_SEL;
> +	writel(val, PAD_FUNCTION_EN_2);

Why does it belong here?

> +#endif
> +	pdev->dev.platform_data = data;
> +}
> +#endif /* __PLAT_KEYBOARD_H */
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 9cc488d..2d7e3a8 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called omap-keypad.
>  
> +config KEYBOARD_SPEAR
> +	tristate "ST SPEAR keyboard support"

No arch/platform dependencies?

> +	help
> +	  Say Y here if you want to use the SPEAR keyboard.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called spear-keboard.
> +
>  config KEYBOARD_TWL4030
>  	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
>  	depends on TWL4030_CORE
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 504b591..b21c54d 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
>  obj-$(CONFIG_KEYBOARD_QT2160)		+= qt2160.o
>  obj-$(CONFIG_KEYBOARD_SAMSUNG)		+= samsung-keypad.o
>  obj-$(CONFIG_KEYBOARD_SH_KEYSC)		+= sh_keysc.o
> +obj-$(CONFIG_KEYBOARD_SPEAR)		+= spear-keyboard.o
>  obj-$(CONFIG_KEYBOARD_STMPE)		+= stmpe-keypad.o
>  obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
>  obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
> diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
> new file mode 100644
> index 0000000..4f5c734
> --- /dev/null
> +++ b/drivers/input/keyboard/spear-keyboard.c
> @@ -0,0 +1,335 @@
> +/*
> + * drivers/input/keyboard/keyboard-spear.c
> + *
> + * SPEAr Keyboard Driver
> + * Based on omap-keypad driver
> + *
> + * 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/clk.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_wakeup.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +#include <plat/keyboard.h>
> +
> +/* Keyboard Regsiters */
> +#define MODE_REG	0x00	/* 16 bit reg */
> +#define STATUS_REG	0x0C	/* 2 bit reg */
> +#define DATA_REG	0x10	/* 8 bit reg */
> +#define INTR_MASK	0x54
> +
> +/* Register Values */
> +/*
> + * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
> + * control register as 1010010(82MHZ)
> + */
> +#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
> +#define START_SCAN	0x0100
> +#define SCAN_RATE_10	0x0000
> +#define SCAN_RATE_20	0x0004
> +#define SCAN_RATE_40	0x0008
> +#define SCAN_RATE_80	0x000C
> +#define MODE_KEYBOARD	0x0002
> +#define DATA_AVAIL	0x2
> +
> +#define KEY_MASK	0xFF000000
> +#define KEY_VALUE	0x00FFFFFF
> +#define ROW_MASK	0xF0
> +#define COLUMN_MASK	0x0F
> +#define ROW_SHIFT	4
> +
> +struct spear_kbd {
> +	struct input_dev *input;
> +	void __iomem *io_base;		/* Keyboard Base Address */
> +	struct clk *clk;
> +	int *keymap;

You need a copy of keymap here so that userspace can modify it safely
via EVIOCSKEYCODE.

> +};
> +/* TODO: Need to optimize this function */
> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
> +{
> +	int i, key;
> +	int *keymap = dev->keymap;
> +
> +	key = KEY(row, col, 0);
> +	for (i = 0; keymap[i] != 0; i++)
> +		if ((keymap[i] & KEY_MASK) == key)
> +			return keymap[i] & KEY_VALUE;
> +	return -ENOKEY;
> +}
> +
> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
> +{
> +	struct spear_kbd *dev = dev_id;
> +	static u8 last_key ;
> +	static u8 last_event;

No statics please, pull it into spear_kbd structure.

> +	int key;
> +	u8 sts, val = 0;
> +
> +	if (dev == NULL) {

How can it be?

> +		pr_err("Keyboard: Invalid dev_id in irq handler\n");
> +		return IRQ_NONE;
> +	}
> +
> +	sts = readb(dev->io_base + STATUS_REG);
> +	if (sts & DATA_AVAIL) {
> +		/* following reads active (row, col) pair */
> +		val = readb(dev->io_base + DATA_REG);
> +		key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
> +					& COLUMN_MASK));
> +
> +		/* valid key press event */
> +		if (key >= 0) {
> +			if (last_event == 1) {
> +				/* check if we missed a release event */
> +				input_report_key(dev->input, last_key,
> +						!last_event);
> +			}
> +			/* notify key press */
> +			last_event = 1;
> +			last_key = key;
> +			input_report_key(dev->input, key, last_event);
> +		} else {
> +			/* notify key release */
> +			last_event = 0;
> +			input_report_key(dev->input, last_key, last_event);
> +		}
> +	} else

Don't you need to clear interrupt here? You got it somehow...

> +		return IRQ_NONE;
> +
> +	/* clear interrupt */
> +	writeb(0, dev->io_base + STATUS_REG);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int __init spear_kbd_probe(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd;
> +	struct kbd_platform_data *pdata = pdev->dev.platform_data;
> +	struct resource *res;
> +	int i, ret, irq;
> +	u16 val = 0;
> +
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "Invalid platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "no keyboard resource defined\n");
> +		return -EBUSY;
> +	}
> +
> +	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
> +		dev_err(&pdev->dev, "keyboard region already claimed\n");
> +		return -EBUSY;
> +	}
> +
> +	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
> +	if (!kbd) {
> +		dev_err(&pdev->dev, "out of memory\n");
> +		ret = -ENOMEM;
> +		goto err_release_mem_region;
> +	}
> +
> +	kbd->clk = clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(kbd->clk)) {
> +		ret = PTR_ERR(kbd->clk);
> +		goto err_kfree;
> +	}
> +
> +	ret = clk_enable(kbd->clk);
> +	if (ret < 0)
> +		goto err_clk_put;
> +
> +	platform_set_drvdata(pdev, kbd);
> +	kbd->keymap = pdata->keymap; /* key mappings */
> +
> +	kbd->io_base = ioremap(res->start, resource_size(res));
> +	if (!kbd->io_base) {
> +		dev_err(&pdev->dev, "ioremap fail for kbd_region\n");
> +		ret = -ENOMEM;
> +		goto err_clear_plat_data;
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0) {
> +		dev_err(&pdev->dev, "not able to get irq for the device\n");
> +		ret = irq;
> +		goto err_iounmap;
> +	}
> +
> +	ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
> +			kbd);
> +	if (ret) {
> +		dev_err(&pdev->dev, "request_irq fail\n");
> +		goto err_iounmap;
> +	}
> +

Are you 100% sure the device is shut off at this point? Because if it
isn't you risk to get interrupt before you allocated your input device.

> +	kbd->input = input_allocate_device();
> +	if (!kbd->input) {
> +		ret = -ENOMEM;
> +		dev_err(&pdev->dev, "input device allocation fail\n");
> +		goto err_free_irq;
> +	}
> +
> +	if (pdata->rep)
> +		__set_bit(EV_REP, kbd->input->evbit);
> +
> +	/* setup input device */
> +	__set_bit(EV_KEY, kbd->input->evbit);
> +
> +	for (i = 0; kbd->keymap[i] != 0; i++)
> +		__set_bit(kbd->keymap[i] & KEY_MAX, kbd->input->keybit);
> +
> +	kbd->input->name = "keyboard";
> +	kbd->input->phys = "keyboard/input0";
> +	kbd->input->dev.parent = &pdev->dev;
> +	kbd->input->id.bustype = BUS_HOST;
> +	kbd->input->id.vendor = 0x0001;
> +	kbd->input->id.product = 0x0001;
> +	kbd->input->id.version = 0x0100;
> +
> +	ret = input_register_device(kbd->input);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Unable to register keyboard device\n");
> +		goto err_free_dev;
> +	}
> +
> +	/* program keyboard */
> +	val |= SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
> +	writew(val, kbd->io_base + MODE_REG);
> +
> +	writeb(1, kbd->io_base + STATUS_REG);
> +
> +	/* start key scan */
> +	val |= START_SCAN;
> +	writew(val, kbd->io_base + MODE_REG);

This should go into open() method.

> +
> +	device_init_wakeup(&pdev->dev, 1);
> +
> +	return 0;
> +
> +err_free_dev:
> +	input_free_device(kbd->input);
> +err_free_irq:
> +	free_irq(irq, pdev);
> +err_iounmap:
> +	iounmap(kbd->io_base);
> +err_clear_plat_data:
> +	platform_set_drvdata(pdev, NULL);
> +	clk_disable(kbd->clk);
> +err_clk_put:
> +	clk_put(kbd->clk);
> +err_kfree:
> +	kfree(kbd);
> +err_release_mem_region:
> +	release_mem_region(res->start, resource_size(res));
> +
> +	return ret;
> +}
> +
> +static int spear_kbd_remove(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	struct resource *res;
> +	u16 val;
> +	int irq;
> +
> +	val = readw(kbd->io_base + MODE_REG);
> +	val &= ~START_SCAN;
> +	writew(val, kbd->io_base + MODE_REG);

Need to go into close() method.

> +
> +	/* unregister input device */
> +	input_unregister_device(kbd->input);
> +	input_free_device(kbd->input);

No free after unregister.

> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq)
> +		free_irq(irq, pdev);

Can it ever be 0 here?

> +
> +	iounmap(kbd->io_base);
> +	platform_set_drvdata(pdev, NULL);
> +	clk_disable(kbd->clk);
> +	clk_put(kbd->clk);
> +	kfree(kbd);
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res)
> +		release_mem_region(res->start, resource_size(res));
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int spear_kbd_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	clk_disable(kbd->clk);
> +	if (device_may_wakeup(&pdev->dev))
> +		enable_irq_wake(irq);
> +
> +	return 0;
> +}
> +
> +static int spear_kbd_resume(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (device_may_wakeup(&pdev->dev))
> +		disable_irq_wake(irq);
> +	clk_enable(kbd->clk);
> +
> +	return 0;
> +}
> +#else
> +#define spear_kbd_suspend	NULL
> +#define spear_kbd_resume	NULL
> +#endif
> +
> +static struct platform_driver spear_kbd_driver = {
> +	.probe		= spear_kbd_probe,
> +	.remove		= spear_kbd_remove,
> +	.suspend	= spear_kbd_suspend,
> +	.resume		= spear_kbd_resume,

Switch to dev_pm_ops please.

> +	.driver		= {
> +		.name	= "keyboard",
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static int __devinit spear_kbd_init(void)
> +{
> +	return platform_driver_register(&spear_kbd_driver);
> +}
> +module_init(spear_kbd_init);
> +
> +static void __exit spear_kbd_exit(void)
> +{
> +	platform_driver_unregister(&spear_kbd_driver);
> +}
> +module_exit(spear_kbd_exit);
> +
> +MODULE_AUTHOR("Rajeev Kumar");
> +MODULE_DESCRIPTION("SPEAr Keyboard Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 1.7.2.2
> 

Thanks.

-- 
Dmitry

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-08-30 16:48     ` Dmitry Torokhov
  0 siblings, 0 replies; 245+ messages in thread
From: Dmitry Torokhov @ 2010-08-30 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rajeev,

On Mon, Aug 30, 2010 at 04:13:01PM +0530, Viresh KUMAR wrote:
> From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
>  arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
>  arch/arm/mach-spear13xx/spear1300_evb.c        |   14 +
>  arch/arm/mach-spear13xx/spear13xx.c            |   19 ++
>  arch/arm/mach-spear3xx/clock.c                 |   12 +
>  arch/arm/mach-spear3xx/include/mach/generic.h  |    1 +
>  arch/arm/mach-spear3xx/spear300.c              |   19 ++
>  arch/arm/mach-spear3xx/spear300_evb.c          |   14 +
>  arch/arm/plat-spear/include/plat/keyboard.h    |  154 +++++++++++
>  drivers/input/keyboard/Kconfig                 |    8 +
>  drivers/input/keyboard/Makefile                |    1 +
>  drivers/input/keyboard/spear-keyboard.c        |  335 ++++++++++++++++++++++++
>  12 files changed, 579 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/plat-spear/include/plat/keyboard.h
>  create mode 100644 drivers/input/keyboard/spear-keyboard.c
> 

First of all, please split platform modifications from the driver itself
(as I care about the latter but less about the former).

> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> index 9252940..c48b779 100644
> --- a/arch/arm/mach-spear13xx/clock.c
> +++ b/arch/arm/mach-spear13xx/clock.c
> @@ -801,7 +801,7 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{.dev_id = "ssp",		.clk = &ssp_clk},
>  	{.dev_id = "gpio0",		.clk = &gpio0_clk},
>  	{.dev_id = "gpio1",		.clk = &gpio1_clk},
> -	{.dev_id = "kbd",		.clk = &kbd_clk},
> +	{.dev_id = "keyboard",		.clk = &kbd_clk},
>  	{.dev_id = "wdt",		.clk = &wdt_clk},
>  };
>  
> diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
> index 7e5d7e1..19c5de0 100644
> --- a/arch/arm/mach-spear13xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear13xx/include/mach/generic.h
> @@ -33,6 +33,7 @@ extern struct amba_device uart_device;
>  extern struct platform_device ehci0_device;
>  extern struct platform_device ehci1_device;
>  extern struct platform_device i2c_device;
> +extern struct platform_device kbd_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-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> index 0a6d26f..0cdad7a 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/spear.h>
> +#include <plat/keyboard.h>
>  
>  static struct amba_device *amba_devs[] __initdata = {
>  	&uart_device,
> @@ -25,15 +26,28 @@ static struct platform_device *plat_devs[] __initdata = {
>  	&ehci0_device,
>  	&ehci1_device,
>  	&i2c_device,
> +	&kbd_device,
>  	&ohci0_device,
>  	&ohci1_device,
>  	&rtc_device,
>  };
>  
> +/* keyboard specific platform data */
> +static DECLARE_KEYMAP(spear_keymap);
> +
> +static struct kbd_platform_data kbd_data = {
> +	.keymap = spear_keymap,
> +	.keymapsize = ARRAY_SIZE(spear_keymap),
> +	.rep = 1,
> +};
> +
>  static void __init spear1300_evb_init(void)
>  {
>  	unsigned int i;
>  
> +	/* set keyboard plat data */
> +	kbd_set_plat_data(&kbd_device, &kbd_data);
> +
>  	/* call spear1300 machine init function */
>  	spear1300_init();
>  
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
> index c8f1aff..342fcd9 100644
> --- a/arch/arm/mach-spear13xx/spear13xx.c
> +++ b/arch/arm/mach-spear13xx/spear13xx.c
> @@ -166,6 +166,25 @@ struct platform_device 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 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/clock.c b/arch/arm/mach-spear3xx/clock.c
> index 79f0159..3a26622 100644
> --- a/arch/arm/mach-spear3xx/clock.c
> +++ b/arch/arm/mach-spear3xx/clock.c
> @@ -470,6 +470,15 @@ static struct clk i2c1_clk = {
>  };
>  #endif
>  
> +#ifdef CONFIG_MACH_SPEAR300
> +/* keyboard clock */
> +static struct clk kbd_clk = {
> +	.flags = ALWAYS_ENABLED,
> +	.pclk = &apb_clk,
> +	.recalc = &follow_parent,
> +};
> +#endif
> +
>  /* array of all spear 3xx clock lookups */
>  static struct clk_lookup spear_clk_lookups[] = {
>  	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
> @@ -511,6 +520,9 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{ .dev_id = "adc",		.clk = &adc_clk},
>  	{ .dev_id = "ssp",		.clk = &ssp_clk},
>  	{ .dev_id = "gpio",		.clk = &gpio_clk},
> +#ifdef CONFIG_MACH_SPEAR300
> +	{ .dev_id = "keyboard",		.clk = &kbd_clk},
> +#endif
>  #ifdef CONFIG_MACH_SPEAR320
>  	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
>  #endif
> diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
> index 3eb2737..70f7ee2 100644
> --- a/arch/arm/mach-spear3xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear3xx/include/mach/generic.h
> @@ -108,6 +108,7 @@ extern struct pmx_driver pmx_driver;
>  /* Add spear300 machine device structure declarations here */
>  extern struct amba_device clcd_device;
>  extern struct amba_device gpio1_device;
> +extern struct platform_device kbd_device;
>  
>  /* pad mux modes */
>  extern struct pmx_mode nand_mode;
> diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
> index 5d8df00..fa314e9 100644
> --- a/arch/arm/mach-spear3xx/spear300.c
> +++ b/arch/arm/mach-spear3xx/spear300.c
> @@ -407,6 +407,25 @@ struct amba_device gpio1_device = {
>  	.irq = {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 = VIRQ_KEYBOARD,
> +		.flags = IORESOURCE_IRQ,
> +	},
> +};
> +
> +struct platform_device kbd_device = {
> +	.name = "keyboard",
> +	.id = -1,
> +	.num_resources = ARRAY_SIZE(kbd_resources),
> +	.resource = kbd_resources,
> +};
> +
>  /* spear3xx shared irq */
>  struct shirq_dev_config shirq_ras1_config[] = {
>  	{
> diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
> index 3b3c6ce..afb773e 100644
> --- a/arch/arm/mach-spear3xx/spear300_evb.c
> +++ b/arch/arm/mach-spear3xx/spear300_evb.c
> @@ -15,6 +15,7 @@
>  #include <asm/mach-types.h>
>  #include <mach/generic.h>
>  #include <mach/spear.h>
> +#include <plat/keyboard.h>
>  
>  /* padmux devices to enable */
>  static struct pmx_dev *pmx_devs[] = {
> @@ -51,6 +52,16 @@ static struct platform_device *plat_devs[] __initdata = {
>  	&rtc_device,
>  
>  	/* spear300 specific devices */
> +	&kbd_device,
> +};
> +
> +/* keyboard specific platform data */
> +static DECLARE_KEYMAP(spear_keymap);
> +
> +static struct kbd_platform_data kbd_data = {
> +	.keymap = spear_keymap,
> +	.keymapsize = ARRAY_SIZE(spear_keymap),
> +	.rep = 1,
>  };
>  
>  static void __init spear300_evb_init(void)
> @@ -62,6 +73,9 @@ static void __init spear300_evb_init(void)
>  	pmx_driver.devs = pmx_devs;
>  	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
>  
> +	/* set keyboard plat data */
> +	kbd_set_plat_data(&kbd_device, &kbd_data);
> +
>  	/* call spear300 machine init function */
>  	spear300_init();
>  
> diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
> new file mode 100644
> index 0000000..8345770
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
> @@ -0,0 +1,154 @@
> +/*
> + * arch/arm/plat-spear/include/plat/keyboard.h
> + *
> + * 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.
> + */
> +
> +#ifndef __PLAT_KEYBOARD_H
> +#define __PLAT_KEYBOARD_H
> +
> +#include <linux/bitops.h>
> +#include <linux/input.h>
> +#include <mach/misc_regs.h>
> +
> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
> +

Please use definitions from include/linux/input/matrix_keypad.h

> +#define DECLARE_KEYMAP(name) \
> +int name[] = {\
> +	KEY(0, 0, KEY_ESC), \
> +	KEY(0, 1, KEY_1), \
> +	KEY(0, 2, KEY_2), \
> +	KEY(0, 3, KEY_3), \
> +	KEY(0, 4, KEY_4), \
> +	KEY(0, 5, KEY_5), \
> +	KEY(0, 6, KEY_6), \
> +	KEY(0, 7, KEY_7), \
> +	KEY(0, 8, KEY_8), \
> +	KEY(1, 0, KEY_9), \
> +	KEY(1, 1, KEY_MINUS), \
> +	KEY(1, 2, KEY_EQUAL), \
> +	KEY(1, 3, KEY_BACKSPACE), \
> +	KEY(1, 4, KEY_TAB), \
> +	KEY(1, 5, KEY_Q), \
> +	KEY(1, 6, KEY_W), \
> +	KEY(1, 7, KEY_E), \
> +	KEY(1, 8, KEY_R), \
> +	KEY(2, 0, KEY_T), \
> +	KEY(2, 1, KEY_Y), \
> +	KEY(2, 2, KEY_U), \
> +	KEY(2, 3, KEY_I), \
> +	KEY(2, 4, KEY_O), \
> +	KEY(2, 5, KEY_P), \
> +	KEY(2, 6, KEY_LEFTBRACE), \
> +	KEY(2, 7, KEY_RIGHTBRACE), \
> +	KEY(2, 8, KEY_ENTER), \
> +	KEY(3, 0, KEY_LEFTCTRL), \
> +	KEY(3, 1, KEY_A), \
> +	KEY(3, 2, KEY_S), \
> +	KEY(3, 3, KEY_D), \
> +	KEY(3, 4, KEY_F), \
> +	KEY(3, 5, KEY_G), \
> +	KEY(3, 6, KEY_H), \
> +	KEY(3, 7, KEY_J), \
> +	KEY(3, 8, KEY_K), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(4, 0, KEY_L), \
> +	KEY(4, 1, KEY_SEMICOLON), \
> +	KEY(4, 2, KEY_APOSTROPHE), \
> +	KEY(4, 3, KEY_GRAVE), \
> +	KEY(4, 4, KEY_LEFTSHIFT), \
> +	KEY(4, 5, KEY_BACKSLASH), \
> +	KEY(4, 6, KEY_Z), \
> +	KEY(4, 7, KEY_X), \
> +	KEY(4, 8, KEY_C), \
> +	KEY(5, 0, KEY_V), \
> +	KEY(5, 1, KEY_B), \
> +	KEY(5, 2, KEY_N), \
> +	KEY(5, 3, KEY_M), \
> +	KEY(5, 4, KEY_COMMA), \
> +	KEY(5, 5, KEY_DOT), \
> +	KEY(5, 6, KEY_SLASH), \
> +	KEY(5, 7, KEY_RIGHTSHIFT), \
> +	KEY(5, 8, KEY_KPASTERISK), \
> +	KEY(6, 0, KEY_LEFTALT), \
> +	KEY(6, 1, KEY_SPACE), \
> +	KEY(6, 2, KEY_CAPSLOCK), \
> +	KEY(6, 3, KEY_F1), \
> +	KEY(6, 4, KEY_F2), \
> +	KEY(6, 5, KEY_F3), \
> +	KEY(6, 6, KEY_F4), \
> +	KEY(6, 7, KEY_F5), \
> +	KEY(6, 8, KEY_F6), \
> +	KEY(7, 0, KEY_F7), \
> +	KEY(7, 1, KEY_F8), \
> +	KEY(7, 2, KEY_F9), \
> +	KEY(7, 3, KEY_F10), \
> +	KEY(7, 4, KEY_NUMLOCK), \
> +	KEY(7, 5, KEY_SCROLLLOCK), \
> +	KEY(7, 6, KEY_KP7), \
> +	KEY(7, 7, KEY_KP8), \
> +	KEY(7, 8, KEY_KP9), \
> +	KEY(8, 0, KEY_KPMINUS), \
> +	KEY(8, 1, KEY_KP4), \
> +	KEY(8, 2, KEY_KP5), \
> +	KEY(8, 3, KEY_KP6), \
> +	KEY(8, 4, KEY_KPPLUS), \
> +	KEY(8, 5, KEY_KP1), \
> +	KEY(8, 6, KEY_KP2), \
> +	KEY(8, 7, KEY_KP3), \
> +	KEY(8, 8, KEY_KP0), \
> +};

Hm, I'd expect this to be in particular board code, not in the header
file.

> +/**
> + * struct kbd_platform_data - keymap for spear keyboards
> + * keymap: pointer to array of values encoded with KEY() macro representing
> + * keymap
> + * keymapsize: number of entries (initialized) in this keymap
> + * rep: current values for autorepeat parameters
> + *
> + * This structure is supposed to be used by platform code to supply
> + * keymaps to drivers that implement keyboards.
> + */
> +struct kbd_platform_data {
> +	int *keymap;
> +	unsigned int keymapsize;
> +	unsigned int rep:1;

Bool please.

> +};
> +
> +/* 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)
> +{
> +#ifdef CONFIG_ARCH_SPEAR13XX
> +#define KBD_PAD_SEL	(BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
> +
> +	u32 val;
> +	/* Workaround:Setting bit for routing it to the IP */
> +	val = readl(PAD_FUNCTION_EN_2);
> +	val &= ~KBD_PAD_SEL;
> +	writel(val, PAD_FUNCTION_EN_2);

Why does it belong here?

> +#endif
> +	pdev->dev.platform_data = data;
> +}
> +#endif /* __PLAT_KEYBOARD_H */
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 9cc488d..2d7e3a8 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called omap-keypad.
>  
> +config KEYBOARD_SPEAR
> +	tristate "ST SPEAR keyboard support"

No arch/platform dependencies?

> +	help
> +	  Say Y here if you want to use the SPEAR keyboard.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called spear-keboard.
> +
>  config KEYBOARD_TWL4030
>  	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
>  	depends on TWL4030_CORE
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 504b591..b21c54d 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
>  obj-$(CONFIG_KEYBOARD_QT2160)		+= qt2160.o
>  obj-$(CONFIG_KEYBOARD_SAMSUNG)		+= samsung-keypad.o
>  obj-$(CONFIG_KEYBOARD_SH_KEYSC)		+= sh_keysc.o
> +obj-$(CONFIG_KEYBOARD_SPEAR)		+= spear-keyboard.o
>  obj-$(CONFIG_KEYBOARD_STMPE)		+= stmpe-keypad.o
>  obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
>  obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
> diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
> new file mode 100644
> index 0000000..4f5c734
> --- /dev/null
> +++ b/drivers/input/keyboard/spear-keyboard.c
> @@ -0,0 +1,335 @@
> +/*
> + * drivers/input/keyboard/keyboard-spear.c
> + *
> + * SPEAr Keyboard Driver
> + * Based on omap-keypad driver
> + *
> + * 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/clk.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_wakeup.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +#include <plat/keyboard.h>
> +
> +/* Keyboard Regsiters */
> +#define MODE_REG	0x00	/* 16 bit reg */
> +#define STATUS_REG	0x0C	/* 2 bit reg */
> +#define DATA_REG	0x10	/* 8 bit reg */
> +#define INTR_MASK	0x54
> +
> +/* Register Values */
> +/*
> + * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
> + * control register as 1010010(82MHZ)
> + */
> +#define PCLK_FREQ_MSK	0xA400	/* 82 MHz */
> +#define START_SCAN	0x0100
> +#define SCAN_RATE_10	0x0000
> +#define SCAN_RATE_20	0x0004
> +#define SCAN_RATE_40	0x0008
> +#define SCAN_RATE_80	0x000C
> +#define MODE_KEYBOARD	0x0002
> +#define DATA_AVAIL	0x2
> +
> +#define KEY_MASK	0xFF000000
> +#define KEY_VALUE	0x00FFFFFF
> +#define ROW_MASK	0xF0
> +#define COLUMN_MASK	0x0F
> +#define ROW_SHIFT	4
> +
> +struct spear_kbd {
> +	struct input_dev *input;
> +	void __iomem *io_base;		/* Keyboard Base Address */
> +	struct clk *clk;
> +	int *keymap;

You need a copy of keymap here so that userspace can modify it safely
via EVIOCSKEYCODE.

> +};
> +/* TODO: Need to optimize this function */
> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
> +{
> +	int i, key;
> +	int *keymap = dev->keymap;
> +
> +	key = KEY(row, col, 0);
> +	for (i = 0; keymap[i] != 0; i++)
> +		if ((keymap[i] & KEY_MASK) == key)
> +			return keymap[i] & KEY_VALUE;
> +	return -ENOKEY;
> +}
> +
> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
> +{
> +	struct spear_kbd *dev = dev_id;
> +	static u8 last_key ;
> +	static u8 last_event;

No statics please, pull it into spear_kbd structure.

> +	int key;
> +	u8 sts, val = 0;
> +
> +	if (dev == NULL) {

How can it be?

> +		pr_err("Keyboard: Invalid dev_id in irq handler\n");
> +		return IRQ_NONE;
> +	}
> +
> +	sts = readb(dev->io_base + STATUS_REG);
> +	if (sts & DATA_AVAIL) {
> +		/* following reads active (row, col) pair */
> +		val = readb(dev->io_base + DATA_REG);
> +		key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
> +					& COLUMN_MASK));
> +
> +		/* valid key press event */
> +		if (key >= 0) {
> +			if (last_event == 1) {
> +				/* check if we missed a release event */
> +				input_report_key(dev->input, last_key,
> +						!last_event);
> +			}
> +			/* notify key press */
> +			last_event = 1;
> +			last_key = key;
> +			input_report_key(dev->input, key, last_event);
> +		} else {
> +			/* notify key release */
> +			last_event = 0;
> +			input_report_key(dev->input, last_key, last_event);
> +		}
> +	} else

Don't you need to clear interrupt here? You got it somehow...

> +		return IRQ_NONE;
> +
> +	/* clear interrupt */
> +	writeb(0, dev->io_base + STATUS_REG);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int __init spear_kbd_probe(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd;
> +	struct kbd_platform_data *pdata = pdev->dev.platform_data;
> +	struct resource *res;
> +	int i, ret, irq;
> +	u16 val = 0;
> +
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "Invalid platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "no keyboard resource defined\n");
> +		return -EBUSY;
> +	}
> +
> +	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
> +		dev_err(&pdev->dev, "keyboard region already claimed\n");
> +		return -EBUSY;
> +	}
> +
> +	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
> +	if (!kbd) {
> +		dev_err(&pdev->dev, "out of memory\n");
> +		ret = -ENOMEM;
> +		goto err_release_mem_region;
> +	}
> +
> +	kbd->clk = clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(kbd->clk)) {
> +		ret = PTR_ERR(kbd->clk);
> +		goto err_kfree;
> +	}
> +
> +	ret = clk_enable(kbd->clk);
> +	if (ret < 0)
> +		goto err_clk_put;
> +
> +	platform_set_drvdata(pdev, kbd);
> +	kbd->keymap = pdata->keymap; /* key mappings */
> +
> +	kbd->io_base = ioremap(res->start, resource_size(res));
> +	if (!kbd->io_base) {
> +		dev_err(&pdev->dev, "ioremap fail for kbd_region\n");
> +		ret = -ENOMEM;
> +		goto err_clear_plat_data;
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0) {
> +		dev_err(&pdev->dev, "not able to get irq for the device\n");
> +		ret = irq;
> +		goto err_iounmap;
> +	}
> +
> +	ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
> +			kbd);
> +	if (ret) {
> +		dev_err(&pdev->dev, "request_irq fail\n");
> +		goto err_iounmap;
> +	}
> +

Are you 100% sure the device is shut off at this point? Because if it
isn't you risk to get interrupt before you allocated your input device.

> +	kbd->input = input_allocate_device();
> +	if (!kbd->input) {
> +		ret = -ENOMEM;
> +		dev_err(&pdev->dev, "input device allocation fail\n");
> +		goto err_free_irq;
> +	}
> +
> +	if (pdata->rep)
> +		__set_bit(EV_REP, kbd->input->evbit);
> +
> +	/* setup input device */
> +	__set_bit(EV_KEY, kbd->input->evbit);
> +
> +	for (i = 0; kbd->keymap[i] != 0; i++)
> +		__set_bit(kbd->keymap[i] & KEY_MAX, kbd->input->keybit);
> +
> +	kbd->input->name = "keyboard";
> +	kbd->input->phys = "keyboard/input0";
> +	kbd->input->dev.parent = &pdev->dev;
> +	kbd->input->id.bustype = BUS_HOST;
> +	kbd->input->id.vendor = 0x0001;
> +	kbd->input->id.product = 0x0001;
> +	kbd->input->id.version = 0x0100;
> +
> +	ret = input_register_device(kbd->input);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Unable to register keyboard device\n");
> +		goto err_free_dev;
> +	}
> +
> +	/* program keyboard */
> +	val |= SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK;
> +	writew(val, kbd->io_base + MODE_REG);
> +
> +	writeb(1, kbd->io_base + STATUS_REG);
> +
> +	/* start key scan */
> +	val |= START_SCAN;
> +	writew(val, kbd->io_base + MODE_REG);

This should go into open() method.

> +
> +	device_init_wakeup(&pdev->dev, 1);
> +
> +	return 0;
> +
> +err_free_dev:
> +	input_free_device(kbd->input);
> +err_free_irq:
> +	free_irq(irq, pdev);
> +err_iounmap:
> +	iounmap(kbd->io_base);
> +err_clear_plat_data:
> +	platform_set_drvdata(pdev, NULL);
> +	clk_disable(kbd->clk);
> +err_clk_put:
> +	clk_put(kbd->clk);
> +err_kfree:
> +	kfree(kbd);
> +err_release_mem_region:
> +	release_mem_region(res->start, resource_size(res));
> +
> +	return ret;
> +}
> +
> +static int spear_kbd_remove(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	struct resource *res;
> +	u16 val;
> +	int irq;
> +
> +	val = readw(kbd->io_base + MODE_REG);
> +	val &= ~START_SCAN;
> +	writew(val, kbd->io_base + MODE_REG);

Need to go into close() method.

> +
> +	/* unregister input device */
> +	input_unregister_device(kbd->input);
> +	input_free_device(kbd->input);

No free after unregister.

> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq)
> +		free_irq(irq, pdev);

Can it ever be 0 here?

> +
> +	iounmap(kbd->io_base);
> +	platform_set_drvdata(pdev, NULL);
> +	clk_disable(kbd->clk);
> +	clk_put(kbd->clk);
> +	kfree(kbd);
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res)
> +		release_mem_region(res->start, resource_size(res));
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int spear_kbd_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	clk_disable(kbd->clk);
> +	if (device_may_wakeup(&pdev->dev))
> +		enable_irq_wake(irq);
> +
> +	return 0;
> +}
> +
> +static int spear_kbd_resume(struct platform_device *pdev)
> +{
> +	struct spear_kbd *kbd = platform_get_drvdata(pdev);
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (device_may_wakeup(&pdev->dev))
> +		disable_irq_wake(irq);
> +	clk_enable(kbd->clk);
> +
> +	return 0;
> +}
> +#else
> +#define spear_kbd_suspend	NULL
> +#define spear_kbd_resume	NULL
> +#endif
> +
> +static struct platform_driver spear_kbd_driver = {
> +	.probe		= spear_kbd_probe,
> +	.remove		= spear_kbd_remove,
> +	.suspend	= spear_kbd_suspend,
> +	.resume		= spear_kbd_resume,

Switch to dev_pm_ops please.

> +	.driver		= {
> +		.name	= "keyboard",
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static int __devinit spear_kbd_init(void)
> +{
> +	return platform_driver_register(&spear_kbd_driver);
> +}
> +module_init(spear_kbd_init);
> +
> +static void __exit spear_kbd_exit(void)
> +{
> +	platform_driver_unregister(&spear_kbd_driver);
> +}
> +module_exit(spear_kbd_exit);
> +
> +MODULE_AUTHOR("Rajeev Kumar");
> +MODULE_DESCRIPTION("SPEAr Keyboard Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 1.7.2.2
> 

Thanks.

-- 
Dmitry

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-08-30 12:14     ` Artem Bityutskiy
@ 2010-08-31  6:34       ` Vipin Kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-08-31  6:34 UTC (permalink / raw)
  To: dedekind1
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

On 8/30/2010 5:44 PM, Artem Bityutskiy wrote:
> On Mon, 2010-08-30 at 16:13 +0530, Viresh KUMAR wrote:
>> From: Vipin Kumar <vipin.kumar@st.com>
>>
>> For a page size of 4096, the number of oob bytes are 128 per page. This demands
>> for an increased ecc_pos array as well as ecc can be placed at more than 64
>> locations.
>>
>> This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
>> for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
>> byte page.
>>
>> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
>> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> 
> Nack, breaking ABI Is not allowed in Linux.
> 
Hello Artem,

I could not understand your point. Can you please elaborate. How does this patch 
break ABI

Regards
Vipin

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-08-31  6:34       ` Vipin Kumar
  0 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-08-31  6:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 8/30/2010 5:44 PM, Artem Bityutskiy wrote:
> On Mon, 2010-08-30 at 16:13 +0530, Viresh KUMAR wrote:
>> From: Vipin Kumar <vipin.kumar@st.com>
>>
>> For a page size of 4096, the number of oob bytes are 128 per page. This demands
>> for an increased ecc_pos array as well as ecc can be placed at more than 64
>> locations.
>>
>> This patch is added because SPEAr platforms NAND controller has 13 bytes of ecc
>> for each 512 bytes of data. This results in 104 bytes of ecc in case of 4096
>> byte page.
>>
>> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
>> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> 
> Nack, breaking ABI Is not allowed in Linux.
> 
Hello Artem,

I could not understand your point. Can you please elaborate. How does this patch 
break ABI

Regards
Vipin

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-08-31  6:34       ` Vipin Kumar
@ 2010-08-31 23:36         ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-08-31 23:36 UTC (permalink / raw)
  To: Vipin Kumar
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

Hi,

On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
> > Nack, breaking ABI Is not allowed in Linux.
> I could not understand your point. Can you please elaborate. How does this patch 
> break ABI

You are changing data structure (struct nand_ecclayout) used for in MTD
ioctl. Tha ioctl is part of the Linux ABI. By changing the data
structure, you are breaking the ABI. This means that current binaries
would stop working with newer versions of the Linux kernel if we'd
accept your patch.

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-08-31 23:36         ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-08-31 23:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
> > Nack, breaking ABI Is not allowed in Linux.
> I could not understand your point. Can you please elaborate. How does this patch 
> break ABI

You are changing data structure (struct nand_ecclayout) used for in MTD
ioctl. Tha ioctl is part of the Linux ABI. By changing the data
structure, you are breaking the ABI. This means that current binaries
would stop working with newer versions of the Linux kernel if we'd
accept your patch.

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* [rtc-linux] [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
@ 2010-09-01  1:22   ` Wan ZongShun
  2010-09-01  3:44     ` viresh kumar
  2010-09-06 19:09   ` Alessandro Zummo
  2010-09-06 22:45   ` Jean-Christophe PLAGNIOL-VILLARD
  2 siblings, 1 reply; 245+ messages in thread
From: Wan ZongShun @ 2010-09-01  1:22 UTC (permalink / raw)
  To: linux-arm-kernel

2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:
> From: Rajeev Kumar <rajeev-dlh.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/clock.c ? ? ? ? ? ? ? ?| ? ?2 +-
> ?arch/arm/mach-spear13xx/include/mach/generic.h | ? ?1 +
> ?arch/arm/mach-spear13xx/spear1300_evb.c ? ? ? ?| ? ?1 +
> ?arch/arm/mach-spear13xx/spear13xx.c ? ? ? ? ? ?| ? 19 +
> ?arch/arm/mach-spear3xx/clock.c ? ? ? ? ? ? ? ? | ? ?2 +-
> ?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/clock.c ? ? ? ? ? ? ? ? | ? ?2 +-
> ?arch/arm/mach-spear6xx/include/mach/generic.h ?| ? ?1 +
> ?arch/arm/mach-spear6xx/spear600_evb.c ? ? ? ? ?| ? ?1 +
> ?arch/arm/mach-spear6xx/spear6xx.c ? ? ? ? ? ? ?| ? 19 +
> ?drivers/rtc/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?7 +
> ?drivers/rtc/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
> ?drivers/rtc/rtc-spear.c ? ? ? ? ? ? ? ? ? ? ? ?| ?598 ++++++++++++++++++++++++
> ?17 files changed, 674 insertions(+), 3 deletions(-)
> ?create mode 100644 drivers/rtc/rtc-spear.c
>


Please split your this patch into two parts, one submitted to LAKM,
the other submitted to Linux-rtc list.

> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> index cef3b13..cc692cc 100644
> --- a/arch/arm/mach-spear13xx/clock.c
> +++ b/arch/arm/mach-spear13xx/clock.c
> @@ -736,7 +736,7 @@ static struct clk_lookup spear_clk_lookups[] = {
> ? ? ? ?{.con_id = "osc3_25m_clk", ? ? ?.clk = &osc3_25m_clk},
>
> ? ? ? ?/* clock derived from 32 KHz osc clk */
> - ? ? ? {.dev_id = "rtc", ? ? ? ? ? ? ? .clk = &rtc_clk},
> + ? ? ? {.dev_id = "rtc-spear", ? ? ? ? .clk = &rtc_clk},
>
> ? ? ? ?/* clock derived from 24/25 MHz osc1/osc3 clk */
> ? ? ? ?{.con_id = "pll1_clk", ? ? ? ? ?.clk = &pll1_clk},
> diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
> index 41c1a53..dc80421 100644
> --- a/arch/arm/mach-spear13xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear13xx/include/mach/generic.h
> @@ -30,6 +30,7 @@
>
> ?/* Add spear13xx family device structure declarations here */
> ?extern struct amba_device uart_device;
> +extern struct platform_device rtc_device;
> ?extern struct sys_timer spear13xx_timer;
>
> ?/* Add spear1300 machine device structure declarations here */
> diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> index d72c8a8..60c5fee 100644
> --- a/arch/arm/mach-spear13xx/spear1300_evb.c
> +++ b/arch/arm/mach-spear13xx/spear1300_evb.c
> @@ -22,6 +22,7 @@ static struct amba_device *amba_devs[] __initdata = {
> ?};
>
> ?static struct platform_device *plat_devs[] __initdata = {
> + ? ? ? &rtc_device,
> ?};
>
> ?static void __init spear1300_evb_init(void)
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
> index d11e300..bdca713 100644
> --- a/arch/arm/mach-spear13xx/spear13xx.c
> +++ b/arch/arm/mach-spear13xx/spear13xx.c
> @@ -37,6 +37,25 @@ struct amba_device 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 rtc_device = {
> + ? ? ? .name = "rtc-spear",
> + ? ? ? .id = -1,
> + ? ? ? .num_resources = ARRAY_SIZE(rtc_resources),
> + ? ? ? .resource = rtc_resources,
> +};
> +
> ?/* Do spear13xx familiy common initialization part here */
> ?void __init spear13xx_init(void)
> ?{
> diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
> index dc19666..147d0a3 100644
> --- a/arch/arm/mach-spear3xx/clock.c
> +++ b/arch/arm/mach-spear3xx/clock.c
> @@ -467,7 +467,7 @@ static struct clk_lookup spear_clk_lookups[] = {
> ? ? ? ?{ .con_id = "osc_32k_clk", ? ? ?.clk = &osc_32k_clk},
> ? ? ? ?{ .con_id = "osc_24m_clk", ? ? ?.clk = &osc_24m_clk},
> ? ? ? ?/* clock derived from 32 KHz osc clk */
> - ? ? ? { .dev_id = "rtc", ? ? ? ? ? ? ?.clk = &rtc_clk},
> + ? ? ? { .dev_id = "rtc-spear", ? ? ? ?.clk = &rtc_clk},
> ? ? ? ?/* clock derived from 24 MHz osc clk */
> ? ? ? ?{ .con_id = "pll1_clk", ? ? ? ? .clk = &pll1_clk},
> ? ? ? ?{ .con_id = "pll3_48m_clk", ? ? .clk = &pll3_48m_clk},
> diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
> index d76ee98..408bb8d 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 gpio_device;
> ?extern struct amba_device uart_device;
> +extern struct platform_device 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 3bb7fbc..392ee4a 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 */
> + ? ? ? &rtc_device,
>
> ? ? ? ?/* spear300 specific devices */
> ?};
> diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
> index 7dd93bd..15ca8fc 100644
> --- a/arch/arm/mach-spear3xx/spear310_evb.c
> +++ b/arch/arm/mach-spear3xx/spear310_evb.c
> @@ -50,6 +50,7 @@ static struct amba_device *amba_devs[] __initdata = {
>
> ?static struct platform_device *plat_devs[] __initdata = {
> ? ? ? ?/* spear3xx specific devices */
> + ? ? ? &rtc_device,
>
> ? ? ? ?/* spear310 specific devices */
> ? ? ? ?&plgpio_device,
> diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
> index 82f4e76..48155cc 100644
> --- a/arch/arm/mach-spear3xx/spear320_evb.c
> +++ b/arch/arm/mach-spear3xx/spear320_evb.c
> @@ -48,6 +48,7 @@ static struct amba_device *amba_devs[] __initdata = {
>
> ?static struct platform_device *plat_devs[] __initdata = {
> ? ? ? ?/* spear3xx specific devices */
> + ? ? ? &rtc_device,
>
> ? ? ? ?/* spear320 specific devices */
> ? ? ? ?&plgpio_device,
> diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
> index 89cf8ea..6d8791e 100644
> --- a/arch/arm/mach-spear3xx/spear3xx.c
> +++ b/arch/arm/mach-spear3xx/spear3xx.c
> @@ -54,6 +54,25 @@ struct amba_device uart_device = {
> ? ? ? ?.irq = {IRQ_UART, NO_IRQ},
> ?};
>
> +/* 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 = 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,
> +};
> +
> ?/* Do spear3xx familiy common initialization part here */
> ?void __init spear3xx_init(void)
> ?{
> diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
> index 4a91991..66fc622 100644
> --- a/arch/arm/mach-spear6xx/clock.c
> +++ b/arch/arm/mach-spear6xx/clock.c
> @@ -569,7 +569,7 @@ static struct clk_lookup spear_clk_lookups[] = {
> ? ? ? ?{ .con_id = "osc_32k_clk", ? ? ?.clk = &osc_32k_clk},
> ? ? ? ?{ .con_id = "osc_30m_clk", ? ? ?.clk = &osc_30m_clk},
> ? ? ? ?/* clock derived from 32 KHz os ? ? ? ? ?clk */
> - ? ? ? { .dev_id = "rtc", ? ? ? ? ? ? ?.clk = &rtc_clk},
> + ? ? ? { .dev_id = "rtc-spear", ? ? ? ?.clk = &rtc_clk},
> ? ? ? ?/* clock derived from 30 MHz os ? ? ? ? ?clk */
> ? ? ? ?{ .con_id = "pll1_clk", ? ? ? ? .clk = &pll1_clk},
> ? ? ? ?{ .con_id = "pll3_48m_clk", ? ? .clk = &pll3_48m_clk},
> diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
> index d6a04f2..674b16c 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 clcd_device;
> ?extern struct amba_device gpio_device[];
> ?extern struct amba_device uart_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 88e69f4..861e83d 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 d0f6b9d..1e403cb 100644
> --- a/arch/arm/mach-spear6xx/spear6xx.c
> +++ b/arch/arm/mach-spear6xx/spear6xx.c
> @@ -121,6 +121,25 @@ struct amba_device gpio_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)
> ?{
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 48ca713..f099473 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -625,6 +625,13 @@ config RTC_DRV_WM8350
> ? ? ? ? ?This driver can also be built as a module. If so, the module
> ? ? ? ? ?will be called "rtc-wm8350".
>
> +config RTC_DRV_SPEAR
> + ? ? ? tristate "SPEAR ST RTC"
> + ? ? ? default y
> + ? ? ? help
> + ? ? ? ?If you say Y here you will get support for the RTC found on
> + ? ? ? ?spear
> +
> ?config RTC_DRV_PCF50633
> ? ? ? ?depends on MFD_PCF50633
> ? ? ? ?tristate "NXP PCF50633 RTC"
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 0f207b3..44df01a 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -86,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
> ?obj-$(CONFIG_RTC_DRV_S3C) ? ? ?+= rtc-s3c.o
> ?obj-$(CONFIG_RTC_DRV_SA1100) ? += rtc-sa1100.o
> ?obj-$(CONFIG_RTC_DRV_SH) ? ? ? += rtc-sh.o
> +obj-$(CONFIG_RTC_DRV_SPEAR) ? ?+= rtc-spear.o
> ?obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
> ?obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
> ?obj-$(CONFIG_RTC_DRV_STMP) ? ? += rtc-stmp3xxx.o
> diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
> new file mode 100644
> index 0000000..5b49124
> --- /dev/null
> +++ b/drivers/rtc/rtc-spear.c
> @@ -0,0 +1,598 @@
> +/*
> + * drivers/rtc/rtc-spear.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/bcd.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/ioport.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
> +#include <linux/wait.h>
> +#include <asm/mach/time.h>
> +
> +/* RTC registers */
> +#define TIME_REG ? ? ? ? ? ? ? 0x00
> +#define DATE_REG ? ? ? ? ? ? ? 0x04
> +#define ALARM_TIME_REG ? ? ? ? 0x08
> +#define ALARM_DATE_REG ? ? ? ? 0x0C
> +#define CTRL_REG ? ? ? ? ? ? ? 0x10
> +#define STATUS_REG ? ? ? ? ? ? 0x14
> +
> +/* TIME_REG & ALARM_TIME_REG */
> +#define SECONDS_UNITS ? ? ? ? ?(0xf<<0) ? ? ? ?/* seconds units position */
> +#define SECONDS_TENS ? ? ? ? ? (0x7<<4) ? ? ? ?/* seconds tens position */
> +#define MINUTES_UNITS ? ? ? ? ?(0xf<<8) ? ? ? ?/* minutes units position */
> +#define MINUTES_TENS ? ? ? ? ? (0x7<<12) ? ? ? /* minutes tens position */
> +#define HOURS_UNITS ? ? ? ? ? ?(0xf<<16) ? ? ? /* hours units position */
> +#define HOURS_TENS ? ? ? ? ? ? (0x3<<20) ? ? ? /* hours tens position */
> +
> +/* DATE_REG & ALARM_DATE_REG */
> +#define DAYS_UNITS ? ? ? ? ? ? (0xf<<0) ? ? ? ?/* days units position */
> +#define DAYS_TENS ? ? ? ? ? ? ?(0x3<<4) ? ? ? ?/* days tens position */
> +#define MONTHS_UNITS ? ? ? ? ? (0xf<<8) ? ? ? ?/* months units position */
> +#define MONTHS_TENS ? ? ? ? ? ?(0x1<<12) ? ? ? /* months tens position */
> +#define YEARS_UNITS ? ? ? ? ? ?(0xf<<16) ? ? ? /* years units position */
> +#define YEARS_TENS ? ? ? ? ? ? (0xf<<20) ? ? ? /* years tens position */
> +#define YEARS_HUNDREDS ? ? ? ? (0xf<<24) ? ? ? /* years hundereds position */
> +#define YEARS_MILLENIUMS ? ? ? (0xf<<28) ? ? ? /* years millenium position */
> +
> +/* MASK SHIFT TIME_REG & ALARM_TIME_REG*/
> +#define SECOND_SHIFT ? ? ? ? ? 0x00 ? ? ? ? ? ?/* seconds units */
> +#define MINUTE_SHIFT ? ? ? ? ? 0x08 ? ? ? ? ? ?/* minutes units position */
> +#define HOUR_SHIFT ? ? ? ? ? ? 0x10 ? ? ? ? ? ?/* hours units position */
> +#define MDAY_SHIFT ? ? ? ? ? ? 0x00 ? ? ? ? ? ?/* Month day shift */
> +#define MONTH_SHIFT ? ? ? ? ? ?0x08 ? ? ? ? ? ?/* Month shift */
> +#define YEAR_SHIFT ? ? ? ? ? ? 0x10 ? ? ? ? ? ?/* Year shift */
> +
> +#define SECOND_MASK ? ? ? ? ? ?0x7F
> +#define MIN_MASK ? ? ? ? ? ? ? 0x7F
> +#define HOUR_MASK ? ? ? ? ? ? ?0x3F
> +#define DAY_MASK ? ? ? ? ? ? ? 0x3F
> +#define MONTH_MASK ? ? ? ? ? ? 0x7F
> +#define YEAR_MASK ? ? ? ? ? ? ?0xFFFF
> +
> +/* date reg equal to time reg, for debug only */
> +#define TIME_BYP ? ? ? ? ? ? ? (1<<9)
> +#define INT_ENABLE ? ? ? ? ? ? (1<<31) ? ? ? ? /* interrupt enable */
> +
> +/* STATUS_REG */
> +#define CLK_UNCONNECTED ? ? ? ? ? ? ? ?(1<<0)
> +#define PEND_WR_TIME ? ? ? ? ? (1<<2)
> +#define PEND_WR_DATE ? ? ? ? ? (1<<3)
> +#define LOST_WR_TIME ? ? ? ? ? (1<<4)
> +#define LOST_WR_DATE ? ? ? ? ? (1<<5)
> +#define RTC_INT_MASK ? ? ? ? ? (1<<31)
> +#define STATUS_BUSY ? ? ? ? ? ?(PEND_WR_TIME | PEND_WR_DATE)
> +#define STATUS_FAIL ? ? ? ? ? ?(LOST_WR_TIME | LOST_WR_DATE)
> +
> +struct spear_rtc_config {
> + ? ? ? struct clk *clk;
> + ? ? ? spinlock_t lock;
> + ? ? ? void __iomem *ioaddr;
> +};
> +
> +static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
> +{
> + ? ? ? unsigned int val;
> + ? ? ? unsigned long flags;
> +
> + ? ? ? spin_lock_irqsave(&config->lock, flags);
> + ? ? ? val = readl(config->ioaddr + STATUS_REG);
> + ? ? ? val |= RTC_INT_MASK;
> + ? ? ? writel(val, config->ioaddr + STATUS_REG);
> + ? ? ? spin_unlock_irqrestore(&config->lock, flags);
> +}
> +
> +static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config)
> +{
> + ? ? ? unsigned int val;
> +
> + ? ? ? val = readl(config->ioaddr + CTRL_REG);
> + ? ? ? if (!(val & INT_ENABLE)) {
> + ? ? ? ? ? ? ? spear_rtc_clear_interrupt(config);
> + ? ? ? ? ? ? ? val |= INT_ENABLE;
> + ? ? ? ? ? ? ? writel(val, config->ioaddr + CTRL_REG);
> + ? ? ? }
> +}
> +
> +static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config)
> +{
> + ? ? ? unsigned int val;
> +
> + ? ? ? val = readl(config->ioaddr + CTRL_REG);
> + ? ? ? if (val & INT_ENABLE) {
> + ? ? ? ? ? ? ? val &= ~INT_ENABLE;
> + ? ? ? ? ? ? ? writel(val, config->ioaddr + CTRL_REG);
> + ? ? ? }
> +}
> +
> +static inline int is_write_complete(struct spear_rtc_config *config)
> +{
> + ? ? ? int ret = 0;
> + ? ? ? unsigned long flags;
> +
> + ? ? ? spin_lock_irqsave(&config->lock, flags);
> + ? ? ? if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL)
> + ? ? ? ? ? ? ? ret = -EIO;
> + ? ? ? spin_unlock_irqrestore(&config->lock, flags);
> +
> + ? ? ? return ret;
> +}
> +
> +static void rtc_wait_not_busy(struct spear_rtc_config *config)
> +{
> + ? ? ? int status, count = 0;
> + ? ? ? unsigned long flags;
> +
> + ? ? ? /* Assuming BUSY may stay active for 80 msec) */
> + ? ? ? for (count = 0; count < 80; count++) {
> + ? ? ? ? ? ? ? spin_lock_irqsave(&config->lock, flags);
> + ? ? ? ? ? ? ? status = readl(config->ioaddr + STATUS_REG);
> + ? ? ? ? ? ? ? spin_unlock_irqrestore(&config->lock, flags);
> + ? ? ? ? ? ? ? if ((status & STATUS_BUSY) == 0)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? /* check status busy, after each msec */
> + ? ? ? ? ? ? ? msleep(1);
> + ? ? ? }
> +}
> +
> +static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
> +{
> + ? ? ? struct rtc_device *rtc = (struct rtc_device *)dev_id;
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? unsigned long flags, events = 0;
> + ? ? ? unsigned int irq_data;
> +
> + ? ? ? spin_lock_irqsave(&config->lock, flags);
> + ? ? ? irq_data = readl(config->ioaddr + STATUS_REG);
> + ? ? ? spin_unlock_irqrestore(&config->lock, flags);
> +
> + ? ? ? if ((irq_data & RTC_INT_MASK)) {
> + ? ? ? ? ? ? ? spear_rtc_clear_interrupt(config);
> + ? ? ? ? ? ? ? events = RTC_IRQF | RTC_AF;
> + ? ? ? ? ? ? ? rtc_update_irq(rtc, 1, events);
> + ? ? ? ? ? ? ? return IRQ_HANDLED;
> + ? ? ? } else
> + ? ? ? ? ? ? ? return IRQ_NONE;
> +
> +}
> +
> +static int tm2bcd(struct rtc_time *tm)
> +{
> + ? ? ? if (rtc_valid_tm(tm) != 0)
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? tm->tm_sec = bin2bcd(tm->tm_sec);
> + ? ? ? tm->tm_min = bin2bcd(tm->tm_min);
> + ? ? ? tm->tm_hour = bin2bcd(tm->tm_hour);
> + ? ? ? tm->tm_mday = bin2bcd(tm->tm_mday);
> + ? ? ? tm->tm_mon = bin2bcd(tm->tm_mon + 1);
> + ? ? ? tm->tm_year = bin2bcd(tm->tm_year);
> +
> + ? ? ? return 0;
> +}
> +
> +static void bcd2tm(struct rtc_time *tm)
> +{
> + ? ? ? tm->tm_sec = bcd2bin(tm->tm_sec);
> + ? ? ? tm->tm_min = bcd2bin(tm->tm_min);
> + ? ? ? tm->tm_hour = bcd2bin(tm->tm_hour);
> + ? ? ? tm->tm_mday = bcd2bin(tm->tm_mday);
> + ? ? ? tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
> + ? ? ? /* epoch == 1900 */
> + ? ? ? tm->tm_year = bcd2bin(tm->tm_year);
> +}
> +
> +/*
> + * spear_rtc_read_time - set the time
> + * @dev: rtc device in use
> + * @tm: holds date and time
> + *
> + * This function read time and date. On success it will return 0
> + * otherwise -ve error is returned.
> + */
> +static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> + ? ? ? struct platform_device *pdev = to_platform_device(dev);
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? unsigned int time, date;
> +
> + ? ? ? /* we don't report wday/yday/isdst ... */
> + ? ? ? rtc_wait_not_busy(config);
> +
> + ? ? ? time = readl(config->ioaddr + TIME_REG);
> + ? ? ? date = readl(config->ioaddr + DATE_REG);
> + ? ? ? tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
> + ? ? ? tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
> + ? ? ? tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
> + ? ? ? tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
> + ? ? ? tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
> + ? ? ? tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
> +
> + ? ? ? bcd2tm(tm);
> + ? ? ? return 0;
> +}
> +
> +/*
> + * spear_rtc_set_time - set the time
> + * @dev: rtc device in use
> + * @tm: holds date and time
> + *
> + * This function set time and date. On success it will return 0
> + * otherwise -ve error is returned.
> + */
> +static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> + ? ? ? struct platform_device *pdev = to_platform_device(dev);
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? unsigned int time, date, err = 0;
> +
> + ? ? ? if (tm2bcd(tm) < 0)
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? rtc_wait_not_busy(config);
> + ? ? ? time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) |
> + ? ? ? ? ? ? ? (tm->tm_hour << HOUR_SHIFT);
> + ? ? ? date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) |
> + ? ? ? ? ? ? ? (tm->tm_year << YEAR_SHIFT);
> + ? ? ? writel(time, config->ioaddr + TIME_REG);
> + ? ? ? writel(date, config->ioaddr + DATE_REG);
> + ? ? ? err = is_write_complete(config);
> + ? ? ? if (err < 0)
> + ? ? ? ? ? ? ? return err;
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * spear_rtc_read_alarm - read the alarm time
> + * @dev: rtc device in use
> + * @alm: holds alarm date and time
> + *
> + * This function read alarm time and date. On success it will return 0
> + * otherwise -ve error is returned.
> + */
> +static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
> +{
> + ? ? ? struct platform_device *pdev = to_platform_device(dev);
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? unsigned int time, date;
> +
> + ? ? ? rtc_wait_not_busy(config);
> +
> + ? ? ? time = readl(config->ioaddr + ALARM_TIME_REG);
> + ? ? ? date = readl(config->ioaddr + ALARM_DATE_REG);
> + ? ? ? alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
> + ? ? ? alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
> + ? ? ? alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
> + ? ? ? alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
> + ? ? ? alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
> + ? ? ? alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
> +
> + ? ? ? bcd2tm(&alm->time);
> + ? ? ? alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE;
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * spear_rtc_set_alarm - set the alarm time
> + * @dev: rtc device in use
> + * @alm: holds alarm date and time
> + *
> + * This function set alarm time and date. On success it will return 0
> + * otherwise -ve error is returned.
> + */
> +static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> +{
> + ? ? ? struct platform_device *pdev = to_platform_device(dev);
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? unsigned int time, date, err = 0;
> +
> + ? ? ? if (tm2bcd(&alm->time) < 0)
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? rtc_wait_not_busy(config);
> +
> + ? ? ? time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min <<
> + ? ? ? ? ? ? ? ? ? ? ? MINUTE_SHIFT) | (alm->time.tm_hour << HOUR_SHIFT);
> + ? ? ? date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon <<
> + ? ? ? ? ? ? ? ? ? ? ? MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT);
> +
> + ? ? ? writel(time, config->ioaddr + ALARM_TIME_REG);
> + ? ? ? writel(date, config->ioaddr + ALARM_DATE_REG);
> + ? ? ? err = is_write_complete(config);
> + ? ? ? if (err < 0)
> + ? ? ? ? ? ? ? return err;
> +
> + ? ? ? if (alm->enabled)
> + ? ? ? ? ? ? ? spear_rtc_enable_interrupt(config);
> + ? ? ? else
> + ? ? ? ? ? ? ? spear_rtc_disable_interrupt(config);
> +
> + ? ? ? return 0;
> +}
> +
> +#ifdef CONFIG_RTC_INTF_DEV
> +static int
> +spear_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
> +{
> + ? ? ? struct platform_device *pdev = to_platform_device(dev);
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? struct rtc_time tm;
> + ? ? ? struct rtc_wkalrm alm;
> + ? ? ? void __user *uarg = (void __user *)arg;
> + ? ? ? int err = 0;
> +
> + ? ? ? switch (cmd) {
> + ? ? ? ? ? ? ? /* AIE = Alarm Interrupt Enable */
> + ? ? ? case RTC_AIE_OFF:
> + ? ? ? ? ? ? ? spear_rtc_disable_interrupt(config);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case RTC_AIE_ON:
> + ? ? ? ? ? ? ? spear_rtc_enable_interrupt(config);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case RTC_SET_TIME:
> + ? ? ? ? ? ? ? if (copy_from_user(&tm, uarg, sizeof(tm)))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? return spear_rtc_set_time(dev, &tm);
> + ? ? ? case RTC_RD_TIME:
> + ? ? ? ? ? ? ? err = spear_rtc_read_time(dev, &tm);
> + ? ? ? ? ? ? ? if (err < 0)
> + ? ? ? ? ? ? ? ? ? ? ? return err;
> +
> + ? ? ? ? ? ? ? if (copy_to_user(uarg, &tm, sizeof(tm)))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case RTC_ALM_SET:
> + ? ? ? ? ? ? ? if (copy_from_user(&alm.time, uarg, sizeof(tm)))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? alm.enabled = 0;
> + ? ? ? ? ? ? ? alm.pending = 0;
> + ? ? ? ? ? ? ? spear_rtc_set_alarm(dev, &alm);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case RTC_ALM_READ:
> + ? ? ? ? ? ? ? err = spear_rtc_read_alarm(dev, &alm);
> + ? ? ? ? ? ? ? if (err < 0)
> + ? ? ? ? ? ? ? ? ? ? ? return err;
> +
> + ? ? ? ? ? ? ? if (copy_to_user(uarg, &alm.time, sizeof(tm)))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? return -ENOIOCTLCMD;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +#else
> +#define spear_rtc_ioctl ? ? ? ?NULL
> +#endif
> +
> +static struct rtc_class_ops spear_rtc_ops = {
> + ? ? ? .ioctl = spear_rtc_ioctl,
> + ? ? ? .read_time = spear_rtc_read_time,
> + ? ? ? .set_time = spear_rtc_set_time,
> + ? ? ? .read_alarm = spear_rtc_read_alarm,
> + ? ? ? .set_alarm = spear_rtc_set_alarm,
> +};
> +
> +static int __devinit spear_rtc_probe(struct platform_device *pdev)
> +{
> + ? ? ? struct resource *res;
> + ? ? ? struct rtc_device *rtc;
> + ? ? ? struct spear_rtc_config *config;
> + ? ? ? unsigned int status = 0;
> + ? ? ? int irq;
> +
> + ? ? ? res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + ? ? ? if (!res) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "no resource defined\n");
> + ? ? ? ? ? ? ? return -EBUSY;
> + ? ? ? }
> + ? ? ? if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "rtc region already claimed\n");
> + ? ? ? ? ? ? ? return -EBUSY;
> + ? ? ? }
> +
> + ? ? ? config = kzalloc(sizeof(*config), GFP_KERNEL);
> + ? ? ? if (!config) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "out of memory\n");
> + ? ? ? ? ? ? ? status = -ENOMEM;
> + ? ? ? ? ? ? ? goto err_release_region;
> + ? ? ? }
> +
> + ? ? ? config->clk = clk_get(&pdev->dev, NULL);
> + ? ? ? if (IS_ERR(config->clk)) {
> + ? ? ? ? ? ? ? status = PTR_ERR(config->clk);
> + ? ? ? ? ? ? ? goto err_kfree;
> + ? ? ? }
> +
> + ? ? ? status = clk_enable(config->clk);
> + ? ? ? if (status < 0)
> + ? ? ? ? ? ? ? goto err_clk_put;
> +
> + ? ? ? config->ioaddr = ioremap(res->start, resource_size(res));
> + ? ? ? if (!config->ioaddr) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "ioremap fail\n");
> + ? ? ? ? ? ? ? status = -ENOMEM;
> + ? ? ? ? ? ? ? goto err_disable_clock;
> + ? ? ? }
> +
> + ? ? ? rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops,
> + ? ? ? ? ? ? ? ? ? ? ? THIS_MODULE);
> + ? ? ? if (IS_ERR(rtc)) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PTR_ERR(rtc));
> + ? ? ? ? ? ? ? status = PTR_ERR(rtc);
> + ? ? ? ? ? ? ? goto err_iounmap;
> + ? ? ? }
> + ? ? ? platform_set_drvdata(pdev, rtc);
> + ? ? ? dev_set_drvdata(&rtc->dev, config);
> +
> + ? ? ? spin_lock_init(&config->lock);
> +
> + ? ? ? /* alarm irqs */
> + ? ? ? irq = platform_get_irq(pdev, 0);
> + ? ? ? if (irq < 0) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "no update irq?\n");
> + ? ? ? ? ? ? ? status = irq;
> + ? ? ? ? ? ? ? goto err_clear_platdata;
> + ? ? ? }
> +
> + ? ? ? status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc);
> + ? ? ? if (status) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? claimed\n", irq);
> + ? ? ? ? ? ? ? goto err_clear_platdata;
> + ? ? ? }
> +
> + ? ? ? if (!device_can_wakeup(&pdev->dev))
> + ? ? ? ? ? ? ? device_init_wakeup(&pdev->dev, 1);
> +
> + ? ? ? return 0;
> +
> +err_clear_platdata:
> + ? ? ? platform_set_drvdata(pdev, NULL);
> + ? ? ? dev_set_drvdata(&rtc->dev, NULL);
> + ? ? ? rtc_device_unregister(rtc);
> +err_iounmap:
> + ? ? ? iounmap(config->ioaddr);
> +err_disable_clock:
> + ? ? ? clk_disable(config->clk);
> +err_clk_put:
> + ? ? ? clk_put(config->clk);
> +err_kfree:
> + ? ? ? kfree(config);
> +err_release_region:
> + ? ? ? release_mem_region(res->start, resource_size(res));
> +
> + ? ? ? return status;
> +}
> +
> +static int __devexit spear_rtc_remove(struct platform_device *pdev)
> +{
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? int irq;
> + ? ? ? struct resource *res;
> +
> + ? ? ? /* leave rtc running, but disable irqs */
> + ? ? ? spear_rtc_disable_interrupt(config);
> + ? ? ? device_init_wakeup(&pdev->dev, 0);
> + ? ? ? irq = platform_get_irq(pdev, 0);
> + ? ? ? if (irq)
> + ? ? ? ? ? ? ? free_irq(irq, pdev);
> + ? ? ? clk_disable(config->clk);
> + ? ? ? clk_put(config->clk);
> + ? ? ? iounmap(config->ioaddr);
> + ? ? ? kfree(config);
> + ? ? ? res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + ? ? ? if (res)
> + ? ? ? ? ? ? ? release_mem_region(res->start, resource_size(res));
> + ? ? ? platform_set_drvdata(pdev, NULL);
> + ? ? ? dev_set_drvdata(&rtc->dev, NULL);
> + ? ? ? rtc_device_unregister(rtc);
> +
> + ? ? ? return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +
> +static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? int irq;
> +
> + ? ? ? irq = platform_get_irq(pdev, 0);
> + ? ? ? if (device_may_wakeup(&pdev->dev))
> + ? ? ? ? ? ? ? enable_irq_wake(irq);
> + ? ? ? else {
> + ? ? ? ? ? ? ? spear_rtc_disable_interrupt(config);
> + ? ? ? ? ? ? ? clk_disable(config->clk);
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static int spear_rtc_resume(struct platform_device *pdev)
> +{
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> + ? ? ? int irq;
> +
> + ? ? ? irq = platform_get_irq(pdev, 0);
> +
> + ? ? ? if (device_may_wakeup(&pdev->dev))
> + ? ? ? ? ? ? ? disable_irq_wake(irq);
> + ? ? ? else {
> + ? ? ? ? ? ? ? clk_enable(config->clk);
> + ? ? ? ? ? ? ? spear_rtc_enable_interrupt(config);
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +#else
> +#define spear_rtc_suspend ? ? ?NULL
> +#define spear_rtc_resume ? ? ? NULL
> +#endif
> +
> +static void spear_rtc_shutdown(struct platform_device *pdev)
> +{
> + ? ? ? struct rtc_device *rtc = platform_get_drvdata(pdev);
> + ? ? ? struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
> +
> + ? ? ? spear_rtc_disable_interrupt(config);
> + ? ? ? clk_disable(config->clk);
> +}
> +
> +static struct platform_driver spear_rtc_driver = {
> + ? ? ? .probe = spear_rtc_probe,
> + ? ? ? .remove = __devexit_p(spear_rtc_remove),
> + ? ? ? .suspend = spear_rtc_suspend,
> + ? ? ? .resume = spear_rtc_resume,
> + ? ? ? .shutdown = spear_rtc_shutdown,
> + ? ? ? .driver = {
> + ? ? ? ? ? ? ? .name = "rtc-spear",
> + ? ? ? ? ? ? ? .owner = THIS_MODULE,
> + ? ? ? },
> +};
> +
> +static int __init rtc_init(void)
> +{
> + ? ? ? return platform_driver_register(&spear_rtc_driver);
> +}
> +module_init(rtc_init);
> +
> +static void __exit rtc_exit(void)
> +{
> + ? ? ? platform_driver_unregister(&spear_rtc_driver);
> +}
> +module_exit(rtc_exit);
> +
> +MODULE_ALIAS("rtc-spear");
> +MODULE_AUTHOR("Rajeev Kumar");
> +MODULE_LICENSE("GPL");
> --
> 1.7.2.2
>
> --
> You received this message because you are subscribed to "rtc-linux".
> Membership options at http://groups.google.com/group/rtc-linux .
> Please read http://groups.google.com/group/rtc-linux/web/checklist
> before submitting a driver.



-- 
*linux-arm-kernel mailing list
mail addr:linux-arm-kernel at lists.infradead.org
you can subscribe by:
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

* linux-arm-NUC900 mailing list
mail addr:NUC900 at googlegroups.com
main web: https://groups.google.com/group/NUC900
you can subscribe it by sending me mail:
mcuos.com at gmail.com

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

* [rtc-linux] [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-09-01  1:22   ` [rtc-linux] " Wan ZongShun
@ 2010-09-01  3:44     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-01  3:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 6:52 AM, Wan ZongShun wrote:
>> >  17 files changed, 674 insertions(+), 3 deletions(-)
>> >  create mode 100644 drivers/rtc/rtc-spear.c
>> >
> 
> Please split your this patch into two parts, one submitted to LAKM,
> the other submitted to Linux-rtc list.
> 

Will be done.

viresh

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

* [PATCH 17/74] ST SPEAr: Adding USB Host support
  2010-08-30 14:10   ` Alan Stern
@ 2010-09-01  3:55     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-01  3:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 8/30/2010 7:40 PM, Alan Stern wrote:
> On Mon, 30 Aug 2010, Viresh KUMAR wrote:
> 
>> > From: Deepak Sikri <deepak.sikri@st.com>
>> > 
> Missing patch description.
> 

Will add.

>> > +static const struct hc_driver ehci_spear_hc_driver = {
>> > +	.description		= hcd_name,
>> > +	.product_desc		= "SPEAr EHCI",
>> > +	.hcd_priv_size		= sizeof(struct spear_ehci),
>> > +
>> > +	/* generic hardware linkage */
>> > +	.irq			= ehci_irq,
>> > +	.flags			= HCD_MEMORY | HCD_USB2,
>> > +
>> > +	/* basic lifecycle operations */
>> > +	.reset			= ehci_spear_setup,
>> > +	.start			= ehci_run,
>> > +	.stop			= ehci_stop,
>> > +	.shutdown		= ehci_shutdown,
>> > +
>> > +	/* managing i/o requests and associated device resources */
>> > +	.urb_enqueue		= ehci_urb_enqueue,
>> > +	.urb_dequeue		= ehci_urb_dequeue,
>> > +	.endpoint_disable	= ehci_endpoint_disable,
>> > +
> Missing .endpoint_reset.

Will add.

viresh.

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-08-31 23:36         ` Artem Bityutskiy
@ 2010-09-01  4:13           ` Vipin Kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-01  4:13 UTC (permalink / raw)
  To: dedekind1
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
> Hi,
> 
> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>> Nack, breaking ABI Is not allowed in Linux.
>> I could not understand your point. Can you please elaborate. How does this patch 
>> break ABI
> 
> You are changing data structure (struct nand_ecclayout) used for in MTD
> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
> structure, you are breaking the ABI. This means that current binaries
> would stop working with newer versions of the Linux kernel if we'd
> accept your patch.
> 
Hello,

The only change that I have made is increasing the number of bytes to keep ecc. 
Since the ecc is generally kept in spare area, it makes sense to have the ecc 
locations to be equal to the maximum spare area possible.

A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
ecc positions) depending on the algorithm used to generate ecc. 
Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
logical to place it in spare area since the linux image supports 4096 page but 
the problem is that the ecc locations supported by linux are less than the 
practically possible scenario so in effect this change is an improvement in linux

Please let me know if you disagree

Regards
Vipin

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01  4:13           ` Vipin Kumar
  0 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-01  4:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
> Hi,
> 
> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>> Nack, breaking ABI Is not allowed in Linux.
>> I could not understand your point. Can you please elaborate. How does this patch 
>> break ABI
> 
> You are changing data structure (struct nand_ecclayout) used for in MTD
> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
> structure, you are breaking the ABI. This means that current binaries
> would stop working with newer versions of the Linux kernel if we'd
> accept your patch.
> 
Hello,

The only change that I have made is increasing the number of bytes to keep ecc. 
Since the ecc is generally kept in spare area, it makes sense to have the ecc 
locations to be equal to the maximum spare area possible.

A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
ecc positions) depending on the algorithm used to generate ecc. 
Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
logical to place it in spare area since the linux image supports 4096 page but 
the problem is that the ecc locations supported by linux are less than the 
practically possible scenario so in effect this change is an improvement in linux

Please let me know if you disagree

Regards
Vipin

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

* Re: [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-08-30 16:48     ` Dmitry Torokhov
@ 2010-09-01  5:23       ` rajeev
  -1 siblings, 0 replies; 245+ messages in thread
From: rajeev @ 2010-09-01  5:23 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, linux-input, Vipin KUMAR, Shiraz HASHIM,
	Deepak SIKRI, linux-arm-kernel

Hi Dmitry 

Please find my answers embedded below.

On 8/30/2010 10:18 PM, Dmitry Torokhov wrote:
> Hi Rajeev,
> 

[snip...]

> 
> First of all, please split platform modifications from the driver itself
> (as I care about the latter but less about the former).
>

Will be done.
 
>> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
>> index 9252940..c48b779 100644

[snip...]

>> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
>> @@ -0,0 +1,154 @@
>> +/*
>> + * arch/arm/plat-spear/include/plat/keyboard.h
>> + *
>> + * 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.
>> + */
>> +
>> +#ifndef __PLAT_KEYBOARD_H
>> +#define __PLAT_KEYBOARD_H
>> +
>> +#include <linux/bitops.h>
>> +#include <linux/input.h>
>> +#include <mach/misc_regs.h>
>> +
>> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
>> +
> 
> Please use definitions from include/linux/input/matrix_keypad.h
> 

Ok. I will check it and modify.

>> +#define DECLARE_KEYMAP(name) \
>> +int name[] = {\
>> +     KEY(0, 0, KEY_ESC), \
>> +     KEY(0, 1, KEY_1), \
>> +     KEY(0, 2, KEY_2), \
>> +     KEY(0, 3, KEY_3), \
>> +     KEY(0, 4, KEY_4), \
>> +     KEY(0, 5, KEY_5), \
>> +     KEY(0, 6, KEY_6), \
>> +     KEY(0, 7, KEY_7), \
>> +     KEY(0, 8, KEY_8), \
>> +     KEY(1, 0, KEY_9), \
>> +     KEY(1, 1, KEY_MINUS), \
>> +     KEY(1, 2, KEY_EQUAL), \
>> +     KEY(1, 3, KEY_BACKSPACE), \
>> +     KEY(1, 4, KEY_TAB), \
>> +     KEY(1, 5, KEY_Q), \
>> +     KEY(1, 6, KEY_W), \
>> +     KEY(1, 7, KEY_E), \
>> +     KEY(1, 8, KEY_R), \
>> +     KEY(2, 0, KEY_T), \
>> +     KEY(2, 1, KEY_Y), \
>> +     KEY(2, 2, KEY_U), \
>> +     KEY(2, 3, KEY_I), \
>> +     KEY(2, 4, KEY_O), \
>> +     KEY(2, 5, KEY_P), \
>> +     KEY(2, 6, KEY_LEFTBRACE), \
>> +     KEY(2, 7, KEY_RIGHTBRACE), \
>> +     KEY(2, 8, KEY_ENTER), \
>> +     KEY(3, 0, KEY_LEFTCTRL), \
>> +     KEY(3, 1, KEY_A), \
>> +     KEY(3, 2, KEY_S), \
>> +     KEY(3, 3, KEY_D), \
>> +     KEY(3, 4, KEY_F), \
>> +     KEY(3, 5, KEY_G), \
>> +     KEY(3, 6, KEY_H), \
>> +     KEY(3, 7, KEY_J), \
>> +     KEY(3, 8, KEY_K), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(5, 0, KEY_V), \
>> +     KEY(5, 1, KEY_B), \
>> +     KEY(5, 2, KEY_N), \
>> +     KEY(5, 3, KEY_M), \
>> +     KEY(5, 4, KEY_COMMA), \
>> +     KEY(5, 5, KEY_DOT), \
>> +     KEY(5, 6, KEY_SLASH), \
>> +     KEY(5, 7, KEY_RIGHTSHIFT), \
>> +     KEY(5, 8, KEY_KPASTERISK), \
>> +     KEY(6, 0, KEY_LEFTALT), \
>> +     KEY(6, 1, KEY_SPACE), \
>> +     KEY(6, 2, KEY_CAPSLOCK), \
>> +     KEY(6, 3, KEY_F1), \
>> +     KEY(6, 4, KEY_F2), \
>> +     KEY(6, 5, KEY_F3), \
>> +     KEY(6, 6, KEY_F4), \
>> +     KEY(6, 7, KEY_F5), \
>> +     KEY(6, 8, KEY_F6), \
>> +     KEY(7, 0, KEY_F7), \
>> +     KEY(7, 1, KEY_F8), \
>> +     KEY(7, 2, KEY_F9), \
>> +     KEY(7, 3, KEY_F10), \
>> +     KEY(7, 4, KEY_NUMLOCK), \
>> +     KEY(7, 5, KEY_SCROLLLOCK), \
>> +     KEY(7, 6, KEY_KP7), \
>> +     KEY(7, 7, KEY_KP8), \
>> +     KEY(7, 8, KEY_KP9), \
>> +     KEY(8, 0, KEY_KPMINUS), \
>> +     KEY(8, 1, KEY_KP4), \
>> +     KEY(8, 2, KEY_KP5), \
>> +     KEY(8, 3, KEY_KP6), \
>> +     KEY(8, 4, KEY_KPPLUS), \
>> +     KEY(8, 5, KEY_KP1), \
>> +     KEY(8, 6, KEY_KP2), \
>> +     KEY(8, 7, KEY_KP3), \
>> +     KEY(8, 8, KEY_KP0), \
>> +};
> 
> Hm, I'd expect this to be in particular board code, not in the header
> file.
> 

Currently we have support for evaluation boards only and all of them will have
this structure in their board source files. In order to remove redundant code we
kept it in plat/keyboard.h.

>> +/**
>> + * struct kbd_platform_data - keymap for spear keyboards
>> + * keymap: pointer to array of values encoded with KEY() macro representing
>> + * keymap
>> + * keymapsize: number of entries (initialized) in this keymap
>> + * rep: current values for autorepeat parameters
>> + *
>> + * This structure is supposed to be used by platform code to supply
>> + * keymaps to drivers that implement keyboards.
>> + */
>> +struct kbd_platform_data {
>> +     int *keymap;
>> +     unsigned int keymapsize;
>> +     unsigned int rep:1;
> 
> Bool please.
> 

OK

>> +};
>> +
>> +/* 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)
>> +{
>> +#ifdef CONFIG_ARCH_SPEAR13XX
>> +#define KBD_PAD_SEL  (BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
>> +
>> +     u32 val;
>> +     /* Workaround:Setting bit for routing it to the IP */
>> +     val = readl(PAD_FUNCTION_EN_2);
>> +     val &= ~KBD_PAD_SEL;
>> +     writel(val, PAD_FUNCTION_EN_2);
> 
> Why does it belong here?
> 

Sorry. It will be handled in padmux framework.

>> +#endif
>> +     pdev->dev.platform_data = data;
>> +}
>> +#endif /* __PLAT_KEYBOARD_H */
>> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
>> index 9cc488d..2d7e3a8 100644
>> --- a/drivers/input/keyboard/Kconfig
>> +++ b/drivers/input/keyboard/Kconfig
>> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
>>         To compile this driver as a module, choose M here: the
>>         module will be called omap-keypad.
>>
>> +config KEYBOARD_SPEAR
>> +     tristate "ST SPEAR keyboard support"
> 
> No arch/platform dependencies?
> 

Will add them.

>> +     help

[snip...]

>> +struct spear_kbd {
>> +     struct input_dev *input;
>> +     void __iomem *io_base;          /* Keyboard Base Address */
>> +     struct clk *clk;
>> +     int *keymap;
> 
> You need a copy of keymap here so that userspace can modify it safely
> via EVIOCSKEYCODE.
> 

We have one copy of struct spear_kbd per device structure. I think it
will be fine if we change this structure only. And so don't need to copy
another structure in driver.

>> +};
>> +/* TODO: Need to optimize this function */
>> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
>> +{
>> +     int i, key;
>> +     int *keymap = dev->keymap;
>> +
>> +     key = KEY(row, col, 0);
>> +     for (i = 0; keymap[i] != 0; i++)
>> +             if ((keymap[i] & KEY_MASK) == key)
>> +                     return keymap[i] & KEY_VALUE;
>> +     return -ENOKEY;
>> +}
>> +
>> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
>> +{
>> +     struct spear_kbd *dev = dev_id;
>> +     static u8 last_key ;
>> +     static u8 last_event;
> 
> No statics please, pull it into spear_kbd structure.
>

Ok
 
>> +     int key;
>> +     u8 sts, val = 0;
>> +
>> +     if (dev == NULL) {
> 
> How can it be?
> 

Not needed, will be fixed.

>> +             pr_err("Keyboard: Invalid dev_id in irq handler\n");
>> +             return IRQ_NONE;
>> +     }
>> +
>> +     sts = readb(dev->io_base + STATUS_REG);
>> +     if (sts & DATA_AVAIL) {
>> +             /* following reads active (row, col) pair */
>> +             val = readb(dev->io_base + DATA_REG);
>> +             key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
>> +                                     & COLUMN_MASK));
>> +
>> +             /* valid key press event */
>> +             if (key >= 0) {
>> +                     if (last_event == 1) {
>> +                             /* check if we missed a release event */
>> +                             input_report_key(dev->input, last_key,
>> +                                             !last_event);
>> +                     }
>> +                     /* notify key press */
>> +                     last_event = 1;
>> +                     last_key = key;
>> +                     input_report_key(dev->input, key, last_event);
>> +             } else {
>> +                     /* notify key release */
>> +                     last_event = 0;
>> +                     input_report_key(dev->input, last_key, last_event);
>> +             }
>> +     } else
> 
> Don't you need to clear interrupt here? You got it somehow...
>

I can think of only one way in which this handler is called for some other
device interrupt, that is when this irq line is shared between peripherals.
In that case if interrupt is not meant for kbd then kbd shouldn't clear it.
Isn't it fine???

>> +             return IRQ_NONE;
>> +
>> +     /* clear interrupt */
>> +     writeb(0, dev->io_base + STATUS_REG);
>> +
>> +     return IRQ_HANDLED;
>> +}
>> +
>> +static int __init spear_kbd_probe(struct platform_device *pdev)
>> +{

[snip...]

>> +     ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
>> +                     kbd);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "request_irq fail\n");
>> +             goto err_iounmap;
>> +     }
>> +
> 
> Are you 100% sure the device is shut off at this point? Because if it
> isn't you risk to get interrupt before you allocated your input device.
>

I will check and place it at correct place.

>> +
>> +     /* start key scan */
>> +     val |= START_SCAN;
>> +     writew(val, kbd->io_base + MODE_REG);
> 
> This should go into open() method.
> 

OK.

>> +static int spear_kbd_remove(struct platform_device *pdev)
>> +{
>> +     struct spear_kbd *kbd = platform_get_drvdata(pdev);
>> +     struct resource *res;
>> +     u16 val;
>> +     int irq;
>> +
>> +     val = readw(kbd->io_base + MODE_REG);
>> +     val &= ~START_SCAN;
>> +     writew(val, kbd->io_base + MODE_REG);
> 
> Need to go into close() method.
>

OK.
 
>> +
>> +     /* unregister input device */
>> +     input_unregister_device(kbd->input);
>> +     input_free_device(kbd->input);
> 
> No free after unregister.
> 

OK.

>> +
>> +     irq = platform_get_irq(pdev, 0);
>> +     if (irq)
>> +             free_irq(irq, pdev);
> 
> Can it ever be 0 here?
> 

No. Will correct.


>> +
>> +static struct platform_driver spear_kbd_driver = {
>> +     .probe          = spear_kbd_probe,
>> +     .remove         = spear_kbd_remove,
>> +     .suspend        = spear_kbd_suspend,
>> +     .resume         = spear_kbd_resume,
> 
> Switch to dev_pm_ops please.
> 

Ok.


Thanks,
rajeev.

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-09-01  5:23       ` rajeev
  0 siblings, 0 replies; 245+ messages in thread
From: rajeev @ 2010-09-01  5:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dmitry 

Please find my answers embedded below.

On 8/30/2010 10:18 PM, Dmitry Torokhov wrote:
> Hi Rajeev,
> 

[snip...]

> 
> First of all, please split platform modifications from the driver itself
> (as I care about the latter but less about the former).
>

Will be done.
 
>> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
>> index 9252940..c48b779 100644

[snip...]

>> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
>> @@ -0,0 +1,154 @@
>> +/*
>> + * arch/arm/plat-spear/include/plat/keyboard.h
>> + *
>> + * 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.
>> + */
>> +
>> +#ifndef __PLAT_KEYBOARD_H
>> +#define __PLAT_KEYBOARD_H
>> +
>> +#include <linux/bitops.h>
>> +#include <linux/input.h>
>> +#include <mach/misc_regs.h>
>> +
>> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
>> +
> 
> Please use definitions from include/linux/input/matrix_keypad.h
> 

Ok. I will check it and modify.

>> +#define DECLARE_KEYMAP(name) \
>> +int name[] = {\
>> +     KEY(0, 0, KEY_ESC), \
>> +     KEY(0, 1, KEY_1), \
>> +     KEY(0, 2, KEY_2), \
>> +     KEY(0, 3, KEY_3), \
>> +     KEY(0, 4, KEY_4), \
>> +     KEY(0, 5, KEY_5), \
>> +     KEY(0, 6, KEY_6), \
>> +     KEY(0, 7, KEY_7), \
>> +     KEY(0, 8, KEY_8), \
>> +     KEY(1, 0, KEY_9), \
>> +     KEY(1, 1, KEY_MINUS), \
>> +     KEY(1, 2, KEY_EQUAL), \
>> +     KEY(1, 3, KEY_BACKSPACE), \
>> +     KEY(1, 4, KEY_TAB), \
>> +     KEY(1, 5, KEY_Q), \
>> +     KEY(1, 6, KEY_W), \
>> +     KEY(1, 7, KEY_E), \
>> +     KEY(1, 8, KEY_R), \
>> +     KEY(2, 0, KEY_T), \
>> +     KEY(2, 1, KEY_Y), \
>> +     KEY(2, 2, KEY_U), \
>> +     KEY(2, 3, KEY_I), \
>> +     KEY(2, 4, KEY_O), \
>> +     KEY(2, 5, KEY_P), \
>> +     KEY(2, 6, KEY_LEFTBRACE), \
>> +     KEY(2, 7, KEY_RIGHTBRACE), \
>> +     KEY(2, 8, KEY_ENTER), \
>> +     KEY(3, 0, KEY_LEFTCTRL), \
>> +     KEY(3, 1, KEY_A), \
>> +     KEY(3, 2, KEY_S), \
>> +     KEY(3, 3, KEY_D), \
>> +     KEY(3, 4, KEY_F), \
>> +     KEY(3, 5, KEY_G), \
>> +     KEY(3, 6, KEY_H), \
>> +     KEY(3, 7, KEY_J), \
>> +     KEY(3, 8, KEY_K), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(4, 0, KEY_L), \
>> +     KEY(4, 1, KEY_SEMICOLON), \
>> +     KEY(4, 2, KEY_APOSTROPHE), \
>> +     KEY(4, 3, KEY_GRAVE), \
>> +     KEY(4, 4, KEY_LEFTSHIFT), \
>> +     KEY(4, 5, KEY_BACKSLASH), \
>> +     KEY(4, 6, KEY_Z), \
>> +     KEY(4, 7, KEY_X), \
>> +     KEY(4, 8, KEY_C), \
>> +     KEY(5, 0, KEY_V), \
>> +     KEY(5, 1, KEY_B), \
>> +     KEY(5, 2, KEY_N), \
>> +     KEY(5, 3, KEY_M), \
>> +     KEY(5, 4, KEY_COMMA), \
>> +     KEY(5, 5, KEY_DOT), \
>> +     KEY(5, 6, KEY_SLASH), \
>> +     KEY(5, 7, KEY_RIGHTSHIFT), \
>> +     KEY(5, 8, KEY_KPASTERISK), \
>> +     KEY(6, 0, KEY_LEFTALT), \
>> +     KEY(6, 1, KEY_SPACE), \
>> +     KEY(6, 2, KEY_CAPSLOCK), \
>> +     KEY(6, 3, KEY_F1), \
>> +     KEY(6, 4, KEY_F2), \
>> +     KEY(6, 5, KEY_F3), \
>> +     KEY(6, 6, KEY_F4), \
>> +     KEY(6, 7, KEY_F5), \
>> +     KEY(6, 8, KEY_F6), \
>> +     KEY(7, 0, KEY_F7), \
>> +     KEY(7, 1, KEY_F8), \
>> +     KEY(7, 2, KEY_F9), \
>> +     KEY(7, 3, KEY_F10), \
>> +     KEY(7, 4, KEY_NUMLOCK), \
>> +     KEY(7, 5, KEY_SCROLLLOCK), \
>> +     KEY(7, 6, KEY_KP7), \
>> +     KEY(7, 7, KEY_KP8), \
>> +     KEY(7, 8, KEY_KP9), \
>> +     KEY(8, 0, KEY_KPMINUS), \
>> +     KEY(8, 1, KEY_KP4), \
>> +     KEY(8, 2, KEY_KP5), \
>> +     KEY(8, 3, KEY_KP6), \
>> +     KEY(8, 4, KEY_KPPLUS), \
>> +     KEY(8, 5, KEY_KP1), \
>> +     KEY(8, 6, KEY_KP2), \
>> +     KEY(8, 7, KEY_KP3), \
>> +     KEY(8, 8, KEY_KP0), \
>> +};
> 
> Hm, I'd expect this to be in particular board code, not in the header
> file.
> 

Currently we have support for evaluation boards only and all of them will have
this structure in their board source files. In order to remove redundant code we
kept it in plat/keyboard.h.

>> +/**
>> + * struct kbd_platform_data - keymap for spear keyboards
>> + * keymap: pointer to array of values encoded with KEY() macro representing
>> + * keymap
>> + * keymapsize: number of entries (initialized) in this keymap
>> + * rep: current values for autorepeat parameters
>> + *
>> + * This structure is supposed to be used by platform code to supply
>> + * keymaps to drivers that implement keyboards.
>> + */
>> +struct kbd_platform_data {
>> +     int *keymap;
>> +     unsigned int keymapsize;
>> +     unsigned int rep:1;
> 
> Bool please.
> 

OK

>> +};
>> +
>> +/* 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)
>> +{
>> +#ifdef CONFIG_ARCH_SPEAR13XX
>> +#define KBD_PAD_SEL  (BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
>> +
>> +     u32 val;
>> +     /* Workaround:Setting bit for routing it to the IP */
>> +     val = readl(PAD_FUNCTION_EN_2);
>> +     val &= ~KBD_PAD_SEL;
>> +     writel(val, PAD_FUNCTION_EN_2);
> 
> Why does it belong here?
> 

Sorry. It will be handled in padmux framework.

>> +#endif
>> +     pdev->dev.platform_data = data;
>> +}
>> +#endif /* __PLAT_KEYBOARD_H */
>> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
>> index 9cc488d..2d7e3a8 100644
>> --- a/drivers/input/keyboard/Kconfig
>> +++ b/drivers/input/keyboard/Kconfig
>> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
>>         To compile this driver as a module, choose M here: the
>>         module will be called omap-keypad.
>>
>> +config KEYBOARD_SPEAR
>> +     tristate "ST SPEAR keyboard support"
> 
> No arch/platform dependencies?
> 

Will add them.

>> +     help

[snip...]

>> +struct spear_kbd {
>> +     struct input_dev *input;
>> +     void __iomem *io_base;          /* Keyboard Base Address */
>> +     struct clk *clk;
>> +     int *keymap;
> 
> You need a copy of keymap here so that userspace can modify it safely
> via EVIOCSKEYCODE.
> 

We have one copy of struct spear_kbd per device structure. I think it
will be fine if we change this structure only. And so don't need to copy
another structure in driver.

>> +};
>> +/* TODO: Need to optimize this function */
>> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
>> +{
>> +     int i, key;
>> +     int *keymap = dev->keymap;
>> +
>> +     key = KEY(row, col, 0);
>> +     for (i = 0; keymap[i] != 0; i++)
>> +             if ((keymap[i] & KEY_MASK) == key)
>> +                     return keymap[i] & KEY_VALUE;
>> +     return -ENOKEY;
>> +}
>> +
>> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
>> +{
>> +     struct spear_kbd *dev = dev_id;
>> +     static u8 last_key ;
>> +     static u8 last_event;
> 
> No statics please, pull it into spear_kbd structure.
>

Ok
 
>> +     int key;
>> +     u8 sts, val = 0;
>> +
>> +     if (dev == NULL) {
> 
> How can it be?
> 

Not needed, will be fixed.

>> +             pr_err("Keyboard: Invalid dev_id in irq handler\n");
>> +             return IRQ_NONE;
>> +     }
>> +
>> +     sts = readb(dev->io_base + STATUS_REG);
>> +     if (sts & DATA_AVAIL) {
>> +             /* following reads active (row, col) pair */
>> +             val = readb(dev->io_base + DATA_REG);
>> +             key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
>> +                                     & COLUMN_MASK));
>> +
>> +             /* valid key press event */
>> +             if (key >= 0) {
>> +                     if (last_event == 1) {
>> +                             /* check if we missed a release event */
>> +                             input_report_key(dev->input, last_key,
>> +                                             !last_event);
>> +                     }
>> +                     /* notify key press */
>> +                     last_event = 1;
>> +                     last_key = key;
>> +                     input_report_key(dev->input, key, last_event);
>> +             } else {
>> +                     /* notify key release */
>> +                     last_event = 0;
>> +                     input_report_key(dev->input, last_key, last_event);
>> +             }
>> +     } else
> 
> Don't you need to clear interrupt here? You got it somehow...
>

I can think of only one way in which this handler is called for some other
device interrupt, that is when this irq line is shared between peripherals.
In that case if interrupt is not meant for kbd then kbd shouldn't clear it.
Isn't it fine???

>> +             return IRQ_NONE;
>> +
>> +     /* clear interrupt */
>> +     writeb(0, dev->io_base + STATUS_REG);
>> +
>> +     return IRQ_HANDLED;
>> +}
>> +
>> +static int __init spear_kbd_probe(struct platform_device *pdev)
>> +{

[snip...]

>> +     ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
>> +                     kbd);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "request_irq fail\n");
>> +             goto err_iounmap;
>> +     }
>> +
> 
> Are you 100% sure the device is shut off at this point? Because if it
> isn't you risk to get interrupt before you allocated your input device.
>

I will check and place it at correct place.

>> +
>> +     /* start key scan */
>> +     val |= START_SCAN;
>> +     writew(val, kbd->io_base + MODE_REG);
> 
> This should go into open() method.
> 

OK.

>> +static int spear_kbd_remove(struct platform_device *pdev)
>> +{
>> +     struct spear_kbd *kbd = platform_get_drvdata(pdev);
>> +     struct resource *res;
>> +     u16 val;
>> +     int irq;
>> +
>> +     val = readw(kbd->io_base + MODE_REG);
>> +     val &= ~START_SCAN;
>> +     writew(val, kbd->io_base + MODE_REG);
> 
> Need to go into close() method.
>

OK.
 
>> +
>> +     /* unregister input device */
>> +     input_unregister_device(kbd->input);
>> +     input_free_device(kbd->input);
> 
> No free after unregister.
> 

OK.

>> +
>> +     irq = platform_get_irq(pdev, 0);
>> +     if (irq)
>> +             free_irq(irq, pdev);
> 
> Can it ever be 0 here?
> 

No. Will correct.


>> +
>> +static struct platform_driver spear_kbd_driver = {
>> +     .probe          = spear_kbd_probe,
>> +     .remove         = spear_kbd_remove,
>> +     .suspend        = spear_kbd_suspend,
>> +     .resume         = spear_kbd_resume,
> 
> Switch to dev_pm_ops please.
> 

Ok.


Thanks,
rajeev.

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

* Re: [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-09-01  5:23       ` rajeev
@ 2010-09-01  5:41         ` rajeev
  -1 siblings, 0 replies; 245+ messages in thread
From: rajeev @ 2010-09-01  5:41 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Viresh KUMAR, linux-arm-kernel, linux-input, Shiraz HASHIM,
	Vipin KUMAR, Deepak SIKRI, Armando VISCONTI, Vipul Kumar SAMAR,
	Pratyush ANAND, Bhupesh SHARMA

On 9/1/2010 10:53 AM, rajeev wrote:
>>> +struct spear_kbd {
>>> >> +     struct input_dev *input;
>>> >> +     void __iomem *io_base;          /* Keyboard Base Address */
>>> >> +     struct clk *clk;
>>> >> +     int *keymap;
>> > 
>> > You need a copy of keymap here so that userspace can modify it safely
>> > via EVIOCSKEYCODE.
>> > 
> We have one copy of struct spear_kbd per device structure. I think it
> will be fine if we change this structure only. And so don't need to copy
> another structure in driver.
> 

Sorry!! I wanted to say "keymap array" not "struct spear_kbd" in above explanation.

rajeev.

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-09-01  5:41         ` rajeev
  0 siblings, 0 replies; 245+ messages in thread
From: rajeev @ 2010-09-01  5:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 10:53 AM, rajeev wrote:
>>> +struct spear_kbd {
>>> >> +     struct input_dev *input;
>>> >> +     void __iomem *io_base;          /* Keyboard Base Address */
>>> >> +     struct clk *clk;
>>> >> +     int *keymap;
>> > 
>> > You need a copy of keymap here so that userspace can modify it safely
>> > via EVIOCSKEYCODE.
>> > 
> We have one copy of struct spear_kbd per device structure. I think it
> will be fine if we change this structure only. And so don't need to copy
> another structure in driver.
> 

Sorry!! I wanted to say "keymap array" not "struct spear_kbd" in above explanation.

rajeev.

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

* Re: [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-09-01  5:23       ` rajeev
@ 2010-09-01  6:31         ` Dmitry Torokhov
  -1 siblings, 0 replies; 245+ messages in thread
From: Dmitry Torokhov @ 2010-09-01  6:31 UTC (permalink / raw)
  To: rajeev
  Cc: Viresh KUMAR, linux-arm-kernel, linux-input, Shiraz HASHIM,
	Vipin KUMAR, Deepak SIKRI, Armando VISCONTI, Vipul Kumar SAMAR,
	Pratyush ANAND, Bhupesh SHARMA

On Wed, Sep 01, 2010 at 10:53:43AM +0530, rajeev wrote:
> Hi Dmitry 
> 
> Please find my answers embedded below.
> 
> On 8/30/2010 10:18 PM, Dmitry Torokhov wrote:
> > Hi Rajeev,
> > 
> 
> [snip...]
> 
> > 
> > First of all, please split platform modifications from the driver itself
> > (as I care about the latter but less about the former).
> >
> 
> Will be done.
>  
> >> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> >> index 9252940..c48b779 100644
> 
> [snip...]
> 
> >> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
> >> @@ -0,0 +1,154 @@
> >> +/*
> >> + * arch/arm/plat-spear/include/plat/keyboard.h
> >> + *
> >> + * 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.
> >> + */
> >> +
> >> +#ifndef __PLAT_KEYBOARD_H
> >> +#define __PLAT_KEYBOARD_H
> >> +
> >> +#include <linux/bitops.h>
> >> +#include <linux/input.h>
> >> +#include <mach/misc_regs.h>
> >> +
> >> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
> >> +
> > 
> > Please use definitions from include/linux/input/matrix_keypad.h
> > 
> 
> Ok. I will check it and modify.
> 
> >> +#define DECLARE_KEYMAP(name) \
> >> +int name[] = {\
> >> +     KEY(0, 0, KEY_ESC), \
> >> +     KEY(0, 1, KEY_1), \
> >> +     KEY(0, 2, KEY_2), \
> >> +     KEY(0, 3, KEY_3), \
> >> +     KEY(0, 4, KEY_4), \
> >> +     KEY(0, 5, KEY_5), \
> >> +     KEY(0, 6, KEY_6), \
> >> +     KEY(0, 7, KEY_7), \
> >> +     KEY(0, 8, KEY_8), \
> >> +     KEY(1, 0, KEY_9), \
> >> +     KEY(1, 1, KEY_MINUS), \
> >> +     KEY(1, 2, KEY_EQUAL), \
> >> +     KEY(1, 3, KEY_BACKSPACE), \
> >> +     KEY(1, 4, KEY_TAB), \
> >> +     KEY(1, 5, KEY_Q), \
> >> +     KEY(1, 6, KEY_W), \
> >> +     KEY(1, 7, KEY_E), \
> >> +     KEY(1, 8, KEY_R), \
> >> +     KEY(2, 0, KEY_T), \
> >> +     KEY(2, 1, KEY_Y), \
> >> +     KEY(2, 2, KEY_U), \
> >> +     KEY(2, 3, KEY_I), \
> >> +     KEY(2, 4, KEY_O), \
> >> +     KEY(2, 5, KEY_P), \
> >> +     KEY(2, 6, KEY_LEFTBRACE), \
> >> +     KEY(2, 7, KEY_RIGHTBRACE), \
> >> +     KEY(2, 8, KEY_ENTER), \
> >> +     KEY(3, 0, KEY_LEFTCTRL), \
> >> +     KEY(3, 1, KEY_A), \
> >> +     KEY(3, 2, KEY_S), \
> >> +     KEY(3, 3, KEY_D), \
> >> +     KEY(3, 4, KEY_F), \
> >> +     KEY(3, 5, KEY_G), \
> >> +     KEY(3, 6, KEY_H), \
> >> +     KEY(3, 7, KEY_J), \
> >> +     KEY(3, 8, KEY_K), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(5, 0, KEY_V), \
> >> +     KEY(5, 1, KEY_B), \
> >> +     KEY(5, 2, KEY_N), \
> >> +     KEY(5, 3, KEY_M), \
> >> +     KEY(5, 4, KEY_COMMA), \
> >> +     KEY(5, 5, KEY_DOT), \
> >> +     KEY(5, 6, KEY_SLASH), \
> >> +     KEY(5, 7, KEY_RIGHTSHIFT), \
> >> +     KEY(5, 8, KEY_KPASTERISK), \
> >> +     KEY(6, 0, KEY_LEFTALT), \
> >> +     KEY(6, 1, KEY_SPACE), \
> >> +     KEY(6, 2, KEY_CAPSLOCK), \
> >> +     KEY(6, 3, KEY_F1), \
> >> +     KEY(6, 4, KEY_F2), \
> >> +     KEY(6, 5, KEY_F3), \
> >> +     KEY(6, 6, KEY_F4), \
> >> +     KEY(6, 7, KEY_F5), \
> >> +     KEY(6, 8, KEY_F6), \
> >> +     KEY(7, 0, KEY_F7), \
> >> +     KEY(7, 1, KEY_F8), \
> >> +     KEY(7, 2, KEY_F9), \
> >> +     KEY(7, 3, KEY_F10), \
> >> +     KEY(7, 4, KEY_NUMLOCK), \
> >> +     KEY(7, 5, KEY_SCROLLLOCK), \
> >> +     KEY(7, 6, KEY_KP7), \
> >> +     KEY(7, 7, KEY_KP8), \
> >> +     KEY(7, 8, KEY_KP9), \
> >> +     KEY(8, 0, KEY_KPMINUS), \
> >> +     KEY(8, 1, KEY_KP4), \
> >> +     KEY(8, 2, KEY_KP5), \
> >> +     KEY(8, 3, KEY_KP6), \
> >> +     KEY(8, 4, KEY_KPPLUS), \
> >> +     KEY(8, 5, KEY_KP1), \
> >> +     KEY(8, 6, KEY_KP2), \
> >> +     KEY(8, 7, KEY_KP3), \
> >> +     KEY(8, 8, KEY_KP0), \
> >> +};
> > 
> > Hm, I'd expect this to be in particular board code, not in the header
> > file.
> > 
> 
> Currently we have support for evaluation boards only and all of them will have
> this structure in their board source files. In order to remove redundant code we
> kept it in plat/keyboard.h.
> 

So call it "spear_default_keymap" and put it right into the driver? And
then allow platform code override it.

> >> +/**
> >> + * struct kbd_platform_data - keymap for spear keyboards
> >> + * keymap: pointer to array of values encoded with KEY() macro representing
> >> + * keymap
> >> + * keymapsize: number of entries (initialized) in this keymap
> >> + * rep: current values for autorepeat parameters
> >> + *
> >> + * This structure is supposed to be used by platform code to supply
> >> + * keymaps to drivers that implement keyboards.
> >> + */
> >> +struct kbd_platform_data {
> >> +     int *keymap;
> >> +     unsigned int keymapsize;
> >> +     unsigned int rep:1;
> > 
> > Bool please.
> > 
> 
> OK
> 
> >> +};
> >> +
> >> +/* 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)
> >> +{
> >> +#ifdef CONFIG_ARCH_SPEAR13XX
> >> +#define KBD_PAD_SEL  (BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
> >> +
> >> +     u32 val;
> >> +     /* Workaround:Setting bit for routing it to the IP */
> >> +     val = readl(PAD_FUNCTION_EN_2);
> >> +     val &= ~KBD_PAD_SEL;
> >> +     writel(val, PAD_FUNCTION_EN_2);
> > 
> > Why does it belong here?
> > 
> 
> Sorry. It will be handled in padmux framework.
> 
> >> +#endif
> >> +     pdev->dev.platform_data = data;
> >> +}
> >> +#endif /* __PLAT_KEYBOARD_H */
> >> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> >> index 9cc488d..2d7e3a8 100644
> >> --- a/drivers/input/keyboard/Kconfig
> >> +++ b/drivers/input/keyboard/Kconfig
> >> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
> >>         To compile this driver as a module, choose M here: the
> >>         module will be called omap-keypad.
> >>
> >> +config KEYBOARD_SPEAR
> >> +     tristate "ST SPEAR keyboard support"
> > 
> > No arch/platform dependencies?
> > 
> 
> Will add them.
> 
> >> +     help
> 
> [snip...]
> 
> >> +struct spear_kbd {
> >> +     struct input_dev *input;
> >> +     void __iomem *io_base;          /* Keyboard Base Address */
> >> +     struct clk *clk;
> >> +     int *keymap;
> > 
> > You need a copy of keymap here so that userspace can modify it safely
> > via EVIOCSKEYCODE.
> > 
> 
> We have one copy of struct spear_kbd per device structure. I think it
> will be fine if we change this structure only. And so don't need to copy
> another structure in driver.

Normally such platform data should be declared as 'const' and drivers
should not modify such data. Also unbinding device from driver and
rebinding later should restore the device into pristine state. Having a
copy of keymap in spear_kbd allows to achieve such behavior.

> 
> >> +};
> >> +/* TODO: Need to optimize this function */
> >> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
> >> +{
> >> +     int i, key;
> >> +     int *keymap = dev->keymap;
> >> +
> >> +     key = KEY(row, col, 0);
> >> +     for (i = 0; keymap[i] != 0; i++)
> >> +             if ((keymap[i] & KEY_MASK) == key)
> >> +                     return keymap[i] & KEY_VALUE;
> >> +     return -ENOKEY;
> >> +}
> >> +
> >> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
> >> +{
> >> +     struct spear_kbd *dev = dev_id;
> >> +     static u8 last_key ;
> >> +     static u8 last_event;
> > 
> > No statics please, pull it into spear_kbd structure.
> >
> 
> Ok
>  
> >> +     int key;
> >> +     u8 sts, val = 0;
> >> +
> >> +     if (dev == NULL) {
> > 
> > How can it be?
> > 
> 
> Not needed, will be fixed.
> 
> >> +             pr_err("Keyboard: Invalid dev_id in irq handler\n");
> >> +             return IRQ_NONE;
> >> +     }
> >> +
> >> +     sts = readb(dev->io_base + STATUS_REG);
> >> +     if (sts & DATA_AVAIL) {
> >> +             /* following reads active (row, col) pair */
> >> +             val = readb(dev->io_base + DATA_REG);
> >> +             key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
> >> +                                     & COLUMN_MASK));
> >> +
> >> +             /* valid key press event */
> >> +             if (key >= 0) {
> >> +                     if (last_event == 1) {
> >> +                             /* check if we missed a release event */
> >> +                             input_report_key(dev->input, last_key,
> >> +                                             !last_event);
> >> +                     }
> >> +                     /* notify key press */
> >> +                     last_event = 1;
> >> +                     last_key = key;
> >> +                     input_report_key(dev->input, key, last_event);
> >> +             } else {
> >> +                     /* notify key release */
> >> +                     last_event = 0;
> >> +                     input_report_key(dev->input, last_key, last_event);
> >> +             }
> >> +     } else
> > 
> > Don't you need to clear interrupt here? You got it somehow...
> >
> 
> I can think of only one way in which this handler is called for some other
> device interrupt, that is when this irq line is shared between peripherals.
> In that case if interrupt is not meant for kbd then kbd shouldn't clear it.

You would be clearing IRQ condition _in your device_ so that sould not
affect the other device in any way.

> Isn't it fine???

I guess it should be OK.

> 
> >> +             return IRQ_NONE;
> >> +
> >> +     /* clear interrupt */
> >> +     writeb(0, dev->io_base + STATUS_REG);
> >> +
> >> +     return IRQ_HANDLED;
> >> +}
> >> +
> >> +static int __init spear_kbd_probe(struct platform_device *pdev)
> >> +{
> 
> [snip...]
> 
> >> +     ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
> >> +                     kbd);
> >> +     if (ret) {
> >> +             dev_err(&pdev->dev, "request_irq fail\n");
> >> +             goto err_iounmap;
> >> +     }
> >> +
> > 
> > Are you 100% sure the device is shut off at this point? Because if it
> > isn't you risk to get interrupt before you allocated your input device.
> >
> 
> I will check and place it at correct place.
> 
> >> +
> >> +     /* start key scan */
> >> +     val |= START_SCAN;
> >> +     writew(val, kbd->io_base + MODE_REG);
> > 
> > This should go into open() method.
> > 
> 
> OK.
> 
> >> +static int spear_kbd_remove(struct platform_device *pdev)
> >> +{
> >> +     struct spear_kbd *kbd = platform_get_drvdata(pdev);
> >> +     struct resource *res;
> >> +     u16 val;
> >> +     int irq;
> >> +
> >> +     val = readw(kbd->io_base + MODE_REG);
> >> +     val &= ~START_SCAN;
> >> +     writew(val, kbd->io_base + MODE_REG);
> > 
> > Need to go into close() method.
> >
> 
> OK.
>  
> >> +
> >> +     /* unregister input device */
> >> +     input_unregister_device(kbd->input);
> >> +     input_free_device(kbd->input);
> > 
> > No free after unregister.
> > 
> 
> OK.
> 
> >> +
> >> +     irq = platform_get_irq(pdev, 0);
> >> +     if (irq)
> >> +             free_irq(irq, pdev);
> > 
> > Can it ever be 0 here?
> > 
> 
> No. Will correct.
> 
> 
> >> +
> >> +static struct platform_driver spear_kbd_driver = {
> >> +     .probe          = spear_kbd_probe,
> >> +     .remove         = spear_kbd_remove,
> >> +     .suspend        = spear_kbd_suspend,
> >> +     .resume         = spear_kbd_resume,
> > 
> > Switch to dev_pm_ops please.
> > 
> 
> Ok.
> 
> 
> Thanks,
> rajeev.
> 

-- 
Dmitry

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-09-01  6:31         ` Dmitry Torokhov
  0 siblings, 0 replies; 245+ messages in thread
From: Dmitry Torokhov @ 2010-09-01  6:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 01, 2010 at 10:53:43AM +0530, rajeev wrote:
> Hi Dmitry 
> 
> Please find my answers embedded below.
> 
> On 8/30/2010 10:18 PM, Dmitry Torokhov wrote:
> > Hi Rajeev,
> > 
> 
> [snip...]
> 
> > 
> > First of all, please split platform modifications from the driver itself
> > (as I care about the latter but less about the former).
> >
> 
> Will be done.
>  
> >> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> >> index 9252940..c48b779 100644
> 
> [snip...]
> 
> >> +++ b/arch/arm/plat-spear/include/plat/keyboard.h
> >> @@ -0,0 +1,154 @@
> >> +/*
> >> + * arch/arm/plat-spear/include/plat/keyboard.h
> >> + *
> >> + * 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.
> >> + */
> >> +
> >> +#ifndef __PLAT_KEYBOARD_H
> >> +#define __PLAT_KEYBOARD_H
> >> +
> >> +#include <linux/bitops.h>
> >> +#include <linux/input.h>
> >> +#include <mach/misc_regs.h>
> >> +
> >> +#define KEY(row, col, val) (((row) << 28 | ((col) << 24) | (val)))
> >> +
> > 
> > Please use definitions from include/linux/input/matrix_keypad.h
> > 
> 
> Ok. I will check it and modify.
> 
> >> +#define DECLARE_KEYMAP(name) \
> >> +int name[] = {\
> >> +     KEY(0, 0, KEY_ESC), \
> >> +     KEY(0, 1, KEY_1), \
> >> +     KEY(0, 2, KEY_2), \
> >> +     KEY(0, 3, KEY_3), \
> >> +     KEY(0, 4, KEY_4), \
> >> +     KEY(0, 5, KEY_5), \
> >> +     KEY(0, 6, KEY_6), \
> >> +     KEY(0, 7, KEY_7), \
> >> +     KEY(0, 8, KEY_8), \
> >> +     KEY(1, 0, KEY_9), \
> >> +     KEY(1, 1, KEY_MINUS), \
> >> +     KEY(1, 2, KEY_EQUAL), \
> >> +     KEY(1, 3, KEY_BACKSPACE), \
> >> +     KEY(1, 4, KEY_TAB), \
> >> +     KEY(1, 5, KEY_Q), \
> >> +     KEY(1, 6, KEY_W), \
> >> +     KEY(1, 7, KEY_E), \
> >> +     KEY(1, 8, KEY_R), \
> >> +     KEY(2, 0, KEY_T), \
> >> +     KEY(2, 1, KEY_Y), \
> >> +     KEY(2, 2, KEY_U), \
> >> +     KEY(2, 3, KEY_I), \
> >> +     KEY(2, 4, KEY_O), \
> >> +     KEY(2, 5, KEY_P), \
> >> +     KEY(2, 6, KEY_LEFTBRACE), \
> >> +     KEY(2, 7, KEY_RIGHTBRACE), \
> >> +     KEY(2, 8, KEY_ENTER), \
> >> +     KEY(3, 0, KEY_LEFTCTRL), \
> >> +     KEY(3, 1, KEY_A), \
> >> +     KEY(3, 2, KEY_S), \
> >> +     KEY(3, 3, KEY_D), \
> >> +     KEY(3, 4, KEY_F), \
> >> +     KEY(3, 5, KEY_G), \
> >> +     KEY(3, 6, KEY_H), \
> >> +     KEY(3, 7, KEY_J), \
> >> +     KEY(3, 8, KEY_K), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(4, 0, KEY_L), \
> >> +     KEY(4, 1, KEY_SEMICOLON), \
> >> +     KEY(4, 2, KEY_APOSTROPHE), \
> >> +     KEY(4, 3, KEY_GRAVE), \
> >> +     KEY(4, 4, KEY_LEFTSHIFT), \
> >> +     KEY(4, 5, KEY_BACKSLASH), \
> >> +     KEY(4, 6, KEY_Z), \
> >> +     KEY(4, 7, KEY_X), \
> >> +     KEY(4, 8, KEY_C), \
> >> +     KEY(5, 0, KEY_V), \
> >> +     KEY(5, 1, KEY_B), \
> >> +     KEY(5, 2, KEY_N), \
> >> +     KEY(5, 3, KEY_M), \
> >> +     KEY(5, 4, KEY_COMMA), \
> >> +     KEY(5, 5, KEY_DOT), \
> >> +     KEY(5, 6, KEY_SLASH), \
> >> +     KEY(5, 7, KEY_RIGHTSHIFT), \
> >> +     KEY(5, 8, KEY_KPASTERISK), \
> >> +     KEY(6, 0, KEY_LEFTALT), \
> >> +     KEY(6, 1, KEY_SPACE), \
> >> +     KEY(6, 2, KEY_CAPSLOCK), \
> >> +     KEY(6, 3, KEY_F1), \
> >> +     KEY(6, 4, KEY_F2), \
> >> +     KEY(6, 5, KEY_F3), \
> >> +     KEY(6, 6, KEY_F4), \
> >> +     KEY(6, 7, KEY_F5), \
> >> +     KEY(6, 8, KEY_F6), \
> >> +     KEY(7, 0, KEY_F7), \
> >> +     KEY(7, 1, KEY_F8), \
> >> +     KEY(7, 2, KEY_F9), \
> >> +     KEY(7, 3, KEY_F10), \
> >> +     KEY(7, 4, KEY_NUMLOCK), \
> >> +     KEY(7, 5, KEY_SCROLLLOCK), \
> >> +     KEY(7, 6, KEY_KP7), \
> >> +     KEY(7, 7, KEY_KP8), \
> >> +     KEY(7, 8, KEY_KP9), \
> >> +     KEY(8, 0, KEY_KPMINUS), \
> >> +     KEY(8, 1, KEY_KP4), \
> >> +     KEY(8, 2, KEY_KP5), \
> >> +     KEY(8, 3, KEY_KP6), \
> >> +     KEY(8, 4, KEY_KPPLUS), \
> >> +     KEY(8, 5, KEY_KP1), \
> >> +     KEY(8, 6, KEY_KP2), \
> >> +     KEY(8, 7, KEY_KP3), \
> >> +     KEY(8, 8, KEY_KP0), \
> >> +};
> > 
> > Hm, I'd expect this to be in particular board code, not in the header
> > file.
> > 
> 
> Currently we have support for evaluation boards only and all of them will have
> this structure in their board source files. In order to remove redundant code we
> kept it in plat/keyboard.h.
> 

So call it "spear_default_keymap" and put it right into the driver? And
then allow platform code override it.

> >> +/**
> >> + * struct kbd_platform_data - keymap for spear keyboards
> >> + * keymap: pointer to array of values encoded with KEY() macro representing
> >> + * keymap
> >> + * keymapsize: number of entries (initialized) in this keymap
> >> + * rep: current values for autorepeat parameters
> >> + *
> >> + * This structure is supposed to be used by platform code to supply
> >> + * keymaps to drivers that implement keyboards.
> >> + */
> >> +struct kbd_platform_data {
> >> +     int *keymap;
> >> +     unsigned int keymapsize;
> >> +     unsigned int rep:1;
> > 
> > Bool please.
> > 
> 
> OK
> 
> >> +};
> >> +
> >> +/* 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)
> >> +{
> >> +#ifdef CONFIG_ARCH_SPEAR13XX
> >> +#define KBD_PAD_SEL  (BIT(18) | BIT(20) | BIT(22) | BIT(24) | BIT(26))
> >> +
> >> +     u32 val;
> >> +     /* Workaround:Setting bit for routing it to the IP */
> >> +     val = readl(PAD_FUNCTION_EN_2);
> >> +     val &= ~KBD_PAD_SEL;
> >> +     writel(val, PAD_FUNCTION_EN_2);
> > 
> > Why does it belong here?
> > 
> 
> Sorry. It will be handled in padmux framework.
> 
> >> +#endif
> >> +     pdev->dev.platform_data = data;
> >> +}
> >> +#endif /* __PLAT_KEYBOARD_H */
> >> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> >> index 9cc488d..2d7e3a8 100644
> >> --- a/drivers/input/keyboard/Kconfig
> >> +++ b/drivers/input/keyboard/Kconfig
> >> @@ -424,6 +424,14 @@ config KEYBOARD_OMAP
> >>         To compile this driver as a module, choose M here: the
> >>         module will be called omap-keypad.
> >>
> >> +config KEYBOARD_SPEAR
> >> +     tristate "ST SPEAR keyboard support"
> > 
> > No arch/platform dependencies?
> > 
> 
> Will add them.
> 
> >> +     help
> 
> [snip...]
> 
> >> +struct spear_kbd {
> >> +     struct input_dev *input;
> >> +     void __iomem *io_base;          /* Keyboard Base Address */
> >> +     struct clk *clk;
> >> +     int *keymap;
> > 
> > You need a copy of keymap here so that userspace can modify it safely
> > via EVIOCSKEYCODE.
> > 
> 
> We have one copy of struct spear_kbd per device structure. I think it
> will be fine if we change this structure only. And so don't need to copy
> another structure in driver.

Normally such platform data should be declared as 'const' and drivers
should not modify such data. Also unbinding device from driver and
rebinding later should restore the device into pristine state. Having a
copy of keymap in spear_kbd allows to achieve such behavior.

> 
> >> +};
> >> +/* TODO: Need to optimize this function */
> >> +static inline int get_key_value(struct spear_kbd *dev, int row, int col)
> >> +{
> >> +     int i, key;
> >> +     int *keymap = dev->keymap;
> >> +
> >> +     key = KEY(row, col, 0);
> >> +     for (i = 0; keymap[i] != 0; i++)
> >> +             if ((keymap[i] & KEY_MASK) == key)
> >> +                     return keymap[i] & KEY_VALUE;
> >> +     return -ENOKEY;
> >> +}
> >> +
> >> +static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
> >> +{
> >> +     struct spear_kbd *dev = dev_id;
> >> +     static u8 last_key ;
> >> +     static u8 last_event;
> > 
> > No statics please, pull it into spear_kbd structure.
> >
> 
> Ok
>  
> >> +     int key;
> >> +     u8 sts, val = 0;
> >> +
> >> +     if (dev == NULL) {
> > 
> > How can it be?
> > 
> 
> Not needed, will be fixed.
> 
> >> +             pr_err("Keyboard: Invalid dev_id in irq handler\n");
> >> +             return IRQ_NONE;
> >> +     }
> >> +
> >> +     sts = readb(dev->io_base + STATUS_REG);
> >> +     if (sts & DATA_AVAIL) {
> >> +             /* following reads active (row, col) pair */
> >> +             val = readb(dev->io_base + DATA_REG);
> >> +             key = get_key_value(dev, (val & ROW_MASK)>>ROW_SHIFT, (val
> >> +                                     & COLUMN_MASK));
> >> +
> >> +             /* valid key press event */
> >> +             if (key >= 0) {
> >> +                     if (last_event == 1) {
> >> +                             /* check if we missed a release event */
> >> +                             input_report_key(dev->input, last_key,
> >> +                                             !last_event);
> >> +                     }
> >> +                     /* notify key press */
> >> +                     last_event = 1;
> >> +                     last_key = key;
> >> +                     input_report_key(dev->input, key, last_event);
> >> +             } else {
> >> +                     /* notify key release */
> >> +                     last_event = 0;
> >> +                     input_report_key(dev->input, last_key, last_event);
> >> +             }
> >> +     } else
> > 
> > Don't you need to clear interrupt here? You got it somehow...
> >
> 
> I can think of only one way in which this handler is called for some other
> device interrupt, that is when this irq line is shared between peripherals.
> In that case if interrupt is not meant for kbd then kbd shouldn't clear it.

You would be clearing IRQ condition _in your device_ so that sould not
affect the other device in any way.

> Isn't it fine???

I guess it should be OK.

> 
> >> +             return IRQ_NONE;
> >> +
> >> +     /* clear interrupt */
> >> +     writeb(0, dev->io_base + STATUS_REG);
> >> +
> >> +     return IRQ_HANDLED;
> >> +}
> >> +
> >> +static int __init spear_kbd_probe(struct platform_device *pdev)
> >> +{
> 
> [snip...]
> 
> >> +     ret = request_irq(irq, spear_kbd_interrupt, 0, "keyboard",
> >> +                     kbd);
> >> +     if (ret) {
> >> +             dev_err(&pdev->dev, "request_irq fail\n");
> >> +             goto err_iounmap;
> >> +     }
> >> +
> > 
> > Are you 100% sure the device is shut off at this point? Because if it
> > isn't you risk to get interrupt before you allocated your input device.
> >
> 
> I will check and place it at correct place.
> 
> >> +
> >> +     /* start key scan */
> >> +     val |= START_SCAN;
> >> +     writew(val, kbd->io_base + MODE_REG);
> > 
> > This should go into open() method.
> > 
> 
> OK.
> 
> >> +static int spear_kbd_remove(struct platform_device *pdev)
> >> +{
> >> +     struct spear_kbd *kbd = platform_get_drvdata(pdev);
> >> +     struct resource *res;
> >> +     u16 val;
> >> +     int irq;
> >> +
> >> +     val = readw(kbd->io_base + MODE_REG);
> >> +     val &= ~START_SCAN;
> >> +     writew(val, kbd->io_base + MODE_REG);
> > 
> > Need to go into close() method.
> >
> 
> OK.
>  
> >> +
> >> +     /* unregister input device */
> >> +     input_unregister_device(kbd->input);
> >> +     input_free_device(kbd->input);
> > 
> > No free after unregister.
> > 
> 
> OK.
> 
> >> +
> >> +     irq = platform_get_irq(pdev, 0);
> >> +     if (irq)
> >> +             free_irq(irq, pdev);
> > 
> > Can it ever be 0 here?
> > 
> 
> No. Will correct.
> 
> 
> >> +
> >> +static struct platform_driver spear_kbd_driver = {
> >> +     .probe          = spear_kbd_probe,
> >> +     .remove         = spear_kbd_remove,
> >> +     .suspend        = spear_kbd_suspend,
> >> +     .resume         = spear_kbd_resume,
> > 
> > Switch to dev_pm_ops please.
> > 
> 
> Ok.
> 
> 
> Thanks,
> rajeev.
> 

-- 
Dmitry

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

* Re: [PATCH 21/74] ST SPEAr : Added keyboard support
  2010-09-01  6:31         ` Dmitry Torokhov
@ 2010-09-01  7:01           ` viresh kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-01  7:01 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Pratyush ANAND, Rajeev KUMAR, Bhupesh SHARMA, Armando VISCONTI,
	linux-input, Vipin KUMAR, Shiraz HASHIM, Vipul Kumar SAMAR,
	Deepak SIKRI, linux-arm-kernel

On 9/1/2010 12:01 PM, Dmitry Torokhov wrote:
>>>> +#define DECLARE_KEYMAP(name) \
>>>> > >> +int name[] = {\
>>>> > >> +     KEY(0, 0, KEY_ESC), \

[snip...]

>>>> > >> +     KEY(8, 6, KEY_KP2), \
>>>> > >> +     KEY(8, 7, KEY_KP3), \
>>>> > >> +     KEY(8, 8, KEY_KP0), \
>>>> > >> +};
>>> > >
>>> > > Hm, I'd expect this to be in particular board code, not in the header
>>> > > file.
>>> > >
>> >
>> > Currently we have support for evaluation boards only and all of them will have
>> > this structure in their board source files. In order to remove redundant code we
>> > kept it in plat/keyboard.h.
>> >
> So call it "spear_default_keymap" and put it right into the driver? And
> then allow platform code override it.
> 

Renaming is fine but I would still like to keep spear_default_keymap in
platform files instead of driver.

>>>> > >> +struct spear_kbd {
>>>> > >> +     struct input_dev *input;
>>>> > >> +     void __iomem *io_base;          /* Keyboard Base Address */
>>>> > >> +     struct clk *clk;
>>>> > >> +     int *keymap;
>>> > >
>>> > > You need a copy of keymap here so that userspace can modify it safely
>>> > > via EVIOCSKEYCODE.
>>> > >
>> >
>> > We have one copy of struct spear_kbd per device structure. I think it
>> > will be fine if we change this structure only. And so don't need to copy
>> > another structure in driver.
> Normally such platform data should be declared as 'const' and drivers
> should not modify such data. Also unbinding device from driver and
> rebinding later should restore the device into pristine state. Having a
> copy of keymap in spear_kbd allows to achieve such behavior.
> 

OK.

viresh.

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

* [PATCH 21/74] ST SPEAr : Added keyboard support
@ 2010-09-01  7:01           ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-01  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 12:01 PM, Dmitry Torokhov wrote:
>>>> +#define DECLARE_KEYMAP(name) \
>>>> > >> +int name[] = {\
>>>> > >> +     KEY(0, 0, KEY_ESC), \

[snip...]

>>>> > >> +     KEY(8, 6, KEY_KP2), \
>>>> > >> +     KEY(8, 7, KEY_KP3), \
>>>> > >> +     KEY(8, 8, KEY_KP0), \
>>>> > >> +};
>>> > >
>>> > > Hm, I'd expect this to be in particular board code, not in the header
>>> > > file.
>>> > >
>> >
>> > Currently we have support for evaluation boards only and all of them will have
>> > this structure in their board source files. In order to remove redundant code we
>> > kept it in plat/keyboard.h.
>> >
> So call it "spear_default_keymap" and put it right into the driver? And
> then allow platform code override it.
> 

Renaming is fine but I would still like to keep spear_default_keymap in
platform files instead of driver.

>>>> > >> +struct spear_kbd {
>>>> > >> +     struct input_dev *input;
>>>> > >> +     void __iomem *io_base;          /* Keyboard Base Address */
>>>> > >> +     struct clk *clk;
>>>> > >> +     int *keymap;
>>> > >
>>> > > You need a copy of keymap here so that userspace can modify it safely
>>> > > via EVIOCSKEYCODE.
>>> > >
>> >
>> > We have one copy of struct spear_kbd per device structure. I think it
>> > will be fine if we change this structure only. And so don't need to copy
>> > another structure in driver.
> Normally such platform data should be declared as 'const' and drivers
> should not modify such data. Also unbinding device from driver and
> rebinding later should restore the device into pristine state. Having a
> copy of keymap in spear_kbd allows to achieve such behavior.
> 

OK.

viresh.

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01  4:13           ` Vipin Kumar
@ 2010-09-01 10:45             ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 10:45 UTC (permalink / raw)
  To: Vipin Kumar
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
> > Hi,
> > 
> > On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
> >>> Nack, breaking ABI Is not allowed in Linux.
> >> I could not understand your point. Can you please elaborate. How does this patch 
> >> break ABI
> > 
> > You are changing data structure (struct nand_ecclayout) used for in MTD
> > ioctl. Tha ioctl is part of the Linux ABI. By changing the data
> > structure, you are breaking the ABI. This means that current binaries
> > would stop working with newer versions of the Linux kernel if we'd
> > accept your patch.
> > 
> Hello,
> 
> The only change that I have made is increasing the number of bytes to keep ecc. 

Right, but this break ABI.

> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
> locations to be equal to the maximum spare area possible.

May be.

> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
> ecc positions) depending on the algorithm used to generate ecc. 
> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
> logical to place it in spare area since the linux image supports 4096 page but 
> the problem is that the ecc locations supported by linux are less than the 
> practically possible scenario so in effect this change is an improvement in linux

Yes, this is historical and a bit unfortunate, but you cannot break ABI
even if you have reasons like that

> Please let me know if you disagree

Please, create an app which uses 'struct nand_ecclayout' and compile it
against the old headers. Check that it works. Then do you kernel
modification and run the same program (without re-compiling) and my
prediction is that it won't work. This is what I call ABI breaking which
is disallowed.

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 10:45             ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
> > Hi,
> > 
> > On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
> >>> Nack, breaking ABI Is not allowed in Linux.
> >> I could not understand your point. Can you please elaborate. How does this patch 
> >> break ABI
> > 
> > You are changing data structure (struct nand_ecclayout) used for in MTD
> > ioctl. Tha ioctl is part of the Linux ABI. By changing the data
> > structure, you are breaking the ABI. This means that current binaries
> > would stop working with newer versions of the Linux kernel if we'd
> > accept your patch.
> > 
> Hello,
> 
> The only change that I have made is increasing the number of bytes to keep ecc. 

Right, but this break ABI.

> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
> locations to be equal to the maximum spare area possible.

May be.

> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
> ecc positions) depending on the algorithm used to generate ecc. 
> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
> logical to place it in spare area since the linux image supports 4096 page but 
> the problem is that the ecc locations supported by linux are less than the 
> practically possible scenario so in effect this change is an improvement in linux

Yes, this is historical and a bit unfortunate, but you cannot break ABI
even if you have reasons like that

> Please let me know if you disagree

Please, create an app which uses 'struct nand_ecclayout' and compile it
against the old headers. Check that it works. Then do you kernel
modification and run the same program (without re-compiling) and my
prediction is that it won't work. This is what I call ABI breaking which
is disallowed.

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 10:45             ` Artem Bityutskiy
@ 2010-09-01 11:04               ` Vipin Kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-01 11:04 UTC (permalink / raw)
  To: dedekind1, dwmw2, dwmw2
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, linux-arm-kernel

On 9/1/2010 4:15 PM, Artem Bityutskiy wrote:
> On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
>> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
>>> Hi,
>>>
>>> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>>>> Nack, breaking ABI Is not allowed in Linux.
>>>> I could not understand your point. Can you please elaborate. How does this patch 
>>>> break ABI
>>>
>>> You are changing data structure (struct nand_ecclayout) used for in MTD
>>> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
>>> structure, you are breaking the ABI. This means that current binaries
>>> would stop working with newer versions of the Linux kernel if we'd
>>> accept your patch.
>>>
>> Hello,
>>
>> The only change that I have made is increasing the number of bytes to keep ecc. 
> 
> Right, but this break ABI.
> 
>> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
>> locations to be equal to the maximum spare area possible.
> 
> May be.
> 
>> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
>> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
>> ecc positions) depending on the algorithm used to generate ecc. 
>> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
>> logical to place it in spare area since the linux image supports 4096 page but 
>> the problem is that the ecc locations supported by linux are less than the 
>> practically possible scenario so in effect this change is an improvement in linux
> 

Hello David/Artem,

I got the point, but this change is essential (at least for me). It may be 
essential to others as well in near future. Please let me know how to handle more 
than 64 bytes of ecc

> Yes, this is historical and a bit unfortunate, but you cannot break ABI
> even if you have reasons like that
> 
>> Please let me know if you disagree
> 
> Please, create an app which uses 'struct nand_ecclayout' and compile it
> against the old headers. Check that it works. Then do you kernel
> modification and run the same program (without re-compiling) and my
> prediction is that it won't work. This is what I call ABI breaking which
> is disallowed.
> 

Regards
Vipin

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 11:04               ` Vipin Kumar
  0 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-01 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 4:15 PM, Artem Bityutskiy wrote:
> On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
>> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
>>> Hi,
>>>
>>> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>>>> Nack, breaking ABI Is not allowed in Linux.
>>>> I could not understand your point. Can you please elaborate. How does this patch 
>>>> break ABI
>>>
>>> You are changing data structure (struct nand_ecclayout) used for in MTD
>>> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
>>> structure, you are breaking the ABI. This means that current binaries
>>> would stop working with newer versions of the Linux kernel if we'd
>>> accept your patch.
>>>
>> Hello,
>>
>> The only change that I have made is increasing the number of bytes to keep ecc. 
> 
> Right, but this break ABI.
> 
>> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
>> locations to be equal to the maximum spare area possible.
> 
> May be.
> 
>> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
>> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
>> ecc positions) depending on the algorithm used to generate ecc. 
>> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
>> logical to place it in spare area since the linux image supports 4096 page but 
>> the problem is that the ecc locations supported by linux are less than the 
>> practically possible scenario so in effect this change is an improvement in linux
> 

Hello David/Artem,

I got the point, but this change is essential (at least for me). It may be 
essential to others as well in near future. Please let me know how to handle more 
than 64 bytes of ecc

> Yes, this is historical and a bit unfortunate, but you cannot break ABI
> even if you have reasons like that
> 
>> Please let me know if you disagree
> 
> Please, create an app which uses 'struct nand_ecclayout' and compile it
> against the old headers. Check that it works. Then do you kernel
> modification and run the same program (without re-compiling) and my
> prediction is that it won't work. This is what I call ABI breaking which
> is disallowed.
> 

Regards
Vipin

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 11:04               ` Vipin Kumar
@ 2010-09-01 21:23                 ` Ryan Mallon
  -1 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 21:23 UTC (permalink / raw)
  To: Vipin Kumar
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	dedekind1, Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR,
	linux-mtd, Deepak SIKRI, dwmw2, linux-arm-kernel

On 09/01/2010 11:04 PM, Vipin Kumar wrote:
> On 9/1/2010 4:15 PM, Artem Bityutskiy wrote:
>> On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
>>> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
>>>> Hi,
>>>>
>>>> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>>>>> Nack, breaking ABI Is not allowed in Linux.
>>>>> I could not understand your point. Can you please elaborate. How does this patch 
>>>>> break ABI
>>>>
>>>> You are changing data structure (struct nand_ecclayout) used for in MTD
>>>> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
>>>> structure, you are breaking the ABI. This means that current binaries
>>>> would stop working with newer versions of the Linux kernel if we'd
>>>> accept your patch.
>>>>
>>> Hello,
>>>
>>> The only change that I have made is increasing the number of bytes to keep ecc. 
>>
>> Right, but this break ABI.
>>
>>> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
>>> locations to be equal to the maximum spare area possible.
>>
>> May be.
>>
>>> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
>>> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
>>> ecc positions) depending on the algorithm used to generate ecc. 
>>> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
>>> logical to place it in spare area since the linux image supports 4096 page but 
>>> the problem is that the ecc locations supported by linux are less than the 
>>> practically possible scenario so in effect this change is an improvement in linux
>>
> 
> Hello David/Artem,
> 
> I got the point, but this change is essential (at least for me). It may be 
> essential to others as well in near future. Please let me know how to handle more 
> than 64 bytes of ecc
> 
>> Yes, this is historical and a bit unfortunate, but you cannot break ABI
>> even if you have reasons like that

We have run into this same problem using large page NAND chips. Our fix
in the past has been the same as presented here simply because it is
easy and for custom boards we do not care if we break the kernel ABI
since the kernel will only be used on our custom board.

However, we are interested in having a proper solution to this problem.
Basically the size of the eccpos array shouldn't be a fixed. Probably
there should be two ioctls, one to get the size of the eccpos array and
a second to get the actual array.

It is unfortunate that we already have the obsolete nand_oobinfo struct,
and any fix to this problem is probably going to obsolete the
nand_ecclayout struct, but we do need to fix this as the existing
infrastructure is not suitable for larger nand chips.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 21:23                 ` Ryan Mallon
  0 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01/2010 11:04 PM, Vipin Kumar wrote:
> On 9/1/2010 4:15 PM, Artem Bityutskiy wrote:
>> On Wed, 2010-09-01 at 09:43 +0530, Vipin Kumar wrote:
>>> On 9/1/2010 5:06 AM, Artem Bityutskiy wrote:
>>>> Hi,
>>>>
>>>> On Tue, 2010-08-31 at 12:04 +0530, Vipin Kumar wrote:
>>>>>> Nack, breaking ABI Is not allowed in Linux.
>>>>> I could not understand your point. Can you please elaborate. How does this patch 
>>>>> break ABI
>>>>
>>>> You are changing data structure (struct nand_ecclayout) used for in MTD
>>>> ioctl. Tha ioctl is part of the Linux ABI. By changing the data
>>>> structure, you are breaking the ABI. This means that current binaries
>>>> would stop working with newer versions of the Linux kernel if we'd
>>>> accept your patch.
>>>>
>>> Hello,
>>>
>>> The only change that I have made is increasing the number of bytes to keep ecc. 
>>
>> Right, but this break ABI.
>>
>>> Since the ecc is generally kept in spare area, it makes sense to have the ecc 
>>> locations to be equal to the maximum spare area possible.
>>
>> May be.
>>
>>> A NAND page with a page size of 4096 would contain a spare area of 128 bytes. 
>>> Now, ecc for the page can be less/more than 64 bytes(currently allocated for 
>>> ecc positions) depending on the algorithm used to generate ecc. 
>>> Incidently, in our case the ecc can fit in 104 bytes and this is still quite 
>>> logical to place it in spare area since the linux image supports 4096 page but 
>>> the problem is that the ecc locations supported by linux are less than the 
>>> practically possible scenario so in effect this change is an improvement in linux
>>
> 
> Hello David/Artem,
> 
> I got the point, but this change is essential (at least for me). It may be 
> essential to others as well in near future. Please let me know how to handle more 
> than 64 bytes of ecc
> 
>> Yes, this is historical and a bit unfortunate, but you cannot break ABI
>> even if you have reasons like that

We have run into this same problem using large page NAND chips. Our fix
in the past has been the same as presented here simply because it is
easy and for custom boards we do not care if we break the kernel ABI
since the kernel will only be used on our custom board.

However, we are interested in having a proper solution to this problem.
Basically the size of the eccpos array shouldn't be a fixed. Probably
there should be two ioctls, one to get the size of the eccpos array and
a second to get the actual array.

It is unfortunate that we already have the obsolete nand_oobinfo struct,
and any fix to this problem is probably going to obsolete the
nand_ecclayout struct, but we do need to fix this as the existing
infrastructure is not suitable for larger nand chips.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 21:23                 ` Ryan Mallon
@ 2010-09-01 21:54                   ` Kevin Cernekee
  -1 siblings, 0 replies; 245+ messages in thread
From: Kevin Cernekee @ 2010-09-01 21:54 UTC (permalink / raw)
  To: Vipin Kumar, Ryan Mallon
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	dedekind1, Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR,
	linux-mtd, Deepak SIKRI, Brian Norris, dwmw2, linux-arm-kernel

On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
> However, we are interested in having a proper solution to this problem.

I would suggest using this patch as a starting point - could you
please review the changes and try it out?

http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160

Thanks.

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 21:54                   ` Kevin Cernekee
  0 siblings, 0 replies; 245+ messages in thread
From: Kevin Cernekee @ 2010-09-01 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
> However, we are interested in having a proper solution to this problem.

I would suggest using this patch as a starting point - could you
please review the changes and try it out?

http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160

Thanks.

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 21:54                   ` Kevin Cernekee
@ 2010-09-01 22:21                     ` Ryan Mallon
  -1 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 22:21 UTC (permalink / raw)
  To: Kevin Cernekee
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	dedekind1, Armando VISCONTI, Vipin Kumar, Shiraz HASHIM,
	Rajeev KUMAR, linux-mtd, Deepak SIKRI, Brian Norris, dwmw2,
	linux-arm-kernel

On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>> However, we are interested in having a proper solution to this problem.
> 
> I would suggest using this patch as a starting point - could you
> please review the changes and try it out?
> 
> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160

That patch still breaks the ABI by renaming struct nand_ecclayout to
nand_ecclayout_user. Any application using the old names will have to be
rewritten to compile against a new kernel.

The old interface should remain unchanged in that include/mtd/mtd-abi.h.
If an application using the old interface calls any of the ecc ioctls
for a nand chip with > 64 bytes ecc it should return an error.

I still think the eccpos field should be a pointer, so that it can
allocate as much space as is needed for the ecc. This also means that
the kernel doesn't need to be changed every time a new NAND chips
appears with a bigger ecc size.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 22:21                     ` Ryan Mallon
  0 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 22:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>> However, we are interested in having a proper solution to this problem.
> 
> I would suggest using this patch as a starting point - could you
> please review the changes and try it out?
> 
> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160

That patch still breaks the ABI by renaming struct nand_ecclayout to
nand_ecclayout_user. Any application using the old names will have to be
rewritten to compile against a new kernel.

The old interface should remain unchanged in that include/mtd/mtd-abi.h.
If an application using the old interface calls any of the ecc ioctls
for a nand chip with > 64 bytes ecc it should return an error.

I still think the eccpos field should be a pointer, so that it can
allocate as much space as is needed for the ecc. This also means that
the kernel doesn't need to be changed every time a new NAND chips
appears with a bigger ecc size.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-08-30 10:43   ` Viresh KUMAR
@ 2010-09-01 22:36     ` Linus Walleij
  -1 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-01 22:36 UTC (permalink / raw)
  To: Viresh KUMAR
  Cc: pratyush.anand, vipulkumar.samar, bhupesh.sharma,
	Sebastian Rasmussen, armando.visconti, Alessandro Rubini,
	Vipin Kumar, shiraz.hashim, rajeev-dlh.kumar, linux-mtd,
	deepak.sikri, dwmw2, linux-arm-kernel

2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:

> From: Vipin Kumar <vipin.kumar@st.com>
>
> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
> interfacing with NAND devices.
> This patch adds the support for glue logic for NAND flash on SPEAr boards

OK...

> (...)
>  create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
>  create mode 100644 arch/arm/plat-spear/include/plat/nand.h
>  create mode 100644 drivers/mtd/nand/spear_nand.c

spear_nand.c?

Why not fsmc-nand.c or similar if this is the name of the block.
We have this in U300, Nomadik NHK8815 and other platforms too,
it doesn't have much to do with SPEAr actually...

Also, what are the include files doing in plat-spear since we have
the same hardware in other platforms? Move them to include/linux/mtd/
so we can use them please.

I *highly* suspect that this driver duplicates some code found in
drivers/mtd/nand/nomadik_nand.c because it's the same silicon.

Alessandro can judge on this, but I have a feeling that driver
should be replaced by this, more mature driver.

> (...)
> diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h
> new file mode 100644
> index 0000000..c0fdcd3
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/fsmc.h
> @@ -0,0 +1,109 @@
> +/*
> + * arch/arm/plat-spear/include/plat/fsmc.h
> + *
> + * SPEAr platform nand interface header file

Replace "SPEAr platform" for "FSMC - Flexible Static Media Controller"

> + *
> + * 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 __PLAT_FSMC_H
> +#define __PLAT_FSMC_H

Change these according to the new suggested placement.

> +
> +#include <linux/delay.h>
> +#include <linux/types.h>
> +#include <asm/param.h>
> +
> +#define FSMC_MAX_NAND_BANKS    4
> +
> +struct nand_bank_regs {
> +       u32 pc;
> +       u32 sts;
> +       u32 comm;
> +       u32 attrib;
> +       u32 ioata;
> +       u32 ecc1;
> +       u32 ecc2;
> +       u32 ecc3;
> +};
> +
> +struct fsmc_regs {
> +       u8 reserved_1[0x40];
> +       struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
> +       u8 reserved_2[0xfe0 - 0xc0];
> +       u32 peripid0;                   /* 0xfe0 */
> +       u32 peripid1;                   /* 0xfe4 */
> +       u32 peripid2;                   /* 0xfe8 */
> +       u32 peripid3;                   /* 0xfec */
> +       u32 pcellid0;                   /* 0xff0 */
> +       u32 pcellid1;                   /* 0xff4 */
> +       u32 pcellid2;                   /* 0xff8 */
> +       u32 pcellid3;                   /* 0xffc */

Do you need to have an u32 for each of these registers?
I think this is the AMBA PrimeCell ID registers which means
that the latter four are just "0xB105F00D" (clever) and
then padded to 32 bits. (Correct me if I'm wrong.)

You can find macros for extracting the important parts of the
field in include/linux/amba/bus.h

> +};
> +
> +#define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ)
> +
> +/* pc register definitions */
> +#define FSMC_RESET             (1 << 0)
> +#define FSMC_WAITON            (1 << 1)
> +#define FSMC_ENABLE            (1 << 2)
> +#define FSMC_DEVTYPE_NAND      (1 << 3)
> +#define FSMC_DEVWID_8          (0 << 4)
> +#define FSMC_DEVWID_16         (1 << 4)
> +#define FSMC_ECCEN             (1 << 6)
> +#define FSMC_ECCPLEN_512       (0 << 7)
> +#define FSMC_ECCPLEN_256       (1 << 7)
> +#define FSMC_TCLR_1            (1 << 9)
> +#define FSMC_TAR_1             (1 << 13)
> +
> +/* sts register definitions */
> +#define FSMC_CODE_RDY          (1 << 15)
> +
> +/* comm register definitions */
> +#define FSMC_TSET_0            (0 << 0)
> +#define FSMC_TWAIT_6           (6 << 8)
> +#define FSMC_THOLD_4           (4 << 16)
> +#define FSMC_THIZ_1            (1 << 24)
> +
> +/* peripid2 register definitions */
> +#define FSMC_REVISION_MSK      (0xf)
> +#define FSMC_REVISION_SHFT     (0x4)
> +
> +#define FSMC_VER1              1
> +#define FSMC_VER2              2
> +#define FSMC_VER3              3
> +#define FSMC_VER4              4
> +#define FSMC_VER5              5
> +#define FSMC_VER6              6
> +#define FSMC_VER7              7
> +#define FSMC_VER8              8
> +
> +static inline u32 get_fsmc_version(struct fsmc_regs *regs)
> +{
> +       return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
> +                               FSMC_REVISION_MSK;

Use macros from <linux/amba/bus.h> to extract version if
possible.

> +}
> +
> +/*
> + * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
> + * and it has to be read consecutively and immediately after the 512
> + * byte data block for hardware to generate the error bit offsets
> + * Managing the ecc bytes in the following way is easier. This way is
> + * similar to oobfree structure maintained already in u-boot nand driver
> + */
> +#define MAX_ECCPLACE_ENTRIES   32
> +
> +struct fsmc_nand_eccplace {
> +       u8 offset;
> +       u8 length;
> +};
> +
> +struct fsmc_eccplace {
> +       struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
> +};
> +
> +#endif /* __PLAT_FSMC_H */
> diff --git a/arch/arm/plat-spear/include/plat/nand.h b/arch/arm/plat-spear/include/plat/nand.h
> new file mode 100644
> index 0000000..712b4b0
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/nand.h
> @@ -0,0 +1,76 @@
> +/*
> + * arch/arm/plat-spear/include/plat/nand.h
> + *
> + * NAND macros for SPEAr platform
> + *

Replace "SPEAr platform" for "FSMC - Flexible Static Media Controller"

> + * 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 __PLAT_NAND_H
> +#define __PLAT_NAND_H

Change this to reflect the new suggested placement.

> +
> +#include <linux/mtd/partitions.h>
> +
> +#define SPEAR_NAND_BW8         1
> +#define SPEAR_NAND_BW16                2

FSMC_NAND*?

> +
> +#if defined(CONFIG_MACH_SPEAR310)
> +#define PLAT_NAND_CLE          (1 << 17)
> +#define PLAT_NAND_ALE          (1 << 16)
> +#else
> +#define PLAT_NAND_CLE          (1 << 16)
> +#define PLAT_NAND_ALE          (1 << 17)
> +#endif

You have to handle this some other way using platform data
I think.

> +
> +struct nand_platform_data {

fsmc_platform_data!

> +       /*
> +        * Board specific information
> +        * Set from arch/arm/mach-spear<mach>/spear<mach>_evb.c
> +        */

Skip this comment...

> +
> +       /*
> +        * Use the default partition table present in the NAND driver if
> +        * partitions is set to NULL.
> +        */
> +       struct mtd_partition    *partitions;
> +       unsigned int            nr_partitions;
> +       unsigned int            options;
> +       unsigned int            width;
> +
> +       /*
> +        * Machine specific information
> +        * Set from arch/arm/mach-spear<mach>/spear<mach>.c
> +        */
> +
> +       unsigned int            bank;
> +       /*
> +        * Set to NULL if bank selection is not supported by machine
> +        * architecture
> +        * -> eg. when controller supports only one bank
> +        */
> +       void                    (*select_bank)(u32 bank, u32 busw);
> +};
> +
> +/* This function is used to set platform data field of pdev->dev */
> +static inline void nand_set_plat_data(struct platform_device *pdev,

What about naming this fsmc_set_plat_data()

> +               struct mtd_partition *partitions, unsigned int nr_partitions,
> +               unsigned int options, unsigned int width)
> +{
> +       struct nand_platform_data *nand_plat_data;
> +       nand_plat_data = dev_get_platdata(&pdev->dev);
> +
> +       if (partitions) {
> +               nand_plat_data->partitions = partitions;
> +               nand_plat_data->nr_partitions = nr_partitions;
> +       }
> +
> +       nand_plat_data->options = options;
> +       nand_plat_data->width = width;
> +}
> +
> +#endif /* __PLAT_NAND_H */
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 8b4b67c..89d35d1 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -531,4 +531,10 @@ config MTD_NAND_JZ4740
>        help
>                Enables support for NAND Flash on JZ4740 SoC based boards.
>
> +config MTD_NAND_SPEAR

MTD_NAND_FSMC

> +       tristate "Support for NAND on SPEAr platforms"

skip "on SPEAr platforms", there will be more.

> +       depends on MTD_NAND && PLAT_SPEAR
> +       help
> +         Enables support for NAND Flash chips wired onto SPEAr boards.

Update help text to fit with U300 and Nomadik etc use.
Something more generic.

> +
>  endif # MTD_NAND
> diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
> new file mode 100644
> index 0000000..da9661b
> --- /dev/null
> +++ b/drivers/mtd/nand/spear_nand.c

Name the file fsmc-nand.c or so.

> @@ -0,0 +1,860 @@
> +/*
> + * drivers/mtd/nand/spear_nand.c
> + *
> + * SPEAr13XX machines common source file

No... "FSMC Flexible Static Media Controller NAND portions driver"

> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Vipin Kumar <vipin.kumar@st.com>
> + * Ashish Priyadarshi
> + *
> + * Based on drivers/mtd/nand/nomadik_nand.c

Aha :-)

But why did you fork it instead of merging the drivers??

> + *
> + * 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/module.h>
> +#include <linux/resource.h>
> +#include <linux/sched.h>
> +#include <linux/types.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/nand_ecc.h>
> +#include <linux/platform_device.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <plat/fsmc.h>
> +#include <plat/nand.h>
> +#include <mtd/mtd-abi.h>
> +
> +static struct nand_ecclayout fsmc_ecc1_layout = {
> +       .eccbytes = 24,
> +       .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
> +               66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
> +       .oobfree = {
> +               {.offset = 8, .length = 8},
> +               {.offset = 24, .length = 8},
> +               {.offset = 40, .length = 8},
> +               {.offset = 56, .length = 8},
> +               {.offset = 72, .length = 8},
> +               {.offset = 88, .length = 8},
> +               {.offset = 104, .length = 8},
> +               {.offset = 120, .length = 8}
> +       }
> +};
> +
> +static struct nand_ecclayout fsmc_ecc4_lp_layout = {
> +       .eccbytes = 104,
> +       .eccpos = {  2,   3,   4,   5,   6,   7,   8,
> +               9,  10,  11,  12,  13,  14,
> +               18,  19,  20,  21,  22,  23,  24,
> +               25,  26,  27,  28,  29,  30,
> +               34,  35,  36,  37,  38,  39,  40,
> +               41,  42,  43,  44,  45,  46,
> +               50,  51,  52,  53,  54,  55,  56,
> +               57,  58,  59,  60,  61,  62,
> +               66,  67,  68,  69,  70,  71,  72,
> +               73,  74,  75,  76,  77,  78,
> +               82,  83,  84,  85,  86,  87,  88,
> +               89,  90,  91,  92,  93,  94,
> +               98,  99, 100, 101, 102, 103, 104,
> +               105, 106, 107, 108, 109, 110,
> +               114, 115, 116, 117, 118, 119, 120,
> +               121, 122, 123, 124, 125, 126
> +       },
> +       .oobfree = {
> +               {.offset = 15, .length = 3},
> +               {.offset = 31, .length = 3},
> +               {.offset = 47, .length = 3},
> +               {.offset = 63, .length = 3},
> +               {.offset = 79, .length = 3},
> +               {.offset = 95, .length = 3},
> +               {.offset = 111, .length = 3},
> +               {.offset = 127, .length = 1}
> +       }
> +};
> +
> +/*
> + * ECC placement definitions in oobfree type format.
> + * There are 13 bytes of ecc for every 512 byte block and it has to be read
> + * consecutively and immediately after the 512 byte data block for hardware to
> + * generate the error bit offsets in 512 byte data.
> + * Managing the ecc bytes in the following way makes it easier for software to
> + * read ecc bytes consecutive to data bytes. This way is similar to
> + * oobfree structure maintained already in generic nand driver
> + */
> +static struct fsmc_eccplace fsmc_ecc4_lp_place = {
> +       .eccplace = {
> +               {.offset = 2, .length = 13},
> +               {.offset = 18, .length = 13},
> +               {.offset = 34, .length = 13},
> +               {.offset = 50, .length = 13},
> +               {.offset = 66, .length = 13},
> +               {.offset = 82, .length = 13},
> +               {.offset = 98, .length = 13},
> +               {.offset = 114, .length = 13}
> +       }
> +};
> +
> +static struct nand_ecclayout fsmc_ecc4_sp_layout = {
> +       .eccbytes = 13,
> +       .eccpos = { 0,  1,  2,  3,  6,  7, 8,
> +               9, 10, 11, 12, 13, 14
> +       },
> +       .oobfree = {
> +               {.offset = 15, .length = 1},
> +       }
> +};
> +
> +static struct fsmc_eccplace fsmc_ecc4_sp_place = {
> +       .eccplace = {
> +               {.offset = 0, .length = 4},
> +               {.offset = 6, .length = 9}
> +       }
> +};

I think ECC placement should be in the platform data.

> +
> +/*
> + * Default partition tables to be used if the partition information not provided
> + * through platform data
> + */
> +#define PARTITION(n, off, sz)  {.name = n, .offset = off, .size = sz}
> +
> +/*
> + * Default partition layout for small page(= 512 bytes) devices
> + * Size for "Root file system" is updated in driver based on actual device size
> + */
> +static struct mtd_partition partition_info_16KB_blk[] = {
> +       PARTITION("X-loader", 0, 4 * 0x4000),
> +       PARTITION("U-Boot", 0x10000, 20 * 0x4000),
> +       PARTITION("Kernel", 0x60000, 256 * 0x4000),
> +       PARTITION("Root File System", 0x460000, 0),
> +};

Ewwww atleast pass this part in from the platform data.

> +
> +/*
> + * Default partition layout for large page(> 512 bytes) devices
> + * Size for "Root file system" is updated in driver based on actual device size
> + */
> +static struct mtd_partition partition_info_128KB_blk[] = {
> +       PARTITION("X-loader", 0, 4 * 0x20000),
> +       PARTITION("U-Boot", 0x80000, 12 * 0x20000),
> +       PARTITION("Kernel", 0x200000, 48 * 0x20000),
> +       PARTITION("Root File System", 0x800000, 0),
> +};

Dito.

The rest of the driver looks really nice to my untrained eye, but I'm
including Alessandro and Sebastian on the review.

Yours,
Linus Walleij

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-01 22:36     ` Linus Walleij
  0 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-01 22:36 UTC (permalink / raw)
  To: linux-arm-kernel

2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:

> From: Vipin Kumar <vipin.kumar@st.com>
>
> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
> interfacing with NAND devices.
> This patch adds the support for glue logic for NAND flash on SPEAr boards

OK...

> (...)
> ?create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
> ?create mode 100644 arch/arm/plat-spear/include/plat/nand.h
> ?create mode 100644 drivers/mtd/nand/spear_nand.c

spear_nand.c?

Why not fsmc-nand.c or similar if this is the name of the block.
We have this in U300, Nomadik NHK8815 and other platforms too,
it doesn't have much to do with SPEAr actually...

Also, what are the include files doing in plat-spear since we have
the same hardware in other platforms? Move them to include/linux/mtd/
so we can use them please.

I *highly* suspect that this driver duplicates some code found in
drivers/mtd/nand/nomadik_nand.c because it's the same silicon.

Alessandro can judge on this, but I have a feeling that driver
should be replaced by this, more mature driver.

> (...)
> diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h
> new file mode 100644
> index 0000000..c0fdcd3
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/fsmc.h
> @@ -0,0 +1,109 @@
> +/*
> + * arch/arm/plat-spear/include/plat/fsmc.h
> + *
> + * SPEAr platform nand interface header file

Replace "SPEAr platform" for "FSMC - Flexible Static Media Controller"

> + *
> + * 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 __PLAT_FSMC_H
> +#define __PLAT_FSMC_H

Change these according to the new suggested placement.

> +
> +#include <linux/delay.h>
> +#include <linux/types.h>
> +#include <asm/param.h>
> +
> +#define FSMC_MAX_NAND_BANKS ? ?4
> +
> +struct nand_bank_regs {
> + ? ? ? u32 pc;
> + ? ? ? u32 sts;
> + ? ? ? u32 comm;
> + ? ? ? u32 attrib;
> + ? ? ? u32 ioata;
> + ? ? ? u32 ecc1;
> + ? ? ? u32 ecc2;
> + ? ? ? u32 ecc3;
> +};
> +
> +struct fsmc_regs {
> + ? ? ? u8 reserved_1[0x40];
> + ? ? ? struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
> + ? ? ? u8 reserved_2[0xfe0 - 0xc0];
> + ? ? ? u32 peripid0; ? ? ? ? ? ? ? ? ? /* 0xfe0 */
> + ? ? ? u32 peripid1; ? ? ? ? ? ? ? ? ? /* 0xfe4 */
> + ? ? ? u32 peripid2; ? ? ? ? ? ? ? ? ? /* 0xfe8 */
> + ? ? ? u32 peripid3; ? ? ? ? ? ? ? ? ? /* 0xfec */
> + ? ? ? u32 pcellid0; ? ? ? ? ? ? ? ? ? /* 0xff0 */
> + ? ? ? u32 pcellid1; ? ? ? ? ? ? ? ? ? /* 0xff4 */
> + ? ? ? u32 pcellid2; ? ? ? ? ? ? ? ? ? /* 0xff8 */
> + ? ? ? u32 pcellid3; ? ? ? ? ? ? ? ? ? /* 0xffc */

Do you need to have an u32 for each of these registers?
I think this is the AMBA PrimeCell ID registers which means
that the latter four are just "0xB105F00D" (clever) and
then padded to 32 bits. (Correct me if I'm wrong.)

You can find macros for extracting the important parts of the
field in include/linux/amba/bus.h

> +};
> +
> +#define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ)
> +
> +/* pc register definitions */
> +#define FSMC_RESET ? ? ? ? ? ? (1 << 0)
> +#define FSMC_WAITON ? ? ? ? ? ?(1 << 1)
> +#define FSMC_ENABLE ? ? ? ? ? ?(1 << 2)
> +#define FSMC_DEVTYPE_NAND ? ? ?(1 << 3)
> +#define FSMC_DEVWID_8 ? ? ? ? ?(0 << 4)
> +#define FSMC_DEVWID_16 ? ? ? ? (1 << 4)
> +#define FSMC_ECCEN ? ? ? ? ? ? (1 << 6)
> +#define FSMC_ECCPLEN_512 ? ? ? (0 << 7)
> +#define FSMC_ECCPLEN_256 ? ? ? (1 << 7)
> +#define FSMC_TCLR_1 ? ? ? ? ? ?(1 << 9)
> +#define FSMC_TAR_1 ? ? ? ? ? ? (1 << 13)
> +
> +/* sts register definitions */
> +#define FSMC_CODE_RDY ? ? ? ? ?(1 << 15)
> +
> +/* comm register definitions */
> +#define FSMC_TSET_0 ? ? ? ? ? ?(0 << 0)
> +#define FSMC_TWAIT_6 ? ? ? ? ? (6 << 8)
> +#define FSMC_THOLD_4 ? ? ? ? ? (4 << 16)
> +#define FSMC_THIZ_1 ? ? ? ? ? ?(1 << 24)
> +
> +/* peripid2 register definitions */
> +#define FSMC_REVISION_MSK ? ? ?(0xf)
> +#define FSMC_REVISION_SHFT ? ? (0x4)
> +
> +#define FSMC_VER1 ? ? ? ? ? ? ?1
> +#define FSMC_VER2 ? ? ? ? ? ? ?2
> +#define FSMC_VER3 ? ? ? ? ? ? ?3
> +#define FSMC_VER4 ? ? ? ? ? ? ?4
> +#define FSMC_VER5 ? ? ? ? ? ? ?5
> +#define FSMC_VER6 ? ? ? ? ? ? ?6
> +#define FSMC_VER7 ? ? ? ? ? ? ?7
> +#define FSMC_VER8 ? ? ? ? ? ? ?8
> +
> +static inline u32 get_fsmc_version(struct fsmc_regs *regs)
> +{
> + ? ? ? return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FSMC_REVISION_MSK;

Use macros from <linux/amba/bus.h> to extract version if
possible.

> +}
> +
> +/*
> + * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
> + * and it has to be read consecutively and immediately after the 512
> + * byte data block for hardware to generate the error bit offsets
> + * Managing the ecc bytes in the following way is easier. This way is
> + * similar to oobfree structure maintained already in u-boot nand driver
> + */
> +#define MAX_ECCPLACE_ENTRIES ? 32
> +
> +struct fsmc_nand_eccplace {
> + ? ? ? u8 offset;
> + ? ? ? u8 length;
> +};
> +
> +struct fsmc_eccplace {
> + ? ? ? struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
> +};
> +
> +#endif /* __PLAT_FSMC_H */
> diff --git a/arch/arm/plat-spear/include/plat/nand.h b/arch/arm/plat-spear/include/plat/nand.h
> new file mode 100644
> index 0000000..712b4b0
> --- /dev/null
> +++ b/arch/arm/plat-spear/include/plat/nand.h
> @@ -0,0 +1,76 @@
> +/*
> + * arch/arm/plat-spear/include/plat/nand.h
> + *
> + * NAND macros for SPEAr platform
> + *

Replace "SPEAr platform" for "FSMC - Flexible Static Media Controller"

> + * 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 __PLAT_NAND_H
> +#define __PLAT_NAND_H

Change this to reflect the new suggested placement.

> +
> +#include <linux/mtd/partitions.h>
> +
> +#define SPEAR_NAND_BW8 ? ? ? ? 1
> +#define SPEAR_NAND_BW16 ? ? ? ? ? ? ? ?2

FSMC_NAND*?

> +
> +#if defined(CONFIG_MACH_SPEAR310)
> +#define PLAT_NAND_CLE ? ? ? ? ?(1 << 17)
> +#define PLAT_NAND_ALE ? ? ? ? ?(1 << 16)
> +#else
> +#define PLAT_NAND_CLE ? ? ? ? ?(1 << 16)
> +#define PLAT_NAND_ALE ? ? ? ? ?(1 << 17)
> +#endif

You have to handle this some other way using platform data
I think.

> +
> +struct nand_platform_data {

fsmc_platform_data!

> + ? ? ? /*
> + ? ? ? ?* Board specific information
> + ? ? ? ?* Set from arch/arm/mach-spear<mach>/spear<mach>_evb.c
> + ? ? ? ?*/

Skip this comment...

> +
> + ? ? ? /*
> + ? ? ? ?* Use the default partition table present in the NAND driver if
> + ? ? ? ?* partitions is set to NULL.
> + ? ? ? ?*/
> + ? ? ? struct mtd_partition ? ?*partitions;
> + ? ? ? unsigned int ? ? ? ? ? ?nr_partitions;
> + ? ? ? unsigned int ? ? ? ? ? ?options;
> + ? ? ? unsigned int ? ? ? ? ? ?width;
> +
> + ? ? ? /*
> + ? ? ? ?* Machine specific information
> + ? ? ? ?* Set from arch/arm/mach-spear<mach>/spear<mach>.c
> + ? ? ? ?*/
> +
> + ? ? ? unsigned int ? ? ? ? ? ?bank;
> + ? ? ? /*
> + ? ? ? ?* Set to NULL if bank selection is not supported by machine
> + ? ? ? ?* architecture
> + ? ? ? ?* -> eg. when controller supports only one bank
> + ? ? ? ?*/
> + ? ? ? void ? ? ? ? ? ? ? ? ? ?(*select_bank)(u32 bank, u32 busw);
> +};
> +
> +/* This function is used to set platform data field of pdev->dev */
> +static inline void nand_set_plat_data(struct platform_device *pdev,

What about naming this fsmc_set_plat_data()

> + ? ? ? ? ? ? ? struct mtd_partition *partitions, unsigned int nr_partitions,
> + ? ? ? ? ? ? ? unsigned int options, unsigned int width)
> +{
> + ? ? ? struct nand_platform_data *nand_plat_data;
> + ? ? ? nand_plat_data = dev_get_platdata(&pdev->dev);
> +
> + ? ? ? if (partitions) {
> + ? ? ? ? ? ? ? nand_plat_data->partitions = partitions;
> + ? ? ? ? ? ? ? nand_plat_data->nr_partitions = nr_partitions;
> + ? ? ? }
> +
> + ? ? ? nand_plat_data->options = options;
> + ? ? ? nand_plat_data->width = width;
> +}
> +
> +#endif /* __PLAT_NAND_H */
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 8b4b67c..89d35d1 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -531,4 +531,10 @@ config MTD_NAND_JZ4740
> ? ? ? ?help
> ? ? ? ? ? ? ? ?Enables support for NAND Flash on JZ4740 SoC based boards.
>
> +config MTD_NAND_SPEAR

MTD_NAND_FSMC

> + ? ? ? tristate "Support for NAND on SPEAr platforms"

skip "on SPEAr platforms", there will be more.

> + ? ? ? depends on MTD_NAND && PLAT_SPEAR
> + ? ? ? help
> + ? ? ? ? Enables support for NAND Flash chips wired onto SPEAr boards.

Update help text to fit with U300 and Nomadik etc use.
Something more generic.

> +
> ?endif # MTD_NAND
> diff --git a/drivers/mtd/nand/spear_nand.c b/drivers/mtd/nand/spear_nand.c
> new file mode 100644
> index 0000000..da9661b
> --- /dev/null
> +++ b/drivers/mtd/nand/spear_nand.c

Name the file fsmc-nand.c or so.

> @@ -0,0 +1,860 @@
> +/*
> + * drivers/mtd/nand/spear_nand.c
> + *
> + * SPEAr13XX machines common source file

No... "FSMC Flexible Static Media Controller NAND portions driver"

> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Vipin Kumar <vipin.kumar@st.com>
> + * Ashish Priyadarshi
> + *
> + * Based on drivers/mtd/nand/nomadik_nand.c

Aha :-)

But why did you fork it instead of merging the drivers??

> + *
> + * 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/module.h>
> +#include <linux/resource.h>
> +#include <linux/sched.h>
> +#include <linux/types.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/nand_ecc.h>
> +#include <linux/platform_device.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <plat/fsmc.h>
> +#include <plat/nand.h>
> +#include <mtd/mtd-abi.h>
> +
> +static struct nand_ecclayout fsmc_ecc1_layout = {
> + ? ? ? .eccbytes = 24,
> + ? ? ? .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
> + ? ? ? ? ? ? ? 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
> + ? ? ? .oobfree = {
> + ? ? ? ? ? ? ? {.offset = 8, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 24, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 40, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 56, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 72, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 88, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 104, .length = 8},
> + ? ? ? ? ? ? ? {.offset = 120, .length = 8}
> + ? ? ? }
> +};
> +
> +static struct nand_ecclayout fsmc_ecc4_lp_layout = {
> + ? ? ? .eccbytes = 104,
> + ? ? ? .eccpos = { ?2, ? 3, ? 4, ? 5, ? 6, ? 7, ? 8,
> + ? ? ? ? ? ? ? 9, ?10, ?11, ?12, ?13, ?14,
> + ? ? ? ? ? ? ? 18, ?19, ?20, ?21, ?22, ?23, ?24,
> + ? ? ? ? ? ? ? 25, ?26, ?27, ?28, ?29, ?30,
> + ? ? ? ? ? ? ? 34, ?35, ?36, ?37, ?38, ?39, ?40,
> + ? ? ? ? ? ? ? 41, ?42, ?43, ?44, ?45, ?46,
> + ? ? ? ? ? ? ? 50, ?51, ?52, ?53, ?54, ?55, ?56,
> + ? ? ? ? ? ? ? 57, ?58, ?59, ?60, ?61, ?62,
> + ? ? ? ? ? ? ? 66, ?67, ?68, ?69, ?70, ?71, ?72,
> + ? ? ? ? ? ? ? 73, ?74, ?75, ?76, ?77, ?78,
> + ? ? ? ? ? ? ? 82, ?83, ?84, ?85, ?86, ?87, ?88,
> + ? ? ? ? ? ? ? 89, ?90, ?91, ?92, ?93, ?94,
> + ? ? ? ? ? ? ? 98, ?99, 100, 101, 102, 103, 104,
> + ? ? ? ? ? ? ? 105, 106, 107, 108, 109, 110,
> + ? ? ? ? ? ? ? 114, 115, 116, 117, 118, 119, 120,
> + ? ? ? ? ? ? ? 121, 122, 123, 124, 125, 126
> + ? ? ? },
> + ? ? ? .oobfree = {
> + ? ? ? ? ? ? ? {.offset = 15, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 31, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 47, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 63, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 79, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 95, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 111, .length = 3},
> + ? ? ? ? ? ? ? {.offset = 127, .length = 1}
> + ? ? ? }
> +};
> +
> +/*
> + * ECC placement definitions in oobfree type format.
> + * There are 13 bytes of ecc for every 512 byte block and it has to be read
> + * consecutively and immediately after the 512 byte data block for hardware to
> + * generate the error bit offsets in 512 byte data.
> + * Managing the ecc bytes in the following way makes it easier for software to
> + * read ecc bytes consecutive to data bytes. This way is similar to
> + * oobfree structure maintained already in generic nand driver
> + */
> +static struct fsmc_eccplace fsmc_ecc4_lp_place = {
> + ? ? ? .eccplace = {
> + ? ? ? ? ? ? ? {.offset = 2, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 18, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 34, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 50, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 66, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 82, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 98, .length = 13},
> + ? ? ? ? ? ? ? {.offset = 114, .length = 13}
> + ? ? ? }
> +};
> +
> +static struct nand_ecclayout fsmc_ecc4_sp_layout = {
> + ? ? ? .eccbytes = 13,
> + ? ? ? .eccpos = { 0, ?1, ?2, ?3, ?6, ?7, 8,
> + ? ? ? ? ? ? ? 9, 10, 11, 12, 13, 14
> + ? ? ? },
> + ? ? ? .oobfree = {
> + ? ? ? ? ? ? ? {.offset = 15, .length = 1},
> + ? ? ? }
> +};
> +
> +static struct fsmc_eccplace fsmc_ecc4_sp_place = {
> + ? ? ? .eccplace = {
> + ? ? ? ? ? ? ? {.offset = 0, .length = 4},
> + ? ? ? ? ? ? ? {.offset = 6, .length = 9}
> + ? ? ? }
> +};

I think ECC placement should be in the platform data.

> +
> +/*
> + * Default partition tables to be used if the partition information not provided
> + * through platform data
> + */
> +#define PARTITION(n, off, sz) ?{.name = n, .offset = off, .size = sz}
> +
> +/*
> + * Default partition layout for small page(= 512 bytes) devices
> + * Size for "Root file system" is updated in driver based on actual device size
> + */
> +static struct mtd_partition partition_info_16KB_blk[] = {
> + ? ? ? PARTITION("X-loader", 0, 4 * 0x4000),
> + ? ? ? PARTITION("U-Boot", 0x10000, 20 * 0x4000),
> + ? ? ? PARTITION("Kernel", 0x60000, 256 * 0x4000),
> + ? ? ? PARTITION("Root File System", 0x460000, 0),
> +};

Ewwww atleast pass this part in from the platform data.

> +
> +/*
> + * Default partition layout for large page(> 512 bytes) devices
> + * Size for "Root file system" is updated in driver based on actual device size
> + */
> +static struct mtd_partition partition_info_128KB_blk[] = {
> + ? ? ? PARTITION("X-loader", 0, 4 * 0x20000),
> + ? ? ? PARTITION("U-Boot", 0x80000, 12 * 0x20000),
> + ? ? ? PARTITION("Kernel", 0x200000, 48 * 0x20000),
> + ? ? ? PARTITION("Root File System", 0x800000, 0),
> +};

Dito.

The rest of the driver looks really nice to my untrained eye, but I'm
including Alessandro and Sebastian on the review.

Yours,
Linus Walleij

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

* [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver
  2010-08-30 10:39 ` [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver Viresh KUMAR
@ 2010-09-01 22:43   ` Linus Walleij
  0 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-01 22:43 UTC (permalink / raw)
  To: linux-arm-kernel

2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:

> (...)
> ?arch/arm/mach-spear13xx/fsmc-nor.c ? ? ? ? ? ? | ? 81 ++++++++++++++++++++++++
> (...)
>  arch/arm/plat-spear/include/plat/fsmc.h        |   51 +++++++++++++++-

Hmmm... again we have this block also in U300 and NHK8815.

> (...)
> +++ b/arch/arm/mach-spear13xx/fsmc-nor.c
> @@ -0,0 +1,81 @@
> +/*
> + * arch/arm/mach-spear13xx/fsmc-nor.c
> + *
> + * FSMC (Flexible Static Memory Controller) interface for NOR

It even says its generic and should live in
drivers/mtd/maps I think for NOR controllers.

> + *
> + * 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/err.h>
> +#include <linux/io.h>
> +#include <plat/fsmc.h>
> +
> +int __init fsmc_nor_init(struct platform_device *pdev, unsigned long base,
> + ? ? ? ? ? ? ? u32 bank, u32 width)
> +{
> + ? ? ? void __iomem *fsmc_nor_base;
> + ? ? ? struct fsmc_regs *regs;
> + ? ? ? struct clk *clk;
> + ? ? ? int ret;
> + ? ? ? u32 ctrl;
> +
> + ? ? ? if (bank > (FSMC_MAX_NOR_BANKS - 1))
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? fsmc_nor_base = ioremap(base, FSMC_NOR_REG_SIZE);
> + ? ? ? if (!fsmc_nor_base)
> + ? ? ? ? ? ? ? return -ENOMEM;
> +
> + ? ? ? clk = clk_get(NULL, "fsmc");
> + ? ? ? if (IS_ERR(clk)) {
> + ? ? ? ? ? ? ? iounmap(fsmc_nor_base);
> + ? ? ? ? ? ? ? return PTR_ERR(clk);
> + ? ? ? }
> +
> + ? ? ? ret = clk_enable(clk);
> + ? ? ? if (ret) {
> + ? ? ? ? ? ? ? iounmap(fsmc_nor_base);
> + ? ? ? ? ? ? ? return ret;
> + ? ? ? }
> +
> + ? ? ? regs = (struct fsmc_regs *)fsmc_nor_base;
> +
> + ? ? ? ctrl = WAIT_ENB | WRT_ENABLE | WPROT | NOR_DEV | BANK_ENABLE;
> +
> + ? ? ? switch (width) {
> + ? ? ? case FSMC_FLASH_WIDTH8:
> + ? ? ? ? ? ? ? ctrl |= WIDTH_8;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case FSMC_FLASH_WIDTH16:
> + ? ? ? ? ? ? ? ctrl |= WIDTH_16;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? ctrl |= WIDTH_8;
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +
> + ? ? ? writel(ctrl, &regs->nor_bank_regs[bank].ctrl);
> + ? ? ? writel(0x0FFFFFFF, &regs->nor_bank_regs[bank].ctrl_tim);
> + ? ? ? writel(ctrl | RSTPWRDWN, &regs->nor_bank_regs[bank].ctrl);
> +
> + ? ? ? iounmap(fsmc_nor_base);
> +
> + ? ? ? return 0;
> +}
> +
> +void __init fsmc_init_board_info(struct platform_device *pdev,
> + ? ? ? ? ? ? ? struct mtd_partition *partitions, unsigned int nr_partitions,
> + ? ? ? ? ? ? ? unsigned int width)
> +{
> + ? ? ? fsmc_init_plat_data(pdev, partitions, nr_partitions, width);
> +}

All this should be in drivers/mtd/maps/fsmc-nor.c or so am I right?

> diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c

That kind of stuff you can keep :-)

> diff --git a/arch/arm/plat-spear/include/plat/fsmc.h b/arch/arm/plat-spear/include/plat/fsmc.h

Noooo combine this with the NAND stuff into include/linux/mtd/fsmc.h!

> index c0fdcd3..5909afd 100644
> --- a/arch/arm/plat-spear/include/plat/fsmc.h
> +++ b/arch/arm/plat-spear/include/plat/fsmc.h
> @@ -15,11 +15,36 @@
> ?#define __PLAT_FSMC_H

Change #define to reflect new suggested placement.

>
> ?#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/mtd/physmap.h>
> ?#include <linux/types.h>
> ?#include <asm/param.h>
>
> +#define FSMC_MAX_NOR_BANKS ? ? 4
> ?#define FSMC_MAX_NAND_BANKS ? ?4
>
> +#define FSMC_FLASH_WIDTH8 ? ? ?1
> +#define FSMC_FLASH_WIDTH16 ? ? 2
> +
> +struct nor_bank_regs {
> + ? ? ? u32 ctrl;
> + ? ? ? u32 ctrl_tim;
> +};
> +
> +/* ctrl register definitions */
> +#define BANK_ENABLE ? ? ? ? ? ?(1 << 0)
> +#define MUXED ? ? ? ? ? ? ? ? ?(1 << 1)
> +#define NOR_DEV ? ? ? ? ? ? ? ? ? ? ? ?(2 << 2)
> +#define WIDTH_8 ? ? ? ? ? ? ? ? ? ? ? ?(0 << 4)
> +#define WIDTH_16 ? ? ? ? ? ? ? (1 << 4)
> +#define RSTPWRDWN ? ? ? ? ? ? ?(1 << 6)
> +#define WPROT ? ? ? ? ? ? ? ? ?(1 << 7)
> +#define WRT_ENABLE ? ? ? ? ? ? (1 << 12)
> +#define WAIT_ENB ? ? ? ? ? ? ? (1 << 13)
> +
> +/* ctrl_tim register definitions */
> +
> ?struct nand_bank_regs {
> ? ? ? ?u32 pc;
> ? ? ? ?u32 sts;
> @@ -31,8 +56,11 @@ struct nand_bank_regs {
> ? ? ? ?u32 ecc3;
> ?};
>
> +#define FSMC_NOR_REG_SIZE ? ? ?0x40
> +
> ?struct fsmc_regs {
> - ? ? ? u8 reserved_1[0x40];
> + ? ? ? struct nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS];
> + ? ? ? u8 reserved_1[0x40 - 0x20];
> ? ? ? ?struct nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
> ? ? ? ?u8 reserved_2[0xfe0 - 0xc0];
> ? ? ? ?u32 peripid0; ? ? ? ? ? ? ? ? ? /* 0xfe0 */
> @@ -106,4 +134,25 @@ struct fsmc_eccplace {
> ? ? ? ?struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
> ?};
>
> +static inline void fsmc_init_plat_data(struct platform_device *pdev,
> + ? ? ? ? ? ? ? struct mtd_partition *partitions, unsigned int nr_partitions,
> + ? ? ? ? ? ? ? unsigned int width)
> +{
> + ? ? ? struct physmap_flash_data *fsmc_plat_data;
> + ? ? ? fsmc_plat_data = dev_get_platdata(&pdev->dev);
> +
> + ? ? ? if (partitions) {
> + ? ? ? ? ? ? ? fsmc_plat_data->parts = partitions;
> + ? ? ? ? ? ? ? fsmc_plat_data->nr_parts = nr_partitions;
> + ? ? ? }
> +
> + ? ? ? fsmc_plat_data->width = width;
> +}
> +
> +extern int __init fsmc_nor_init(struct platform_device *pdev,
> + ? ? ? ? ? ? ? unsigned long base, u32 bank, u32 width);
> +extern void __init fsmc_init_board_info(struct platform_device *pdev,
> + ? ? ? ? ? ? ? struct mtd_partition *partitions, unsigned int nr_partitions,
> + ? ? ? ? ? ? ? unsigned int width);
> +
> ?#endif /* __PLAT_FSMC_H */

Thanks!

Yours,
Linus Walleij

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 22:21                     ` Ryan Mallon
@ 2010-09-01 22:53                       ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 22:53 UTC (permalink / raw)
  To: Ryan Mallon
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Kevin Cernekee, Vipin Kumar, Shiraz HASHIM,
	Rajeev KUMAR, linux-mtd, Deepak SIKRI, Brian Norris, dwmw2,
	linux-arm-kernel

On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
> > On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
> >> However, we are interested in having a proper solution to this problem.
> > 
> > I would suggest using this patch as a starting point - could you
> > please review the changes and try it out?
> > 
> > http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
> 
> That patch still breaks the ABI by renaming struct nand_ecclayout to
> nand_ecclayout_user.

Hmm, would you please show why my binary file 'nandwrite' would have to
be re-built?

>  Any application using the old names will have to be
> rewritten to compile against a new kernel.

Not necessary. mtd-utils, for example, maintain their own copy of the
mtd-abi.h file, which I personally think is a good idea.

But if your apps depend on the kernel headers, then yes, you will need
to amend it or copy the old header into your project.

IOW, the patch breaks API by renaming, but not ABI, I think. I do not
see this as a major problem - just a small inconvenience.

> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
> If an application using the old interface calls any of the ecc ioctls
> for a nand chip with > 64 bytes ecc it should return an error.

It will, because size of the structure is part of the ioctl number,
even. See the corresponding ioctl macro definition.

> I still think the eccpos field should be a pointer, so that it can
> allocate as much space as is needed for the ecc. This also means that
> the kernel doesn't need to be changed every time a new NAND chips
> appears with a bigger ecc size.

Sure, this is the whole point: go ahead and design the new ioctl, and
then deprecate the old one. Just invest men/hours into that and we are
all right :-)

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 22:53                       ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 22:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
> > On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
> >> However, we are interested in having a proper solution to this problem.
> > 
> > I would suggest using this patch as a starting point - could you
> > please review the changes and try it out?
> > 
> > http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
> 
> That patch still breaks the ABI by renaming struct nand_ecclayout to
> nand_ecclayout_user.

Hmm, would you please show why my binary file 'nandwrite' would have to
be re-built?

>  Any application using the old names will have to be
> rewritten to compile against a new kernel.

Not necessary. mtd-utils, for example, maintain their own copy of the
mtd-abi.h file, which I personally think is a good idea.

But if your apps depend on the kernel headers, then yes, you will need
to amend it or copy the old header into your project.

IOW, the patch breaks API by renaming, but not ABI, I think. I do not
see this as a major problem - just a small inconvenience.

> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
> If an application using the old interface calls any of the ecc ioctls
> for a nand chip with > 64 bytes ecc it should return an error.

It will, because size of the structure is part of the ioctl number,
even. See the corresponding ioctl macro definition.

> I still think the eccpos field should be a pointer, so that it can
> allocate as much space as is needed for the ecc. This also means that
> the kernel doesn't need to be changed every time a new NAND chips
> appears with a bigger ecc size.

Sure, this is the whole point: go ahead and design the new ioctl, and
then deprecate the old one. Just invest men/hours into that and we are
all right :-)

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 11:04               ` Vipin Kumar
@ 2010-09-01 23:23                 ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 23:23 UTC (permalink / raw)
  To: Vipin Kumar
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

Hi,

On Wed, 2010-09-01 at 16:34 +0530, Vipin Kumar wrote:
> I got the point, but this change is essential (at least for me). It may be 
> essential to others as well in near future. Please let me know how to handle more 
> than 64 bytes of ecc

Invent new ioctl, and declare the old one deprecated.

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 23:23                 ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-01 23:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, 2010-09-01 at 16:34 +0530, Vipin Kumar wrote:
> I got the point, but this change is essential (at least for me). It may be 
> essential to others as well in near future. Please let me know how to handle more 
> than 64 bytes of ecc

Invent new ioctl, and declare the old one deprecated.

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 22:53                       ` Artem Bityutskiy
@ 2010-09-01 23:37                         ` Ryan Mallon
  -1 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 23:37 UTC (permalink / raw)
  To: dedekind1
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Kevin Cernekee, Vipin Kumar, Shiraz HASHIM,
	Rajeev KUMAR, linux-mtd, Deepak SIKRI, Brian Norris, dwmw2,
	linux-arm-kernel

On 09/02/2010 10:53 AM, Artem Bityutskiy wrote:
> On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
>> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>>>> However, we are interested in having a proper solution to this problem.
>>>
>>> I would suggest using this patch as a starting point - could you
>>> please review the changes and try it out?
>>>
>>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
>>
>> That patch still breaks the ABI by renaming struct nand_ecclayout to
>> nand_ecclayout_user.
> 
> Hmm, would you please show why my binary file 'nandwrite' would have to
> be re-built?
> 
>>  Any application using the old names will have to be
>> rewritten to compile against a new kernel.
> 
> Not necessary. mtd-utils, for example, maintain their own copy of the
> mtd-abi.h file, which I personally think is a good idea.
> 
> But if your apps depend on the kernel headers, then yes, you will need
> to amend it or copy the old header into your project.
> 
> IOW, the patch breaks API by renaming, but not ABI, I think. I do not
> see this as a major problem - just a small inconvenience.

Sorry, you are correct, it breaks the API not the ABI. I understood that
such changes were still to be avoided.

>> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
>> If an application using the old interface calls any of the ecc ioctls
>> for a nand chip with > 64 bytes ecc it should return an error.
> 
> It will, because size of the structure is part of the ioctl number,
> even. See the corresponding ioctl macro definition.

Right, but I don't think it needs the complexity of the shrink_ecc
function from Kevin's patch. The old ioctl should return an error
(possibly with a kernel message) if the requested nand chip has > 64
bytes ecc. Otherwise it should just copy upto 64 bytes into the old
nand_ecclayout structure and return.

Any new structure should be totally independent and should, IMHO, have
an arbitrary sized array for the ecc. It should have its own new set of
ioctls, one for getting the size of the ecc and one for getting the
actual ecc data. Though I can't remember if ioctls support arbitrary
sized arguments to make this possible.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 23:37                         ` Ryan Mallon
  0 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02/2010 10:53 AM, Artem Bityutskiy wrote:
> On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
>> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>>>> However, we are interested in having a proper solution to this problem.
>>>
>>> I would suggest using this patch as a starting point - could you
>>> please review the changes and try it out?
>>>
>>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
>>
>> That patch still breaks the ABI by renaming struct nand_ecclayout to
>> nand_ecclayout_user.
> 
> Hmm, would you please show why my binary file 'nandwrite' would have to
> be re-built?
> 
>>  Any application using the old names will have to be
>> rewritten to compile against a new kernel.
> 
> Not necessary. mtd-utils, for example, maintain their own copy of the
> mtd-abi.h file, which I personally think is a good idea.
> 
> But if your apps depend on the kernel headers, then yes, you will need
> to amend it or copy the old header into your project.
> 
> IOW, the patch breaks API by renaming, but not ABI, I think. I do not
> see this as a major problem - just a small inconvenience.

Sorry, you are correct, it breaks the API not the ABI. I understood that
such changes were still to be avoided.

>> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
>> If an application using the old interface calls any of the ecc ioctls
>> for a nand chip with > 64 bytes ecc it should return an error.
> 
> It will, because size of the structure is part of the ioctl number,
> even. See the corresponding ioctl macro definition.

Right, but I don't think it needs the complexity of the shrink_ecc
function from Kevin's patch. The old ioctl should return an error
(possibly with a kernel message) if the requested nand chip has > 64
bytes ecc. Otherwise it should just copy upto 64 bytes into the old
nand_ecclayout structure and return.

Any new structure should be totally independent and should, IMHO, have
an arbitrary sized array for the ecc. It should have its own new set of
ioctls, one for getting the size of the ecc and one for getting the
actual ecc data. Though I can't remember if ioctls support arbitrary
sized arguments to make this possible.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 23:37                         ` Ryan Mallon
@ 2010-09-01 23:43                           ` Ryan Mallon
  -1 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 23:43 UTC (permalink / raw)
  To: dedekind1
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Kevin Cernekee, Vipin Kumar, Shiraz HASHIM,
	Rajeev KUMAR, linux-mtd, Deepak SIKRI, Brian Norris, dwmw2,
	linux-arm-kernel

On 09/02/2010 11:37 AM, Ryan Mallon wrote:
> On 09/02/2010 10:53 AM, Artem Bityutskiy wrote:
>> On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
>>> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>>>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>>>>> However, we are interested in having a proper solution to this problem.
>>>>
>>>> I would suggest using this patch as a starting point - could you
>>>> please review the changes and try it out?
>>>>
>>>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
>>>
>>> That patch still breaks the ABI by renaming struct nand_ecclayout to
>>> nand_ecclayout_user.
>>
>> Hmm, would you please show why my binary file 'nandwrite' would have to
>> be re-built?
>>
>>>  Any application using the old names will have to be
>>> rewritten to compile against a new kernel.
>>
>> Not necessary. mtd-utils, for example, maintain their own copy of the
>> mtd-abi.h file, which I personally think is a good idea.
>>
>> But if your apps depend on the kernel headers, then yes, you will need
>> to amend it or copy the old header into your project.
>>
>> IOW, the patch breaks API by renaming, but not ABI, I think. I do not
>> see this as a major problem - just a small inconvenience.
> 
> Sorry, you are correct, it breaks the API not the ABI. I understood that
> such changes were still to be avoided.
> 
>>> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
>>> If an application using the old interface calls any of the ecc ioctls
>>> for a nand chip with > 64 bytes ecc it should return an error.
>>
>> It will, because size of the structure is part of the ioctl number,
>> even. See the corresponding ioctl macro definition.
> 
> Right, but I don't think it needs the complexity of the shrink_ecc
> function from Kevin's patch. The old ioctl should return an error
> (possibly with a kernel message) if the requested nand chip has > 64
> bytes ecc. Otherwise it should just copy upto 64 bytes into the old
> nand_ecclayout structure and return.

Oops, I misread the patch. The shrink_ecclayout function is actually
fine. The only change I would make is to possible add a warning/error if
the data is being truncated.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-01 23:43                           ` Ryan Mallon
  0 siblings, 0 replies; 245+ messages in thread
From: Ryan Mallon @ 2010-09-01 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02/2010 11:37 AM, Ryan Mallon wrote:
> On 09/02/2010 10:53 AM, Artem Bityutskiy wrote:
>> On Thu, 2010-09-02 at 10:21 +1200, Ryan Mallon wrote:
>>> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>>>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>>>>> However, we are interested in having a proper solution to this problem.
>>>>
>>>> I would suggest using this patch as a starting point - could you
>>>> please review the changes and try it out?
>>>>
>>>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
>>>
>>> That patch still breaks the ABI by renaming struct nand_ecclayout to
>>> nand_ecclayout_user.
>>
>> Hmm, would you please show why my binary file 'nandwrite' would have to
>> be re-built?
>>
>>>  Any application using the old names will have to be
>>> rewritten to compile against a new kernel.
>>
>> Not necessary. mtd-utils, for example, maintain their own copy of the
>> mtd-abi.h file, which I personally think is a good idea.
>>
>> But if your apps depend on the kernel headers, then yes, you will need
>> to amend it or copy the old header into your project.
>>
>> IOW, the patch breaks API by renaming, but not ABI, I think. I do not
>> see this as a major problem - just a small inconvenience.
> 
> Sorry, you are correct, it breaks the API not the ABI. I understood that
> such changes were still to be avoided.
> 
>>> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
>>> If an application using the old interface calls any of the ecc ioctls
>>> for a nand chip with > 64 bytes ecc it should return an error.
>>
>> It will, because size of the structure is part of the ioctl number,
>> even. See the corresponding ioctl macro definition.
> 
> Right, but I don't think it needs the complexity of the shrink_ecc
> function from Kevin's patch. The old ioctl should return an error
> (possibly with a kernel message) if the requested nand chip has > 64
> bytes ecc. Otherwise it should just copy upto 64 bytes into the old
> nand_ecclayout structure and return.

Oops, I misread the patch. The shrink_ecclayout function is actually
fine. The only change I would make is to possible add a warning/error if
the data is being truncated.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-01 22:21                     ` Ryan Mallon
@ 2010-09-02  6:33                       ` Brian Norris
  -1 siblings, 0 replies; 245+ messages in thread
From: Brian Norris @ 2010-09-02  6:33 UTC (permalink / raw)
  To: Ryan Mallon
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	dedekind1, Armando VISCONTI, Kevin Cernekee, Vipin Kumar,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI,
	Brian Norris, dwmw2, linux-arm-kernel

On 9/1/2010 3:21 PM, Ryan Mallon wrote:
> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
> 
> That patch still breaks the ABI by renaming struct nand_ecclayout to
> nand_ecclayout_user. Any application using the old names will have to be
> rewritten to compile against a new kernel.

I don't know how exactly all user-space apps deal with this, but isn't
that what the following typedef is for? (include/mtd/mtd-user.h)
	typedef struct nand_ecclayout nand_ecclayout_t;
changed to:
	typedef struct nand_ecclayout_user nand_ecclayout_t;

So any app that properly used nand_ecclayout_t would not need changes
even when using the new headers. Again, I don't know who has been using
what in user-space.

> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
> If an application using the old interface calls any of the ecc ioctls
> for a nand chip with > 64 bytes ecc it should return an error.
> 
> I still think the eccpos field should be a pointer, so that it can
> allocate as much space as is needed for the ecc. This also means that
> the kernel doesn't need to be changed every time a new NAND chips
> appears with a bigger ecc size.

Yes, dynamic allocation would probably make more sense in the future.
However, it seems difficult (or impossible?) to create an
arbitrary-sized ioctl; the size is hard-coded into the ioctl definition.

I'm curious how many applications actually need to have the ecclayout.
nandwrite doesn't actually use it, just oobinfo.

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-02  6:33                       ` Brian Norris
  0 siblings, 0 replies; 245+ messages in thread
From: Brian Norris @ 2010-09-02  6:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/1/2010 3:21 PM, Ryan Mallon wrote:
> On 09/02/2010 09:54 AM, Kevin Cernekee wrote:
>> On Wed, Sep 1, 2010 at 2:23 PM, Ryan Mallon <ryan@bluewatersys.com> wrote:
>> http://git.infradead.org/users/dedekind/l2-mtd-2.6.git/commitdiff/b6d6ae730be2750fac166ed9df11ee6ea54d9160
> 
> That patch still breaks the ABI by renaming struct nand_ecclayout to
> nand_ecclayout_user. Any application using the old names will have to be
> rewritten to compile against a new kernel.

I don't know how exactly all user-space apps deal with this, but isn't
that what the following typedef is for? (include/mtd/mtd-user.h)
	typedef struct nand_ecclayout nand_ecclayout_t;
changed to:
	typedef struct nand_ecclayout_user nand_ecclayout_t;

So any app that properly used nand_ecclayout_t would not need changes
even when using the new headers. Again, I don't know who has been using
what in user-space.

> The old interface should remain unchanged in that include/mtd/mtd-abi.h.
> If an application using the old interface calls any of the ecc ioctls
> for a nand chip with > 64 bytes ecc it should return an error.
> 
> I still think the eccpos field should be a pointer, so that it can
> allocate as much space as is needed for the ecc. This also means that
> the kernel doesn't need to be changed every time a new NAND chips
> appears with a bigger ecc size.

Yes, dynamic allocation would probably make more sense in the future.
However, it seems difficult (or impossible?) to create an
arbitrary-sized ioctl; the size is hard-coded into the ioctl definition.

I'm curious how many applications actually need to have the ecclayout.
nandwrite doesn't actually use it, just oobinfo.

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-01 22:36     ` Linus Walleij
@ 2010-09-02  8:09       ` Armando Visconti
  -1 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02  8:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Alessandro Rubini, Vipin KUMAR,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

Ciao Linus,

Linus Walleij wrote:
> 2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:
>
>   
>> From: Vipin Kumar <vipin.kumar@st.com>
>>
>> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
>> interfacing with NAND devices.
>> This patch adds the support for glue logic for NAND flash on SPEAr boards
>>     
>
> OK...
>
>   
>> (...)
>>  create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
>>  create mode 100644 arch/arm/plat-spear/include/plat/nand.h
>>  create mode 100644 drivers/mtd/nand/spear_nand.c
>>     
>
> spear_nand.c?
>
> Why not fsmc-nand.c or similar if this is the name of the block.
> We have this in U300, Nomadik NHK8815 and other platforms too,
> it doesn't have much to do with SPEAr actually...
>
> Also, what are the include files doing in plat-spear since we have
> the same hardware in other platforms? Move them to include/linux/mtd/
> so we can use them please.
>
> I *highly* suspect that this driver duplicates some code found in
> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>   
Why nomadik_nand.c?
Shouldn't the fsmc_nand.c rule apply also in this case?


> Alessandro can judge on this, but I have a feeling that driver
> should be replaced by this, more mature driver.
>   
Maybe.
But I suspect that may be few differences in the ECC accelerator inside, 
in fact.

In our FSMC previous case it was a Hamming accelerator, and I think this 
apply
also for nomadik (maybe). In our sp1300 case it is a BCH with 104 bytes 
of ECC.

This is one of the options when generating the h/w block, so FSMCs may 
differ.
If we want to re-use same driver I guess we might change something and 
accept
few parameters from the platform.

Vipin can for sure comment more on this.....


Rgds,
Arm

-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti@st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-02  8:09       ` Armando Visconti
  0 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02  8:09 UTC (permalink / raw)
  To: linux-arm-kernel

Ciao Linus,

Linus Walleij wrote:
> 2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:
>
>   
>> From: Vipin Kumar <vipin.kumar@st.com>
>>
>> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
>> interfacing with NAND devices.
>> This patch adds the support for glue logic for NAND flash on SPEAr boards
>>     
>
> OK...
>
>   
>> (...)
>>  create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
>>  create mode 100644 arch/arm/plat-spear/include/plat/nand.h
>>  create mode 100644 drivers/mtd/nand/spear_nand.c
>>     
>
> spear_nand.c?
>
> Why not fsmc-nand.c or similar if this is the name of the block.
> We have this in U300, Nomadik NHK8815 and other platforms too,
> it doesn't have much to do with SPEAr actually...
>
> Also, what are the include files doing in plat-spear since we have
> the same hardware in other platforms? Move them to include/linux/mtd/
> so we can use them please.
>
> I *highly* suspect that this driver duplicates some code found in
> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>   
Why nomadik_nand.c?
Shouldn't the fsmc_nand.c rule apply also in this case?


> Alessandro can judge on this, but I have a feeling that driver
> should be replaced by this, more mature driver.
>   
Maybe.
But I suspect that may be few differences in the ECC accelerator inside, 
in fact.

In our FSMC previous case it was a Hamming accelerator, and I think this 
apply
also for nomadik (maybe). In our sp1300 case it is a BCH with 104 bytes 
of ECC.

This is one of the options when generating the h/w block, so FSMCs may 
differ.
If we want to re-use same driver I guess we might change something and 
accept
few parameters from the platform.

Vipin can for sure comment more on this.....


Rgds,
Arm

-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti at st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 08/74] ST SPEAr1300: Adding default config file
  2010-08-30 10:38 ` [PATCH 08/74] ST SPEAr1300: Adding default config file Viresh KUMAR
@ 2010-09-02  8:51   ` Russell King - ARM Linux
  2010-09-03  1:45     ` Nicolas Pitre
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:39PM +0530, Viresh KUMAR wrote:
> From: Shiraz Hashim <shiraz.hashim@st.com>

This defconfig is too large and verbose to go anywhere near mainline,
even temporarily.  You need to talk to Uwe about how to shrink it down.

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-02  8:09       ` Armando Visconti
@ 2010-09-02  8:52         ` Armando Visconti
  -1 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02  8:52 UTC (permalink / raw)
  To: Linus Walleij, Alessandro Rubini
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Armando Visconti, Vipin KUMAR,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

Alessandro,
>
>
>> Alessandro can judge on this, but I have a feeling that driver
>> should be replaced by this, more mature driver.
>>   
> Maybe.
> But I suspect that may be few differences in the ECC accelerator 
> inside, in fact.
>
> In our FSMC previous case it was a Hamming accelerator, and I think 
> this apply
> also for nomadik (maybe). In our sp1300 case it is a BCH with 104 
> bytes of ECC.
>
> This is one of the options when generating the h/w block, so FSMCs may 
> differ.
> If we want to re-use same driver I guess we might change something and 
> accept
> few parameters from the platform.
>
> Vipin can for sure comment more on this.....
Mmmh .... it seems that the driver already handles the different types 
of h/w ecc.
And in fact it works for our new and old SPEAr platform at the same
time.

So, probably, it would work for Nomadik also...

Ciao,
Arm
>
>
> Rgds,
> Arm
>


-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti@st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-02  8:52         ` Armando Visconti
  0 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

Alessandro,
>
>
>> Alessandro can judge on this, but I have a feeling that driver
>> should be replaced by this, more mature driver.
>>   
> Maybe.
> But I suspect that may be few differences in the ECC accelerator 
> inside, in fact.
>
> In our FSMC previous case it was a Hamming accelerator, and I think 
> this apply
> also for nomadik (maybe). In our sp1300 case it is a BCH with 104 
> bytes of ECC.
>
> This is one of the options when generating the h/w block, so FSMCs may 
> differ.
> If we want to re-use same driver I guess we might change something and 
> accept
> few parameters from the platform.
>
> Vipin can for sure comment more on this.....
Mmmh .... it seems that the driver already handles the different types 
of h/w ecc.
And in fact it works for our new and old SPEAr platform at the same
time.

So, probably, it would work for Nomadik also...

Ciao,
Arm
>
>
> Rgds,
> Arm
>


-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti at st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files
  2010-08-30 10:38 ` [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files Viresh KUMAR
@ 2010-09-02  8:56   ` Russell King - ARM Linux
  2010-09-03  6:57     ` Shiraz Hashim
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:35PM +0530, Viresh KUMAR wrote:
> +#ifndef __MACH_GENERIC_H
> +#define __MACH_GENERIC_H
> +
> +#include <asm/mach/time.h>
> +#include <asm/mach/map.h>
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/amba/bus.h>

linux/ before asm/ please.

> +#ifndef __MACH_HARDWARE_H
> +#define __MACH_HARDWARE_H
> +
> +#include <mach/spear.h>
> +
> +/* Vitual to physical translation of statically mapped space */
> +#define IO_ADDRESS(x)		(x | 0xF0000000)
> +
> +/* typesafe io address */
> +#define __io_address(n)		__io(IO_ADDRESS(n))

Wrong use of __io().  __io() is just a macro for asm/io.h to make use of,
and in any case should be defined in your mach/io.h file.

> diff --git a/arch/arm/mach-spear13xx/include/mach/system.h b/arch/arm/mach-spear13xx/include/mach/system.h
> new file mode 100644
> index 0000000..6ce0819
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/include/mach/system.h
> @@ -0,0 +1,43 @@
> +/*
> + * arch/arm/mach-spear13xx/include/mach/system.h
> + *
> + * spear13xx Machine family specific architecture functions
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim@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_SYSTEM_H
> +#define __MACH_SYSTEM_H
> +
> +#include <linux/io.h>
> +#include <mach/hardware.h>
> +#include <mach/misc_regs.h>
> +
> +static inline void arch_idle(void)
> +{
> +	/*
> +	 * This should do all the clock switching
> +	 * and wait for interrupt tricks
> +	 */
> +	cpu_do_idle();
> +}
> +
> +static inline void arch_reset(char mode, const char *cmd)
> +{
> +	pr_info("Going to reboot...\n");

The kernel already prints a message for reboot, so this is superfluous.

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

* [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files
  2010-08-30 10:38 ` [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files Viresh KUMAR
@ 2010-09-02  9:04   ` Russell King - ARM Linux
  2010-09-03  6:38     ` Shiraz Hashim
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:36PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
> new file mode 100644
> index 0000000..8b75d1b
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/platsmp.c
> @@ -0,0 +1,203 @@
> +/*
> + * arch/arm/mach-spear13xx/platsmp.c
> + *
> + * based upon linux/arch/arm/mach-realview/platsmp.c
> + *
> + * Copyright (C) 2010 ST Microelectronics Ltd.
> + * Shiraz Hashim <shiraz.hashim@st.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <asm/cacheflush.h>
> +#include <asm/hardware/gic.h>
> +#include <asm/localtimer.h>
> +#include <asm/mach-types.h>
> +#include <asm/smp_scu.h>
> +#include <asm/unified.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/jiffies.h>
> +#include <linux/smp.h>
> +#include <mach/generic.h>
> +#include <mach/hardware.h>

linux/ before asm/ before mach/ please.

> +
> +/*
> + * control for which core is the next to come out of the secondary
> + * boot "holding pen"
> + */
> +volatile int __cpuinitdata pen_release = -1;
> +static DEFINE_SPINLOCK(boot_lock);
> +
> +static void __iomem *scu_base_addr(void)
> +{
> +	return __io_address(SPEAR13XX_SCU_BASE);
> +}
> +
> +static inline unsigned int get_core_count(void)
> +{
> +	void __iomem *scu_base = scu_base_addr();
> +
> +	if (scu_base)
> +		return scu_get_core_count(scu_base);
> +	return 1;
> +}
> +
> +void __cpuinit platform_secondary_init(unsigned int cpu)
> +{
> +	trace_hardirqs_off();
> +
> +	/*
> +	 * if any interrupts are already enabled for the primary
> +	 * core (e.g. timer irq), then they will not have been enabled
> +	 * for us: do so
> +	 */
> +	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
> +
> +	/*
> +	 * let the primary processor know we're out of the
> +	 * pen, then head off into the C entry point
> +	 */
> +	pen_release = -1;
> +	smp_wmb();
> +
> +	/*
> +	 * Synchronise with the boot thread.
> +	 */
> +	spin_lock(&boot_lock);
> +	spin_unlock(&boot_lock);
> +}
> +
> +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> +	unsigned long timeout;
> +
> +	/*
> +	 * set synchronisation state between this boot processor
> +	 * and the secondary one
> +	 */
> +	spin_lock(&boot_lock);
> +
> +	/*
> +	 * The secondary processor is waiting to be released from
> +	 * the holding pen - release it, then wait for it to flag
> +	 * that it has been released by resetting pen_release.
> +	 *
> +	 * Note that "pen_release" is the hardware CPU ID, whereas
> +	 * "cpu" is Linux's internal ID.
> +	 */
> +
> +	/*
> +	 * Note: Following is important otherwise cpu2 doesn't come up
> +	 * as secondary_data must be flushed before pen_release also
> +	 */
> +
> +	flush_cache_all();

You don't need this.  secondary_data is already taken care of as of a
few kernel releases ago.

> +	pen_release = cpu;
> +	flush_cache_all();
> +
> +	timeout = jiffies + (1 * HZ);
> +	while (time_before(jiffies, timeout)) {
> +		smp_rmb();
> +		if (pen_release == -1)
> +			break;
> +
> +		udelay(10);
> +	}
> +
> +	/*
> +	 * now the secondary core is starting up let it run its
> +	 * calibrations, then wait for it to finish
> +	 */
> +	spin_unlock(&boot_lock);
> +
> +	return pen_release != -1 ? -ENOSYS : 0;
> +}
> +
> +static void __init poke_milo(void)
> +{
> +	/* nobody is to be released from the pen yet */
> +	pen_release = -1;
> +
> +	/*
> +	 * Write the address of secondary startup into the system-wide
> +	 * location (presently it is in SRAM). The BootMonitor waits
> +	 * for this register to become non-zero.
> +	 */
> +	__raw_writel(BSYM(virt_to_phys(spear13xx_secondary_startup)),
> +			__io_address(SPEAR13XX_SYS_LOCATION));
> +
> +	mb();

Please get rid of this function.  You don't have milo, and milo is pretty
much dead anyway.  Please read the Versatile Express SMP code and base
your version off that (cleaned up) version instead.

> +}
> +
> +/*
> + * Initialise the CPU possible map early - this describes the CPUs
> + * which may be present or become present in the system.
> + */
> +void __init smp_init_cpus(void)
> +{
> +	unsigned int i, ncores = get_core_count();
> +
> +	for (i = 0; i < ncores; i++)
> +		set_cpu_possible(i, true);
> +}
> +
> +void __init smp_prepare_cpus(unsigned int max_cpus)
> +{
> +	unsigned int ncores = get_core_count();
> +	unsigned int cpu = smp_processor_id();
> +	int i;
> +
> +	/* sanity check */
> +	if (ncores == 0) {
> +		pr_err("Realview: strange CM count of 0? Default to 1\n");
> +
> +		ncores = 1;
> +	}
> +
> +	if (ncores > num_possible_cpus()) {
> +		ncores = num_possible_cpus();
> +		pr_err(
> +		       "spear13xx: no. of cores (%d) greater than configured "
> +		       "maximum of %d - clipping\n",
> +		       ncores, ncores);
> +	}
> +
> +	smp_store_cpu_info(cpu);
> +
> +	/*
> +	 * are we trying to boot more cores than exist?
> +	 */
> +	if (max_cpus > ncores)
> +		max_cpus = ncores;
> +
> +	/*
> +	 * Initialise the present map, which describes the set of CPUs
> +	 * actually populated at the present time.
> +	 */
> +	for (i = 0; i < max_cpus; i++)
> +		set_cpu_present(i, true);
> +
> +	/*
> +	 * Initialise the SCU if there are more than one CPU and let
> +	 * them know where to start. Note that, on modern versions of
> +	 * MILO, the "poke" doesn't actually do anything until each
> +	 * individual core is sent a soft interrupt to get it out of
> +	 * WFI
> +	 */
> +	if (max_cpus > 1) {
> +		/*
> +		 * Enable the local timer or broadcast device for the
> +		 * boot CPU, but only if we have more than one CPU.
> +		 */
> +		percpu_timer_setup();
> +
> +		scu_enable(scu_base_addr());
> +		poke_milo();
> +	}
> +}
> diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
> new file mode 100644
> index 0000000..c1b82f1
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear1300.c
> @@ -0,0 +1,23 @@
> +/*
> + * arch/arm/mach-spear13xx/spear1300.c
> + *
> + * SPEAr1300 machine source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim@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 <mach/generic.h>
> +#include <mach/spear.h>
> +
> +/* Add spear1300 specific devices here */
> +
> +void __init spear1300_init(void)
> +{
> +	/* call spear13xx family common init function */
> +	spear13xx_init();
> +}
> diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> new file mode 100644
> index 0000000..d72c8a8
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear1300_evb.c
> @@ -0,0 +1,48 @@
> +/*
> + * arch/arm/mach-spear13xx/spear1300_evb.c
> + *
> + * SPEAr1300 evaluation board source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim@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/types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +#include <mach/generic.h>
> +#include <mach/spear.h>
> +
> +static struct amba_device *amba_devs[] __initdata = {
> +	&uart_device,
> +};
> +
> +static struct platform_device *plat_devs[] __initdata = {
> +};
> +
> +static void __init spear1300_evb_init(void)
> +{
> +	unsigned int i;
> +
> +	/* call spear1300 machine init function */
> +	spear1300_init();
> +
> +	/* Add Platform Devices */
> +	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
> +
> +	/* Add Amba Devices */
> +	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
> +		amba_device_register(amba_devs[i], &iomem_resource);
> +}
> +
> +MACHINE_START(SPEAR1300, "ST-SPEAR1300-EVB")
> +	.boot_params	=	0x00000100,
> +	.map_io		=	spear13xx_map_io,
> +	.init_irq	=	spear13xx_init_irq,
> +	.timer		=	&spear13xx_timer,
> +	.init_machine	=	spear1300_evb_init,
> +MACHINE_END
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
> new file mode 100644
> index 0000000..d11e300
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear13xx.c
> @@ -0,0 +1,98 @@
> +/*
> + * arch/arm/mach-spear13xx/spear13xx.c
> + *
> + * SPEAr13XX machines common source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim@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/types.h>
> +#include <linux/ptrace.h>
> +#include <linux/io.h>
> +#include <asm/hardware/gic.h>
> +#include <asm/irq.h>
> +#include <asm/localtimer.h>
> +#include <asm/mach/arch.h>
> +#include <asm/smp_twd.h>
> +#include <mach/irqs.h>
> +#include <mach/generic.h>
> +#include <mach/hardware.h>

So do you need all these includes?

> +
> +/* Add spear13xx machines common devices here */
> +/* uart device registeration */
> +struct amba_device uart_device = {
> +	.dev = {
> +		.init_name = "uart",
> +	},
> +	.res = {
> +		.start = SPEAR13XX_UART_BASE,
> +		.end = SPEAR13XX_UART_BASE + SZ_4K - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	.irq = {IRQ_UART, NO_IRQ},
> +};
> +
> +/* Do spear13xx familiy common initialization part here */
> +void __init spear13xx_init(void)
> +{
> +	/* nothing to do for now */
> +}
> +
> +/* This will initialize vic */
> +void __init spear13xx_init_irq(void)
> +{
> +	gic_dist_init(0, __io_address(SPEAR13XX_GIC_DIST_BASE), 29);
> +	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
> +}
> +
> +/* Following will create static virtual/physical mappings */
> +struct map_desc spear13xx_io_desc[] __initdata = {
> +	{
> +		.virtual	= IO_ADDRESS(SPEAR13XX_UART_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_UART_BASE),
> +		.length		= SZ_4K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_A9SM_PERIP_BASE),
> +		.length		= SZ_8K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_MISC_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_MISC_BASE),
> +		.length		= SZ_8K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_SYSRAM0_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM0_BASE),
> +		.length		= SZ_32K,
> +		.type		= MT_DEVICE
> +	},
> +};
> +
> +/* This will create static memory mapping for selected devices */
> +void __init spear13xx_map_io(void)
> +{
> +	iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
> +
> +	/* This will initialize clock framework */
> +	clk_init();
> +}
> +
> +static void __init spear13xx_timer_init(void)
> +{
> +#ifdef CONFIG_LOCAL_TIMERS
> +	/* Setup the local timer base */
> +	twd_base = __io_address(SPEAR13XX_LOCAL_TMR_BASE);
> +#endif
> +	spear_setup_timer();
> +}
> +
> +struct sys_timer spear13xx_timer = {
> +	.init = spear13xx_timer_init,
> +};
> -- 
> 1.7.2.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx
  2010-08-30 10:38 ` [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx Viresh KUMAR
@ 2010-09-02  9:08   ` Russell King - ARM Linux
  2010-09-06  9:43     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

> +static int clcd_check(struct clcd_fb *fb, struct fb_var_screeninfo
> +		*var)
> +{
> +	var->xres_virtual = var->xres = (var->xres + 15) & ~15;
> +	var->yres_virtual = var->yres = (var->yres + 1) & ~1;
> +
> +	var->nonstd = 0;
> +	var->accel_flags = 0;

This looks insufficient.

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

* [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform
  2010-08-30 10:38 ` [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform Viresh KUMAR
@ 2010-09-02  9:13   ` Russell King - ARM Linux
  2010-09-03  3:44     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:45PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/plat-spear/plgpio.c b/arch/arm/plat-spear/plgpio.c
> new file mode 100644
> index 0000000..847ff9c
> --- /dev/null
> +++ b/arch/arm/plat-spear/plgpio.c
> @@ -0,0 +1,453 @@
> +/*
> + * 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 <mach/gpio.h>

You're already including linux/gpio.h, which means mach/gpio.h will already
be included.

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

* [PATCH 32/74] ST SPEAr: Adding clk_set_rate support
  2010-08-30 10:38 ` [PATCH 32/74] ST SPEAr: Adding clk_set_rate support Viresh KUMAR
@ 2010-09-02  9:21   ` Russell King - ARM Linux
  2010-09-06 10:03     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:56PM +0530, Viresh KUMAR wrote:
> 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>

Can't this patch be rolled into a previous patch - especially as it deletes
a load of code added by that previous patch (eg, clk_is_enabled)?  It
doesn't look like it depends on the other various changes between that
patch and this one.

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

* Re: [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
  2010-09-02  6:33                       ` Brian Norris
@ 2010-09-02  9:49                         ` Artem Bityutskiy
  -1 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-02  9:49 UTC (permalink / raw)
  To: Brian Norris
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Armando VISCONTI, Kevin Cernekee, Vipin Kumar, Shiraz HASHIM,
	Ryan Mallon, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

On Wed, 2010-09-01 at 23:33 -0700, Brian Norris wrote:
> 
> I'm curious how many applications actually need to have the ecclayout.
> nandwrite doesn't actually use it, just oobinfo. 

That is good point - I think we should not accept new ioctl before the
submitter shows us how and for what he will use it.

My point is simple - OOB layout should be transparent to users-space.
Messing with this is error-prone.

-- 
Best Regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char
@ 2010-09-02  9:49                         ` Artem Bityutskiy
  0 siblings, 0 replies; 245+ messages in thread
From: Artem Bityutskiy @ 2010-09-02  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2010-09-01 at 23:33 -0700, Brian Norris wrote:
> 
> I'm curious how many applications actually need to have the ecclayout.
> nandwrite doesn't actually use it, just oobinfo. 

That is good point - I think we should not accept new ioctl before the
submitter shows us how and for what he will use it.

My point is simple - OOB layout should be transparent to users-space.
Messing with this is error-prone.

-- 
Best Regards,
Artem Bityutskiy (???????? ?????)

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

* [PATCH 31/74] ST SPEAr: Adding support for SSP PL022
  2010-08-30 10:38 ` [PATCH 31/74] ST SPEAr: Adding support for SSP PL022 Viresh KUMAR
@ 2010-09-02  9:57   ` Russell King - ARM Linux
  2010-09-03  3:50     ` viresh kumar
  2010-09-02 19:18   ` Linus Walleij
  1 sibling, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:55PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> index 8658d48..8399c15 100644
> --- a/arch/arm/mach-spear13xx/clock.c
> +++ b/arch/arm/mach-spear13xx/clock.c
> @@ -799,7 +799,7 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{.dev_id = "i2s0",		.clk = &i2s0_clk},
>  	{.dev_id = "i2s1",		.clk = &i2s1_clk},
>  	{.dev_id = "adc",		.clk = &adc_clk},
> -	{.dev_id = "ssp",		.clk = &ssp_clk},
> +	{.dev_id = "ssp-pl022",		.clk = &ssp_clk},

All these kinds of changes are just noise in these patches, which add
to the review workload (and review tiredness.)  Your previous patches
added the original definitions.  Please roll these changes into your
previous patches so that there's less overall changes to look at in
your patch series.

It really is not necessary to show how you got from A to B via every
minute step.

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

* [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration
  2010-08-30 10:38 ` [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration Viresh KUMAR
@ 2010-09-02 10:02   ` Russell King - ARM Linux
  2010-09-06 11:26     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:08:59PM +0530, Viresh KUMAR wrote:

No description, so I'm going to have to guess about this.

> +static inline void
> +spear_amba_device_register(struct amba_device **devices, u32 count)
> +{
> +	u32 i;
> +
> +	for (i = 0; i < count; i++) {
> +		struct clk *clk = clk_get_sys(devices[i]->dev.init_name, NULL);
> +		if (IS_ERR(clk))
> +			continue;
> +
> +		clk_enable(clk);
> +		amba_device_register(devices[i], &iomem_resource);
> +		clk_disable(clk);

My guess is that you're doing this to work around the fact that your
SoC enables/disables both the bus clock and the functional clock to
each primecell, and so you're finding that you need to enable the
clock to access the device registers.

We've fixed this in the generic code by introducing an 'apb_pclk' clock
which the core bus code controls (and eventually drivers.)  See discussion
earlier this month/last month on this list about this.

That makes this patch redundant.

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

* [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file
  2010-08-30 10:39 ` [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file Viresh KUMAR
@ 2010-09-02 10:04   ` Russell King - ARM Linux
  2010-09-03  3:52     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:02PM +0530, Viresh KUMAR wrote:
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Do this in the patch which adds the sdhci clock instead.  This patch
on its own is pure noise.

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

* [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310
  2010-08-30 10:39 ` [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310 Viresh KUMAR
@ 2010-09-02 10:07   ` Russell King - ARM Linux
  2010-09-03  3:53     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:04PM +0530, Viresh KUMAR wrote:
> From: Bhupesh Sharma <bhupesh.sharma@st.com>
> 
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@st.com>
> Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---
>  arch/arm/Makefile                                |    1 +
>  arch/arm/configs/spear1310-smp_defconfig         |  875 ++++++++++++++++++++++

NAK.  No new large defconfigs.

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-08-30 10:39 ` [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs Viresh KUMAR
@ 2010-09-02 10:22   ` Russell King - ARM Linux
  2010-09-02 10:40     ` Will Deacon
  2010-09-06  7:44     ` Shiraz Hashim
  0 siblings, 2 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:09PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h b/arch/arm/mach-spear13xx/include/mach/smp.h
> index 6e028a1..e2e55fc 100644
> --- a/arch/arm/mach-spear13xx/include/mach/smp.h
> +++ b/arch/arm/mach-spear13xx/include/mach/smp.h
> @@ -24,6 +24,12 @@
>  		cpunum &= 0x0F;				\
>  	})
>  
> +/*
> + * set_event() is used to wake up secondary core from wfe using sev. Booting
> + * code puts the second core into wfe(standby).
> + */
> +#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")

This shouldn't be something that platforms define on their own.  Please
add a sev() macro to arch/arm/include/asm/system.h instead.  Also take a
look at arch/arm/mach-omap2/omap-smp.c for an alternative idea about how
to handle this.

Lastly, consider rolling the OMAP solution into the patch which adds SMP
support for spear13xx.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-08-30 10:39 ` [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume Viresh KUMAR
@ 2010-09-02 10:23   ` Russell King - ARM Linux
  2010-09-03  6:24     ` deepaksi
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:12PM +0530, Viresh KUMAR wrote:
> From: Deepak Sikri <deepak.sikri@st.com>
> 

The reason being?

> Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---
>  arch/arm/common/gic.c |   13 +++++++++++++
>  1 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 7dfa9a8..e816ef1 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -201,6 +201,18 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
>  	chip->unmask(irq);
>  }
>  
> +#ifdef CONFIG_PM
> +
> +static int gic_set_wake(unsigned int irq, unsigned int on)
> +{
> +	return 0;
> +}
> +
> +#else
> +
> +#define gic_set_wake NULL
> +#endif
> +
>  static struct irq_chip gic_chip = {
>  	.name		= "GIC",
>  	.ack		= gic_ack_irq,
> @@ -210,6 +222,7 @@ static struct irq_chip gic_chip = {
>  #ifdef CONFIG_SMP
>  	.set_affinity	= gic_set_cpu,
>  #endif
> +	.set_wake	= gic_set_wake,
>  };
>  
>  void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
> -- 
> 1.7.2.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework
  2010-08-30 10:39 ` [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework Viresh KUMAR
@ 2010-09-02 10:24   ` Russell King - ARM Linux
  2010-09-03  6:20     ` deepaksi
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:13PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index c4d1df3..ef92faa 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -822,6 +822,8 @@ config PLAT_SPEAR
>  	select COMMON_CLKDEV
>  	select GENERIC_CLOCKEVENTS
>  	select HAVE_CLK
> +	select ARCH_HAS_CPUFREQ
> +

You should avoid this blank line.
>  	help
>  	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-09-02 10:22   ` Russell King - ARM Linux
@ 2010-09-02 10:40     ` Will Deacon
  2010-09-02 11:07       ` Shilimkar, Santosh
  2010-09-02 13:08       ` Russell King - ARM Linux
  2010-09-06  7:44     ` Shiraz Hashim
  1 sibling, 2 replies; 245+ messages in thread
From: Will Deacon @ 2010-09-02 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

[added Jeff Ohlstein]

> On Mon, Aug 30, 2010 at 04:09:09PM +0530, Viresh KUMAR wrote:
> > diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h b/arch/arm/mach-spear13xx/include/mach/smp.h
> > index 6e028a1..e2e55fc 100644
> > --- a/arch/arm/mach-spear13xx/include/mach/smp.h
> > +++ b/arch/arm/mach-spear13xx/include/mach/smp.h
> > @@ -24,6 +24,12 @@
> >  		cpunum &= 0x0F;				\
> >  	})
> >
> > +/*
> > + * set_event() is used to wake up secondary core from wfe using sev. Booting
> > + * code puts the second core into wfe(standby).
> > + */
> > +#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
> 
> This shouldn't be something that platforms define on their own.  Please
> add a sev() macro to arch/arm/include/asm/system.h instead.  Also take a
> look at arch/arm/mach-omap2/omap-smp.c for an alternative idea about how
> to handle this.

There was patch posted last month from Code Aurora:

http://lists.infradead.org/pipermail/linux-arm-kernel/2010-July/021401.html

which proposed adding a sev() macro to processor.h. They also added
a wfe() macro, so maybe all of this should go in system.h instead.

Will

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-09-02 10:40     ` Will Deacon
@ 2010-09-02 11:07       ` Shilimkar, Santosh
  2010-09-02 15:59         ` Russell King - ARM Linux
  2010-09-02 13:08       ` Russell King - ARM Linux
  1 sibling, 1 reply; 245+ messages in thread
From: Shilimkar, Santosh @ 2010-09-02 11:07 UTC (permalink / raw)
  To: linux-arm-kernel

> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> kernel-bounces at lists.infradead.org] On Behalf Of Will Deacon
> Sent: Thursday, September 02, 2010 4:10 PM
> To: 'Russell King - ARM Linux'; Viresh KUMAR
> Cc: pratyush.anand at st.com; vipulkumar.samar at st.com; bhupesh.sharma at st.com;
> armando.visconti at st.com; Vipin Kumar; shiraz.hashim at st.com; rajeev-
> dlh.kumar at st.com; johlstei at codeaurora.org; deepak.sikri at st.com; linux-arm-
> kernel at lists.infradead.org
> Subject: RE: [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
> 
> Hi Russell,
> 
> [added Jeff Ohlstein]
> 
> > On Mon, Aug 30, 2010 at 04:09:09PM +0530, Viresh KUMAR wrote:
> > > diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h
> b/arch/arm/mach-spear13xx/include/mach/smp.h
> > > index 6e028a1..e2e55fc 100644
> > > --- a/arch/arm/mach-spear13xx/include/mach/smp.h
> > > +++ b/arch/arm/mach-spear13xx/include/mach/smp.h
> > > @@ -24,6 +24,12 @@
> > >  		cpunum &= 0x0F;				\
> > >  	})
> > >
> > > +/*
> > > + * set_event() is used to wake up secondary core from wfe using sev.
> Booting
> > > + * code puts the second core into wfe(standby).
> > > + */
> > > +#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
> >
> > This shouldn't be something that platforms define on their own.  Please
> > add a sev() macro to arch/arm/include/asm/system.h instead.  Also take a
> > look at arch/arm/mach-omap2/omap-smp.c for an alternative idea about how
> > to handle this.
> 
> There was patch posted last month from Code Aurora:
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-
> July/021401.html
> 
> which proposed adding a sev() macro to processor.h. They also added
> a wfe() macro, so maybe all of this should go in system.h instead.
> 
May be we should have barrier version of these
There is one already exist in mainline already in spin lock code
"dsb_sev(void)"

 

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-02  8:09       ` Armando Visconti
@ 2010-09-02 11:15         ` Linus Walleij
  -1 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-02 11:15 UTC (permalink / raw)
  To: Armando Visconti
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Alessandro Rubini, Vipin KUMAR,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

2010/9/2 Armando Visconti <armando.visconti@st.com>:

>> I *highly* suspect that this driver duplicates some code found in
>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>
> Why nomadik_nand.c?
> Shouldn't the fsmc_nand.c rule apply also in this case?

As I said I think nomadik_nand.c shall be deleted and replaced with
this driver.

Unless Alessandro hits me on the fingers... If it is made generic
I can provide testing for the U300. (Maybe I can get my NHK8815
card booting too, I don't know.)

Yours,
Linus Walleij

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-02 11:15         ` Linus Walleij
  0 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-02 11:15 UTC (permalink / raw)
  To: linux-arm-kernel

2010/9/2 Armando Visconti <armando.visconti@st.com>:

>> I *highly* suspect that this driver duplicates some code found in
>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>
> Why nomadik_nand.c?
> Shouldn't the fsmc_nand.c rule apply also in this case?

As I said I think nomadik_nand.c shall be deleted and replaced with
this driver.

Unless Alessandro hits me on the fingers... If it is made generic
I can provide testing for the U300. (Maybe I can get my NHK8815
card booting too, I don't know.)

Yours,
Linus Walleij

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-02 11:15         ` Linus Walleij
@ 2010-09-02 12:33           ` Armando Visconti
  -1 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02 12:33 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Alessandro Rubini, Vipin KUMAR,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

Linus Walleij wrote:
> 2010/9/2 Armando Visconti <armando.visconti@st.com>:
>
>   
>>> I *highly* suspect that this driver duplicates some code found in
>>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>>>       
>> Why nomadik_nand.c?
>> Shouldn't the fsmc_nand.c rule apply also in this case?
>>     
>
> As I said I think nomadik_nand.c shall be deleted and replaced with
> this driver.
>
> Unless Alessandro hits me on the fingers... If it is made generic
> I can provide testing for the U300. (Maybe I can get my NHK8815
> card booting too, I don't know.)
>   
As I said before, the SPEAr driver should work on Nomadik too
as it looks generic enough and for us it is working
on two different platforms with different FSMC versions.

This, unless the Nomadik FSMC is a customized h/w block, which
I seem to remember in fact ...

Ciao,
Arm


-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti@st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-02 12:33           ` Armando Visconti
  0 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-02 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

Linus Walleij wrote:
> 2010/9/2 Armando Visconti <armando.visconti@st.com>:
>
>   
>>> I *highly* suspect that this driver duplicates some code found in
>>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>>>       
>> Why nomadik_nand.c?
>> Shouldn't the fsmc_nand.c rule apply also in this case?
>>     
>
> As I said I think nomadik_nand.c shall be deleted and replaced with
> this driver.
>
> Unless Alessandro hits me on the fingers... If it is made generic
> I can provide testing for the U300. (Maybe I can get my NHK8815
> card booting too, I don't know.)
>   
As I said before, the SPEAr driver should work on Nomadik too
as it looks generic enough and for us it is working
on two different platforms with different FSMC versions.

This, unless the Nomadik FSMC is a customized h/w block, which
I seem to remember in fact ...

Ciao,
Arm


-- 
-- "Every step appears to be the unavoidable consequence of the
-- preceding one." (A. Einstein) 
-- 
Armando Visconti                  Mobile: (+39) 346 8879146
Senior SW Engineer                Fax:    (+39) 02 93519290
CPG                               Work:   (+39) 02 93519683
Computer System Division          e-mail: armando.visconti at st.com
ST Microelectronics               TINA:   051  4683
                                    
 

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-09-02 10:40     ` Will Deacon
  2010-09-02 11:07       ` Shilimkar, Santosh
@ 2010-09-02 13:08       ` Russell King - ARM Linux
  1 sibling, 0 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 02, 2010 at 11:40:08AM +0100, Will Deacon wrote:
> There was patch posted last month from Code Aurora:
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-July/021401.html
> 
> which proposed adding a sev() macro to processor.h. They also added
> a wfe() macro, so maybe all of this should go in system.h instead.

I think so, and system.h seems to be a better place for it.

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

* [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig
  2010-08-30 10:39 ` [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
@ 2010-09-02 15:40   ` Russell King - ARM Linux
  2010-09-03  3:56     ` viresh kumar
  2010-09-07  9:18     ` viresh kumar
  0 siblings, 2 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 30, 2010 at 04:09:35PM +0530, Viresh KUMAR wrote:
> We only need one defconfig for SPEAr13xx now since we can build all
> boards into one kernel.

All this kind of thing should be rolled into previous patches.

We really don't need to know that you developed SPEAr13xx support
such that it initially couldn't build all boards into a kernel,
what the changes were to achieve a kernel for everything, and that
there were several defconfigs in existence before one grand unified
one was possible.

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-09-02 11:07       ` Shilimkar, Santosh
@ 2010-09-02 15:59         ` Russell King - ARM Linux
  0 siblings, 0 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 02, 2010 at 04:37:37PM +0530, Shilimkar, Santosh wrote:
> May be we should have barrier version of these
> There is one already exist in mainline already in spin lock code
> "dsb_sev(void)"

I don't think so - they're not a general purpose event passing mechanism.
Their use is fairly well limited to two situations:

1. spin locks, where we already have dsb_sev as we care about ordering.
2. smp secondary cpu bring-up code, where we care a little less about the
   ordering.

I think coupling a barrier with these will just make people want to have
a version without the barrier.  At least if we don't provide the barrier,
people have the option of using mb() before sev() if they desire ordering.

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

* [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/
  2010-08-30 10:38 ` [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/ Viresh KUMAR
@ 2010-09-02 16:27   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-06 11:52     ` viresh kumar
  2010-09-07 11:35     ` viresh kumar
  0 siblings, 2 replies; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-02 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 16:08 Mon 30 Aug     , Viresh KUMAR wrote:
> From: Shiraz Hashim <shiraz.hashim@st.com>
missing patch descriptin
> 
> Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---
>  arch/arm/Kconfig  |   12 ++++++++----
>  arch/arm/Makefile |    1 +
>  2 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 9295110..950c045 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1144,11 +1144,13 @@ config SMP
>  	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
>  	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
>  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
> -		 ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
> +		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
> +		 ARCH_VEXPRESS_CA9X4)
can we get rid of such long list by introducing a HAVE somthing
etc....

Best Regards,
J.

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

* [PATCH 31/74] ST SPEAr: Adding support for SSP PL022
  2010-08-30 10:38 ` [PATCH 31/74] ST SPEAr: Adding support for SSP PL022 Viresh KUMAR
  2010-09-02  9:57   ` Russell King - ARM Linux
@ 2010-09-02 19:18   ` Linus Walleij
  2010-09-03  3:58     ` viresh kumar
  1 sibling, 1 reply; 245+ messages in thread
From: Linus Walleij @ 2010-09-02 19:18 UTC (permalink / raw)
  To: linux-arm-kernel

2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:

> (...)
> diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> (...)
> +/* Currently no gpios are free on eval board so it is kept commented */
> +#if 0

Argh!

> +/* spi board information */
> +/* spi0 flash Chip Select Control function, controlled by gpio pin mentioned */
> +DECLARE_SPI_CS_CONTROL(0, flash, /* mention gpio number here */);
> +/* 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, /* mention gpio number here */);
> +/* spi0 spidev Chip Info structure */
> +DECLARE_SPI_CHIP_INFO(0, dev, spi0_dev_cs_control);
> +#endif
> +
> +static struct spi_board_info __initdata spi_board_info[] = {
> +#if 0

And again!

> + ? ? ? /* spi0 board info */
> + ? ? ? {
> + ? ? ? ? ? ? ? .modalias = "spidev",
> + ? ? ? ? ? ? ? .controller_data = &spi0_dev_chip_info,
> + ? ? ? ? ? ? ? .max_speed_hz = 10000000,
> + ? ? ? ? ? ? ? .bus_num = 0,
> + ? ? ? ? ? ? ? .chip_select = 0,
> + ? ? ? ? ? ? ? .mode = 0,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .modalias = "m25p80",
> + ? ? ? ? ? ? ? .controller_data = &spi0_flash_chip_info,
> + ? ? ? ? ? ? ? .max_speed_hz = 1000000,
> + ? ? ? ? ? ? ? .bus_num = 0,
> + ? ? ? ? ? ? ? .chip_select = 1,
> + ? ? ? ? ? ? ? .mode = 0,
> + ? ? ? }
> +#endif

Don't commit commented-out code.

> (...)
> diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
> (...)
> +/*
> + * Chip select of spidev, currently no gpio is free on eval board so it is kept
> + * commented
> + */
> +#if 0

Again!

> (...)
> +static struct spi_board_info __initdata spi_board_info[] = {
> + ? ? ? /* spi0 board info */
> + ? ? ? {
> +#if 0

And again!

> + ? ? ? ? ? ? ? .modalias = "spidev",
> + ? ? ? ? ? ? ? .controller_data = &spi0_dev_chip_info,
> + ? ? ? ? ? ? ? .max_speed_hz = 10000000,
> + ? ? ? ? ? ? ? .bus_num = 0,
> + ? ? ? ? ? ? ? .chip_select = 0,
> + ? ? ? ? ? ? ? .mode = 0,
> + ? ? ? }, {
> +#endif

Please grep your code for all #if 0 and remove it.

Yours,
Linus Walleij

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

* [PATCH 08/74] ST SPEAr1300: Adding default config file
  2010-09-02  8:51   ` Russell King - ARM Linux
@ 2010-09-03  1:45     ` Nicolas Pitre
  2010-09-03  7:32       ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: Nicolas Pitre @ 2010-09-03  1:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2 Sep 2010, Russell King - ARM Linux wrote:

> On Mon, Aug 30, 2010 at 04:08:39PM +0530, Viresh KUMAR wrote:
> > From: Shiraz Hashim <shiraz.hashim@st.com>
> 
> This defconfig is too large and verbose to go anywhere near mainline,
> even temporarily.  You need to talk to Uwe about how to shrink it down.

These days, all you need to do is:

	  make savedefconfig

and look for a defconfig file in the current directory.


Nicolas

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

* [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform
  2010-09-02  9:13   ` Russell King - ARM Linux
@ 2010-09-03  3:44     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 2:43 PM, Russell King - ARM Linux wrote:
>> +#include <linux/gpio.h>
>> > +#include <linux/slab.h>
>> > +#include <linux/platform_device.h>
>> > +#include <mach/gpio.h>
> You're already including linux/gpio.h, which means mach/gpio.h will already
> be included.
> .
> 

Correct. Will remove mach/gpio.h

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

* [PATCH 31/74] ST SPEAr: Adding support for SSP PL022
  2010-09-02  9:57   ` Russell King - ARM Linux
@ 2010-09-03  3:50     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:27 PM, Russell King - ARM Linux wrote:
> All these kinds of changes are just noise in these patches, which add
> to the review workload (and review tiredness.)  Your previous patches
> added the original definitions.  Please roll these changes into your
> previous patches so that there's less overall changes to look at in
> your patch series.
> 
> It really is not necessary to show how you got from A to B via every
> minute step.
> .

Ok.

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

* [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file
  2010-09-02 10:04   ` Russell King - ARM Linux
@ 2010-09-03  3:52     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:34 PM, Russell King - ARM Linux wrote:
> Do this in the patch which adds the sdhci clock instead.  This patch
> on its own is pure noise.

OK.

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

* [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310
  2010-09-02 10:07   ` Russell King - ARM Linux
@ 2010-09-03  3:53     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:37 PM, Russell King - ARM Linux wrote:
>>  arch/arm/Makefile                                |    1 +
>> >  arch/arm/configs/spear1310-smp_defconfig         |  875 ++++++++++++++++++++++
> NAK.  No new large defconfigs.

Ok. Will correct all defconfig patches.

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

* [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig
  2010-09-02 15:40   ` Russell King - ARM Linux
@ 2010-09-03  3:56     ` viresh kumar
  2010-09-07  9:18     ` viresh kumar
  1 sibling, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 9:10 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:09:35PM +0530, Viresh KUMAR wrote:
>> > We only need one defconfig for SPEAr13xx now since we can build all
>> > boards into one kernel.
> All this kind of thing should be rolled into previous patches.
> 
> We really don't need to know that you developed SPEAr13xx support
> such that it initially couldn't build all boards into a kernel,
> what the changes were to achieve a kernel for everything, and that
> there were several defconfigs in existence before one grand unified
> one was possible.

Ok.

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

* [PATCH 31/74] ST SPEAr: Adding support for SSP PL022
  2010-09-02 19:18   ` Linus Walleij
@ 2010-09-03  3:58     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  3:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/3/2010 12:48 AM, Linus Walleij wrote:
>> > +               .modalias = "spidev",
>> > +               .controller_data = &spi0_dev_chip_info,
>> > +               .max_speed_hz = 10000000,
>> > +               .bus_num = 0,
>> > +               .chip_select = 0,
>> > +               .mode = 0,
>> > +       }, {
>> > +#endif
> Please grep your code for all #if 0 and remove it.

Sorry for the noise!!! Will correct it.

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

* [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms
  2010-08-30 10:39 ` [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms Viresh KUMAR
@ 2010-09-03  6:00   ` Sundar
  2010-09-30  9:37     ` Shiraz Hashim
  0 siblings, 1 reply; 245+ messages in thread
From: Sundar @ 2010-09-03  6:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Aug 30, 2010 at 4:09 PM, Viresh KUMAR <viresh.kumar@st.com> wrote:
> From: Deepak Sikri <deepak.sikri@st.com>
>
> Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
> Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---

> +       flush_cache_all();
> +       asm volatile(
> +       "       mcr     p15, 0, %1, c7, c5, 0\n"
> +       "       mcr     p15, 0, %1, c7, c10, 4\n"

Isnt this a Cortex-A9 platform? If yes, then this is not implemented
on the Cortex-A9 if I am right.
You should use a dsb() here.

> +               /*
> +                * here's the WFI
> +                */
> +               asm(".word      0xe320f003\n"
> +                   :

Also, why not a simple asm volatile("wfi" : : : "memory"); instead of
hard coded values.

Regards,
Sundar

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

* [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework
  2010-09-02 10:24   ` Russell King - ARM Linux
@ 2010-09-03  6:20     ` deepaksi
  0 siblings, 0 replies; 245+ messages in thread
From: deepaksi @ 2010-09-03  6:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:54 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:09:13PM +0530, Viresh KUMAR wrote:
>   
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index c4d1df3..ef92faa 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -822,6 +822,8 @@ config PLAT_SPEAR
>>  	select COMMON_CLKDEV
>>  	select GENERIC_CLOCKEVENTS
>>  	select HAVE_CLK
>> +	select ARCH_HAS_CPUFREQ
>> +
>>     
> You should avoid this blank line.
>   

Ok..
>>  	help
>>  	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
>>     
> .
>
>   

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-02 10:23   ` Russell King - ARM Linux
@ 2010-09-03  6:24     ` deepaksi
  2010-09-03  7:34       ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: deepaksi @ 2010-09-03  6:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:53 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:09:12PM +0530, Viresh KUMAR wrote:
>   
>> From: Deepak Sikri <deepak.sikri@st.com>
>>
>>     
> The reason being?
>
>   

For configuring the wake up sources ( normally in the PM framework for
suspend resume operations), you need to use the following set of api
enable_irq_wake(). This handler has a appropriate callback for the vic,
similar to the plugin that we have added in for gic which does enable
the wake interrupt sources only. But since gic handler did not had this
call back associated was always returning -ENXIO, which was breaking the
existing drivers. In case no checks are provided for the return value of 
enable_irq_wake(), the things were fine.



>> Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
>> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
>> ---
>>  arch/arm/common/gic.c |   13 +++++++++++++
>>  1 files changed, 13 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
>> index 7dfa9a8..e816ef1 100644
>> --- a/arch/arm/common/gic.c
>> +++ b/arch/arm/common/gic.c
>> @@ -201,6 +201,18 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
>>  	chip->unmask(irq);
>>  }
>>  
>> +#ifdef CONFIG_PM
>> +
>> +static int gic_set_wake(unsigned int irq, unsigned int on)
>> +{
>> +	return 0;
>> +}
>> +
>> +#else
>> +
>> +#define gic_set_wake NULL
>> +#endif
>> +
>>  static struct irq_chip gic_chip = {
>>  	.name		= "GIC",
>>  	.ack		= gic_ack_irq,
>> @@ -210,6 +222,7 @@ static struct irq_chip gic_chip = {
>>  #ifdef CONFIG_SMP
>>  	.set_affinity	= gic_set_cpu,
>>  #endif
>> +	.set_wake	= gic_set_wake,
>>  };
>>  
>>  void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
>> -- 
>> 1.7.2.2
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>     
> .
>
>   

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

* [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files
  2010-09-02  9:04   ` Russell King - ARM Linux
@ 2010-09-03  6:38     ` Shiraz Hashim
  0 siblings, 0 replies; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-03  6:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Russell,

On 9/2/2010 2:34 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:08:36PM +0530, Viresh KUMAR wrote:
>> diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
>> new file mode 100644
>> index 0000000..8b75d1b
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/platsmp.c
>> @@ -0,0 +1,203 @@
>> +/*
>> + * arch/arm/mach-spear13xx/platsmp.c
>> + *
>> + * based upon linux/arch/arm/mach-realview/platsmp.c
>> + *
>> + * Copyright (C) 2010 ST Microelectronics Ltd.
>> + * Shiraz Hashim <shiraz.hashim@st.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <asm/cacheflush.h>
>> +#include <asm/hardware/gic.h>
>> +#include <asm/localtimer.h>
>> +#include <asm/mach-types.h>
>> +#include <asm/smp_scu.h>
>> +#include <asm/unified.h>
>> +#include <linux/delay.h>
>> +#include <linux/device.h>
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/jiffies.h>
>> +#include <linux/smp.h>
>> +#include <mach/generic.h>
>> +#include <mach/hardware.h>
> 
> linux/ before asm/ before mach/ please. 

OK. Would check it across.

>> +
>> +/*
>> + * control for which core is the next to come out of the secondary
>> + * boot "holding pen"
>> + */
>> +volatile int __cpuinitdata pen_release = -1;
>> +static DEFINE_SPINLOCK(boot_lock);
>> +
>> +static void __iomem *scu_base_addr(void)
>> +{
>> +     return __io_address(SPEAR13XX_SCU_BASE);
>> +}
>> +
>> +static inline unsigned int get_core_count(void)
>> +{
>> +     void __iomem *scu_base = scu_base_addr();
>> +
>> +     if (scu_base)
>> +             return scu_get_core_count(scu_base);
>> +     return 1;
>> +}
>> +
>> +void __cpuinit platform_secondary_init(unsigned int cpu)
>> +{
>> +     trace_hardirqs_off();
>> +
>> +     /*
>> +      * if any interrupts are already enabled for the primary
>> +      * core (e.g. timer irq), then they will not have been enabled
>> +      * for us: do so
>> +      */
>> +     gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
>> +
>> +     /*
>> +      * let the primary processor know we're out of the
>> +      * pen, then head off into the C entry point
>> +      */
>> +     pen_release = -1;
>> +     smp_wmb();
>> +
>> +     /*
>> +      * Synchronise with the boot thread.
>> +      */
>> +     spin_lock(&boot_lock);
>> +     spin_unlock(&boot_lock);
>> +}
>> +
>> +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
>> +{
>> +     unsigned long timeout;
>> +
>> +     /*
>> +      * set synchronisation state between this boot processor
>> +      * and the secondary one
>> +      */
>> +     spin_lock(&boot_lock);
>> +
>> +     /*
>> +      * The secondary processor is waiting to be released from
>> +      * the holding pen - release it, then wait for it to flag
>> +      * that it has been released by resetting pen_release.
>> +      *
>> +      * Note that "pen_release" is the hardware CPU ID, whereas
>> +      * "cpu" is Linux's internal ID.
>> +      */
>> +
>> +     /*
>> +      * Note: Following is important otherwise cpu2 doesn't come up
>> +      * as secondary_data must be flushed before pen_release also
>> +      */
>> +
>> +     flush_cache_all();
> 
> You don't need this.  secondary_data is already taken care of as of a
> few kernel releases ago.
> 

OK.

>> +     pen_release = cpu;
>> +     flush_cache_all();
>> +
>> +     timeout = jiffies + (1 * HZ);
>> +     while (time_before(jiffies, timeout)) {
>> +             smp_rmb();
>> +             if (pen_release == -1)
>> +                     break;
>> +
>> +             udelay(10);
>> +     }
>> +
>> +     /*
>> +      * now the secondary core is starting up let it run its
>> +      * calibrations, then wait for it to finish
>> +      */
>> +     spin_unlock(&boot_lock);
>> +
>> +     return pen_release != -1 ? -ENOSYS : 0;
>> +}
>> +
>> +static void __init poke_milo(void)
>> +{
>> +     /* nobody is to be released from the pen yet */
>> +     pen_release = -1;
>> +
>> +     /*
>> +      * Write the address of secondary startup into the system-wide
>> +      * location (presently it is in SRAM). The BootMonitor waits
>> +      * for this register to become non-zero.
>> +      */
>> +     __raw_writel(BSYM(virt_to_phys(spear13xx_secondary_startup)),
>> +                     __io_address(SPEAR13XX_SYS_LOCATION));
>> +
>> +     mb();
> 
> Please get rid of this function.  You don't have milo, and milo is pretty
> much dead anyway.  Please read the Versatile Express SMP code and base
> your version off that (cleaned up) version instead.
> 

OK. I would refer the code.

>> +}
>> +
>> +/*
>> + * Initialise the CPU possible map early - this describes the CPUs
>> + * which may be present or become present in the system.
>> + */
>> +void __init smp_init_cpus(void)
>> +{
>> +     unsigned int i, ncores = get_core_count();
>> +
>> +     for (i = 0; i < ncores; i++)
>> +             set_cpu_possible(i, true);
>> +}
>> +
>> +void __init smp_prepare_cpus(unsigned int max_cpus)
>> +{
>> +     unsigned int ncores = get_core_count();
>> +     unsigned int cpu = smp_processor_id();
>> +     int i;
>> +
>> +     /* sanity check */
>> +     if (ncores == 0) {
>> +             pr_err("Realview: strange CM count of 0? Default to 1\n");
>> +
>> +             ncores = 1;
>> +     }
>> +
>> +     if (ncores > num_possible_cpus()) {
>> +             ncores = num_possible_cpus();
>> +             pr_err(
>> +                    "spear13xx: no. of cores (%d) greater than configured "
>> +                    "maximum of %d - clipping\n",
>> +                    ncores, ncores);
>> +     }
>> +
>> +     smp_store_cpu_info(cpu);
>> +
>> +     /*
>> +      * are we trying to boot more cores than exist?
>> +      */
>> +     if (max_cpus > ncores)
>> +             max_cpus = ncores;
>> +
>> +     /*
>> +      * Initialise the present map, which describes the set of CPUs
>> +      * actually populated at the present time.
>> +      */
>> +     for (i = 0; i < max_cpus; i++)
>> +             set_cpu_present(i, true);
>> +
>> +     /*
>> +      * Initialise the SCU if there are more than one CPU and let
>> +      * them know where to start. Note that, on modern versions of
>> +      * MILO, the "poke" doesn't actually do anything until each
>> +      * individual core is sent a soft interrupt to get it out of
>> +      * WFI
>> +      */
>> +     if (max_cpus > 1) {
>> +             /*
>> +              * Enable the local timer or broadcast device for the
>> +              * boot CPU, but only if we have more than one CPU.
>> +              */
>> +             percpu_timer_setup();
>> +
>> +             scu_enable(scu_base_addr());
>> +             poke_milo();
>> +     }
>> +}
>> diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
>> new file mode 100644
>> index 0000000..c1b82f1
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/spear1300.c
>> @@ -0,0 +1,23 @@
>> +/*
>> + * arch/arm/mach-spear13xx/spear1300.c
>> + *
>> + * SPEAr1300 machine source file
>> + *
>> + * Copyright (C) 2010 ST Microelectronics
>> + * Shiraz Hashim <shiraz.hashim@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 <mach/generic.h>
>> +#include <mach/spear.h>
>> +
>> +/* Add spear1300 specific devices here */
>> +
>> +void __init spear1300_init(void)
>> +{
>> +     /* call spear13xx family common init function */
>> +     spear13xx_init();
>> +}
>> diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
>> new file mode 100644
>> index 0000000..d72c8a8
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/spear1300_evb.c
>> @@ -0,0 +1,48 @@
>> +/*
>> + * arch/arm/mach-spear13xx/spear1300_evb.c
>> + *
>> + * SPEAr1300 evaluation board source file
>> + *
>> + * Copyright (C) 2010 ST Microelectronics
>> + * Shiraz Hashim <shiraz.hashim@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/types.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach-types.h>
>> +#include <mach/generic.h>
>> +#include <mach/spear.h>
>> +
>> +static struct amba_device *amba_devs[] __initdata = {
>> +     &uart_device,
>> +};
>> +
>> +static struct platform_device *plat_devs[] __initdata = {
>> +};
>> +
>> +static void __init spear1300_evb_init(void)
>> +{
>> +     unsigned int i;
>> +
>> +     /* call spear1300 machine init function */
>> +     spear1300_init();
>> +
>> +     /* Add Platform Devices */
>> +     platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
>> +
>> +     /* Add Amba Devices */
>> +     for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
>> +             amba_device_register(amba_devs[i], &iomem_resource);
>> +}
>> +
>> +MACHINE_START(SPEAR1300, "ST-SPEAR1300-EVB")
>> +     .boot_params    =       0x00000100,
>> +     .map_io         =       spear13xx_map_io,
>> +     .init_irq       =       spear13xx_init_irq,
>> +     .timer          =       &spear13xx_timer,
>> +     .init_machine   =       spear1300_evb_init,
>> +MACHINE_END
>> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
>> new file mode 100644
>> index 0000000..d11e300
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/spear13xx.c
>> @@ -0,0 +1,98 @@
>> +/*
>> + * arch/arm/mach-spear13xx/spear13xx.c
>> + *
>> + * SPEAr13XX machines common source file
>> + *
>> + * Copyright (C) 2010 ST Microelectronics
>> + * Shiraz Hashim <shiraz.hashim@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/types.h>
>> +#include <linux/ptrace.h>
>> +#include <linux/io.h>
>> +#include <asm/hardware/gic.h>
>> +#include <asm/irq.h>
>> +#include <asm/localtimer.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/smp_twd.h>
>> +#include <mach/irqs.h>
>> +#include <mach/generic.h>
>> +#include <mach/hardware.h>
> 
> So do you need all these includes?
> 

I would cross check and eliminate un-necessary ones.

>> +
>> +/* Add spear13xx machines common devices here */
>> +/* uart device registeration */
>> +struct amba_device uart_device = {
>> +     .dev = {
>> +             .init_name = "uart",
>> +     },
>> +     .res = {
>> +             .start = SPEAR13XX_UART_BASE,
>> +             .end = SPEAR13XX_UART_BASE + SZ_4K - 1,
>> +             .flags = IORESOURCE_MEM,
>> +     },
>> +     .irq = {IRQ_UART, NO_IRQ},
>> +};
>> +
>> +/* Do spear13xx familiy common initialization part here */
>> +void __init spear13xx_init(void)
>> +{
>> +     /* nothing to do for now */
>> +}
>> +
>> +/* This will initialize vic */
>> +void __init spear13xx_init_irq(void)
>> +{
>> +     gic_dist_init(0, __io_address(SPEAR13XX_GIC_DIST_BASE), 29);
>> +     gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
>> +}
>> +
>> +/* Following will create static virtual/physical mappings */
>> +struct map_desc spear13xx_io_desc[] __initdata = {
>> +     {
>> +             .virtual        = IO_ADDRESS(SPEAR13XX_UART_BASE),
>> +             .pfn            = __phys_to_pfn(SPEAR13XX_UART_BASE),
>> +             .length         = SZ_4K,
>> +             .type           = MT_DEVICE
>> +     }, {
>> +             .virtual        = IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE),
>> +             .pfn            = __phys_to_pfn(SPEAR13XX_A9SM_PERIP_BASE),
>> +             .length         = SZ_8K,
>> +             .type           = MT_DEVICE
>> +     }, {
>> +             .virtual        = IO_ADDRESS(SPEAR13XX_MISC_BASE),
>> +             .pfn            = __phys_to_pfn(SPEAR13XX_MISC_BASE),
>> +             .length         = SZ_8K,
>> +             .type           = MT_DEVICE
>> +     }, {
>> +             .virtual        = IO_ADDRESS(SPEAR13XX_SYSRAM0_BASE),
>> +             .pfn            = __phys_to_pfn(SPEAR13XX_SYSRAM0_BASE),
>> +             .length         = SZ_32K,
>> +             .type           = MT_DEVICE
>> +     },
>> +};
>> +
>> +/* This will create static memory mapping for selected devices */
>> +void __init spear13xx_map_io(void)
>> +{
>> +     iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
>> +
>> +     /* This will initialize clock framework */
>> +     clk_init();
>> +}
>> +
>> +static void __init spear13xx_timer_init(void)
>> +{
>> +#ifdef CONFIG_LOCAL_TIMERS
>> +     /* Setup the local timer base */
>> +     twd_base = __io_address(SPEAR13XX_LOCAL_TMR_BASE);
>> +#endif
>> +     spear_setup_timer();
>> +}
>> +
>> +struct sys_timer spear13xx_timer = {
>> +     .init = spear13xx_timer_init,
>> +};
>> --
>> 1.7.2.2

regards
Shiraz

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

* [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files
  2010-09-02  8:56   ` Russell King - ARM Linux
@ 2010-09-03  6:57     ` Shiraz Hashim
  0 siblings, 0 replies; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-03  6:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Russel,

On 9/2/2010 2:26 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:08:35PM +0530, Viresh KUMAR wrote:
>> +#ifndef __MACH_GENERIC_H
>> +#define __MACH_GENERIC_H
>> +
>> +#include <asm/mach/time.h>
>> +#include <asm/mach/map.h>
>> +#include <linux/init.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/amba/bus.h>
> 
> linux/ before asm/ please.
> 

OK, would correct it.

>> +#ifndef __MACH_HARDWARE_H
>> +#define __MACH_HARDWARE_H
>> +
>> +#include <mach/spear.h>
>> +
>> +/* Vitual to physical translation of statically mapped space */
>> +#define IO_ADDRESS(x)		(x | 0xF0000000)
>> +
>> +/* typesafe io address */
>> +#define __io_address(n)		__io(IO_ADDRESS(n))
> 
> Wrong use of __io().  __io() is just a macro for asm/io.h to make use of,
> and in any case should be defined in your mach/io.h file.

__io is defined in plat/io.h which is included in mach/io.h. I see other machs
(ux500, realview, versatile) also defining __io_address like this for typesafe
access. Is it wrong ?

>> diff --git a/arch/arm/mach-spear13xx/include/mach/system.h b/arch/arm/mach-spear13xx/include/mach/system.h
>> new file mode 100644
>> index 0000000..6ce0819
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/include/mach/system.h
>> @@ -0,0 +1,43 @@
>> +/*
>> + * arch/arm/mach-spear13xx/include/mach/system.h
>> + *
>> + * spear13xx Machine family specific architecture functions
>> + *
>> + * Copyright (C) 2010 ST Microelectronics
>> + * Shiraz Hashim <shiraz.hashim@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_SYSTEM_H
>> +#define __MACH_SYSTEM_H
>> +
>> +#include <linux/io.h>
>> +#include <mach/hardware.h>
>> +#include <mach/misc_regs.h>
>> +
>> +static inline void arch_idle(void)
>> +{
>> +	/*
>> +	 * This should do all the clock switching
>> +	 * and wait for interrupt tricks
>> +	 */
>> +	cpu_do_idle();
>> +}
>> +
>> +static inline void arch_reset(char mode, const char *cmd)
>> +{
>> +	pr_info("Going to reboot...\n");
> 
> The kernel already prints a message for reboot, so this is superfluous.
> .

OK, would remove this.

regards
Shiraz

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-02  8:09       ` Armando Visconti
@ 2010-09-03  7:11         ` Vipin Kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-03  7:11 UTC (permalink / raw)
  To: Armando VISCONTI
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Linus Walleij, Alessandro Rubini,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

On 9/2/2010 1:39 PM, Armando VISCONTI wrote:
> Ciao Linus,
> 
> Linus Walleij wrote:
>> 2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:
>>
>>   
>>> From: Vipin Kumar <vipin.kumar@st.com>
>>>
>>> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
>>> interfacing with NAND devices.
>>> This patch adds the support for glue logic for NAND flash on SPEAr boards
>>>     
>>
>> OK...
>>
>>   
>>> (...)
>>>  create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
>>>  create mode 100644 arch/arm/plat-spear/include/plat/nand.h
>>>  create mode 100644 drivers/mtd/nand/spear_nand.c
>>>     
>>
>> spear_nand.c?
>>
>> Why not fsmc-nand.c or similar if this is the name of the block.
>> We have this in U300, Nomadik NHK8815 and other platforms too,
>> it doesn't have much to do with SPEAr actually...
>>
>> Also, what are the include files doing in plat-spear since we have
>> the same hardware in other platforms? Move them to include/linux/mtd/
>> so we can use them please.
>>
>> I *highly* suspect that this driver duplicates some code found in
>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>>   
> Why nomadik_nand.c?
> Shouldn't the fsmc_nand.c rule apply also in this case?
> 
> 
>> Alessandro can judge on this, but I have a feeling that driver
>> should be replaced by this, more mature driver.
>>   

Hello All,

> Maybe.
> But I suspect that may be few differences in the ECC accelerator inside, 
> in fact.
> 
> In our FSMC previous case it was a Hamming accelerator, and I think this 
> apply
> also for nomadik (maybe). In our sp1300 case it is a BCH with 104 bytes 
> of ECC.

Adding on top of what Armando has already pointed out, FSMC block may 
have different versions and each of them may support different features 
based on its configuration eg. spear device's FSMC block is version8 
and is configured for 13 byte ecc(per 512 bytes data, BCH8 algorithm). 
There are other possibilities eg. BCH4, BCH2 etc which are not used in 
spear devices.

Making it generic would also entail supporting all possible configurations 
through single driver (makes more sense)

Customization was the prime reason for keeping the driver spear 
dependent and naming it as spear_nand.c

Alessandro/Sebastian: Is it OK to add a common driver for all FSMC versions
and customizations

Comments/Suggestions welcome

Regards
Vipin

> 
> This is one of the options when generating the h/w block, so FSMCs may 
> differ.
> If we want to re-use same driver I guess we might change something and 
> accept
> few parameters from the platform.
> 
> Vipin can for sure comment more on this.....
> 
> 
> Rgds,
> Arm
> 

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-03  7:11         ` Vipin Kumar
  0 siblings, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-09-03  7:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 1:39 PM, Armando VISCONTI wrote:
> Ciao Linus,
> 
> Linus Walleij wrote:
>> 2010/8/30 Viresh KUMAR <viresh.kumar@st.com>:
>>
>>   
>>> From: Vipin Kumar <vipin.kumar@st.com>
>>>
>>> SPEAr platforms use Flexible Static Memory Controller(FSMC) provided by ST for
>>> interfacing with NAND devices.
>>> This patch adds the support for glue logic for NAND flash on SPEAr boards
>>>     
>>
>> OK...
>>
>>   
>>> (...)
>>>  create mode 100644 arch/arm/plat-spear/include/plat/fsmc.h
>>>  create mode 100644 arch/arm/plat-spear/include/plat/nand.h
>>>  create mode 100644 drivers/mtd/nand/spear_nand.c
>>>     
>>
>> spear_nand.c?
>>
>> Why not fsmc-nand.c or similar if this is the name of the block.
>> We have this in U300, Nomadik NHK8815 and other platforms too,
>> it doesn't have much to do with SPEAr actually...
>>
>> Also, what are the include files doing in plat-spear since we have
>> the same hardware in other platforms? Move them to include/linux/mtd/
>> so we can use them please.
>>
>> I *highly* suspect that this driver duplicates some code found in
>> drivers/mtd/nand/nomadik_nand.c because it's the same silicon.
>>   
> Why nomadik_nand.c?
> Shouldn't the fsmc_nand.c rule apply also in this case?
> 
> 
>> Alessandro can judge on this, but I have a feeling that driver
>> should be replaced by this, more mature driver.
>>   

Hello All,

> Maybe.
> But I suspect that may be few differences in the ECC accelerator inside, 
> in fact.
> 
> In our FSMC previous case it was a Hamming accelerator, and I think this 
> apply
> also for nomadik (maybe). In our sp1300 case it is a BCH with 104 bytes 
> of ECC.

Adding on top of what Armando has already pointed out, FSMC block may 
have different versions and each of them may support different features 
based on its configuration eg. spear device's FSMC block is version8 
and is configured for 13 byte ecc(per 512 bytes data, BCH8 algorithm). 
There are other possibilities eg. BCH4, BCH2 etc which are not used in 
spear devices.

Making it generic would also entail supporting all possible configurations 
through single driver (makes more sense)

Customization was the prime reason for keeping the driver spear 
dependent and naming it as spear_nand.c

Alessandro/Sebastian: Is it OK to add a common driver for all FSMC versions
and customizations

Comments/Suggestions welcome

Regards
Vipin

> 
> This is one of the options when generating the h/w block, so FSMCs may 
> differ.
> If we want to re-use same driver I guess we might change something and 
> accept
> few parameters from the platform.
> 
> Vipin can for sure comment more on this.....
> 
> 
> Rgds,
> Arm
> 

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

* [PATCH 08/74] ST SPEAr1300: Adding default config file
  2010-09-03  1:45     ` Nicolas Pitre
@ 2010-09-03  7:32       ` Russell King - ARM Linux
  2010-09-03  7:44         ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-03  7:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 02, 2010 at 09:45:23PM -0400, Nicolas Pitre wrote:
> On Thu, 2 Sep 2010, Russell King - ARM Linux wrote:
> 
> > On Mon, Aug 30, 2010 at 04:08:39PM +0530, Viresh KUMAR wrote:
> > > From: Shiraz Hashim <shiraz.hashim@st.com>
> > 
> > This defconfig is too large and verbose to go anywhere near mainline,
> > even temporarily.  You need to talk to Uwe about how to shrink it down.
> 
> These days, all you need to do is:
> 
> 	  make savedefconfig
> 
> and look for a defconfig file in the current directory.

Ah right.  Wonder why no one documented that.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-03  6:24     ` deepaksi
@ 2010-09-03  7:34       ` Russell King - ARM Linux
  2010-09-06 11:55         ` deepaksi
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-03  7:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 03, 2010 at 11:54:06AM +0530, deepaksi wrote:
> On 9/2/2010 3:53 PM, Russell King - ARM Linux wrote:
> > On Mon, Aug 30, 2010 at 04:09:12PM +0530, Viresh KUMAR wrote:
> >   
> >> From: Deepak Sikri <deepak.sikri@st.com>
> >>
> >>     
> > The reason being?
> >
> >   
> 
> For configuring the wake up sources ( normally in the PM framework for
> suspend resume operations), you need to use the following set of api
> enable_irq_wake(). This handler has a appropriate callback for the vic,
> similar to the plugin that we have added in for gic which does enable
> the wake interrupt sources only. But since gic handler did not had this
> call back associated was always returning -ENXIO, which was breaking the
> existing drivers. In case no checks are provided for the return value of 
> enable_irq_wake(), the things were fine.

So how are wakeup sources configured if this callback does nothing?

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

* [PATCH 08/74] ST SPEAr1300: Adding default config file
  2010-09-03  7:32       ` Russell King - ARM Linux
@ 2010-09-03  7:44         ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-03  7:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/3/2010 1:02 PM, Russell King - ARM Linux wrote:
>> These days, all you need to do is:
>> > 
>> > 	  make savedefconfig
>> > 
>> > and look for a defconfig file in the current directory.
> Ah right.  Wonder why no one documented that.

Thanks for the info. It was really helpful.

viresh.

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

* RE: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-03  7:11         ` Vipin Kumar
@ 2010-09-03 11:22           ` Sebastian RASMUSSEN
  -1 siblings, 0 replies; 245+ messages in thread
From: Sebastian RASMUSSEN @ 2010-09-03 11:22 UTC (permalink / raw)
  To: Vipin KUMAR, Armando VISCONTI
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Linus Walleij, Alessandro Rubini, Shiraz HASHIM, Rajeev KUMAR,
	linux-mtd, Deepak SIKRI, dwmw2, linux-arm-kernel

Hi!

> Adding on top of what Armando has already pointed out, FSMC block may 
> have different versions and each of them may support different features 
> based on its configuration eg. spear device's FSMC block is version8 
> and is configured for 13 byte ecc(per 512 bytes data, BCH8 algorithm). 
> There are other possibilities eg. BCH4, BCH2 etc which are not used in 
> spear devices.

Looking at the future trend of NAND flash memories I believe that BCH8 is
likely to be of most interest, but of course having backwards compatibility
with already existing FSMC block usage is interesting enough.

> Making it generic would also entail supporting all possible configurations 
> through single driver (makes more sense)
[...]
> Alessandro/Sebastian: Is it OK to add a common driver for all FSMC versions
> and customizations

I believe that a common driver is the best way forward, yes. Let me know if I
can assist you in any of the development or testing.

 / Sebastian

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-03 11:22           ` Sebastian RASMUSSEN
  0 siblings, 0 replies; 245+ messages in thread
From: Sebastian RASMUSSEN @ 2010-09-03 11:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> Adding on top of what Armando has already pointed out, FSMC block may 
> have different versions and each of them may support different features 
> based on its configuration eg. spear device's FSMC block is version8 
> and is configured for 13 byte ecc(per 512 bytes data, BCH8 algorithm). 
> There are other possibilities eg. BCH4, BCH2 etc which are not used in 
> spear devices.

Looking at the future trend of NAND flash memories I believe that BCH8 is
likely to be of most interest, but of course having backwards compatibility
with already existing FSMC block usage is interesting enough.

> Making it generic would also entail supporting all possible configurations 
> through single driver (makes more sense)
[...]
> Alessandro/Sebastian: Is it OK to add a common driver for all FSMC versions
> and customizations

I believe that a common driver is the best way forward, yes. Let me know if I
can assist you in any of the development or testing.

 / Sebastian

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-02 11:15         ` Linus Walleij
@ 2010-09-03 11:23           ` Alessandro Rubini
  -1 siblings, 0 replies; 245+ messages in thread
From: Alessandro Rubini @ 2010-09-03 11:23 UTC (permalink / raw)
  To: armando.visconti
  Cc: pratyush.anand, viresh.kumar, vipulkumar.samar, bhupesh.sharma,
	sebastian.rasmussen, linus.ml.walleij, rubini-list, vipin.kumar,
	shiraz.hashim, rajeev-dlh.kumar, linux-mtd, deepak.sikri, dwmw2,
	linux-arm-kernel

Linus:
>> As I said I think nomadik_nand.c shall be deleted and replaced with
>> this driver.

Armando:
> As I said before, the SPEAr driver should work on Nomadik too
> as it looks generic enough and for us it is working
> on two different platforms with different FSMC versions.

Ok. I can't test it for a while, so I'll take your word. If needed
I'll make my homework later to fix 8815 over the new driver.

Note however that the platform data in
arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
new driver.  If you remove my version please at least compile-check
the nhk with the new patch-set.

thanks
/alessandro

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-03 11:23           ` Alessandro Rubini
  0 siblings, 0 replies; 245+ messages in thread
From: Alessandro Rubini @ 2010-09-03 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

Linus:
>> As I said I think nomadik_nand.c shall be deleted and replaced with
>> this driver.

Armando:
> As I said before, the SPEAr driver should work on Nomadik too
> as it looks generic enough and for us it is working
> on two different platforms with different FSMC versions.

Ok. I can't test it for a while, so I'll take your word. If needed
I'll make my homework later to fix 8815 over the new driver.

Note however that the platform data in
arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
new driver.  If you remove my version please at least compile-check
the nhk with the new patch-set.

thanks
/alessandro

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-03 11:23           ` Alessandro Rubini
@ 2010-09-03 17:26             ` Linus Walleij
  -1 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-03 17:26 UTC (permalink / raw)
  To: Alessandro Rubini, armando.visconti, linus.ml.walleij,
	viresh.kumar, linux-arm-kernel, linux-mtd, dwmw2, pratyush.anand,
	vipulkumar.samar, bhupesh.sharma, vipin.kumar, shiraz.hashim,
	rajeev-dlh.kumar, deepak.sikri, sebastian.rasmussen

2010/9/3 Alessandro Rubini <rubini-list@gnudd.com>:

> Note however that the platform data in
> arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
> new driver.  If you remove my version please at least compile-check
> the nhk with the new patch-set.

What about we put this new FSMC generic thing in, and
then remove the old one with the same patch that
instead activates the new one. No need to rush that.

Right now I mostly worry about having it in the proper
place with the proper name and the headers accessible from
all archs...

Linus Walleij

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-03 17:26             ` Linus Walleij
  0 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-03 17:26 UTC (permalink / raw)
  To: linux-arm-kernel

2010/9/3 Alessandro Rubini <rubini-list@gnudd.com>:

> Note however that the platform data in
> arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
> new driver. ?If you remove my version please at least compile-check
> the nhk with the new patch-set.

What about we put this new FSMC generic thing in, and
then remove the old one with the same patch that
instead activates the new one. No need to rush that.

Right now I mostly worry about having it in the proper
place with the proper name and the headers accessible from
all archs...

Linus Walleij

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-03 17:26             ` Linus Walleij
@ 2010-09-06  7:25               ` Armando Visconti
  -1 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-06  7:25 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Pratyush ANAND, Viresh KUMAR, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Alessandro Rubini, Vipin KUMAR,
	Shiraz HASHIM, Rajeev KUMAR, linux-mtd, Deepak SIKRI, dwmw2,
	linux-arm-kernel

Linus Walleij wrote:
> 2010/9/3 Alessandro Rubini <rubini-list@gnudd.com>:
>
>   
>> Note however that the platform data in
>> arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
>> new driver.  If you remove my version please at least compile-check
>> the nhk with the new patch-set.
>>     
>
> What about we put this new FSMC generic thing in, and
> then remove the old one with the same patch that
> instead activates the new one. No need to rush that.
>
> Right now I mostly worry about having it in the proper
> place with the proper name and the headers accessible from
> all archs...
>
> Linus Walleij
>   
Agreed.

THis also because, as I already mentioned, I seem to remember that the
Nomadik FSMC it is not exactly the standard one, but a modified (not 
configured)
version.

So, you may better check with Andrea Gallo whether this is really the case
or not.

Rgds,
Arm

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-06  7:25               ` Armando Visconti
  0 siblings, 0 replies; 245+ messages in thread
From: Armando Visconti @ 2010-09-06  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

Linus Walleij wrote:
> 2010/9/3 Alessandro Rubini <rubini-list@gnudd.com>:
>
>   
>> Note however that the platform data in
>> arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
>> new driver.  If you remove my version please at least compile-check
>> the nhk with the new patch-set.
>>     
>
> What about we put this new FSMC generic thing in, and
> then remove the old one with the same patch that
> instead activates the new one. No need to rush that.
>
> Right now I mostly worry about having it in the proper
> place with the proper name and the headers accessible from
> all archs...
>
> Linus Walleij
>   
Agreed.

THis also because, as I already mentioned, I seem to remember that the
Nomadik FSMC it is not exactly the standard one, but a modified (not 
configured)
version.

So, you may better check with Andrea Gallo whether this is really the case
or not.

Rgds,
Arm

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

* [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs
  2010-09-02 10:22   ` Russell King - ARM Linux
  2010-09-02 10:40     ` Will Deacon
@ 2010-09-06  7:44     ` Shiraz Hashim
  1 sibling, 0 replies; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-06  7:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Russell,

On 9/2/2010 3:52 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:09:09PM +0530, Viresh KUMAR wrote:
>> diff --git a/arch/arm/mach-spear13xx/include/mach/smp.h b/arch/arm/mach-spear13xx/include/mach/smp.h
>> index 6e028a1..e2e55fc 100644
>> --- a/arch/arm/mach-spear13xx/include/mach/smp.h
>> +++ b/arch/arm/mach-spear13xx/include/mach/smp.h
>> @@ -24,6 +24,12 @@
>>  		cpunum &= 0x0F;				\
>>  	})
>>  
>> +/*
>> + * set_event() is used to wake up secondary core from wfe using sev. Booting
>> + * code puts the second core into wfe(standby).
>> + */
>> +#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
> 
> This shouldn't be something that platforms define on their own.  Please
> add a sev() macro to arch/arm/include/asm/system.h instead.  Also take a
> look at arch/arm/mach-omap2/omap-smp.c for an alternative idea about how
> to handle this.

OK.
 
> Lastly, consider rolling the OMAP solution into the patch which adds SMP
> support for spear13xx.

OK. I would merge it.

regards
Shiraz

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

* [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx
  2010-09-02  9:08   ` Russell King - ARM Linux
@ 2010-09-06  9:43     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-06  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 2:38 PM, Russell King - ARM Linux wrote:
>> +static int clcd_check(struct clcd_fb *fb, struct fb_var_screeninfo
>> +		*var)
>> +{
>> +	var->xres_virtual = var->xres = (var->xres + 15) & ~15;
>> +	var->yres_virtual = var->yres = (var->yres + 1) & ~1;
>> +
>> +	var->nonstd = 0;
>> +	var->accel_flags = 0;
> 
> This looks insufficient.
> .
> 

Ok. will use clcdfb_check.

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

* [PATCH 32/74] ST SPEAr: Adding clk_set_rate support
  2010-09-02  9:21   ` Russell King - ARM Linux
@ 2010-09-06 10:03     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-06 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 2:51 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:08:56PM +0530, Viresh KUMAR wrote:
>> 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>
> 
> Can't this patch be rolled into a previous patch - especially as it deletes
> a load of code added by that previous patch (eg, clk_is_enabled)?  It
> doesn't look like it depends on the other various changes between that
> patch and this one.
> .
> 

OK.

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

* [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration
  2010-09-02 10:02   ` Russell King - ARM Linux
@ 2010-09-06 11:26     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-06 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 3:32 PM, Russell King - ARM Linux wrote:
> On Mon, Aug 30, 2010 at 04:08:59PM +0530, Viresh KUMAR wrote:
> 
> No description, so I'm going to have to guess about this.

Sorry!!

> 
>> +static inline void
>> +spear_amba_device_register(struct amba_device **devices, u32 count)
>> +{
>> +	u32 i;
>> +
>> +	for (i = 0; i < count; i++) {
>> +		struct clk *clk = clk_get_sys(devices[i]->dev.init_name, NULL);
>> +		if (IS_ERR(clk))
>> +			continue;
>> +
>> +		clk_enable(clk);
>> +		amba_device_register(devices[i], &iomem_resource);
>> +		clk_disable(clk);
> 
> My guess is that you're doing this to work around the fact that your
> SoC enables/disables both the bus clock and the functional clock to
> each primecell, and so you're finding that you need to enable the
> clock to access the device registers.
> 
> We've fixed this in the generic code by introducing an 'apb_pclk' clock
> which the core bus code controls (and eventually drivers.)  See discussion
> earlier this month/last month on this list about this.
> 
> That makes this patch redundant.
> .

Yes this patch is not required.

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

* [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/
  2010-09-02 16:27   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-06 11:52     ` viresh kumar
  2010-09-07 11:35     ` viresh kumar
  1 sibling, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-06 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 9:57 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:08 Mon 30 Aug     , Viresh KUMAR wrote:
>> > From: Shiraz Hashim <shiraz.hashim@st.com>
> missing patch descriptin

Sorry!!

>> > 
>> > Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
>> > Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
>> > ---
>> >  arch/arm/Kconfig  |   12 ++++++++----
>> >  arch/arm/Makefile |    1 +
>> >  2 files changed, 9 insertions(+), 4 deletions(-)
>> > 
>> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> > index 9295110..950c045 100644
>> > --- a/arch/arm/Kconfig
>> > +++ b/arch/arm/Kconfig
>> > @@ -1144,11 +1144,13 @@ config SMP
>> >  	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
>> >  	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
>> >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
>> > -		 ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
>> > +		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
>> > +		 ARCH_VEXPRESS_CA9X4)
> can we get rid of such long list by introducing a HAVE somthing
> etc....

Yes. We can select SMP from different Architecture config's.
Will do this in a separate patch.

viresh.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-03  7:34       ` Russell King - ARM Linux
@ 2010-09-06 11:55         ` deepaksi
  2010-09-08 15:12           ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: deepaksi @ 2010-09-06 11:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/3/2010 1:04 PM, Russell King - ARM Linux wrote:
> On Fri, Sep 03, 2010 at 11:54:06AM +0530, deepaksi wrote:
>   
>> On 9/2/2010 3:53 PM, Russell King - ARM Linux wrote:
>>     
>>> On Mon, Aug 30, 2010 at 04:09:12PM +0530, Viresh KUMAR wrote:
>>>   
>>>       
>>>> From: Deepak Sikri <deepak.sikri@st.com>
>>>>
>>>>     
>>>>         
>>> The reason being?
>>>
>>>   
>>>       
>> For configuring the wake up sources ( normally in the PM framework for
>> suspend resume operations), you need to use the following set of api
>> enable_irq_wake(). This handler has a appropriate callback for the vic,
>> similar to the plugin that we have added in for gic which does enable
>> the wake interrupt sources only. But since gic handler did not had this
>> call back associated was always returning -ENXIO, which was breaking the
>> existing drivers. In case no checks are provided for the return value of 
>> enable_irq_wake(), the things were fine.
>>     
> So how are wakeup sources configured if this callback does nothing?
> .
>
>   
In most of the architectures that I could refer across(including SPEAr
family -SPEAr13xx),
have a separate power management unit(PMU) which is required to be
configured to define the wake
up sources. The PMU takes care of waking up the system from sleep, as
and when the wake up
interrupts are triggered. This routing is independent of GIC, and hence
the handling was not added.

Contrary to that, in some of our hardware architecture using VIC
(including SPEAr 3xx/6xx), there
was no explicit PMU, and the wake up trigger was exclusively done
through VIC, and hence the VIC
call backs had the necessary implementation.

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
  2010-09-01  1:22   ` [rtc-linux] " Wan ZongShun
@ 2010-09-06 19:09   ` Alessandro Zummo
  2010-09-07  3:30     ` rajeev
  2010-09-07 10:13     ` viresh kumar
  2010-09-06 22:45   ` Jean-Christophe PLAGNIOL-VILLARD
  2 siblings, 2 replies; 245+ messages in thread
From: Alessandro Zummo @ 2010-09-06 19:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 30 Aug 2010 16:11:00 +0530
Viresh KUMAR <viresh.kumar@st.com> wrote:

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

 Hi, there are quite a few issues. Please read the
 checklist at http://groups.google.com/group/rtc-linux/web/checklist

-- 

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Torino, Italy

  http://www.towertech.it

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-08-30 10:39 ` [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver Viresh KUMAR
@ 2010-09-06 22:40   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07 10:51     ` viresh kumar
  2010-10-01  5:42     ` Vipin Kumar
  0 siblings, 2 replies; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 22:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 16:09 Mon 30 Aug     , Viresh KUMAR wrote:
> From: Vipin Kumar <vipin.kumar@st.com>
> 
> 2 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
> 
> 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/clock.c                 |   12 +++
>  arch/arm/mach-spear3xx/emi.c                   |   86 ++++++++++++++++++++++++
>  arch/arm/mach-spear3xx/include/mach/emi.h      |   79 ++++++++++++++++++++++
>  arch/arm/mach-spear3xx/include/mach/generic.h  |    2 +
>  arch/arm/mach-spear3xx/include/mach/spear310.h |    9 +++
>  arch/arm/mach-spear3xx/include/mach/spear320.h |    6 ++
>  arch/arm/mach-spear3xx/spear310.c              |   20 ++++++
>  arch/arm/mach-spear3xx/spear310_evb.c          |   18 +++++
>  arch/arm/mach-spear3xx/spear320.c              |   20 ++++++
>  arch/arm/mach-spear3xx/spear320_evb.c          |   17 +++++
>  11 files changed, 273 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/clock.c b/arch/arm/mach-spear3xx/clock.c
> index 41a2b5e..4f049fe 100644
> --- a/arch/arm/mach-spear3xx/clock.c
> +++ b/arch/arm/mach-spear3xx/clock.c
> @@ -552,6 +552,15 @@ static struct clk adc_clk = {
>  	.recalc = &follow_parent,
>  };
>  
> +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
can you create a macro for this?
or even better detect it

> +/* emi clock */
> +static struct clk emi_clk = {
> +	.flags = ALWAYS_ENABLED,
> +	.pclk = &ahb_clk,
> +	.recalc = &follow_parent,
> +};
> +#endif
> +
>  /* ssp clock */
>  static struct clk ssp0_clk = {
>  	.pclk = &apb_clk,
> @@ -744,6 +753,9 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{ .dev_id = "adc",		.clk = &adc_clk},
>  	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
>  	{ .dev_id = "gpio",		.clk = &gpio_clk},
> +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
> +	{ .dev_id = "physmap-flash",	.clk = &emi_clk},
> +#endif
>  #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
>  	defined(CONFIG_MACH_SPEAR320)
>  	{ .con_id = "fsmc",		.clk = &fsmc_clk},
> diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c
> new file mode 100644
> index 0000000..dd5cb8e
> --- /dev/null
> +++ b/arch/arm/mach-spear3xx/emi.c
> @@ -0,0 +1,86 @@
> +/*
> + * 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 <mach/emi.h>
> +
> +int __init emi_init(struct platform_device *pdev, unsigned long base,
> +		u32 bank, u32 width)
> +{
how about request the memory region

and use platform device to register the bank ressource instead of define

it will make it more flexible
> +	void __iomem *emi_reg_base;
> +	struct clk *clk;
> +	int ret;
> +
> +	if (bank > (EMI_MAX_BANKS - 1))
> +		return -EINVAL;
> +
> +	emi_reg_base = ioremap(base, EMI_REG_SIZE);
> +	if (!emi_reg_base)
> +		return -ENOMEM;
> +
> +	clk = clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(clk)) {
> +		iounmap(emi_reg_base);
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_enable(clk);
> +	if (ret) {
> +		iounmap(emi_reg_base);
> +		return ret;
> +	}
> +
> +	/* set the timing */
> +	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);
you always set the same timmings?

it's wired as the timings as supposed to be nor or nand specific

and you can you more than one nor or nand

so NACK

> +
> +	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 << bank, emi_reg_base + ACK_REG);
> +
> +	iounmap(emi_reg_base);
> +
> +	return 0;
> +}
> +
> +void __init emi_init_board_info(struct platform_device *pdev,
> +		struct mtd_partition *partitions, unsigned int nr_partitions,
> +		unsigned int width)
> +{
> +	emi_init_plat_data(pdev, partitions, nr_partitions, width);
> +}
???
> 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..f3cbfbc
> --- /dev/null
> +++ b/arch/arm/mach-spear3xx/include/mach/emi.h
> @@ -0,0 +1,79 @@
> +/*
> + * 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 TIMEOUT_REG		(0x90)
> +#define ACK_REG			(0x94)
> +#define IRQ_REG			(0x98)
> +
> +#define EMI_MAX_BANKS		6
> +
> +#elif defined(CONFIG_MACH_SPEAR320)
> +#define TIMEOUT_REG		(0x60)
> +#define ACK_REG			(0x64)
> +#define IRQ_REG			(0x68)
> +
> +#define 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)
> +
> +static inline void emi_init_plat_data(struct platform_device *pdev,
> +		struct mtd_partition *partitions, unsigned int nr_partitions,
> +		unsigned int width)
> +{
> +	struct physmap_flash_data *emi_plat_data;
> +	emi_plat_data = dev_get_platdata(&pdev->dev);
> +
> +	if (partitions) {
> +		emi_plat_data->parts = partitions;
> +		emi_plat_data->nr_parts = nr_partitions;
> +	}
> +
> +	emi_plat_data->width = width;
> +}
> +
> +extern int __init emi_init(struct platform_device *pdev, unsigned long base,
> +		u32 bank, u32 width);
> +extern void __init emi_init_board_info(struct platform_device *pdev,
> +		struct mtd_partition *partitions, unsigned int nr_partitions,
> +		unsigned int width);
> +#endif
> diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
> index 4d04dbe..6c6eced 100644
> --- a/arch/arm/mach-spear3xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear3xx/include/mach/generic.h
> @@ -167,6 +167,7 @@ extern struct amba_device uart2_device;
>  extern struct amba_device uart3_device;
>  extern struct amba_device uart4_device;
>  extern struct amba_device uart5_device;
> +extern struct platform_device emi_nor_device;
>  extern struct platform_device plgpio_device;
>  extern struct platform_device nand_device;
>  
> @@ -192,6 +193,7 @@ extern struct amba_device uart1_device;
>  extern struct amba_device uart2_device;
>  extern struct platform_device can0_device;
>  extern struct platform_device can1_device;
> +extern struct platform_device emi_nor_device;
>  extern struct platform_device i2c1_device;
>  extern struct platform_device nand_device;
>  extern struct platform_device plgpio_device;
> diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
> index 1e85347..37556b6 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 940f0d8..4f60073 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.c b/arch/arm/mach-spear3xx/spear310.c
> index 29e3c2c..32c492d 100644
> --- a/arch/arm/mach-spear3xx/spear310.c
> +++ b/arch/arm/mach-spear3xx/spear310.c
> @@ -11,6 +11,7 @@
>   * warranty of any kind, whether express or implied.
>   */
>  
> +#include <linux/mtd/physmap.h>
>  #include <linux/ptrace.h>
>  #include <asm/irq.h>
>  #include <mach/generic.h>
> @@ -268,6 +269,25 @@ int spear300_o2p(int offset)
>  		return offset + 2;
>  }
>  
> +/* emi nor flash device registeration */
> +static struct physmap_flash_data emi_norflash_data;
> +
> +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,
> +	},
> +};
it's board specfic not mach

NACK

Best Regards,
J.

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
  2010-09-01  1:22   ` [rtc-linux] " Wan ZongShun
  2010-09-06 19:09   ` Alessandro Zummo
@ 2010-09-06 22:45   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  8:35     ` viresh kumar
  2 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 22:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 16:11 Mon 30 Aug     , Viresh KUMAR wrote:
> From: Rajeev Kumar <rajeev-dlh.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/clock.c                |    2 +-
>  arch/arm/mach-spear13xx/include/mach/generic.h |    1 +
>  arch/arm/mach-spear13xx/spear1300_evb.c        |    1 +
>  arch/arm/mach-spear13xx/spear13xx.c            |   19 +
>  arch/arm/mach-spear3xx/clock.c                 |    2 +-
>  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/clock.c                 |    2 +-
>  arch/arm/mach-spear6xx/include/mach/generic.h  |    1 +
>  arch/arm/mach-spear6xx/spear600_evb.c          |    1 +
>  arch/arm/mach-spear6xx/spear6xx.c              |   19 +
>  drivers/rtc/Kconfig                            |    7 +
>  drivers/rtc/Makefile                           |    1 +
>  drivers/rtc/rtc-spear.c                        |  598 ++++++++++++++++++++++++
>  17 files changed, 674 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/rtc/rtc-spear.c
> 
> diff --git a/arch/arm/mach-spear13xx/clock.c b/arch/arm/mach-spear13xx/clock.c
> index cef3b13..cc692cc 100644
> --- a/arch/arm/mach-spear13xx/clock.c
> +++ b/arch/arm/mach-spear13xx/clock.c
> @@ -736,7 +736,7 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{.con_id = "osc3_25m_clk",	.clk = &osc3_25m_clk},
>  
>  	/* clock derived from 32 KHz osc clk */
> -	{.dev_id = "rtc",		.clk = &rtc_clk},
> +	{.dev_id = "rtc-spear",		.clk = &rtc_clk},
>  
>  	/* clock derived from 24/25 MHz osc1/osc3 clk */
>  	{.con_id = "pll1_clk",		.clk = &pll1_clk},
> diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
> index 41c1a53..dc80421 100644
> --- a/arch/arm/mach-spear13xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear13xx/include/mach/generic.h
> @@ -30,6 +30,7 @@
>  
>  /* Add spear13xx family device structure declarations here */
>  extern struct amba_device uart_device;
> +extern struct platform_device rtc_device;
no need to export all theres platform devices

it will be better to export funtion as done on AT91

to register the device

as

spear_rtc_device_add();

and the sme for the other devices etc...

btw you do not respect the kernel coding style please check your patches

Best Regards,
J.

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

* [PATCH 01/74] ST SPEAr: Padmux code Updated
  2010-08-30 10:38 ` [PATCH 01/74] ST SPEAr: Padmux code Updated Viresh KUMAR
@ 2010-09-06 22:49   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  3:51     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 22:49 UTC (permalink / raw)
  To: linux-arm-kernel

>  
> -void spear300_pmx_init(void)
> -{
> -	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
> +	/* pmx initialization */
> +	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
>  			SPEAR300_SOC_CONFIG_SIZE);
> +	if (pmx_driver.base) {
> +		ret = pmx_register(&pmx_driver);
> +		if (ret)
> +			printk(KERN_ERR "padmux: registeration failed. err no"
> +					": %d\n", ret);
> +		iounmap(pmx_driver.base);
why unmap it?

Best Regards,
J.

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-08-30 10:38 ` [PATCH 03/74] ST SPEAr: Formalized timer support Viresh KUMAR
@ 2010-09-06 22:55   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-13  3:22     ` Shiraz Hashim
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 22:55 UTC (permalink / raw)
  To: linux-arm-kernel

>  
> -#endif
> +static void __init spear3xx_timer_init(void)
> +{
> +	spear_setup_timer();
why not call it directly?


> +}
> +
> +struct sys_timer spear3xx_timer = {
> +	.init = spear3xx_timer_init,
> +};
> diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
> index 16205a5..e5967ed 100644
> --- a/arch/arm/mach-spear6xx/include/mach/generic.h
> +++ b/arch/arm/mach-spear6xx/include/mach/generic.h
> @@ -31,9 +31,10 @@
>  /* Add spear6xx family device structure declarations here */
>  extern struct amba_device gpio_device[];
>  extern struct amba_device uart_device[];
> -extern struct sys_timer spear_sys_timer;
> +extern struct sys_timer spear6xx_timer;
>  
>  /* Add spear6xx family function declarations here */
> +void __init spear_setup_timer(void);
>  void __init spear6xx_map_io(void);
>  void __init spear6xx_init_irq(void);
>  void __init spear6xx_init(void);
> diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
> index daff8d0..bdd5b76 100644
> --- a/arch/arm/mach-spear6xx/spear600_evb.c
> +++ b/arch/arm/mach-spear6xx/spear600_evb.c
> @@ -42,10 +42,11 @@ static void __init spear600_evb_init(void)
>  		amba_device_register(amba_devs[i], &iomem_resource);
>  }
>  
> +
please remove
>  MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
>  	.boot_params	=	0x00000100,
>  	.map_io		=	spear6xx_map_io,
>  	.init_irq	=	spear6xx_init_irq,
> -	.timer		=	&spear_sys_timer,
> +	.timer		=	&spear6xx_timer,
>  	.init_machine	=	spear600_evb_init,
>  MACHINE_END
> diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
> index baf6bcc..88a82ca 100644
> --- a/arch/arm/mach-spear6xx/spear6xx.c
> +++ b/arch/arm/mach-spear6xx/spear6xx.c
> @@ -155,3 +155,12 @@ void __init spear6xx_map_io(void)
>  	/* This will initialize clock framework */
>  	clk_init();
>  }
> +
> +static void __init spear6xx_timer_init(void)
> +{
> +	spear_setup_timer();
> +}
> +
> +struct sys_timer spear6xx_timer = {
> +	.init = spear6xx_timer_init,
> +};
> diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
> index ab21165..850d0cf 100644
> --- a/arch/arm/plat-spear/time.c
> +++ b/arch/arm/plat-spear/time.c
> @@ -66,6 +66,13 @@
>  static __iomem void *gpt_base;
>  static struct clk *gpt_clk;
>  
> +/* following defines the parent clock to be used */
> +#ifdef CONFIG_ARCH_SPEAR13XX
> +static char pclk_name[] = "osc1_24m_clk";
> +#else
> +static char pclk_name[] = "pll3_48m_clk";
> +#endif
why 2 name?
it will be better to use clkdev and create an alias
btw how about move the timer to drivers/clocksource?
> +
>  static void clockevent_set_mode(enum clock_event_mode mode,
>  				struct clock_event_device *clk_event_dev);
>  static int clockevent_next_event(unsigned long evt,
> @@ -215,7 +222,8 @@ static void __init spear_clockevent_init(void)
>  
>  void __init spear_setup_timer(void)
>  {
> -	struct clk *pll3_clk;
> +	struct clk *clk;
> +	int ret;
>  
>  	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
>  		pr_err("%s:cannot get IO addr\n", __func__);
> @@ -234,26 +242,32 @@ void __init spear_setup_timer(void)
>  		goto err_iomap;
>  	}
>  
> -	pll3_clk = clk_get(NULL, "pll3_48m_clk");
> -	if (!pll3_clk) {
> -		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
> +	/* get the parent clock */
> +	clk = clk_get(NULL, pclk_name);
> +
> +	if (!clk) {
> +		pr_err("%s:couldn't get %s as parent for gpt\n",
> +				__func__, pclk_name);
>  		goto err_iomap;
>  	}
>  
> -	clk_set_parent(gpt_clk, pll3_clk);
> +	clk_set_parent(gpt_clk, clk);
??
why not do this in the clock file?

Best Regards,
J.

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

* [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320
  2010-08-30 10:38 ` [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320 Viresh KUMAR
@ 2010-09-06 22:58   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  8:36     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 22:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

	not relased to this patch series

Best Regards,
J.
On 16:08 Mon 30 Aug     , Viresh KUMAR wrote:
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---
>  arch/arm/mach-spear3xx/include/mach/spear320.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
> index cacf17a..53677e4 100644
> --- a/arch/arm/mach-spear3xx/include/mach/spear320.h
> +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
> @@ -62,7 +62,7 @@
>  #define SPEAR320_SMII1_BASE		0xAB000000
>  #define SPEAR320_SMII1_SIZE		0x01000000
>  
> -#define SPEAR320_SOC_CONFIG_BASE	0xB4000000
> +#define SPEAR320_SOC_CONFIG_BASE	0xB3000000
>  #define SPEAR320_SOC_CONFIG_SIZE	0x00000070
>  /* Interrupt registers offsets and masks */
>  #define INT_STS_MASK_REG		0x04
> -- 
> 1.7.2.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-08-30 10:38 ` [PATCH 13/74] ST SPEAr: Update clock framework and definitions Viresh KUMAR
@ 2010-09-06 23:09   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  3:58     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

>  
>  /* array of all spear 13xx clock lookups */
> @@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	/* clock derived from pll1 clk */
>  	{.con_id = "cpu_clk",		.clk = &cpu_clk},
>  	{.con_id = "ahb_clk",		.clk = &ahb_clk},
> -	{ .con_id = "apb_clk",		.clk = &apb_clk},
> +	{.con_id = "apb_clk",		.clk = &apb_clk},
> +
how about use macro here to simplify the code

+#define CLKDEV_ID(__clk) { .con_id = #__clk, .clk = &(__clk) }
and 
+#define CLKDEV_ID_CLK(__clk) { .con_id = #__clk, .clk = &(__clk##_clk) }
> +	/* synthesizers/prescaled clocks */
> +	{.con_id = "pll1div2_clk",		.clk = &pll1div2_clk},
> +	{.con_id = "pll1div4_clk",		.clk = &pll1div4_clk},
> +	{.con_id = "c3_synth_clk",		.clk = &c3_synth_clk},
> +	{.con_id = "gmii_txclk123_pad_clk",	.clk = &gmii_txclk125_pad},
> +	{.con_id = "clcd_synth_clk",		.clk = &clcd_synth_clk},
> +	{.con_id = "uart_synth_clk",		.clk = &uart_synth_clk},
> +	{.con_id = "sd_synth_clk",		.clk = &sd_synth_clk},
> +	{.con_id = "cfxd_synth_clk",		.clk = &cfxd_synth_clk},
> +	{.con_id = "gmac_phy_input_clk",	.clk = &gmac_phy_input_clk},
> +	{.con_id = "gmac_phy_synth_clk",	.clk = &gmac_phy_synth_clk},
> +	{.con_id = "gmac_phy_clk",		.clk = &gmac_phy_clk},
>  
>  	/* clocks having multiple parent source from above clocks */
> -	{.dev_id = "uart",		.clk = &uart_clk},
> +	{.dev_id = "clcd",		.clk = &clcd_clk},
>  	{.dev_id = "gpt0",		.clk = &gpt0_clk},
>  	{.dev_id = "gpt1",		.clk = &gpt1_clk},
>  	{.dev_id = "gpt2",		.clk = &gpt2_clk},
>  	{.dev_id = "gpt3",		.clk = &gpt3_clk},
> +	{.dev_id = "uart",		.clk = &uart_clk},
>  
> -	/* clock derived from ahb/apb clk */
> -	{ .dev_id = "smi",		.clk = &smi_clk},
> -	{ .dev_id = "wdt",		.clk = &wdt_clk},
> +	/* clock derived from ahb clk */
> +	{.dev_id = "smi",		.clk = &smi_clk},
> +	{.dev_id = "uhci0",		.clk = &uhci0_clk},
> +	{.dev_id = "uhci1",		.clk = &uhci1_clk},
> +	{.dev_id = "usbd",		.clk = &usbd_clk},
> +	{.dev_id = "i2c",		.clk = &i2c_clk},
> +	{.dev_id = "dma0",		.clk = &dma0_clk},
> +	{.dev_id = "dma1",		.clk = &dma1_clk},
> +	{.dev_id = "jpeg",		.clk = &jpeg_clk},
> +	{.dev_id = "gmac",		.clk = &gmac_clk},
> +	{.dev_id = "c3",		.clk = &c3_clk},
> +	{.dev_id = "pcie0",		.clk = &pcie0_clk},
> +	{.dev_id = "pcie1",		.clk = &pcie1_clk},
> +	{.dev_id = "pcie2",		.clk = &pcie2_clk},
> +	{.dev_id = "cfxd",		.clk = &cfxd_clk},
> +	{.dev_id = "sd",		.clk = &sd_clk},
> +	{.dev_id = "fsmc",		.clk = &fsmc_clk},
> +	{.dev_id = "sysram0",		.clk = &sysram0_clk},
> +	{.dev_id = "sysram1",		.clk = &sysram1_clk},
> +
> +	/* clock derived from apb clk */
> +	{.dev_id = "i2s0",		.clk = &i2s0_clk},
> +	{.dev_id = "i2s1",		.clk = &i2s1_clk},
> +	{.dev_id = "adc",		.clk = &adc_clk},
> +	{.dev_id = "ssp",		.clk = &ssp_clk},
> +	{.dev_id = "gpio0",		.clk = &gpio0_clk},
> +	{.dev_id = "gpio1",		.clk = &gpio1_clk},
> +	{.dev_id = "kbd",		.clk = &kbd_clk},
> +	{.dev_id = "wdt",		.clk = &wdt_clk},
>  };
>  
>  void __init clk_init(void)
> diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> index 2e87a07..c4dcab2 100644
> --- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> +++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
how about clock.h header?
> @@ -36,12 +36,16 @@
>  /* PLL related registers and bit values */
>  #define PLL_CFG			((unsigned int *)(MISC_BASE + 0x210))
>  	/* PLL_CFG bit values */
> -	#define OSC_24M_MASK	0
> -	#define OSC_25M_MASK	1
> -	#define PLL_CLK_MASK	3
> -	#define PLL1_CLK_SHIFT	20
> -	#define PLL2_CLK_SHIFT	22
> -	#define PLL3_CLK_SHIFT	24
> +	#define OSC_24M_VAL			0
> +	#define OSC_25M_VAL			1
> +	#define PLL_CLK_MASK			3
> +	#define PLL1_CLK_SHIFT			20
> +	#define PLL2_CLK_SHIFT			22
> +	#define PLL3_CLK_SHIFT			24
Best Regards,
J.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-08-30 10:38 ` [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware Viresh KUMAR
@ 2010-09-06 23:12   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  4:02     ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-06 23:12 UTC (permalink / raw)
  To: linux-arm-kernel

> diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
> index 147d0a3..ae6c244 100644
> --- a/arch/arm/mach-spear3xx/clock.c
> +++ b/arch/arm/mach-spear3xx/clock.c
> @@ -460,6 +460,15 @@ static struct clk gpio_clk = {
>  
>  static struct clk dummy_apb_pclk;
>  
> +#ifdef CONFIG_MACH_SPEAR320
> +/* i2c1 clock */
> +static struct clk i2c1_clk = {
> +	.flags = ALWAYS_ENABLED,
> +	.pclk = &ahb_clk,
> +	.recalc = &follow_parent,
> +};
> +#endif
> +
>  /* array of all spear 3xx clock lookups */
>  static struct clk_lookup spear_clk_lookups[] = {
>  	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
> @@ -491,7 +500,7 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{ .dev_id = "clcd",		.clk = &clcd_clk},
>  	/* clock derived from ahb clk */
>  	{ .con_id = "apb_clk",		.clk = &apb_clk},
> -	{ .dev_id = "i2c",		.clk = &i2c_clk},
> +	{ .dev_id = "i2c_designware.0",	.clk = &i2c_clk},
>  	{ .dev_id = "dma",		.clk = &dma_clk},
>  	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
>  	{ .dev_id = "gmac",		.clk = &gmac_clk},
> @@ -501,6 +510,9 @@ static struct clk_lookup spear_clk_lookups[] = {
>  	{ .dev_id = "adc",		.clk = &adc_clk},
>  	{ .dev_id = "ssp",		.clk = &ssp_clk},
>  	{ .dev_id = "gpio",		.clk = &gpio_clk},
> +#ifdef CONFIG_MACH_SPEAR320
> +	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
> +#endif
how about split this file in 2
one for 320 and one for 310 so we can avoid all this ifdef

Best Regards,
J.

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-09-06 19:09   ` Alessandro Zummo
@ 2010-09-07  3:30     ` rajeev
  2010-09-07 10:13     ` viresh kumar
  1 sibling, 0 replies; 245+ messages in thread
From: rajeev @ 2010-09-07  3:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Alessandro Zummo

On 9/7/2010 12:39 AM, Alessandro Zummo wrote:
>> From: Rajeev Kumar <rajeev-dlh.kumar@st.com>
>  Hi, there are quite a few issues. Please read the
>  checklist at http://groups.google.com/group/rtc-linux/web/checklist

I will go through the checklist.
Rajeev

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

* [PATCH 01/74] ST SPEAr: Padmux code Updated
  2010-09-06 22:49   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  3:51     ` viresh kumar
  2010-09-07  4:07       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07  3:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:19 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>  
>> > -void spear300_pmx_init(void)
>> > -{
>> > -	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
>> > +	/* pmx initialization */
>> > +	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
>> >  			SPEAR300_SOC_CONFIG_SIZE);
>> > +	if (pmx_driver.base) {
>> > +		ret = pmx_register(&pmx_driver);
>> > +		if (ret)
>> > +			printk(KERN_ERR "padmux: registeration failed. err no"
>> > +					": %d\n", ret);
>> > +		iounmap(pmx_driver.base);
> why unmap it?

pmx_register will actually enable all selected devices and configure padmux.
After this we will never change device configuration again. So don't need
this mapping.

viresh.

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-09-06 23:09   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  3:58     ` viresh kumar
  2010-09-07  4:06       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07  3:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:39 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>  /* array of all spear 13xx clock lookups */
>> > @@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
>> >  	/* clock derived from pll1 clk */
>> >  	{.con_id = "cpu_clk",		.clk = &cpu_clk},
>> >  	{.con_id = "ahb_clk",		.clk = &ahb_clk},
>> > -	{ .con_id = "apb_clk",		.clk = &apb_clk},
>> > +	{.con_id = "apb_clk",		.clk = &apb_clk},
>> > +
> how about use macro here to simplify the code
> 
> +#define CLKDEV_ID(__clk) { .con_id = #__clk, .clk = &(__clk) }
> and 
> +#define CLKDEV_ID_CLK(__clk) { .con_id = #__clk, .clk = &(__clk##_clk) }

We had that in mind while designing but we chose it this way. There are
not many fields to fill here, so it looks fine without macro's too.
I didn't wanted to create an abstraction layer here.

>> > diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
>> > index 2e87a07..c4dcab2 100644
>> > --- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
>> > +++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> how about clock.h header?

If i understand correctly you want me to rename misc_regs.h as clock.h?
Actually misc_regs.h have all miscellaneous registers for spear, like:
clock specific, reset register, some muxing registers too.. They are
not only for "clock". So we kept this name.

viresh.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-09-06 23:12   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  4:02     ` viresh kumar
  2010-09-07  4:12       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07  4:02 UTC (permalink / raw)
  To: linux-arm-kernel

Jean,

Thanks for reviewing our patches. Really appreciate your effort.

On 9/7/2010 4:42 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> > @@ -501,6 +510,9 @@ static struct clk_lookup spear_clk_lookups[] = {
>> >  	{ .dev_id = "adc",		.clk = &adc_clk},
>> >  	{ .dev_id = "ssp",		.clk = &ssp_clk},
>> >  	{ .dev_id = "gpio",		.clk = &gpio_clk},
>> > +#ifdef CONFIG_MACH_SPEAR320
>> > +	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
>> > +#endif
> how about split this file in 2
> one for 320 and one for 310 so we can avoid all this ifdef

There was a mistake in this patch series. As you can see in the last patches,
we worked on single image solution for spear*xx family. When we select all
machines then all clocks are getting registered. which is wrong?

I have corrected it in my local repo. Now i have created clk_lookup arrays
for individual machines and one for common clk structures. So you will not
find this mess finally in V2 release.

thanks
viresh.

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-09-07  3:58     ` viresh kumar
@ 2010-09-07  4:06       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  9:01         ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07  4:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 09:28 Tue 07 Sep     , viresh kumar wrote:
> On 9/7/2010 4:39 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>  /* array of all spear 13xx clock lookups */
> >> > @@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
> >> >  	/* clock derived from pll1 clk */
> >> >  	{.con_id = "cpu_clk",		.clk = &cpu_clk},
> >> >  	{.con_id = "ahb_clk",		.clk = &ahb_clk},
> >> > -	{ .con_id = "apb_clk",		.clk = &apb_clk},
> >> > +	{.con_id = "apb_clk",		.clk = &apb_clk},
> >> > +
> > how about use macro here to simplify the code
> > 
> > +#define CLKDEV_ID(__clk) { .con_id = #__clk, .clk = &(__clk) }
> > and 
> > +#define CLKDEV_ID_CLK(__clk) { .con_id = #__clk, .clk = &(__clk##_clk) }
> 
> We had that in mind while designing but we chose it this way. There are
> not many fields to fill here, so it looks fine without macro's too.
> I didn't wanted to create an abstraction layer here.
the macro will also avoid human mistake
> 
> >> > diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> >> > index 2e87a07..c4dcab2 100644
> >> > --- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> >> > +++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
> > how about clock.h header?
> 
> If i understand correctly you want me to rename misc_regs.h as clock.h?
> Actually misc_regs.h have all miscellaneous registers for spear, like:
> clock specific, reset register, some muxing registers too.. They are
> not only for "clock". So we kept this name.
no split it

Best Regards,
J.

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

* [PATCH 01/74] ST SPEAr: Padmux code Updated
  2010-09-07  3:51     ` viresh kumar
@ 2010-09-07  4:07       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  4:10         ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07  4:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 09:21 Tue 07 Sep     , viresh kumar wrote:
> On 9/7/2010 4:19 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>  
> >> > -void spear300_pmx_init(void)
> >> > -{
> >> > -	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
> >> > +	/* pmx initialization */
> >> > +	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
> >> >  			SPEAR300_SOC_CONFIG_SIZE);
> >> > +	if (pmx_driver.base) {
> >> > +		ret = pmx_register(&pmx_driver);
> >> > +		if (ret)
> >> > +			printk(KERN_ERR "padmux: registeration failed. err no"
> >> > +					": %d\n", ret);
> >> > +		iounmap(pmx_driver.base);
> > why unmap it?
> 
> pmx_register will actually enable all selected devices and configure padmux.
> After this we will never change device configuration again. So don't need
> this mapping.
so put a comment in the code

Best Regards,
J.

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

* [PATCH 01/74] ST SPEAr: Padmux code Updated
  2010-09-07  4:07       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  4:10         ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07  4:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 9:37 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 09:21 Tue 07 Sep     , viresh kumar wrote:
>> On 9/7/2010 4:19 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>>  
>>>>> -void spear300_pmx_init(void)
>>>>> -{
>>>>> -	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
>>>>> +	/* pmx initialization */
>>>>> +	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE,
>>>>>  			SPEAR300_SOC_CONFIG_SIZE);
>>>>> +	if (pmx_driver.base) {
>>>>> +		ret = pmx_register(&pmx_driver);
>>>>> +		if (ret)
>>>>> +			printk(KERN_ERR "padmux: registeration failed. err no"
>>>>> +					": %d\n", ret);
>>>>> +		iounmap(pmx_driver.base);
>>> why unmap it?
>>
>> pmx_register will actually enable all selected devices and configure padmux.
>> After this we will never change device configuration again. So don't need
>> this mapping.
> so put a comment in the code
> 

Will do that.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-09-07  4:02     ` viresh kumar
@ 2010-09-07  4:12       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07  9:16         ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07  4:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 09:32 Tue 07 Sep     , viresh kumar wrote:
> Jean,
> 
> Thanks for reviewing our patches. Really appreciate your effort.
> 
> On 9/7/2010 4:42 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >> > @@ -501,6 +510,9 @@ static struct clk_lookup spear_clk_lookups[] = {
> >> >  	{ .dev_id = "adc",		.clk = &adc_clk},
> >> >  	{ .dev_id = "ssp",		.clk = &ssp_clk},
> >> >  	{ .dev_id = "gpio",		.clk = &gpio_clk},
> >> > +#ifdef CONFIG_MACH_SPEAR320
> >> > +	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
> >> > +#endif
> > how about split this file in 2
> > one for 320 and one for 310 so we can avoid all this ifdef
> 
> There was a mistake in this patch series. As you can see in the last patches,
> we worked on single image solution for spear*xx family. When we select all
> machines then all clocks are getting registered. which is wrong?
> 
> I have corrected it in my local repo. Now i have created clk_lookup arrays
> for individual machines and one for common clk structures. So you will not
> find this mess finally in V2 release.

please split your v2 patch series in related changset it will simplify the
review

Best Regards,
J.

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-09-06 22:45   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  8:35     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:15 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> > diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
>> > index 41c1a53..dc80421 100644
>> > --- a/arch/arm/mach-spear13xx/include/mach/generic.h
>> > +++ b/arch/arm/mach-spear13xx/include/mach/generic.h
>> > @@ -30,6 +30,7 @@
>> >  
>> >  /* Add spear13xx family device structure declarations here */
>> >  extern struct amba_device uart_device;
>> > +extern struct platform_device rtc_device;
> no need to export all theres platform devices
> 
> it will be better to export funtion as done on AT91
> 
> to register the device
> 
> as
> 
> spear_rtc_device_add();
> 
> and the sme for the other devices etc...

We don't want to create unnecessary abstraction. Even if we add functions
then these function prototypes have to be added in generic.h. This will
increase lines of code, without much advantages.

> 
> btw you do not respect the kernel coding style please check your patches

Sorry!! But we have been following coding style, have run checkpatch too...
Can you please pin point where are we wrong, so that we don't commit same
mistakes again next time.

regards,
viresh.

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

* [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320
  2010-09-06 22:58   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  8:36     ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07  8:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:28 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Hi,
> 
> 	not relased to this patch series

Jean,

Current patch series is named "Updating SPEAr Support".
This patch is just an bug fix. Why shouldn't it be part of this series.

regards,
viresh

> On 16:08 Mon 30 Aug     , Viresh KUMAR wrote:
>> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
>> ---
>>  arch/arm/mach-spear3xx/include/mach/spear320.h |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
>> index cacf17a..53677e4 100644
>> --- a/arch/arm/mach-spear3xx/include/mach/spear320.h
>> +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
>> @@ -62,7 +62,7 @@
>>  #define SPEAR320_SMII1_BASE		0xAB000000
>>  #define SPEAR320_SMII1_SIZE		0x01000000
>>  
>> -#define SPEAR320_SOC_CONFIG_BASE	0xB4000000
>> +#define SPEAR320_SOC_CONFIG_BASE	0xB3000000
>>  #define SPEAR320_SOC_CONFIG_SIZE	0x00000070
>>  /* Interrupt registers offsets and masks */
>>  #define INT_STS_MASK_REG		0x04
>> -- 
>> 1.7.2.2
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> .
> 

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-09-07  4:06       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  9:01         ` viresh kumar
  2010-09-07  9:09           ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07  9:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 9:36 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 09:28 Tue 07 Sep     , viresh kumar wrote:
>> > On 9/7/2010 4:39 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>> > >>  /* array of all spear 13xx clock lookups */
>>>>> > >> > @@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
>>>>> > >> >  	/* clock derived from pll1 clk */
>>>>> > >> >  	{.con_id = "cpu_clk",		.clk = &cpu_clk},
>>>>> > >> >  	{.con_id = "ahb_clk",		.clk = &ahb_clk},
>>>>> > >> > -	{ .con_id = "apb_clk",		.clk = &apb_clk},
>>>>> > >> > +	{.con_id = "apb_clk",		.clk = &apb_clk},
>>>>> > >> > +
>>> > > how about use macro here to simplify the code
>>> > > 
>>> > > +#define CLKDEV_ID(__clk) { .con_id = #__clk, .clk = &(__clk) }
>>> > > and 
>>> > > +#define CLKDEV_ID_CLK(__clk) { .con_id = #__clk, .clk = &(__clk##_clk) }
>> > 
>> > We had that in mind while designing but we chose it this way. There are
>> > not many fields to fill here, so it looks fine without macro's too.
>> > I didn't wanted to create an abstraction layer here.
> the macro will also avoid human mistake

OK. Will do it in a separate patch.

>> > 
>>>>> > >> > diff --git a/arch/arm/mach-spear13xx/include/mach/misc_regs.h b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
>>>>> > >> > index 2e87a07..c4dcab2 100644
>>>>> > >> > --- a/arch/arm/mach-spear13xx/include/mach/misc_regs.h
>>>>> > >> > +++ b/arch/arm/mach-spear13xx/include/mach/misc_regs.h
>>> > > how about clock.h header?
>> > 
>> > If i understand correctly you want me to rename misc_regs.h as clock.h?
>> > Actually misc_regs.h have all miscellaneous registers for spear, like:
>> > clock specific, reset register, some muxing registers too.. They are
>> > not only for "clock". So we kept this name.
> no split it

We have "Miscellaneous Registers" as a seperate module in our device manuals
and we don't want to break this terminology. Misc regs are intermixed, and it
is difficult to separate the registers on basis of various system parameters
(like clock, power etc.)

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-09-07  9:01         ` viresh kumar
@ 2010-09-07  9:09           ` Russell King - ARM Linux
  2010-09-07  9:16             ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-07  9:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 07, 2010 at 02:31:30PM +0530, viresh kumar wrote:
> On 9/7/2010 9:36 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 09:28 Tue 07 Sep     , viresh kumar wrote:
> >> > On 9/7/2010 4:39 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>> > >>  /* array of all spear 13xx clock lookups */
> >>>>> > >> > @@ -327,18 +749,58 @@ static struct clk_lookup spear_clk_lookups[] = {
> >>>>> > >> >  	/* clock derived from pll1 clk */
> >>>>> > >> >  	{.con_id = "cpu_clk",		.clk = &cpu_clk},
> >>>>> > >> >  	{.con_id = "ahb_clk",		.clk = &ahb_clk},
> >>>>> > >> > -	{ .con_id = "apb_clk",		.clk = &apb_clk},
> >>>>> > >> > +	{.con_id = "apb_clk",		.clk = &apb_clk},
> >>>>> > >> > +
> >>> > > how about use macro here to simplify the code
> >>> > > 
> >>> > > +#define CLKDEV_ID(__clk) { .con_id = #__clk, .clk = &(__clk) }
> >>> > > and 
> >>> > > +#define CLKDEV_ID_CLK(__clk) { .con_id = #__clk, .clk = &(__clk##_clk) }
> >> > 
> >> > We had that in mind while designing but we chose it this way. There are
> >> > not many fields to fill here, so it looks fine without macro's too.
> >> > I didn't wanted to create an abstraction layer here.
> > the macro will also avoid human mistake
> 
> OK. Will do it in a separate patch.

I'd suggest leaving it as is - presumably its already been tested and
so works.

Adding that macro just encourages bad usage anyway - by encouraging
people to name individual clocks by their source rather than by their
consumer.  Naming clocks by their source has been proven many times to
make things more complicated and difficult in the long run.

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

* [PATCH 13/74] ST SPEAr: Update clock framework and definitions
  2010-09-07  9:09           ` Russell King - ARM Linux
@ 2010-09-07  9:16             ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 2:39 PM, Russell King - ARM Linux wrote:
> I'd suggest leaving it as is - presumably its already been tested and
> so works.
> 
> Adding that macro just encourages bad usage anyway - by encouraging
> people to name individual clocks by their source rather than by their
> consumer.  Naming clocks by their source has been proven many times to
> make things more complicated and difficult in the long run.

OK.

thanks
viresh.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-09-07  4:12       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07  9:16         ` viresh kumar
  2010-09-07  9:44           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 9:42 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> please split your v2 patch series in related changset it will simplify the
> review

Jean,

I would prefer not to do this change in current series due to following reasons:
- Would make difficult for reviewers to locate V2 for V1 they have reviewed.
- My patches are intermixed, so would be difficult for me to create related
change sets as currently patches are very much intermixed.

I will take care of this next time i send another patch series.

regards
viresh.

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

* [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig
  2010-09-02 15:40   ` Russell King - ARM Linux
  2010-09-03  3:56     ` viresh kumar
@ 2010-09-07  9:18     ` viresh kumar
  1 sibling, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 9:10 PM, Russell King - ARM Linux wrote:
>> > We only need one defconfig for SPEAr13xx now since we can build all
>> > boards into one kernel.
> All this kind of thing should be rolled into previous patches.
> 
> We really don't need to know that you developed SPEAr13xx support
> such that it initially couldn't build all boards into a kernel,
> what the changes were to achieve a kernel for everything, and that
> there were several defconfigs in existence before one grand unified
> one was possible.

Ok.

viresh.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-09-07  9:16         ` viresh kumar
@ 2010-09-07  9:44           ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07 10:17             ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 14:46 Tue 07 Sep     , viresh kumar wrote:
> On 9/7/2010 9:42 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > please split your v2 patch series in related changset it will simplify the
> > review
> 
> Jean,
> 
> I would prefer not to do this change in current series due to following reasons:
> - Would make difficult for reviewers to locate V2 for V1 they have reviewed.
> - My patches are intermixed, so would be difficult for me to create related
> change sets as currently patches are very much intermixed.
> 
> I will take care of this next time i send another patch series.
It's really difficult to reiew it and take long time
so reduce the number of patch and by related changeset will help a lot

Best Regards,
J.

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

* [PATCH 15/74] ST SPEAr: adding support for rtc
  2010-09-06 19:09   ` Alessandro Zummo
  2010-09-07  3:30     ` rajeev
@ 2010-09-07 10:13     ` viresh kumar
  1 sibling, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 12:39 AM, Alessandro Zummo wrote:
> On Mon, 30 Aug 2010 16:11:00 +0530
> Viresh KUMAR <viresh.kumar@st.com> wrote:
> 
>> > From: Rajeev Kumar <rajeev-dlh.kumar@st.com>
>  Hi, there are quite a few issues. Please read the
>  checklist at http://groups.google.com/group/rtc-linux/web/checklist

Alessandro,

I tried to find issues in driver, with help of checklist. I could find
very few changes initially, they are:
- Correct MODULE_* at end of file
- add platform dependency in Kconfig
- remove .owner
- removed few #includes.

If there are any more issues that you might have encountered, then
please let me know before i send V2.

thanks
viresh.

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

* [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware
  2010-09-07  9:44           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07 10:17             ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-07 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 3:14 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 14:46 Tue 07 Sep     , viresh kumar wrote:
>> > On 9/7/2010 9:42 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> > > please split your v2 patch series in related changset it will simplify the
>>> > > review
>> > 
>> > Jean,
>> > 
>> > I would prefer not to do this change in current series due to following reasons:
>> > - Would make difficult for reviewers to locate V2 for V1 they have reviewed.
>> > - My patches are intermixed, so would be difficult for me to create related
>> > change sets as currently patches are very much intermixed.
>> > 
>> > I will take care of this next time i send another patch series.
> It's really difficult to reiew it and take long time
> so reduce the number of patch and by related changeset will help a lot

Jean: I agree with what you are saying, but doing it in current patch series will
be difficult.

Russell: Can we go ahead with a single patch set this time. By next time we will
take care of this.

viresh.

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-06 22:40   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07 10:51     ` viresh kumar
  2010-09-07 11:38       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-10-01  5:42     ` Vipin Kumar
  1 sibling, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:10 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
>> > index 41a2b5e..4f049fe 100644
>> > --- a/arch/arm/mach-spear3xx/clock.c
>> > +++ b/arch/arm/mach-spear3xx/clock.c
>> > @@ -552,6 +552,15 @@ static struct clk adc_clk = {
>> >       .recalc = &follow_parent,
>> >  };
>> >
>> > +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
> can you create a macro for this?
> or even better detect it
> 

It should be statically allocated, registering this to clkdev framework
should be dynamic, which is done in my local repository (as mentioned in
i2c patch).

Regarding creating macros: As we have three machines in spear3xx (300, 310, 320)
we need to create 4 macros (300 & 310, 310 &320, 300 & 320, 300&310&320),
This will make it even more complex to read. So, i would like to keep it as it is.

>> > +/* emi clock */
>> > +static struct clk emi_clk = {
>> > +     .flags = ALWAYS_ENABLED,
>> > +     .pclk = &ahb_clk,
>> > +     .recalc = &follow_parent,
>> > +};
>> > +#endif


>> +/* emi nor flash device registeration */
>> > +static struct physmap_flash_data emi_norflash_data;
>> > +
>> > +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,
>> > +     },
>> > +};
> it's board specfic not mach
> 
> NACK

No. This is machine specific. Same for all boards.

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

* [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/
  2010-09-02 16:27   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-06 11:52     ` viresh kumar
@ 2010-09-07 11:35     ` viresh kumar
  2010-09-07 20:56       ` Russell King - ARM Linux
  1 sibling, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/2/2010 9:57 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> > index 9295110..950c045 100644
>> > --- a/arch/arm/Kconfig
>> > +++ b/arch/arm/Kconfig
>> > @@ -1144,11 +1144,13 @@ config SMP
>> >  	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
>> >  	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
>> >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
>> > -		 ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
>> > +		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
>> > +		 ARCH_VEXPRESS_CA9X4)
> can we get rid of such long list by introducing a HAVE somthing
> etc....


I tried to do this, but have some doubts. With this change architectures
can not disable features selected using select statement.
So, if i want image without SMP for SPEAr13xx now, i can't do it.


Please correct me if this is not the right way of doing it.

regards,
viresh.
--------------------------------------

[PATCH] arch/arm/Kconfig: removing arch/machine dependencies from SMP, LOCAL_TIMERS, HAVE_ARM_SCU AND HAVE_ARM_TWD

Individual architectures/machines should select SMP, LOCAL_TIMERS, HAVE_ARM_SCU
AND HAVE_ARM_TWD from there config options

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/Kconfig               |   30 +++++++++++++++++-------------
 arch/arm/mach-omap2/Kconfig    |    4 ++++
 arch/arm/mach-realview/Kconfig |    8 ++++++++
 arch/arm/mach-vexpress/Kconfig |    3 +++
 arch/arm/plat-spear/Kconfig    |    4 ++++
 5 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f6ec629..4617efa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -238,6 +238,8 @@ config ARCH_REALVIEW
 	select PLAT_VERSATILE
 	select ARM_TIMER_SP804
 	select GPIO_PL061 if GPIOLIB
+	select HAVE_ARM_SCU if SMP
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	help
 	  This enables support for ARM Ltd RealView boards.
 
@@ -261,6 +263,7 @@ config ARCH_VEXPRESS
 	select ARM_TIMER_SP804
 	select COMMON_CLKDEV
 	select GENERIC_CLOCKEVENTS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	select HAVE_CLK
 	select ICST
 	select PLAT_VERSATILE
@@ -566,6 +569,10 @@ config ARCH_TEGRA
 	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ARCH_HAS_BARRIERS if CACHE_L2X0
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	help
 	  This enables support for NVIDIA Tegra based systems (Tegra APX,
 	  Tegra 6xx and Tegra 2 series).
@@ -733,6 +740,10 @@ config ARCH_S5PV310
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select GENERIC_CLOCKEVENTS
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	help
 	  Samsung S5PV310 series based systems
 
@@ -779,6 +790,10 @@ config ARCH_U8500
 	select GENERIC_CLOCKEVENTS
 	select COMMON_CLKDEV
 	select ARCH_REQUIRE_GPIOLIB
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	help
 	  Support for ST-Ericsson's Ux500 architecture
 
@@ -1146,15 +1161,9 @@ source "kernel/time/Kconfig"
 
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
-		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
-		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
-		 ARCH_VEXPRESS_CA9X4)
+	depends on EXPERIMENTAL
 	depends on GENERIC_CLOCKEVENTS
 	select USE_GENERIC_SMP_HELPERS
-	select HAVE_ARM_SCU if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 ||\
-		 ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
-		 ARCH_VEXPRESS_CA9X4
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -1222,13 +1231,8 @@ config HOTPLUG_CPU
 
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
-	depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
-		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
-		ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
-		ARCH_VEXPRESS_CA9X4)
+	depends on SMP
 	default y
-	select HAVE_ARM_TWD if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 || \
-		ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b48bacf..674bb71 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -43,6 +43,10 @@ config ARCH_OMAP4
 	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select ARM_GIC
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index b4575ae..30a06ff 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -11,6 +11,8 @@ config REALVIEW_EB_A9MP
 	bool "Support Multicore Cortex-A9"
 	depends on MACH_REALVIEW_EB
 	select CPU_V7
+	select SMP
+	select LOCAL_TIMERS
 	help
 	  Enable support for the Cortex-A9MPCore tile on the Realview platform.
 
@@ -18,6 +20,8 @@ config REALVIEW_EB_ARM11MP
 	bool "Support ARM11MPCore tile"
 	depends on MACH_REALVIEW_EB
 	select CPU_V6
+	select SMP
+	select LOCAL_TIMERS
 	select ARCH_HAS_BARRIERS if SMP
 	help
 	  Enable support for the ARM11MPCore tile on the Realview platform.
@@ -36,6 +40,8 @@ config MACH_REALVIEW_PB11MP
 	select CPU_V6
 	select ARM_GIC
 	select HAVE_PATA_PLATFORM
+	select SMP
+	select LOCAL_TIMERS
 	select ARCH_HAS_BARRIERS if SMP
 	help
 	  Include support for the ARM(R) RealView MPCore Platform Baseboard.
@@ -73,6 +79,8 @@ config MACH_REALVIEW_PBX
 	select ARM_GIC
 	select HAVE_PATA_PLATFORM
 	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
+	select SMP
+	select LOCAL_TIMERS
 	select ZONE_DMA if SPARSEMEM
 	help
 	  Include support for the ARM(R) RealView PBX platform.
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 3f19b66..8475646 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 	select CPU_V7
 	select ARM_GIC
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
 
 endmenu
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index b8e4988..18e2229 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -13,6 +13,10 @@ config ARCH_SPEAR13XX
 	select ARM_GIC
 	select CPU_V7
 	select ARCH_SUPPORTS_MSI
+	select SMP
+	select HAVE_ARM_SCU if SMP
+	select LOCAL_TIMERS
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	help
 	  Supports for ARM's SPEAR13XX family

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-07 10:51     ` viresh kumar
@ 2010-09-07 11:38       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07 11:54         ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 16:21 Tue 07 Sep     , viresh kumar wrote:
> On 9/7/2010 4:10 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >> diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
> >> > index 41a2b5e..4f049fe 100644
> >> > --- a/arch/arm/mach-spear3xx/clock.c
> >> > +++ b/arch/arm/mach-spear3xx/clock.c
> >> > @@ -552,6 +552,15 @@ static struct clk adc_clk = {
> >> >       .recalc = &follow_parent,
> >> >  };
> >> >
> >> > +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
> > can you create a macro for this?
> > or even better detect it
> > 
> 
> It should be statically allocated, registering this to clkdev framework
> should be dynamic, which is done in my local repository (as mentioned in
> i2c patch).
> 
> Regarding creating macros: As we have three machines in spear3xx (300, 310, 320)
> we need to create 4 macros (300 & 310, 310 &320, 300 & 320, 300&310&320),
> This will make it even more complex to read. So, i would like to keep it as it is.
> 
> >> > +/* emi clock */
> >> > +static struct clk emi_clk = {
> >> > +     .flags = ALWAYS_ENABLED,
> >> > +     .pclk = &ahb_clk,
> >> > +     .recalc = &follow_parent,
> >> > +};
> >> > +#endif
> 
> 
> >> +/* emi nor flash device registeration */
> >> > +static struct physmap_flash_data emi_norflash_data;
> >> > +
> >> > +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,
> >> > +     },
> >> > +};
> > it's board specfic not mach
> > 
> > NACK
> 
> No. This is machine specific. Same for all boards.
NACK as you can have a flash at other place and more than one flash
and the size depend on the flash

Best Regards,
J.

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-07 11:38       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-07 11:54         ` viresh kumar
  2010-09-07 13:32           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: viresh kumar @ 2010-09-07 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>> +/* emi nor flash device registeration */
>>>>> > >> > +static struct physmap_flash_data emi_norflash_data;
>>>>> > >> > +
>>>>> > >> > +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,
>>>>> > >> > +     },
>>>>> > >> > +};
>>> > > it's board specfic not mach
>>> > > 
>>> > > NACK
>> > 
>> > No. This is machine specific. Same for all boards.
> NACK as you can have a flash at other place and more than one flash
> and the size depend on the flash

Correct!! Size has to be board specific. Will modify it.

thanks
viresh.

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-07 11:54         ` viresh kumar
@ 2010-09-07 13:32           ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-10  8:11             ` Vipin Kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-07 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:24 Tue 07 Sep     , viresh kumar wrote:
> On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>> +/* emi nor flash device registeration */
> >>>>> > >> > +static struct physmap_flash_data emi_norflash_data;
> >>>>> > >> > +
> >>>>> > >> > +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,
> >>>>> > >> > +     },
> >>>>> > >> > +};
> >>> > > it's board specfic not mach
> >>> > > 
> >>> > > NACK
> >> > 
> >> > No. This is machine specific. Same for all boards.
> > NACK as you can have a flash at other place and more than one flash
> > and the size depend on the flash
> 
> Correct!! Size has to be board specific. Will modify it.
and the start also as you may have 2 nor flash on different bank

Best Regards,
J.

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

* [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/
  2010-09-07 11:35     ` viresh kumar
@ 2010-09-07 20:56       ` Russell King - ARM Linux
  0 siblings, 0 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-07 20:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 07, 2010 at 05:05:19PM +0530, viresh kumar wrote:
> On 9/2/2010 9:57 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> >> > index 9295110..950c045 100644
> >> > --- a/arch/arm/Kconfig
> >> > +++ b/arch/arm/Kconfig
> >> > @@ -1144,11 +1144,13 @@ config SMP
> >> >  	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
> >> >  	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
> >> >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
> >> > -		 ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
> >> > +		 ARCH_S5PV310 || ARCH_SPEAR13XX || ARCH_TEGRA || ARCH_U8500 ||\
> >> > +		 ARCH_VEXPRESS_CA9X4)
> > can we get rid of such long list by introducing a HAVE somthing
> > etc....
> 
> 
> I tried to do this, but have some doubts. With this change architectures
> can not disable features selected using select statement.
> So, if i want image without SMP for SPEAr13xx now, i can't do it.
> 
> 
> Please correct me if this is not the right way of doing it.
> 
> regards,
> viresh.
> --------------------------------------
> 
> [PATCH] arch/arm/Kconfig: removing arch/machine dependencies from SMP, LOCAL_TIMERS, HAVE_ARM_SCU AND HAVE_ARM_TWD
> 
> Individual architectures/machines should select SMP, LOCAL_TIMERS, HAVE_ARM_SCU
> AND HAVE_ARM_TWD from there config options

I've already killed most of this off.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-06 11:55         ` deepaksi
@ 2010-09-08 15:12           ` Russell King - ARM Linux
  2010-09-09  4:17             ` deepaksi
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-08 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 06, 2010 at 05:25:31PM +0530, deepaksi wrote:
> On 9/3/2010 1:04 PM, Russell King - ARM Linux wrote:
> > So how are wakeup sources configured if this callback does nothing?
> > .
>
> In most of the architectures that I could refer across(including SPEAr
> family -SPEAr13xx),
> have a separate power management unit(PMU) which is required to be
> configured to define the wake
> up sources. The PMU takes care of waking up the system from sleep, as
> and when the wake up
> interrupts are triggered. This routing is independent of GIC, and hence
> the handling was not added.
> 
> Contrary to that, in some of our hardware architecture using VIC
> (including SPEAr 3xx/6xx), there
> was no explicit PMU, and the wake up trigger was exclusively done
> through VIC, and hence the VIC
> call backs had the necessary implementation.

What I read into this is that you're using enable_irq_wake() in your
drivers _and_ another mechanism to configure what wakes up the system
via the PMU - maybe with drivers explicitly calling out to the PMU
to achieve this?

This sounds a little haphazard, especially from the drivers point of
view.  Surely there's a more sensible solution to this rather than
adding do-nothing irq_wake support?

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-08 15:12           ` Russell King - ARM Linux
@ 2010-09-09  4:17             ` deepaksi
  2010-09-20 13:44               ` deepaksi
  0 siblings, 1 reply; 245+ messages in thread
From: deepaksi @ 2010-09-09  4:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/8/2010 8:42 PM, Russell King - ARM Linux wrote:
> On Mon, Sep 06, 2010 at 05:25:31PM +0530, deepaksi wrote:
>   
>> On 9/3/2010 1:04 PM, Russell King - ARM Linux wrote:
>>     
>>> So how are wakeup sources configured if this callback does nothing?
>>> .
>>>       
>> In most of the architectures that I could refer across(including SPEAr
>> family -SPEAr13xx),
>> have a separate power management unit(PMU) which is required to be
>> configured to define the wake
>> up sources. The PMU takes care of waking up the system from sleep, as
>> and when the wake up
>> interrupts are triggered. This routing is independent of GIC, and hence
>> the handling was not added.
>>
>> Contrary to that, in some of our hardware architecture using VIC
>> (including SPEAr 3xx/6xx), there
>> was no explicit PMU, and the wake up trigger was exclusively done
>> through VIC, and hence the VIC
>> call backs had the necessary implementation.
>>     
> What I read into this is that you're using enable_irq_wake() in your
> drivers _and_ another mechanism to configure what wakes up the system
> via the PMU - maybe with drivers explicitly calling out to the PMU
> to achieve this?
>   

This is even true for the drivers already in the kernel for example
stmmac driver ( using synopsis GMAC core): drivers/net/stmmac/
if we don not check for the return type, then probably it makes sense to
remove the dunny handlers, else another alternative could be to modify
the enable_irq_wake() call, to return the proper values.

Changing the driver specific to SPEAr is fine, but SPEAr platform does
uses the existing drivers in the kernel.


> This sounds a little haphazard, especially from the drivers point of
> view.  Surely there's a more sensible solution to this rather than
> adding do-nothing irq_wake support?
> .
>
>   
How do you recommend to go about this ?

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-03 17:26             ` Linus Walleij
@ 2010-09-10  4:21               ` viresh kumar
  -1 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-10  4:21 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Pratyush ANAND, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Armando VISCONTI, Alessandro Rubini,
	Vipin KUMAR, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

On 9/3/2010 10:56 PM, Linus Walleij wrote:
>> > Note however that the platform data in
>> > arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
>> > new driver.  If you remove my version please at least compile-check
>> > the nhk with the new patch-set.
> What about we put this new FSMC generic thing in, and
> then remove the old one with the same patch that
> instead activates the new one. No need to rush that.
> 
> Right now I mostly worry about having it in the proper
> place with the proper name and the headers accessible from
> all archs...

Linus,

Sorry for replying late!!!

The solution looks fine to us, but currently we don't have
enough bandwidth to rework on the suggested solution.

Maybe, we can go ahead with current patch, get it acked. Then send another
patch later to fix mentioned issues.

How do you suggest to proceed on this?

viresh.

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-10  4:21               ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-10  4:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/3/2010 10:56 PM, Linus Walleij wrote:
>> > Note however that the platform data in
>> > arch/arm/mach-nomadik/board-nhk8815.c should be fixed to reference the
>> > new driver.  If you remove my version please at least compile-check
>> > the nhk with the new patch-set.
> What about we put this new FSMC generic thing in, and
> then remove the old one with the same patch that
> instead activates the new one. No need to rush that.
> 
> Right now I mostly worry about having it in the proper
> place with the proper name and the headers accessible from
> all archs...

Linus,

Sorry for replying late!!!

The solution looks fine to us, but currently we don't have
enough bandwidth to rework on the suggested solution.

Maybe, we can go ahead with current patch, get it acked. Then send another
patch later to fix mentioned issues.

How do you suggest to proceed on this?

viresh.

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-07 13:32           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-10  8:11             ` Vipin Kumar
  2010-09-10  8:56               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: Vipin Kumar @ 2010-09-10  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 7:02 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 17:24 Tue 07 Sep     , viresh kumar wrote:
>> On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>>>> +/* emi nor flash device registeration */
>>>>>>>>>>> +static struct physmap_flash_data emi_norflash_data;
>>>>>>>>>>> +
>>>>>>>>>>> +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,
>>>>>>>>>>> +     },
>>>>>>>>>>> +};
>>>>>>> it's board specfic not mach
>>>>>>>
>>>>>>> NACK
>>>>>
>>>>> No. This is machine specific. Same for all boards.
>>> NACK as you can have a flash at other place and more than one flash
>>> and the size depend on the flash
>>
>> Correct!! Size has to be board specific. Will modify it.
> and the start also as you may have 2 nor flash on different bank
> 

The start addresses in our case are fixed for a particular bank.

Regards
Vipin

> Best Regards,
> J.
> .
> 

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

* Re: [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
  2010-09-10  4:21               ` viresh kumar
@ 2010-09-10  8:38                 ` Linus Walleij
  -1 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-10  8:38 UTC (permalink / raw)
  To: viresh kumar
  Cc: Pratyush ANAND, Vipul Kumar SAMAR, Bhupesh SHARMA,
	Sebastian RASMUSSEN, Armando VISCONTI, Alessandro Rubini,
	Vipin KUMAR, Shiraz HASHIM, Rajeev KUMAR, linux-mtd,
	Deepak SIKRI, dwmw2, linux-arm-kernel

2010/9/10 viresh kumar <viresh.kumar@st.com>:

>> Right now I mostly worry about having it in the proper
>> place with the proper name and the headers accessible from
>> all archs...
>
> The solution looks fine to us, but currently we don't have
> enough bandwidth to rework on the suggested solution.
>
> Maybe, we can go ahead with current patch, get it acked. Then send another
> patch later to fix mentioned issues.
>
> How do you suggest to proceed on this?

Easy, I will attempt to step in and fix it up and also test it on
U300. :-)

Yours,
Linus Walleij

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

* [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms
@ 2010-09-10  8:38                 ` Linus Walleij
  0 siblings, 0 replies; 245+ messages in thread
From: Linus Walleij @ 2010-09-10  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

2010/9/10 viresh kumar <viresh.kumar@st.com>:

>> Right now I mostly worry about having it in the proper
>> place with the proper name and the headers accessible from
>> all archs...
>
> The solution looks fine to us, but currently we don't have
> enough bandwidth to rework on the suggested solution.
>
> Maybe, we can go ahead with current patch, get it acked. Then send another
> patch later to fix mentioned issues.
>
> How do you suggest to proceed on this?

Easy, I will attempt to step in and fix it up and also test it on
U300. :-)

Yours,
Linus Walleij

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-10  8:11             ` Vipin Kumar
@ 2010-09-10  8:56               ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-10  9:06                 ` Vipin Kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-10  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 13:41 Fri 10 Sep     , Vipin Kumar wrote:
> On 9/7/2010 7:02 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 17:24 Tue 07 Sep     , viresh kumar wrote:
> >> On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>>>> +/* emi nor flash device registeration */
> >>>>>>>>>>> +static struct physmap_flash_data emi_norflash_data;
> >>>>>>>>>>> +
> >>>>>>>>>>> +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,
> >>>>>>>>>>> +     },
> >>>>>>>>>>> +};
> >>>>>>> it's board specfic not mach
> >>>>>>>
> >>>>>>> NACK
> >>>>>
> >>>>> No. This is machine specific. Same for all boards.
> >>> NACK as you can have a flash at other place and more than one flash
> >>> and the size depend on the flash
> >>
> >> Correct!! Size has to be board specific. Will modify it.
> > and the start also as you may have 2 nor flash on different bank
> > 
> 
> The start addresses in our case are fixed for a particular bank.
but not for the nor so let this decide by every board
not by the SoC

Best Regards,
J.

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-10  8:56               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-10  9:06                 ` Vipin Kumar
  2010-09-10  9:21                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: Vipin Kumar @ 2010-09-10  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/10/2010 2:26 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 13:41 Fri 10 Sep     , Vipin Kumar wrote:
>> On 9/7/2010 7:02 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> On 17:24 Tue 07 Sep     , viresh kumar wrote:
>>>> On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>>>>>> +/* emi nor flash device registeration */
>>>>>>>>>>>>> +static struct physmap_flash_data emi_norflash_data;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +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,
>>>>>>>>>>>>> +     },
>>>>>>>>>>>>> +};
>>>>>>>>> it's board specfic not mach
>>>>>>>>>
>>>>>>>>> NACK
>>>>>>>
>>>>>>> No. This is machine specific. Same for all boards.
>>>>> NACK as you can have a flash at other place and more than one flash
>>>>> and the size depend on the flash
>>>>
>>>> Correct!! Size has to be board specific. Will modify it.
>>> and the start also as you may have 2 nor flash on different bank
>>>
>>
>> The start addresses in our case are fixed for a particular bank.
> but not for the nor so let this decide by every board
> not by the SoC
> 

The NOR memory is placed within the system memory address space.
For NAND offourse, it lies beyond system space. 

EMI is a Parallel NOR memory controller and the base address and 
maximum size of each bank is fixed in our system...

Regards
Vipin

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-10  9:06                 ` Vipin Kumar
@ 2010-09-10  9:21                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 14:36 Fri 10 Sep     , Vipin Kumar wrote:
> On 9/10/2010 2:26 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 13:41 Fri 10 Sep     , Vipin Kumar wrote:
> >> On 9/7/2010 7:02 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>> On 17:24 Tue 07 Sep     , viresh kumar wrote:
> >>>> On 9/7/2010 5:08 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>>>>>> +/* emi nor flash device registeration */
> >>>>>>>>>>>>> +static struct physmap_flash_data emi_norflash_data;
> >>>>>>>>>>>>> +
> >>>>>>>>>>>>> +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,
> >>>>>>>>>>>>> +     },
> >>>>>>>>>>>>> +};
> >>>>>>>>> it's board specfic not mach
> >>>>>>>>>
> >>>>>>>>> NACK
> >>>>>>>
> >>>>>>> No. This is machine specific. Same for all boards.
> >>>>> NACK as you can have a flash at other place and more than one flash
> >>>>> and the size depend on the flash
> >>>>
> >>>> Correct!! Size has to be board specific. Will modify it.
> >>> and the start also as you may have 2 nor flash on different bank
> >>>
> >>
> >> The start addresses in our case are fixed for a particular bank.
> > but not for the nor so let this decide by every board
> > not by the SoC
> > 
> 
> The NOR memory is placed within the system memory address space.
> For NAND offourse, it lies beyond system space. 
> 
> EMI is a Parallel NOR memory controller and the base address and 
> maximum size of each bank is fixed in our system...
but the then is not necessarely at bank 0

Best Regards,
J.

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-09-06 22:55   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-13  3:22     ` Shiraz Hashim
  2010-09-13  3:37       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-13  7:49       ` Russell King - ARM Linux
  0 siblings, 2 replies; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-13  3:22 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Jean,

On 9/7/2010 4:25 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>  
>> -#endif
>> +static void __init spear3xx_timer_init(void)
>> +{
>> +	spear_setup_timer();
> why not call it directly?

A single level of abstraction was provided so that if archs (spear3xx/6xx/13xx)
required to do something extra.

>> +}
>> +
>> +struct sys_timer spear3xx_timer = {
>> +	.init = spear3xx_timer_init,
>> +};
>> diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
>> index 16205a5..e5967ed 100644
>> --- a/arch/arm/mach-spear6xx/include/mach/generic.h
>> +++ b/arch/arm/mach-spear6xx/include/mach/generic.h
>> @@ -31,9 +31,10 @@
>>  /* Add spear6xx family device structure declarations here */
>>  extern struct amba_device gpio_device[];
>>  extern struct amba_device uart_device[];
>> -extern struct sys_timer spear_sys_timer;
>> +extern struct sys_timer spear6xx_timer;
>>  
>>  /* Add spear6xx family function declarations here */
>> +void __init spear_setup_timer(void);
>>  void __init spear6xx_map_io(void);
>>  void __init spear6xx_init_irq(void);
>>  void __init spear6xx_init(void);
>> diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
>> index daff8d0..bdd5b76 100644
>> --- a/arch/arm/mach-spear6xx/spear600_evb.c
>> +++ b/arch/arm/mach-spear6xx/spear600_evb.c
>> @@ -42,10 +42,11 @@ static void __init spear600_evb_init(void)
>>  		amba_device_register(amba_devs[i], &iomem_resource);
>>  }
>>  
>> +
> please remove

OK

>>  MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
>>  	.boot_params	=	0x00000100,
>>  	.map_io		=	spear6xx_map_io,
>>  	.init_irq	=	spear6xx_init_irq,
>> -	.timer		=	&spear_sys_timer,
>> +	.timer		=	&spear6xx_timer,
>>  	.init_machine	=	spear600_evb_init,
>>  MACHINE_END
>> diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
>> index baf6bcc..88a82ca 100644
>> --- a/arch/arm/mach-spear6xx/spear6xx.c
>> +++ b/arch/arm/mach-spear6xx/spear6xx.c
>> @@ -155,3 +155,12 @@ void __init spear6xx_map_io(void)
>>  	/* This will initialize clock framework */
>>  	clk_init();
>>  }
>> +
>> +static void __init spear6xx_timer_init(void)
>> +{
>> +	spear_setup_timer();
>> +}
>> +
>> +struct sys_timer spear6xx_timer = {
>> +	.init = spear6xx_timer_init,
>> +};
>> diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
>> index ab21165..850d0cf 100644
>> --- a/arch/arm/plat-spear/time.c
>> +++ b/arch/arm/plat-spear/time.c
>> @@ -66,6 +66,13 @@
>>  static __iomem void *gpt_base;
>>  static struct clk *gpt_clk;
>>  
>> +/* following defines the parent clock to be used */
>> +#ifdef CONFIG_ARCH_SPEAR13XX
>> +static char pclk_name[] = "osc1_24m_clk";
>> +#else
>> +static char pclk_name[] = "pll3_48m_clk";
>> +#endif
> why 2 name?

spear13xx has different parent clock for gpt than spear3xx/6xx.

> it will be better to use clkdev and create an alias

This is specifically to chose parent clock, which can be different in different
architectures. clkdev corresponding to parent clock is already defined. We use
name here to get the clock.

> btw how about move the timer to drivers/clocksource?

I don't know whether this is the right place. Every body else has placed timer
code in his respective mach/plat directory.

>> +
>>  static void clockevent_set_mode(enum clock_event_mode mode,
>>  				struct clock_event_device *clk_event_dev);
>>  static int clockevent_next_event(unsigned long evt,
>> @@ -215,7 +222,8 @@ static void __init spear_clockevent_init(void)
>>  
>>  void __init spear_setup_timer(void)
>>  {
>> -	struct clk *pll3_clk;
>> +	struct clk *clk;
>> +	int ret;
>>  
>>  	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
>>  		pr_err("%s:cannot get IO addr\n", __func__);
>> @@ -234,26 +242,32 @@ void __init spear_setup_timer(void)
>>  		goto err_iomap;
>>  	}
>>  
>> -	pll3_clk = clk_get(NULL, "pll3_48m_clk");
>> -	if (!pll3_clk) {
>> -		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
>> +	/* get the parent clock */
>> +	clk = clk_get(NULL, pclk_name);
>> +
>> +	if (!clk) {
>> +		pr_err("%s:couldn't get %s as parent for gpt\n",
>> +				__func__, pclk_name);
>>  		goto err_iomap;
>>  	}
>>  
>> -	clk_set_parent(gpt_clk, pll3_clk);
>> +	clk_set_parent(gpt_clk, clk);
> ??
> why not do this in the clock file?

The functional clock of the timer very much depends on the parent clock it
selects. This is a part of the timer itself, hence it is kept here.

regards
Shiraz

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-09-13  3:22     ` Shiraz Hashim
@ 2010-09-13  3:37       ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-13  4:04         ` Shiraz Hashim
  2010-09-13  7:49       ` Russell King - ARM Linux
  1 sibling, 1 reply; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-13  3:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 08:52 Mon 13 Sep     , Shiraz Hashim wrote:
> Dear Jean,
> 
> On 9/7/2010 4:25 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>  
> >> -#endif
> >> +static void __init spear3xx_timer_init(void)
> >> +{
> >> +	spear_setup_timer();
> > why not call it directly?
> 
> A single level of abstraction was provided so that if archs (spear3xx/6xx/13xx)
> required to do something extra.
it does not seems to be needed at all so for now call it directly is enough
> >> +/* following defines the parent clock to be used */
> >> +#ifdef CONFIG_ARCH_SPEAR13XX
> >> +static char pclk_name[] = "osc1_24m_clk";
> >> +#else
> >> +static char pclk_name[] = "pll3_48m_clk";
> >> +#endif
> > why 2 name?
> 
> spear13xx has different parent clock for gpt than spear3xx/6xx.
so use a generic name which will be an alias specify on the soc clock
so here no need to do the ifdef specially if you want to support both of them
in the same kernel
> 
> > it will be better to use clkdev and create an alias
> 
> This is specifically to chose parent clock, which can be different in different
> architectures. clkdev corresponding to parent clock is already defined. We use
> name here to get the clock.
> 
> > btw how about move the timer to drivers/clocksource?
> 
> I don't know whether this is the right place. Every body else has placed timer
> code in his respective mach/plat directory.
> 
> >> +
> >>  static void clockevent_set_mode(enum clock_event_mode mode,
> >>  				struct clock_event_device *clk_event_dev);
> >>  static int clockevent_next_event(unsigned long evt,
> >> @@ -215,7 +222,8 @@ static void __init spear_clockevent_init(void)
> >>  
> >>  void __init spear_setup_timer(void)
> >>  {
> >> -	struct clk *pll3_clk;
> >> +	struct clk *clk;
> >> +	int ret;
> >>  
> >>  	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
> >>  		pr_err("%s:cannot get IO addr\n", __func__);
> >> @@ -234,26 +242,32 @@ void __init spear_setup_timer(void)
> >>  		goto err_iomap;
> >>  	}
> >>  
> >> -	pll3_clk = clk_get(NULL, "pll3_48m_clk");
> >> -	if (!pll3_clk) {
> >> -		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
> >> +	/* get the parent clock */
> >> +	clk = clk_get(NULL, pclk_name);
> >> +
> >> +	if (!clk) {
> >> +		pr_err("%s:couldn't get %s as parent for gpt\n",
> >> +				__func__, pclk_name);
> >>  		goto err_iomap;
> >>  	}
> >>  
> >> -	clk_set_parent(gpt_clk, pll3_clk);
> >> +	clk_set_parent(gpt_clk, clk);
> > ??
> > why not do this in the clock file?
> 
> The functional clock of the timer very much depends on the parent clock it
> selects. This is a part of the timer itself, hence it is kept here.
it's seems to be more soc depends than timer

Best Regards,
J.

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-09-13  3:37       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-13  4:04         ` Shiraz Hashim
  2010-09-13  4:37           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-13  4:04 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Jean,

On 9/13/2010 9:07 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 08:52 Mon 13 Sep     , Shiraz Hashim wrote:
>> Dear Jean,
>>
>> On 9/7/2010 4:25 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>>>  
>>>> -#endif
>>>> +static void __init spear3xx_timer_init(void)
>>>> +{
>>>> +	spear_setup_timer();
>>> why not call it directly?
>>
>> A single level of abstraction was provided so that if archs (spear3xx/6xx/13xx)
>> required to do something extra.
>
> it does not seems to be needed at all so for now call it directly is enough
>

OK. So, I think what could be better is to set the parent clock of the gpt in
the arch specific function like spear3xx_timer_init. This would also remove this
part from the timer code.

>>>> +/* following defines the parent clock to be used */
>>>> +#ifdef CONFIG_ARCH_SPEAR13XX
>>>> +static char pclk_name[] = "osc1_24m_clk";
>>>> +#else
>>>> +static char pclk_name[] = "pll3_48m_clk";
>>>> +#endif
>>> why 2 name?
>>
>> spear13xx has different parent clock for gpt than spear3xx/6xx.
> so use a generic name which will be an alias specify on the soc clock
> so here no need to do the ifdef specially if you want to support both of them
> in the same kernel

As described above would move the parent clock selection to the respective timer
init function for archs. Would that be fine ?

>>
>>> it will be better to use clkdev and create an alias
>>
>> This is specifically to chose parent clock, which can be different in different
>> architectures. clkdev corresponding to parent clock is already defined. We use
>> name here to get the clock.
>>
>>> btw how about move the timer to drivers/clocksource?
>>
>> I don't know whether this is the right place. Every body else has placed timer
>> code in his respective mach/plat directory.
>>
>>>> +
>>>>  static void clockevent_set_mode(enum clock_event_mode mode,
>>>>  				struct clock_event_device *clk_event_dev);
>>>>  static int clockevent_next_event(unsigned long evt,
>>>> @@ -215,7 +222,8 @@ static void __init spear_clockevent_init(void)
>>>>  
>>>>  void __init spear_setup_timer(void)
>>>>  {
>>>> -	struct clk *pll3_clk;
>>>> +	struct clk *clk;
>>>> +	int ret;
>>>>  
>>>>  	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
>>>>  		pr_err("%s:cannot get IO addr\n", __func__);
>>>> @@ -234,26 +242,32 @@ void __init spear_setup_timer(void)
>>>>  		goto err_iomap;
>>>>  	}
>>>>  
>>>> -	pll3_clk = clk_get(NULL, "pll3_48m_clk");
>>>> -	if (!pll3_clk) {
>>>> -		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
>>>> +	/* get the parent clock */
>>>> +	clk = clk_get(NULL, pclk_name);
>>>> +
>>>> +	if (!clk) {
>>>> +		pr_err("%s:couldn't get %s as parent for gpt\n",
>>>> +				__func__, pclk_name);
>>>>  		goto err_iomap;
>>>>  	}
>>>>  
>>>> -	clk_set_parent(gpt_clk, pll3_clk);
>>>> +	clk_set_parent(gpt_clk, clk);
>>> ??
>>> why not do this in the clock file?

Better to be done in timer init function of respective archs like spear3xx_timer_init

>>
>> The functional clock of the timer very much depends on the parent clock it
>> selects. This is a part of the timer itself, hence it is kept here.
>
> it's seems to be more soc depends than timer
>

yes, OK, would above solution be fine.

regards
Shiraz

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-09-13  4:04         ` Shiraz Hashim
@ 2010-09-13  4:37           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 245+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-09-13  4:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 09:34 Mon 13 Sep     , Shiraz Hashim wrote:
> Dear Jean,
> 
> On 9/13/2010 9:07 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 08:52 Mon 13 Sep     , Shiraz Hashim wrote:
> >> Dear Jean,
> >>
> >> On 9/7/2010 4:25 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>>>  
> >>>> -#endif
> >>>> +static void __init spear3xx_timer_init(void)
> >>>> +{
> >>>> +	spear_setup_timer();
> >>> why not call it directly?
> >>
> >> A single level of abstraction was provided so that if archs (spear3xx/6xx/13xx)
> >> required to do something extra.
> >
> > it does not seems to be needed at all so for now call it directly is enough
> >
> 
> OK. So, I think what could be better is to set the parent clock of the gpt in
> the arch specific function like spear3xx_timer_init. This would also remove this
> part from the timer code.
ok

Best Regards,
J.

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

* [PATCH 03/74] ST SPEAr: Formalized timer support
  2010-09-13  3:22     ` Shiraz Hashim
  2010-09-13  3:37       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-09-13  7:49       ` Russell King - ARM Linux
  1 sibling, 0 replies; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-13  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 13, 2010 at 08:52:49AM +0530, Shiraz Hashim wrote:
> Dear Jean,
> 
> On 9/7/2010 4:25 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>  
> >> -#endif
> >> +static void __init spear3xx_timer_init(void)
> >> +{
> >> +	spear_setup_timer();
> > why not call it directly?
> 
> A single level of abstraction was provided so that if archs (spear3xx/6xx/13xx)
> required to do something extra.

Please don't build abstraction layers on top of abstraction layers.  Use
what's already provided instead.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-09  4:17             ` deepaksi
@ 2010-09-20 13:44               ` deepaksi
  2010-09-20 13:48                 ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: deepaksi @ 2010-09-20 13:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,




On 9/9/2010 9:47 AM, deepaksi wrote:
> On 9/8/2010 8:42 PM, Russell King - ARM Linux wrote:
>   
>> On Mon, Sep 06, 2010 at 05:25:31PM +0530, deepaksi wrote:
>>   
>>     
>>> On 9/3/2010 1:04 PM, Russell King - ARM Linux wrote:
>>>     
>>>       
>>>> So how are wakeup sources configured if this callback does nothing?
>>>> .
>>>>       
>>>>         
>>> In most of the architectures that I could refer across(including SPEAr
>>> family -SPEAr13xx),
>>> have a separate power management unit(PMU) which is required to be
>>> configured to define the wake
>>> up sources. The PMU takes care of waking up the system from sleep, as
>>> and when the wake up
>>> interrupts are triggered. This routing is independent of GIC, and hence
>>> the handling was not added.
>>>
>>> Contrary to that, in some of our hardware architecture using VIC
>>> (including SPEAr 3xx/6xx), there
>>> was no explicit PMU, and the wake up trigger was exclusively done
>>> through VIC, and hence the VIC
>>> call backs had the necessary implementation.
>>>     
>>>       
>> What I read into this is that you're using enable_irq_wake() in your
>> drivers _and_ another mechanism to configure what wakes up the system
>> via the PMU - maybe with drivers explicitly calling out to the PMU
>> to achieve this?
>>   
>>     
> This is even true for the drivers already in the kernel for example
> stmmac driver ( using synopsis GMAC core): drivers/net/stmmac/
> if we don not check for the return type, then probably it makes sense to
> remove the dunny handlers, else another alternative could be to modify
> the enable_irq_wake() call, to return the proper values.
>
> Changing the driver specific to SPEAr is fine, but SPEAr platform does
> uses the existing drivers in the kernel.
>
>
>   
>> This sounds a little haphazard, especially from the drivers point of
>> view.  Surely there's a more sensible solution to this rather than
>> adding do-nothing irq_wake support?
>> .
>>
>>   
>>     
> How do you recommend to go about this ?
>
>   
I request you to provide some more inputs on this, so that we can close
the issue.

Rgds
Deepak

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 13:44               ` deepaksi
@ 2010-09-20 13:48                 ` Russell King - ARM Linux
  2010-09-20 14:56                   ` Rob Herring
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-20 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 20, 2010 at 07:14:33PM +0530, deepaksi wrote:
> I request you to provide some more inputs on this, so that we can close
> the issue.

I don't know, especially so without seeing the drivers.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 13:48                 ` Russell King - ARM Linux
@ 2010-09-20 14:56                   ` Rob Herring
  2010-09-20 15:07                     ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: Rob Herring @ 2010-09-20 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/20/2010 08:48 AM, Russell King - ARM Linux wrote:
> On Mon, Sep 20, 2010 at 07:14:33PM +0530, deepaksi wrote:
>> I request you to provide some more inputs on this, so that we can close
>> the issue.
>
> I don't know, especially so without seeing the drivers.

Assuming there is no powergating of the GIC, then this patch should be 
sufficient depending on one question. Whose responsibility is it to 
disable non-wakeup irqs: the interrupt controller code or each driver? 
If drivers are not trusted to disable their interrupt, then GIC 
suspend/resume functions are needed to disable/re-enable non-wakeup irqs.

With powergating of the GIC, saving and restoring of the GIC state in 
addition to external handling of wake-up would be needed.

Rob

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 14:56                   ` Rob Herring
@ 2010-09-20 15:07                     ` Russell King - ARM Linux
  2010-09-20 16:55                       ` Rob Herring
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-20 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 20, 2010 at 09:56:10AM -0500, Rob Herring wrote:
> On 09/20/2010 08:48 AM, Russell King - ARM Linux wrote:
>> On Mon, Sep 20, 2010 at 07:14:33PM +0530, deepaksi wrote:
>>> I request you to provide some more inputs on this, so that we can close
>>> the issue.
>>
>> I don't know, especially so without seeing the drivers.
>
> Assuming there is no powergating of the GIC, then this patch should be  
> sufficient depending on one question.

The GIC provides no wakeup capabilities.  Providing a dummy 'set_wake'
function means that driver authors will expect a successful
enable_irq_wake() to work - when it results in precisely nothing
being done.

With the situation described, what I envisage is drivers doing something
like:

	err = enable_irq_wake(irq);
	if (err == 0) {
		/* everything is fine, don't need to do anything else */
	} else if (err == -ENXIO) {
		/* IRQ controller doesn't support wakeups, try something else */
	} else {
		/* an error occurred trying to enable wakeups */
	}

If we go around adding dummy set_irq_wake functions to IRQ controllers
which don't support wakeup, then there's no way for drivers to know
this, and there is no method (other than by #ifdeffery) for them to
sort out this mess.

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 15:07                     ` Russell King - ARM Linux
@ 2010-09-20 16:55                       ` Rob Herring
  2010-09-20 18:07                         ` Russell King - ARM Linux
  0 siblings, 1 reply; 245+ messages in thread
From: Rob Herring @ 2010-09-20 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

Russell,

On 09/20/2010 10:07 AM, Russell King - ARM Linux wrote:
> On Mon, Sep 20, 2010 at 09:56:10AM -0500, Rob Herring wrote:
>> On 09/20/2010 08:48 AM, Russell King - ARM Linux wrote:
>>> On Mon, Sep 20, 2010 at 07:14:33PM +0530, deepaksi wrote:
>>>> I request you to provide some more inputs on this, so that we can close
>>>> the issue.
>>>
>>> I don't know, especially so without seeing the drivers.
>>
>> Assuming there is no powergating of the GIC, then this patch should be
>> sufficient depending on one question.
>
> The GIC provides no wakeup capabilities.  Providing a dummy 'set_wake'
> function means that driver authors will expect a successful
> enable_irq_wake() to work - when it results in precisely nothing
> being done.

There is no programming distinction between an irq and an wakeup if the 
GIC is powered on in suspend which is platform dependent. It is only a 
s/w distinction of what interrupts you allow to wake you up. If GIC 
remains powered, then it can assert nirq to the core and wake-up. If the 
core is powered down, the external power controller can monitor the NIRQ 
line to wake-up the core. So the powergating of the core has no impact 
on the prvgramming of the GIC for wake-up.

>
> With the situation described, what I envisage is drivers doing something
> like:
>
> 	err = enable_irq_wake(irq);
> 	if (err == 0) {
> 		/* everything is fine, don't need to do anything else */
> 	} else if (err == -ENXIO) {
> 		/* IRQ controller doesn't support wakeups, try something else */
> 	} else {
> 		/* an error occurred trying to enable wakeups */
> 	}
>
> If we go around adding dummy set_irq_wake functions to IRQ controllers
> which don't support wakeup, then there's no way for drivers to know
> this, and there is no method (other than by #ifdeffery) for them to
> sort out this mess.

How about adding a set_wake function ptr as a parameter to 
gic_dist_init? If a platform needs more than the basic operation, they 
can override it.

It doesn't make sense to push the platform dependent behavior of an 
interrupt controller into the drivers. enable_irq_wake is the defined 
way to enable wakeup. Why suggest drivers implement a custom interface 
for that? That will introduce ifdeffery in common drivers like ARM 
Primecell blocks.

Rob

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 16:55                       ` Rob Herring
@ 2010-09-20 18:07                         ` Russell King - ARM Linux
  2010-09-30  5:33                           ` viresh kumar
  0 siblings, 1 reply; 245+ messages in thread
From: Russell King - ARM Linux @ 2010-09-20 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 20, 2010 at 11:55:50AM -0500, Rob Herring wrote:
> There is no programming distinction between an irq and an wakeup if the  
> GIC is powered on in suspend which is platform dependent. It is only a  
> s/w distinction of what interrupts you allow to wake you up. If GIC  
> remains powered, then it can assert nirq to the core and wake-up. If the  
> core is powered down, the external power controller can monitor the NIRQ  
> line to wake-up the core. So the powergating of the core has no impact  
> on the prvgramming of the GIC for wake-up.

Well, not everyone does this - and I know of no platforms where it has
been reported for the GIC to be able to wake the system up.  TI OMAP
doesn't allow it, neither does the one being discussed in this thread.

The system being discussed here has an external power controller which
needs to be appropriately programmed.

You can see this because the proposed patch doesn't add code like that
in vic.c, but adds a no-operation function so that set_wake() becomes
a no-op returning zero.

> How about adding a set_wake function ptr as a parameter to  
> gic_dist_init? If a platform needs more than the basic operation, they  
> can override it.

As I can see, we're not talking about wake-up being able to be done from
the IRQ controller here, but something entirely external and unrelated
to it.

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

* [PATCH 00/74] Updating SPEAr Support
  2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
                   ` (73 preceding siblings ...)
  2010-08-30 10:44   ` Viresh KUMAR
@ 2010-09-21 11:32 ` Matthias Fuchs
  2010-09-21 11:50   ` viresh kumar
  74 siblings, 1 reply; 245+ messages in thread
From: Matthias Fuchs @ 2010-09-21 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Viresh,

are you also planning a USB gadget driver for the SPEAr?
Or is this already done?

Matthias

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

* [PATCH 00/74] Updating SPEAr Support
  2010-09-21 11:32 ` [PATCH 00/74] Updating SPEAr Support Matthias Fuchs
@ 2010-09-21 11:50   ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-21 11:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/21/2010 05:02 PM, Matthias Fuchs wrote:
> Hi Viresh,
> 
> are you also planning a USB gadget driver for the SPEAr?
> Or is this already done?

Matthias,

It is under testing currently, will be available in our next
branch in few days.

viresh

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

* [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume
  2010-09-20 18:07                         ` Russell King - ARM Linux
@ 2010-09-30  5:33                           ` viresh kumar
  0 siblings, 0 replies; 245+ messages in thread
From: viresh kumar @ 2010-09-30  5:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/20/2010 11:37 PM, Russell King - ARM Linux wrote:
> On Mon, Sep 20, 2010 at 11:55:50AM -0500, Rob Herring wrote:
>> There is no programming distinction between an irq and an wakeup if the  
>> GIC is powered on in suspend which is platform dependent. It is only a  
>> s/w distinction of what interrupts you allow to wake you up. If GIC  
>> remains powered, then it can assert nirq to the core and wake-up. If the  
>> core is powered down, the external power controller can monitor the NIRQ  
>> line to wake-up the core. So the powergating of the core has no impact  
>> on the prvgramming of the GIC for wake-up.
> 
> Well, not everyone does this - and I know of no platforms where it has
> been reported for the GIC to be able to wake the system up.  TI OMAP
> doesn't allow it, neither does the one being discussed in this thread.
> 
> The system being discussed here has an external power controller which
> needs to be appropriately programmed.
> 
> You can see this because the proposed patch doesn't add code like that
> in vic.c, but adds a no-operation function so that set_wake() becomes
> a no-op returning zero.
> 
>> How about adding a set_wake function ptr as a parameter to  
>> gic_dist_init? If a platform needs more than the basic operation, they  
>> can override it.
> 
> As I can see, we're not talking about wake-up being able to be done from
> the IRQ controller here, but something entirely external and unrelated
> to it.
> .
> 

Russell,

Should i keep this patch in "SPEAr Support patch series version 2"?

viresh.

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

* [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms
  2010-09-03  6:00   ` Sundar
@ 2010-09-30  9:37     ` Shiraz Hashim
  0 siblings, 0 replies; 245+ messages in thread
From: Shiraz Hashim @ 2010-09-30  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Sundar,

Sorry for replying so late :).

On 9/3/2010 11:30 AM, Sundar wrote:
> Hi,
> 
> On Mon, Aug 30, 2010 at 4:09 PM, Viresh KUMAR <viresh.kumar@st.com> wrote:
>> From: Deepak Sikri <deepak.sikri@st.com>
>>
>> Signed-off-by: Deepak Sikri <deepak.sikri@st.com>
>> Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
>> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
>> ---
> 
>> +       flush_cache_all();
>> +       asm volatile(
>> +       "       mcr     p15, 0, %1, c7, c5, 0\n"
>> +       "       mcr     p15, 0, %1, c7, c10, 4\n"
> 
> Isnt this a Cortex-A9 platform? If yes, then this is not implemented
> on the Cortex-A9 if I am right.
> You should use a dsb() here.

yes, I would place dsb here.

>> +               /*
>> +                * here's the WFI
>> +                */
>> +               asm(".word      0xe320f003\n"
>> +                   :
> 
> Also, why not a simple asm volatile("wfi" : : : "memory"); instead of
> hard coded values.

Would add a wfi() macro in asm/system.h including sev() as suggested by
Russell. This statement would be replaced by a simple wfi().

regards
Shiraz

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

* [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
  2010-09-06 22:40   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-09-07 10:51     ` viresh kumar
@ 2010-10-01  5:42     ` Vipin Kumar
  1 sibling, 0 replies; 245+ messages in thread
From: Vipin Kumar @ 2010-10-01  5:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 9/7/2010 4:10 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c
>> > new file mode 100644
>> > index 0000000..dd5cb8e
>> > --- /dev/null
>> > +++ b/arch/arm/mach-spear3xx/emi.c
>> > @@ -0,0 +1,86 @@
>> > +/*
>> > + * 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 <mach/emi.h>
>> > +
>> > +int __init emi_init(struct platform_device *pdev, unsigned long base,
>> > +             u32 bank, u32 width)
>> > +{
> how about request the memory region
> 
> and use platform device to register the bank ressource instead of define
> 
> it will make it more flexible


Hello Jean,

Sorry for replying late

Since the physmap driver implementation is generic for all the CFI device 
controllers, the driver expects only the actual flash base address in 
resource. Offcourse, the controller needs to be initialized separately.

Moreover, in most of the platforms where physmap driver is being used, the 
controllers are initialized independently. i.e only the NOR flash base 
addresses are passed as resource

examples are 

arch/arm/mach-at91/board-cap9adk.c
arch/arm/mach-ep93xx/adssphere.c
arch/arm/mach-ep93xx/micro9.c

and many more

Regards
Vipin

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

end of thread, other threads:[~2010-10-01  5:42 UTC | newest]

Thread overview: 245+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-30 10:38 [PATCH 00/74] Updating SPEAr Support Viresh KUMAR
2010-08-30 10:38 ` [PATCH 01/74] ST SPEAr: Padmux code Updated Viresh KUMAR
2010-09-06 22:49   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  3:51     ` viresh kumar
2010-09-07  4:07       ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  4:10         ` viresh kumar
2010-08-30 10:38 ` [PATCH 02/74] ST SPEAr: Making clock functions more generic Viresh KUMAR
2010-08-30 10:38 ` [PATCH 03/74] ST SPEAr: Formalized timer support Viresh KUMAR
2010-09-06 22:55   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-13  3:22     ` Shiraz Hashim
2010-09-13  3:37       ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-13  4:04         ` Shiraz Hashim
2010-09-13  4:37           ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-13  7:49       ` Russell King - ARM Linux
2010-08-30 10:38 ` [PATCH 04/74] ST SPEAr13XX: Adding machine specific header files Viresh KUMAR
2010-09-02  8:56   ` Russell King - ARM Linux
2010-09-03  6:57     ` Shiraz Hashim
2010-08-30 10:38 ` [PATCH 05/74] ST SPEAr13XX: Adding machine specific src files Viresh KUMAR
2010-09-02  9:04   ` Russell King - ARM Linux
2010-09-03  6:38     ` Shiraz Hashim
2010-08-30 10:38 ` [PATCH 06/74] ST SPEAr: Adding support for SPEAr13xx SoC in spear generic plat/ Viresh KUMAR
2010-08-30 10:38 ` [PATCH 07/74] ST SPEAr13XX: Added compilation support in arch/arm/ Viresh KUMAR
2010-09-02 16:27   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-06 11:52     ` viresh kumar
2010-09-07 11:35     ` viresh kumar
2010-09-07 20:56       ` Russell King - ARM Linux
2010-08-30 10:38 ` [PATCH 08/74] ST SPEAr1300: Adding default config file Viresh KUMAR
2010-09-02  8:51   ` Russell King - ARM Linux
2010-09-03  1:45     ` Nicolas Pitre
2010-09-03  7:32       ` Russell King - ARM Linux
2010-09-03  7:44         ` viresh kumar
2010-08-30 10:38 ` [PATCH 09/74] ST SPEAr: Adding information in Documentation/ and MAINTAINERS Viresh KUMAR
2010-08-30 10:38 ` [PATCH 10/74] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx Viresh KUMAR
2010-09-02  9:08   ` Russell King - ARM Linux
2010-09-06  9:43     ` viresh kumar
2010-08-30 10:38 ` [PATCH 11/74] ST SPEAr: Adding support for divisor per parent clock Viresh KUMAR
2010-08-30 10:38 ` [PATCH 12/74] ST SPEAr: Correcting SOC Config base address for spear320 Viresh KUMAR
2010-09-06 22:58   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  8:36     ` viresh kumar
2010-08-30 10:38 ` [PATCH 13/74] ST SPEAr: Update clock framework and definitions Viresh KUMAR
2010-09-06 23:09   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  3:58     ` viresh kumar
2010-09-07  4:06       ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  9:01         ` viresh kumar
2010-09-07  9:09           ` Russell King - ARM Linux
2010-09-07  9:16             ` viresh kumar
2010-08-30 10:38 ` [PATCH 14/74] ST SPEAr: Adding PLGPIO driver for spear platform Viresh KUMAR
2010-09-02  9:13   ` Russell King - ARM Linux
2010-09-03  3:44     ` viresh kumar
2010-08-30 10:38 ` [PATCH 16/74] ST SPEAr: adding support for synopsis i2c designware Viresh KUMAR
2010-09-06 23:12   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  4:02     ` viresh kumar
2010-09-07  4:12       ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  9:16         ` viresh kumar
2010-09-07  9:44           ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07 10:17             ` viresh kumar
2010-08-30 10:38 ` [PATCH 18/74] ST SPEAr: enhanced spear clock framework Viresh KUMAR
2010-08-30 10:38 ` [PATCH 19/74] ST SPEAr: Adding Debugfs support on " Viresh KUMAR
2010-08-30 10:38 ` [PATCH 20/74] Clock Framework: Adding ENABLED_ON_INIT feature in clk Viresh KUMAR
2010-08-30 10:38 ` [PATCH 22/74] ST SPEAr: Added ARM PL061 GPIO Support on SPEAr13xx and modified resource size Viresh KUMAR
2010-08-30 10:38 ` [PATCH 23/74] ST SPEAr: Adding support for ST's PWM IP Viresh KUMAR
2010-08-30 10:38 ` [PATCH 25/74] ST SPEAr: Adding support for serial nor flash in all spear platforms Viresh KUMAR
2010-08-30 10:38 ` [PATCH 26/74] ST SPEAr: Adding Watchdog support Viresh KUMAR
2010-08-30 10:38 ` [PATCH 30/74] ST SPEAr: Added PCIE host controller base driver support Viresh KUMAR
2010-08-30 10:38 ` [PATCH 31/74] ST SPEAr: Adding support for SSP PL022 Viresh KUMAR
2010-09-02  9:57   ` Russell King - ARM Linux
2010-09-03  3:50     ` viresh kumar
2010-09-02 19:18   ` Linus Walleij
2010-09-03  3:58     ` viresh kumar
2010-08-30 10:38 ` [PATCH 32/74] ST SPEAr: Adding clk_set_rate support Viresh KUMAR
2010-09-02  9:21   ` Russell King - ARM Linux
2010-09-06 10:03     ` viresh kumar
2010-08-30 10:38 ` [PATCH 33/74] ST SPEAr: Adding support for SDHCI (SDIO) Viresh KUMAR
2010-08-30 10:38 ` [PATCH 34/74] ST SPEAr: Changing resource size of amba devices to SZ_4K Viresh KUMAR
2010-08-30 10:38 ` [PATCH 35/74] ST SPEAr: Enabling clocks before amba device registeration Viresh KUMAR
2010-09-02 10:02   ` Russell King - ARM Linux
2010-09-06 11:26     ` viresh kumar
2010-08-30 10:39 ` [PATCH 36/74] ST SPEAr: Replacing SIZE macro's with actual required size Viresh KUMAR
2010-08-30 10:39 ` [PATCH 37/74] SPEAr: removing size based macros except those necessary Viresh KUMAR
2010-08-30 10:39 ` [PATCH 38/74] ST SPEAr3xx: Rearranging declarations in clock.c file Viresh KUMAR
2010-09-02 10:04   ` Russell King - ARM Linux
2010-09-03  3:52     ` viresh kumar
2010-08-30 10:39 ` [PATCH 39/74] ST SPEAr: Adding miscellaneous devices and clocks Viresh KUMAR
2010-08-30 10:39 ` [PATCH 40/74] ST SPEAr 13xx : Adding support for SPEAr1310 Viresh KUMAR
2010-09-02 10:07   ` Russell King - ARM Linux
2010-09-03  3:53     ` viresh kumar
2010-08-30 10:39 ` [PATCH 41/74] ST SPEAr : Adding CAN platform support for SPEAr320 and SPEAr1310 Viresh KUMAR
2010-08-30 10:39 ` [PATCH 42/74] ST SPEAr: Adding support for DDR in clock framework Viresh KUMAR
2010-08-30 10:39 ` [PATCH 43/74] ST SPEAr : EMI (Extrenal Memory Interface) controller driver Viresh KUMAR
2010-09-06 22:40   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07 10:51     ` viresh kumar
2010-09-07 11:38       ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07 11:54         ` viresh kumar
2010-09-07 13:32           ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-10  8:11             ` Vipin Kumar
2010-09-10  8:56               ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-10  9:06                 ` Vipin Kumar
2010-09-10  9:21                   ` Jean-Christophe PLAGNIOL-VILLARD
2010-10-01  5:42     ` Vipin Kumar
2010-08-30 10:39 ` [PATCH 44/74] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver Viresh KUMAR
2010-09-01 22:43   ` Linus Walleij
2010-08-30 10:39 ` [PATCH 45/74] SPEAr : SEV Send event to secondary CPUs Viresh KUMAR
2010-09-02 10:22   ` Russell King - ARM Linux
2010-09-02 10:40     ` Will Deacon
2010-09-02 11:07       ` Shilimkar, Santosh
2010-09-02 15:59         ` Russell King - ARM Linux
2010-09-02 13:08       ` Russell King - ARM Linux
2010-09-06  7:44     ` Shiraz Hashim
2010-08-30 10:39 ` [PATCH 46/74] SPEAr Clock Framework: Adding support for PLL frequency change Viresh KUMAR
2010-08-30 10:39 ` [PATCH 47/74] SPEAr Power Management: Added the support for Standby mode Viresh KUMAR
2010-08-30 10:39 ` [PATCH 48/74] GIC: Added dummy handlers for Power Management Suspend Resume Viresh KUMAR
2010-09-02 10:23   ` Russell King - ARM Linux
2010-09-03  6:24     ` deepaksi
2010-09-03  7:34       ` Russell King - ARM Linux
2010-09-06 11:55         ` deepaksi
2010-09-08 15:12           ` Russell King - ARM Linux
2010-09-09  4:17             ` deepaksi
2010-09-20 13:44               ` deepaksi
2010-09-20 13:48                 ` Russell King - ARM Linux
2010-09-20 14:56                   ` Rob Herring
2010-09-20 15:07                     ` Russell King - ARM Linux
2010-09-20 16:55                       ` Rob Herring
2010-09-20 18:07                         ` Russell King - ARM Linux
2010-09-30  5:33                           ` viresh kumar
2010-08-30 10:39 ` [PATCH 49/74] SPEAr CPU freq: Adding support for CPU Freq framework Viresh KUMAR
2010-09-02 10:24   ` Russell King - ARM Linux
2010-09-03  6:20     ` deepaksi
2010-08-30 10:39 ` [PATCH 51/74] ST SPEAr1310: Adding fsmc nor support Viresh KUMAR
2010-08-30 10:39 ` [PATCH 52/74] ST SPEAr13xx: Adding CPU hotplug support added for SMP platforms Viresh KUMAR
2010-09-03  6:00   ` Sundar
2010-09-30  9:37     ` Shiraz Hashim
2010-08-30 10:39 ` [PATCH 53/74] ST SPEAr13xx: add l2 cache support Viresh KUMAR
2010-08-30 10:39 ` [PATCH 54/74] ST SPEAr: SDHCI- selecting SD_MMC from misc and fixing sdhci_synth rate to 48 MHz Viresh KUMAR
2010-08-30 10:39 ` [PATCH 55/74] ST SPEAr13xx: Modified static mappings Viresh KUMAR
2010-08-30 10:39 ` [PATCH 56/74] SPEAr13xx: Adding and Updating Clock definitions Viresh KUMAR
2010-08-30 10:39 ` [PATCH 57/74] SPEAr : Pad multiplexing handling modified Viresh KUMAR
2010-08-30 10:39 ` [PATCH 58/74] SPEAr13xx : Fixed part devices in SPEAr13xx addded to the generic implementation Viresh KUMAR
2010-08-30 10:39 ` [PATCH 59/74] SPEAr : Adding SPEAr1310 pad multiplexing devices Viresh KUMAR
2010-08-30 10:39 ` [PATCH 60/74] ST SPEAr3xx: Passing pmx devices address from machine *.c files Viresh KUMAR
2010-08-30 10:39 ` [PATCH 61/74] SPEAr3xx: Make local structres static Viresh KUMAR
2010-08-30 10:39 ` [PATCH 62/74] SPEAR3xx: Rename register/irq defines to remove naming conflicts Viresh KUMAR
2010-08-30 10:39 ` [PATCH 63/74] SPEAr3xx: Rework pmx_dev code to remove conflicts Viresh KUMAR
2010-08-30 10:39 ` [PATCH 64/74] SPEAr3xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
2010-08-30 10:39 ` [PATCH 65/74] SPEAr3xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
2010-08-30 10:39 ` [PATCH 66/74] ST SPEAr: Appending spear3** with global structures Viresh KUMAR
2010-08-30 10:39 ` [PATCH 67/74] ST SPEAr3xx: Updating plgpio and emi source to make it compliant with single image strategy Viresh KUMAR
2010-08-30 10:39 ` [PATCH 68/74] SPEAr6xx: Rework Kconfig for single image solution Viresh KUMAR
2010-08-30 10:39 ` [PATCH 69/74] ST SPEAR6xx: renaming spear600_defconfig as spear6xx_defconfig Viresh KUMAR
2010-08-30 10:39 ` [PATCH 70/74] SPEAr13XX: Update register/macros/devices/routine names and pmx dev registration to implement single image for multiple boards Viresh KUMAR
2010-08-30 10:39 ` [PATCH 71/74] SPEAr13xx: Rework KConfig to allow all boards to be compiled in Viresh KUMAR
2010-08-30 10:39 ` [PATCH 72/74] SPEAr13xx: Replace defconfigs with single unfied defconfig Viresh KUMAR
2010-09-02 15:40   ` Russell King - ARM Linux
2010-09-03  3:56     ` viresh kumar
2010-09-07  9:18     ` viresh kumar
2010-08-30 10:39 ` [PATCH 73/74] ST SPEAr: Updating defconfigs Viresh KUMAR
2010-08-30 10:39 ` [PATCH 74/74] ST SPEAr: Enabling devices in various evb.c files Viresh KUMAR
2010-08-30 10:41 ` [PATCH 15/74] ST SPEAr: adding support for rtc Viresh KUMAR
2010-09-01  1:22   ` [rtc-linux] " Wan ZongShun
2010-09-01  3:44     ` viresh kumar
2010-09-06 19:09   ` Alessandro Zummo
2010-09-07  3:30     ` rajeev
2010-09-07 10:13     ` viresh kumar
2010-09-06 22:45   ` Jean-Christophe PLAGNIOL-VILLARD
2010-09-07  8:35     ` viresh kumar
2010-08-30 10:42 ` [PATCH 17/74] ST SPEAr: Adding USB Host support Viresh KUMAR
2010-08-30 14:10   ` Alan Stern
2010-09-01  3:55     ` viresh kumar
2010-08-30 10:43 ` [PATCH 21/74] ST SPEAr : Added keyboard support Viresh KUMAR
2010-08-30 10:43   ` Viresh KUMAR
2010-08-30 16:48   ` Dmitry Torokhov
2010-08-30 16:48     ` Dmitry Torokhov
2010-09-01  5:23     ` rajeev
2010-09-01  5:23       ` rajeev
2010-09-01  5:41       ` rajeev
2010-09-01  5:41         ` rajeev
2010-09-01  6:31       ` Dmitry Torokhov
2010-09-01  6:31         ` Dmitry Torokhov
2010-09-01  7:01         ` viresh kumar
2010-09-01  7:01           ` viresh kumar
2010-08-30 10:43 ` [PATCH 24/74] ST SPEAr: Add smi driver for serial NOR flash Viresh KUMAR
2010-08-30 10:43   ` Viresh KUMAR
2010-08-30 10:43 ` [PATCH 27/74] ST SPEAr : NAND interface driver for spear platforms Viresh KUMAR
2010-08-30 10:43   ` Viresh KUMAR
2010-09-01 22:36   ` Linus Walleij
2010-09-01 22:36     ` Linus Walleij
2010-09-02  8:09     ` Armando Visconti
2010-09-02  8:09       ` Armando Visconti
2010-09-02  8:52       ` Armando Visconti
2010-09-02  8:52         ` Armando Visconti
2010-09-02 11:15       ` Linus Walleij
2010-09-02 11:15         ` Linus Walleij
2010-09-02 12:33         ` Armando Visconti
2010-09-02 12:33           ` Armando Visconti
2010-09-03 11:23         ` Alessandro Rubini
2010-09-03 11:23           ` Alessandro Rubini
2010-09-03 17:26           ` Linus Walleij
2010-09-03 17:26             ` Linus Walleij
2010-09-06  7:25             ` Armando Visconti
2010-09-06  7:25               ` Armando Visconti
2010-09-10  4:21             ` viresh kumar
2010-09-10  4:21               ` viresh kumar
2010-09-10  8:38               ` Linus Walleij
2010-09-10  8:38                 ` Linus Walleij
2010-09-03  7:11       ` Vipin Kumar
2010-09-03  7:11         ` Vipin Kumar
2010-09-03 11:22         ` Sebastian RASMUSSEN
2010-09-03 11:22           ` Sebastian RASMUSSEN
2010-08-30 10:43 ` [PATCH 28/74] Incrementing the ecc_pos array to contain 128 char Viresh KUMAR
2010-08-30 10:43   ` Viresh KUMAR
2010-08-30 12:14   ` Artem Bityutskiy
2010-08-30 12:14     ` Artem Bityutskiy
2010-08-31  6:34     ` Vipin Kumar
2010-08-31  6:34       ` Vipin Kumar
2010-08-31 23:36       ` Artem Bityutskiy
2010-08-31 23:36         ` Artem Bityutskiy
2010-09-01  4:13         ` Vipin Kumar
2010-09-01  4:13           ` Vipin Kumar
2010-09-01 10:45           ` Artem Bityutskiy
2010-09-01 10:45             ` Artem Bityutskiy
2010-09-01 11:04             ` Vipin Kumar
2010-09-01 11:04               ` Vipin Kumar
2010-09-01 21:23               ` Ryan Mallon
2010-09-01 21:23                 ` Ryan Mallon
2010-09-01 21:54                 ` Kevin Cernekee
2010-09-01 21:54                   ` Kevin Cernekee
2010-09-01 22:21                   ` Ryan Mallon
2010-09-01 22:21                     ` Ryan Mallon
2010-09-01 22:53                     ` Artem Bityutskiy
2010-09-01 22:53                       ` Artem Bityutskiy
2010-09-01 23:37                       ` Ryan Mallon
2010-09-01 23:37                         ` Ryan Mallon
2010-09-01 23:43                         ` Ryan Mallon
2010-09-01 23:43                           ` Ryan Mallon
2010-09-02  6:33                     ` Brian Norris
2010-09-02  6:33                       ` Brian Norris
2010-09-02  9:49                       ` Artem Bityutskiy
2010-09-02  9:49                         ` Artem Bityutskiy
2010-09-01 23:23               ` Artem Bityutskiy
2010-09-01 23:23                 ` Artem Bityutskiy
2010-08-30 10:43 ` [PATCH 29/74] Newly erased page read workaround Viresh KUMAR
2010-08-30 10:43   ` Viresh KUMAR
2010-08-30 10:44 ` [PATCH 50/74] ST SPEAr: PCIE gadget suppport Viresh KUMAR
2010-08-30 10:44   ` Viresh KUMAR
2010-09-21 11:32 ` [PATCH 00/74] Updating SPEAr Support Matthias Fuchs
2010-09-21 11:50   ` viresh kumar

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