All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx
@ 2010-11-12  7:17 Haojian Zhuang
  2010-11-12  7:17 ` [PATCH 02/11] ARM: pxa: redefine irqs.h Haojian Zhuang
  2010-11-12  8:00 ` [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Eric Miao
  0 siblings, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

PXA300/PXA310/PXA320/PXA930/PXA935 are sharing one cpu family id.
It's a little confusion on cpu_is_pxa3xx().

Now reduce the scope of cpu_is_pxa3xx(). Make it focusing on
PXA300/PXA310/PXA320. PXA930/PXA935 is coverd by cpu_is_pxa93x().

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-pxa/include/mach/hardware.h |   26 +++++++++-----------------
 1 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index ca188cd..59f145a 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -145,53 +145,44 @@
 #define __cpu_is_pxa27x(id)	(0)
 #endif
 
-#ifdef CONFIG_CPU_PXA300
+#ifdef CONFIG_PXA3xx
 #define __cpu_is_pxa300(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x688;				\
 	 })
-#else
-#define __cpu_is_pxa300(id)	(0)
-#endif
 
-#ifdef CONFIG_CPU_PXA310
 #define __cpu_is_pxa310(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x689;				\
 	 })
-#else
-#define __cpu_is_pxa310(id)	(0)
-#endif
 
-#ifdef CONFIG_CPU_PXA320
 #define __cpu_is_pxa320(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x603 || _id == 0x682;		\
 	 })
 #else
+#define __cpu_is_pxa300(id)	(0)
+#define __cpu_is_pxa310(id)	(0)
 #define __cpu_is_pxa320(id)	(0)
 #endif
 
-#ifdef CONFIG_CPU_PXA930
+#ifdef CONFIG_PXA93x
 #define __cpu_is_pxa930(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x683;				\
 	 })
-#else
-#define __cpu_is_pxa930(id)	(0)
-#endif
 
-#ifdef CONFIG_CPU_PXA935
 #define __cpu_is_pxa935(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x693;				\
 	 })
 #else
+#define __cpu_is_pxa930(id)	(0)
 #define __cpu_is_pxa935(id)	(0)
 #endif
 
@@ -264,7 +255,7 @@
 /*
  * CPUID Core Generation Bit
  * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
- * == 0x3 for pxa300/pxa310/pxa320
+ * == 0x3 for pxa300/pxa310/pxa320 and pxa930/pxa935
  */
 #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
 #define __cpu_is_pxa2xx(id)				\
@@ -279,8 +270,9 @@
 #ifdef CONFIG_PXA3xx
 #define __cpu_is_pxa3xx(id)				\
 	({						\
-		unsigned int _id = (id) >> 13 & 0x7;	\
-		_id == 0x3;				\
+		__cpu_is_pxa300(id)			\
+			|| __cpu_is_pxa310(id)		\
+			|| __cpu_is_pxa320(id);		\
 	 })
 #else
 #define __cpu_is_pxa3xx(id)	(0)
-- 
1.5.6.5

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

* [PATCH 02/11] ARM: pxa: redefine irqs.h
  2010-11-12  7:17 [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
@ 2010-11-12  7:17 ` Haojian Zhuang
  2010-11-12  7:17   ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Haojian Zhuang
  2010-11-12  8:02   ` [PATCH 02/11] ARM: pxa: redefine irqs.h Eric Miao
  2010-11-12  8:00 ` [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Eric Miao
  1 sibling, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

A lot of componets of PXA93x are shared with PXA3xx. From CPUID, they belong
to same family. But it's confustion that code of PXA93x is depend on PXA3xx
by default.

Now clean the scope of both PXA3xx and PXA93X. Only PXA300/PXA310/PXA320 is
family member of PXA3xx. Only PXA930/PXA935 is family member of PXA93x. Remove
the code dependany on IRQ definition.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-pxa/include/mach/irqs.h |   47 ++++++++++-----------------------
 arch/arm/mach-pxa/irq.c               |   11 +++++--
 2 files changed, 22 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index d372caa..cb7ee26 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -21,16 +21,14 @@
 
 #define PXA_IRQ(x)	(PXA_ISA_IRQ_NUM + (x))
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define IRQ_SSP3	PXA_IRQ(0)	/* SSP3 service request */
 #define IRQ_MSL		PXA_IRQ(1)	/* MSL Interface interrupt */
-#define IRQ_USBH2	PXA_IRQ(2)	/* USB Host interrupt 1 (OHCI) */
-#define IRQ_USBH1	PXA_IRQ(3)	/* USB Host interrupt 2 (non-OHCI) */
+#define IRQ_USBH2	PXA_IRQ(2)	/* USB Host interrupt 1 (OHCI,PXA27x) */
+#define IRQ_USBH1	PXA_IRQ(3)	/* USB Host interrupt 2 (non-OHCI,PXA27x) */
 #define IRQ_KEYPAD	PXA_IRQ(4)	/* Key pad controller */
-#define IRQ_MEMSTK	PXA_IRQ(5)	/* Memory Stick interrupt */
+#define IRQ_MEMSTK	PXA_IRQ(5)	/* Memory Stick interrupt (PXA27x) */
+#define IRQ_ACIPC0	PXA_IRQ(5)	/* AP-CP Communication (PXA930) */
 #define IRQ_PWRI2C	PXA_IRQ(6)	/* Power I2C interrupt */
-#endif
-
 #define IRQ_HWUART	PXA_IRQ(7)	/* HWUART Transmit/Receive/Error (PXA26x) */
 #define IRQ_OST_4_11	PXA_IRQ(7)	/* OS timer 4-11 matches (PXA27x) */
 #define	IRQ_GPIO0	PXA_IRQ(8)	/* GPIO0 Edge Detect */
@@ -38,7 +36,8 @@
 #define	IRQ_GPIO_2_x	PXA_IRQ(10)	/* GPIO[2-x] Edge Detect */
 #define	IRQ_USB		PXA_IRQ(11)	/* USB Service */
 #define	IRQ_PMU		PXA_IRQ(12)	/* Performance Monitoring Unit */
-#define	IRQ_I2S		PXA_IRQ(13)	/* I2S Interrupt */
+#define	IRQ_I2S		PXA_IRQ(13)	/* I2S Interrupt (PXA27x) */
+#define IRQ_SSP4	PXA_IRQ(13)	/* SSP4 service request (PXA3xx) */
 #define	IRQ_AC97	PXA_IRQ(14)	/* AC97 Interrupt */
 #define IRQ_ASSP	PXA_IRQ(15)	/* Audio SSP Service Request (PXA25x) */
 #define IRQ_USIM	PXA_IRQ(15)     /* Smart Card interface interrupt (PXA27x) */
@@ -47,6 +46,7 @@
 #define	IRQ_LCD		PXA_IRQ(17)	/* LCD Controller Service Request */
 #define	IRQ_I2C		PXA_IRQ(18)	/* I2C Service Request */
 #define	IRQ_ICP		PXA_IRQ(19)	/* ICP Transmit/Receive/Error */
+#define IRQ_ACIPC2	PXA_IRQ(19)	/* AP-CP Communication (PXA930) */
 #define	IRQ_STUART	PXA_IRQ(20)	/* STUART Transmit/Receive/Error */
 #define	IRQ_BTUART	PXA_IRQ(21)	/* BTUART Transmit/Receive/Error */
 #define	IRQ_FFUART	PXA_IRQ(22)	/* FFUART Transmit/Receive/Error*/
@@ -60,19 +60,17 @@
 #define	IRQ_RTC1Hz	PXA_IRQ(30)	/* RTC HZ Clock Tick */
 #define	IRQ_RTCAlrm	PXA_IRQ(31)	/* RTC Alarm */
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define IRQ_TPM		PXA_IRQ(32)	/* TPM interrupt */
 #define IRQ_CAMERA	PXA_IRQ(33)	/* Camera Interface */
-#endif
-
-#ifdef CONFIG_PXA3xx
-#define IRQ_SSP4	PXA_IRQ(13)	/* SSP4 service request */
 #define IRQ_CIR		PXA_IRQ(34)	/* Consumer IR */
 #define IRQ_COMM_WDT	PXA_IRQ(35) 	/* Comm WDT interrupt */
 #define IRQ_TSI		PXA_IRQ(36)	/* Touch Screen Interface (PXA320) */
+#define IRQ_ENHROT	PXA_IRQ(37)	/* Enhanced Rotary (PXA930) */
 #define IRQ_USIM2	PXA_IRQ(38)	/* USIM2 Controller */
-#define IRQ_GCU		PXA_IRQ(39)	/* Graphics Controller */
+#define IRQ_GCU		PXA_IRQ(39)	/* Graphics Controller (PXA3xx) */
+#define IRQ_ACIPC1	PXA_IRQ(40)	/* AP-CP Communication (PXA930) */
 #define IRQ_MMC2	PXA_IRQ(41)	/* MMC2 Controller */
+#define IRQ_TRKBALL	PXA_IRQ(43)	/* Track Ball (PXA930) */
 #define IRQ_1WIRE	PXA_IRQ(44)	/* 1-Wire Controller */
 #define IRQ_NAND	PXA_IRQ(45)	/* NAND Controller */
 #define IRQ_USB2	PXA_IRQ(46)	/* USB 2.0 Device Controller */
@@ -80,30 +78,13 @@
 #define IRQ_WAKEUP1	PXA_IRQ(50)	/* EXT_WAKEUP1 */
 #define IRQ_DMEMC	PXA_IRQ(51)	/* Dynamic Memory Controller */
 #define IRQ_MMC3	PXA_IRQ(55)	/* MMC3 Controller (PXA310) */
-#endif
 
-#ifdef CONFIG_CPU_PXA935
 #define IRQ_U2O		PXA_IRQ(64)	/* USB OTG 2.0 Controller (PXA935) */
 #define IRQ_U2H		PXA_IRQ(65)	/* USB Host 2.0 Controller (PXA935) */
-
-#define IRQ_MMC3_PXA935	PXA_IRQ(72)	/* MMC3 Controller (PXA935) */
-#define IRQ_MMC4_PXA935	PXA_IRQ(73)	/* MMC4 Controller (PXA935) */
-#define IRQ_MMC5_PXA935	PXA_IRQ(74)	/* MMC5 Controller (PXA935) */
-
+#define IRQ_PXA935_MMC0	PXA_IRQ(72)	/* MMC0 Controller (PXA935) */
+#define IRQ_PXA935_MMC1	PXA_IRQ(73)	/* MMC1 Controller (PXA935) */
+#define IRQ_PXA935_MMC2	PXA_IRQ(74)	/* MMC2 Controller (PXA935) */
 #define IRQ_U2P		PXA_IRQ(93)	/* USB PHY D+/D- Lines (PXA935) */
-#endif
-
-#ifdef CONFIG_CPU_PXA930
-#define IRQ_ENHROT	PXA_IRQ(37)	/* Enhanced Rotary (PXA930) */
-#define IRQ_ACIPC0	PXA_IRQ(5)
-#define IRQ_ACIPC1	PXA_IRQ(40)
-#define IRQ_ACIPC2	PXA_IRQ(19)
-#define IRQ_TRKBALL	PXA_IRQ(43)	/* Track Ball */
-#endif
-
-#ifdef CONFIG_CPU_PXA950
-#define IRQ_GC500	PXA_IRQ(70)	/* Graphics Controller (PXA950) */
-#endif
 
 #define PXA_GPIO_IRQ_BASE	PXA_IRQ(96)
 #define PXA_GPIO_IRQ_NUM	(192)
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 1beb40f..b5cafe2 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -37,6 +37,11 @@
 
 static int pxa_internal_irq_nr;
 
+static inline int cpu_has_ipr(void)
+{
+	return !cpu_is_pxa25x();
+}
+
 static void pxa_mask_irq(unsigned int irq)
 {
 	_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
@@ -134,7 +139,7 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 	}
 
 	/* initialize interrupt priority */
-	if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+	if (cpu_has_ipr()) {
 		for (i = 0; i < irq_nr; i++)
 			IPR(i) = i | (1 << 31);
 	}
@@ -165,7 +170,7 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 		_ICMR(irq) = 0;
 	}
 
-	if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+	if (cpu_has_ipr()) {
 		for (i = 0; i < pxa_internal_irq_nr; i++)
 			saved_ipr[i] = IPR(i);
 	}
@@ -177,7 +182,7 @@ static int pxa_irq_resume(struct sys_device *dev)
 {
 	int i, irq = PXA_IRQ(0);
 
-	if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+	if (cpu_has_ipr()) {
 		for (i = 0; i < pxa_internal_irq_nr; i++)
 			IPR(i) = saved_ipr[i];
 	}
-- 
1.5.6.5

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

* [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx
  2010-11-12  7:17 ` [PATCH 02/11] ARM: pxa: redefine irqs.h Haojian Zhuang
@ 2010-11-12  7:17   ` Haojian Zhuang
  2010-11-12  7:17     ` [PATCH 04/11] ARM: pxa: update to read ICHP Haojian Zhuang
  2010-11-12  8:07     ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Eric Miao
  2010-11-12  8:02   ` [PATCH 02/11] ARM: pxa: redefine irqs.h Eric Miao
  1 sibling, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

In order to avoid confusion, seperate pxa93x from pxa3xx.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-pxa/Kconfig            |   18 +-
 arch/arm/mach-pxa/Makefile           |    2 +-
 arch/arm/mach-pxa/clock.h            |   20 ++
 arch/arm/mach-pxa/devices.c          |   10 +-
 arch/arm/mach-pxa/generic.c          |    8 +-
 arch/arm/mach-pxa/generic.h          |    3 +-
 arch/arm/mach-pxa/mfp-pxa3xx.c       |    5 +-
 arch/arm/mach-pxa/pxa3xx.c           |    9 -
 arch/arm/mach-pxa/pxa930.c           |  206 ---------------
 arch/arm/mach-pxa/pxa93x.c           |  471 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-pxa/saar.c             |    2 +-
 arch/arm/mach-pxa/smemc.c            |   10 +-
 arch/arm/mach-pxa/tavorevb.c         |    2 +-
 arch/arm/plat-pxa/Makefile           |    1 +
 arch/arm/plat-pxa/include/plat/mfp.h |    4 +-
 15 files changed, 525 insertions(+), 246 deletions(-)
 delete mode 100644 arch/arm/mach-pxa/pxa930.c
 create mode 100644 arch/arm/mach-pxa/pxa93x.c

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index dd235ec..84123d4 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -37,18 +37,18 @@ config MACH_LITTLETON
 	select CPU_PXA310
 
 config MACH_TAVOREVB
-	bool "PXA930 Evaluation Board (aka TavorEVB)"
-	select PXA3xx
+	bool "PXA935 Evaluation Board (aka TavorEVB)"
 	select CPU_PXA930
+	select CPU_PXA935
 
 config MACH_TAVOREVB3
 	bool "PXA95x Development Platform (aka TavorEVB III)"
 	select CPU_PXA950
 
 config MACH_SAAR
-	bool "PXA930 Handheld Platform (aka SAAR)"
-	select PXA3xx
+	bool "PXA935 Handheld Platform (aka SAAR)"
 	select CPU_PXA930
+	select CPU_PXA935
 
 comment "Third Party Dev Platforms (sorted by vendor name)"
 
@@ -639,15 +639,21 @@ config CPU_PXA320
 	help
 	  PXA320 (codename Monahans-P)
 
+config PXA93x
+	bool
+	select CPU_XSC3
+	help
+	  Select code specific to PXA93x variants
+
 config CPU_PXA930
 	bool
-	select PXA3xx
+	select PXA93x
 	help
 	  PXA930 (codename Tavor-P)
 
 config CPU_PXA935
 	bool
-	select CPU_PXA930
+	select PXA93x
 	help
 	  PXA935 (codename Tavor-P65)
 
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index e2f89c2..ebdb899 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -19,9 +19,9 @@ endif
 obj-$(CONFIG_PXA25x)		+= mfp-pxa2xx.o pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)		+= mfp-pxa2xx.o pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)		+= mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
+obj-$(CONFIG_PXA93x)		+= mfp-pxa3xx.o pxa93x.o smemc.o
 obj-$(CONFIG_CPU_PXA300)	+= pxa300.o
 obj-$(CONFIG_CPU_PXA320)	+= pxa320.o
-obj-$(CONFIG_CPU_PXA930)	+= pxa930.o
 
 # NOTE: keep the order of boards in accordance to their order in Kconfig
 
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index d848874..0d824eb 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -67,3 +67,23 @@ extern void clk_pxa3xx_cken_enable(struct clk *);
 extern void clk_pxa3xx_cken_disable(struct clk *);
 #endif
 
+#ifdef CONFIG_PXA93x
+#define DEFINE_PXA93_CKEN(_name, _cken, _rate, _delay)	\
+struct clk clk_##_name = {				\
+		.ops	= &clk_pxa93x_cken_ops,		\
+		.rate	= _rate,			\
+		.cken	= CKEN_##_cken,			\
+		.delay	= _delay,			\
+	}
+
+#define DEFINE_PXA93_CK(_name, _cken, _ops)		\
+struct clk clk_##_name = {				\
+		.ops	= _ops,				\
+		.cken	= CKEN_##_cken,			\
+	}
+
+extern const struct clkops clk_pxa93x_cken_ops;
+extern void clk_pxa93x_cken_enable(struct clk *);
+extern void clk_pxa93x_cken_disable(struct clk *);
+#endif
+
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index aaa1166..881ccc3 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -342,7 +342,7 @@ struct platform_device pxa27x_device_i2c_power = {
 };
 #endif
 
-#ifdef CONFIG_PXA3xx
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
 static struct resource pxa3xx_resources_i2c_power[] = {
 	{
 		.start  = 0x40f500c0,
@@ -632,7 +632,7 @@ struct platform_device pxa25x_device_assp = {
 };
 #endif /* CONFIG_PXA25x */
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
 
 static struct resource pxa27x_resource_keypad[] = {
 	[0] = {
@@ -864,9 +864,9 @@ void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
 {
 	pxa_register_device(&pxa27x_device_camera, info);
 }
-#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA93x */
 
-#ifdef CONFIG_PXA3xx
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
 static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
 
 static struct resource pxa3xx_resource_ssp4[] = {
@@ -1053,7 +1053,7 @@ struct platform_device pxa3xx_device_gcu = {
 	},
 };
 
-#endif /* CONFIG_PXA3xx */
+#endif /* CONFIG_PXA3xx || CONFIG_PXA93x */
 
 /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
  * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index d4ce8f9..84e2cc3 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -29,6 +29,7 @@
 #include <mach/reset.h>
 #include <mach/gpio.h>
 #include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
 
 #include "generic.h"
 
@@ -36,9 +37,10 @@ void clear_reset_status(unsigned int mask)
 {
 	if (cpu_is_pxa2xx())
 		pxa2xx_clear_reset_status(mask);
-
-	if (cpu_is_pxa3xx())
-		pxa3xx_clear_reset_status(mask);
+	else {
+		/* RESET_STATUS_* has a 1:1 mapping with ARSR */
+		ARSR = mask;
+	}
 }
 
 unsigned long get_clock_tick_rate(void)
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index d2e8bc3..7dec811 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -20,6 +20,7 @@ extern void __init pxa26x_init_irq(void);
 #endif
 extern void __init pxa27x_init_irq(void);
 extern void __init pxa3xx_init_irq(void);
+extern void __init pxa93x_init_irq(void);
 
 extern void __init pxa_map_io(void);
 extern void __init pxa25x_map_io(void);
@@ -58,10 +59,8 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
 
 #ifdef CONFIG_PXA3xx
 extern unsigned pxa3xx_get_clk_frequency_khz(int);
-extern void pxa3xx_clear_reset_status(unsigned int);
 #else
 #define pxa3xx_get_clk_frequency_khz(x)		(0)
-static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
 #endif
 
 extern struct sysdev_class pxa_irq_sysclass;
diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c
index 7a270ee..1bb58a3 100644
--- a/arch/arm/mach-pxa/mfp-pxa3xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa3xx.c
@@ -62,9 +62,6 @@ struct sysdev_class pxa3xx_mfp_sysclass = {
 
 static int __init mfp_init_devicefs(void)
 {
-	if (cpu_is_pxa3xx())
-		return sysdev_class_register(&pxa3xx_mfp_sysclass);
-
-	return 0;
+	return sysdev_class_register(&pxa3xx_mfp_sysclass);
 }
 postcore_initcall(mfp_init_devicefs);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index dc658ad..8957466 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -50,9 +50,6 @@
 #define PECR_IE(n)	((1 << ((n) * 2)) << 28)
 #define PECR_IS(n)	((1 << ((n) * 2)) << 29)
 
-/* crystal frequency to static memory controller multiplier (SMCFS) */
-static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
-
 /* crystal frequency to HSIO bus frequency multiplier (HSS) */
 static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
 
@@ -100,12 +97,6 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
 	return CLK / 1000;
 }
 
-void pxa3xx_clear_reset_status(unsigned int mask)
-{
-	/* RESET_STATUS_* has a 1:1 mapping with ARSR */
-	ARSR = mask;
-}
-
 /*
  * Return the current AC97 clock frequency.
  */
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
deleted file mode 100644
index 7d29dd3..0000000
--- a/arch/arm/mach-pxa/pxa930.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/pxa930.c
- *
- * Code specific to PXA930
- *
- * Copyright (C) 2007-2008 Marvell Internation Ltd.
- *
- * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/pxa930.h>
-
-static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
-
-	MFP_ADDR(GPIO0, 0x02e0),
-	MFP_ADDR(GPIO1, 0x02dc),
-	MFP_ADDR(GPIO2, 0x02e8),
-	MFP_ADDR(GPIO3, 0x02d8),
-	MFP_ADDR(GPIO4, 0x02e4),
-	MFP_ADDR(GPIO5, 0x02ec),
-	MFP_ADDR(GPIO6, 0x02f8),
-	MFP_ADDR(GPIO7, 0x02fc),
-	MFP_ADDR(GPIO8, 0x0300),
-	MFP_ADDR(GPIO9, 0x02d4),
-	MFP_ADDR(GPIO10, 0x02f4),
-	MFP_ADDR(GPIO11, 0x02f0),
-	MFP_ADDR(GPIO12, 0x0304),
-	MFP_ADDR(GPIO13, 0x0310),
-	MFP_ADDR(GPIO14, 0x0308),
-	MFP_ADDR(GPIO15, 0x030c),
-	MFP_ADDR(GPIO16, 0x04e8),
-	MFP_ADDR(GPIO17, 0x04f4),
-	MFP_ADDR(GPIO18, 0x04f8),
-	MFP_ADDR(GPIO19, 0x04fc),
-	MFP_ADDR(GPIO20, 0x0518),
-	MFP_ADDR(GPIO21, 0x051c),
-	MFP_ADDR(GPIO22, 0x04ec),
-	MFP_ADDR(GPIO23, 0x0500),
-	MFP_ADDR(GPIO24, 0x04f0),
-	MFP_ADDR(GPIO25, 0x0504),
-	MFP_ADDR(GPIO26, 0x0510),
-	MFP_ADDR(GPIO27, 0x0514),
-	MFP_ADDR(GPIO28, 0x0520),
-	MFP_ADDR(GPIO29, 0x0600),
-	MFP_ADDR(GPIO30, 0x0618),
-	MFP_ADDR(GPIO31, 0x0610),
-	MFP_ADDR(GPIO32, 0x060c),
-	MFP_ADDR(GPIO33, 0x061c),
-	MFP_ADDR(GPIO34, 0x0620),
-	MFP_ADDR(GPIO35, 0x0628),
-	MFP_ADDR(GPIO36, 0x062c),
-	MFP_ADDR(GPIO37, 0x0630),
-	MFP_ADDR(GPIO38, 0x0634),
-	MFP_ADDR(GPIO39, 0x0638),
-	MFP_ADDR(GPIO40, 0x063c),
-	MFP_ADDR(GPIO41, 0x0614),
-	MFP_ADDR(GPIO42, 0x0624),
-	MFP_ADDR(GPIO43, 0x0608),
-	MFP_ADDR(GPIO44, 0x0604),
-	MFP_ADDR(GPIO45, 0x050c),
-	MFP_ADDR(GPIO46, 0x0508),
-	MFP_ADDR(GPIO47, 0x02bc),
-	MFP_ADDR(GPIO48, 0x02b4),
-	MFP_ADDR(GPIO49, 0x02b8),
-	MFP_ADDR(GPIO50, 0x02c8),
-	MFP_ADDR(GPIO51, 0x02c0),
-	MFP_ADDR(GPIO52, 0x02c4),
-	MFP_ADDR(GPIO53, 0x02d0),
-	MFP_ADDR(GPIO54, 0x02cc),
-	MFP_ADDR(GPIO55, 0x029c),
-	MFP_ADDR(GPIO56, 0x02a0),
-	MFP_ADDR(GPIO57, 0x0294),
-	MFP_ADDR(GPIO58, 0x0298),
-	MFP_ADDR(GPIO59, 0x02a4),
-	MFP_ADDR(GPIO60, 0x02a8),
-	MFP_ADDR(GPIO61, 0x02b0),
-	MFP_ADDR(GPIO62, 0x02ac),
-	MFP_ADDR(GPIO63, 0x0640),
-	MFP_ADDR(GPIO64, 0x065c),
-	MFP_ADDR(GPIO65, 0x0648),
-	MFP_ADDR(GPIO66, 0x0644),
-	MFP_ADDR(GPIO67, 0x0674),
-	MFP_ADDR(GPIO68, 0x0658),
-	MFP_ADDR(GPIO69, 0x0654),
-	MFP_ADDR(GPIO70, 0x0660),
-	MFP_ADDR(GPIO71, 0x0668),
-	MFP_ADDR(GPIO72, 0x0664),
-	MFP_ADDR(GPIO73, 0x0650),
-	MFP_ADDR(GPIO74, 0x066c),
-	MFP_ADDR(GPIO75, 0x064c),
-	MFP_ADDR(GPIO76, 0x0670),
-	MFP_ADDR(GPIO77, 0x0678),
-	MFP_ADDR(GPIO78, 0x067c),
-	MFP_ADDR(GPIO79, 0x0694),
-	MFP_ADDR(GPIO80, 0x069c),
-	MFP_ADDR(GPIO81, 0x06a0),
-	MFP_ADDR(GPIO82, 0x06a4),
-	MFP_ADDR(GPIO83, 0x0698),
-	MFP_ADDR(GPIO84, 0x06bc),
-	MFP_ADDR(GPIO85, 0x06b4),
-	MFP_ADDR(GPIO86, 0x06b0),
-	MFP_ADDR(GPIO87, 0x06c0),
-	MFP_ADDR(GPIO88, 0x06c4),
-	MFP_ADDR(GPIO89, 0x06ac),
-	MFP_ADDR(GPIO90, 0x0680),
-	MFP_ADDR(GPIO91, 0x0684),
-	MFP_ADDR(GPIO92, 0x0688),
-	MFP_ADDR(GPIO93, 0x0690),
-	MFP_ADDR(GPIO94, 0x068c),
-	MFP_ADDR(GPIO95, 0x06a8),
-	MFP_ADDR(GPIO96, 0x06b8),
-	MFP_ADDR(GPIO97, 0x0410),
-	MFP_ADDR(GPIO98, 0x0418),
-	MFP_ADDR(GPIO99, 0x041c),
-	MFP_ADDR(GPIO100, 0x0414),
-	MFP_ADDR(GPIO101, 0x0408),
-	MFP_ADDR(GPIO102, 0x0324),
-	MFP_ADDR(GPIO103, 0x040c),
-	MFP_ADDR(GPIO104, 0x0400),
-	MFP_ADDR(GPIO105, 0x0328),
-	MFP_ADDR(GPIO106, 0x0404),
-
-	MFP_ADDR(nXCVREN, 0x0204),
-	MFP_ADDR(DF_CLE_nOE, 0x020c),
-	MFP_ADDR(DF_nADV1_ALE, 0x0218),
-	MFP_ADDR(DF_SCLK_E, 0x0214),
-	MFP_ADDR(DF_SCLK_S, 0x0210),
-	MFP_ADDR(nBE0, 0x021c),
-	MFP_ADDR(nBE1, 0x0220),
-	MFP_ADDR(DF_nADV2_ALE, 0x0224),
-	MFP_ADDR(DF_INT_RnB, 0x0228),
-	MFP_ADDR(DF_nCS0, 0x022c),
-	MFP_ADDR(DF_nCS1, 0x0230),
-	MFP_ADDR(nLUA, 0x0254),
-	MFP_ADDR(nLLA, 0x0258),
-	MFP_ADDR(DF_nWE, 0x0234),
-	MFP_ADDR(DF_nRE_nOE, 0x0238),
-	MFP_ADDR(DF_ADDR0, 0x024c),
-	MFP_ADDR(DF_ADDR1, 0x0250),
-	MFP_ADDR(DF_ADDR2, 0x025c),
-	MFP_ADDR(DF_ADDR3, 0x0260),
-	MFP_ADDR(DF_IO0, 0x023c),
-	MFP_ADDR(DF_IO1, 0x0240),
-	MFP_ADDR(DF_IO2, 0x0244),
-	MFP_ADDR(DF_IO3, 0x0248),
-	MFP_ADDR(DF_IO4, 0x0264),
-	MFP_ADDR(DF_IO5, 0x0268),
-	MFP_ADDR(DF_IO6, 0x026c),
-	MFP_ADDR(DF_IO7, 0x0270),
-	MFP_ADDR(DF_IO8, 0x0274),
-	MFP_ADDR(DF_IO9, 0x0278),
-	MFP_ADDR(DF_IO10, 0x027c),
-	MFP_ADDR(DF_IO11, 0x0280),
-	MFP_ADDR(DF_IO12, 0x0284),
-	MFP_ADDR(DF_IO13, 0x0288),
-	MFP_ADDR(DF_IO14, 0x028c),
-	MFP_ADDR(DF_IO15, 0x0290),
-
-	MFP_ADDR(GSIM_UIO, 0x0314),
-	MFP_ADDR(GSIM_UCLK, 0x0318),
-	MFP_ADDR(GSIM_UDET, 0x031c),
-	MFP_ADDR(GSIM_nURST, 0x0320),
-
-	MFP_ADDR(PMIC_INT, 0x06c8),
-
-	MFP_ADDR(RDY, 0x0200),
-
-	MFP_ADDR_END,
-};
-
-static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
-	MFP_ADDR(GPIO159, 0x0524),
-	MFP_ADDR(GPIO163, 0x0534),
-	MFP_ADDR(GPIO167, 0x0544),
-	MFP_ADDR(GPIO168, 0x0548),
-	MFP_ADDR(GPIO169, 0x054c),
-	MFP_ADDR(GPIO170, 0x0550),
-	MFP_ADDR(GPIO171, 0x0554),
-	MFP_ADDR(GPIO172, 0x0558),
-	MFP_ADDR(GPIO173, 0x055c),
-
-	MFP_ADDR_END,
-};
-
-static int __init pxa930_init(void)
-{
-	if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
-		mfp_init_base(io_p2v(MFPR_BASE));
-		mfp_init_addr(pxa930_mfp_addr_map);
-	}
-
-	if (cpu_is_pxa935())
-		mfp_init_addr(pxa935_mfp_addr_map);
-
-	return 0;
-}
-
-core_initcall(pxa930_init);
diff --git a/arch/arm/mach-pxa/pxa93x.c b/arch/arm/mach-pxa/pxa93x.c
new file mode 100644
index 0000000..dc7fa9f
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa93x.c
@@ -0,0 +1,471 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa93x.c
+ *
+ * code specific to pxa93x aka Tavor
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ *
+ * 2007-09-02: eric miao <eric.miao@marvell.com>
+ *             initial version
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/pxa930.h>
+#include <mach/reset.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/regs-intc.h>
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK	13000000
+
+/* Ring Oscillator Clock: 60MHz */
+#define RO_CLK		60000000
+
+#define ACCR_D0CS	(1 << 26)
+#define ACCR_PCCE	(1 << 11)
+
+#define PECR_IE(n)	((1 << ((n) * 2)) << 28)
+#define PECR_IS(n)	((1 << ((n) * 2)) << 29)
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
+
+static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
+
+	MFP_ADDR(GPIO0, 0x02e0),
+	MFP_ADDR(GPIO1, 0x02dc),
+	MFP_ADDR(GPIO2, 0x02e8),
+	MFP_ADDR(GPIO3, 0x02d8),
+	MFP_ADDR(GPIO4, 0x02e4),
+	MFP_ADDR(GPIO5, 0x02ec),
+	MFP_ADDR(GPIO6, 0x02f8),
+	MFP_ADDR(GPIO7, 0x02fc),
+	MFP_ADDR(GPIO8, 0x0300),
+	MFP_ADDR(GPIO9, 0x02d4),
+	MFP_ADDR(GPIO10, 0x02f4),
+	MFP_ADDR(GPIO11, 0x02f0),
+	MFP_ADDR(GPIO12, 0x0304),
+	MFP_ADDR(GPIO13, 0x0310),
+	MFP_ADDR(GPIO14, 0x0308),
+	MFP_ADDR(GPIO15, 0x030c),
+	MFP_ADDR(GPIO16, 0x04e8),
+	MFP_ADDR(GPIO17, 0x04f4),
+	MFP_ADDR(GPIO18, 0x04f8),
+	MFP_ADDR(GPIO19, 0x04fc),
+	MFP_ADDR(GPIO20, 0x0518),
+	MFP_ADDR(GPIO21, 0x051c),
+	MFP_ADDR(GPIO22, 0x04ec),
+	MFP_ADDR(GPIO23, 0x0500),
+	MFP_ADDR(GPIO24, 0x04f0),
+	MFP_ADDR(GPIO25, 0x0504),
+	MFP_ADDR(GPIO26, 0x0510),
+	MFP_ADDR(GPIO27, 0x0514),
+	MFP_ADDR(GPIO28, 0x0520),
+	MFP_ADDR(GPIO29, 0x0600),
+	MFP_ADDR(GPIO30, 0x0618),
+	MFP_ADDR(GPIO31, 0x0610),
+	MFP_ADDR(GPIO32, 0x060c),
+	MFP_ADDR(GPIO33, 0x061c),
+	MFP_ADDR(GPIO34, 0x0620),
+	MFP_ADDR(GPIO35, 0x0628),
+	MFP_ADDR(GPIO36, 0x062c),
+	MFP_ADDR(GPIO37, 0x0630),
+	MFP_ADDR(GPIO38, 0x0634),
+	MFP_ADDR(GPIO39, 0x0638),
+	MFP_ADDR(GPIO40, 0x063c),
+	MFP_ADDR(GPIO41, 0x0614),
+	MFP_ADDR(GPIO42, 0x0624),
+	MFP_ADDR(GPIO43, 0x0608),
+	MFP_ADDR(GPIO44, 0x0604),
+	MFP_ADDR(GPIO45, 0x050c),
+	MFP_ADDR(GPIO46, 0x0508),
+	MFP_ADDR(GPIO47, 0x02bc),
+	MFP_ADDR(GPIO48, 0x02b4),
+	MFP_ADDR(GPIO49, 0x02b8),
+	MFP_ADDR(GPIO50, 0x02c8),
+	MFP_ADDR(GPIO51, 0x02c0),
+	MFP_ADDR(GPIO52, 0x02c4),
+	MFP_ADDR(GPIO53, 0x02d0),
+	MFP_ADDR(GPIO54, 0x02cc),
+	MFP_ADDR(GPIO55, 0x029c),
+	MFP_ADDR(GPIO56, 0x02a0),
+	MFP_ADDR(GPIO57, 0x0294),
+	MFP_ADDR(GPIO58, 0x0298),
+	MFP_ADDR(GPIO59, 0x02a4),
+	MFP_ADDR(GPIO60, 0x02a8),
+	MFP_ADDR(GPIO61, 0x02b0),
+	MFP_ADDR(GPIO62, 0x02ac),
+	MFP_ADDR(GPIO63, 0x0640),
+	MFP_ADDR(GPIO64, 0x065c),
+	MFP_ADDR(GPIO65, 0x0648),
+	MFP_ADDR(GPIO66, 0x0644),
+	MFP_ADDR(GPIO67, 0x0674),
+	MFP_ADDR(GPIO68, 0x0658),
+	MFP_ADDR(GPIO69, 0x0654),
+	MFP_ADDR(GPIO70, 0x0660),
+	MFP_ADDR(GPIO71, 0x0668),
+	MFP_ADDR(GPIO72, 0x0664),
+	MFP_ADDR(GPIO73, 0x0650),
+	MFP_ADDR(GPIO74, 0x066c),
+	MFP_ADDR(GPIO75, 0x064c),
+	MFP_ADDR(GPIO76, 0x0670),
+	MFP_ADDR(GPIO77, 0x0678),
+	MFP_ADDR(GPIO78, 0x067c),
+	MFP_ADDR(GPIO79, 0x0694),
+	MFP_ADDR(GPIO80, 0x069c),
+	MFP_ADDR(GPIO81, 0x06a0),
+	MFP_ADDR(GPIO82, 0x06a4),
+	MFP_ADDR(GPIO83, 0x0698),
+	MFP_ADDR(GPIO84, 0x06bc),
+	MFP_ADDR(GPIO85, 0x06b4),
+	MFP_ADDR(GPIO86, 0x06b0),
+	MFP_ADDR(GPIO87, 0x06c0),
+	MFP_ADDR(GPIO88, 0x06c4),
+	MFP_ADDR(GPIO89, 0x06ac),
+	MFP_ADDR(GPIO90, 0x0680),
+	MFP_ADDR(GPIO91, 0x0684),
+	MFP_ADDR(GPIO92, 0x0688),
+	MFP_ADDR(GPIO93, 0x0690),
+	MFP_ADDR(GPIO94, 0x068c),
+	MFP_ADDR(GPIO95, 0x06a8),
+	MFP_ADDR(GPIO96, 0x06b8),
+	MFP_ADDR(GPIO97, 0x0410),
+	MFP_ADDR(GPIO98, 0x0418),
+	MFP_ADDR(GPIO99, 0x041c),
+	MFP_ADDR(GPIO100, 0x0414),
+	MFP_ADDR(GPIO101, 0x0408),
+	MFP_ADDR(GPIO102, 0x0324),
+	MFP_ADDR(GPIO103, 0x040c),
+	MFP_ADDR(GPIO104, 0x0400),
+	MFP_ADDR(GPIO105, 0x0328),
+	MFP_ADDR(GPIO106, 0x0404),
+
+	MFP_ADDR(nXCVREN, 0x0204),
+	MFP_ADDR(DF_CLE_nOE, 0x020c),
+	MFP_ADDR(DF_nADV1_ALE, 0x0218),
+	MFP_ADDR(DF_SCLK_E, 0x0214),
+	MFP_ADDR(DF_SCLK_S, 0x0210),
+	MFP_ADDR(nBE0, 0x021c),
+	MFP_ADDR(nBE1, 0x0220),
+	MFP_ADDR(DF_nADV2_ALE, 0x0224),
+	MFP_ADDR(DF_INT_RnB, 0x0228),
+	MFP_ADDR(DF_nCS0, 0x022c),
+	MFP_ADDR(DF_nCS1, 0x0230),
+	MFP_ADDR(nLUA, 0x0254),
+	MFP_ADDR(nLLA, 0x0258),
+	MFP_ADDR(DF_nWE, 0x0234),
+	MFP_ADDR(DF_nRE_nOE, 0x0238),
+	MFP_ADDR(DF_ADDR0, 0x024c),
+	MFP_ADDR(DF_ADDR1, 0x0250),
+	MFP_ADDR(DF_ADDR2, 0x025c),
+	MFP_ADDR(DF_ADDR3, 0x0260),
+	MFP_ADDR(DF_IO0, 0x023c),
+	MFP_ADDR(DF_IO1, 0x0240),
+	MFP_ADDR(DF_IO2, 0x0244),
+	MFP_ADDR(DF_IO3, 0x0248),
+	MFP_ADDR(DF_IO4, 0x0264),
+	MFP_ADDR(DF_IO5, 0x0268),
+	MFP_ADDR(DF_IO6, 0x026c),
+	MFP_ADDR(DF_IO7, 0x0270),
+	MFP_ADDR(DF_IO8, 0x0274),
+	MFP_ADDR(DF_IO9, 0x0278),
+	MFP_ADDR(DF_IO10, 0x027c),
+	MFP_ADDR(DF_IO11, 0x0280),
+	MFP_ADDR(DF_IO12, 0x0284),
+	MFP_ADDR(DF_IO13, 0x0288),
+	MFP_ADDR(DF_IO14, 0x028c),
+	MFP_ADDR(DF_IO15, 0x0290),
+
+	MFP_ADDR(GSIM_UIO, 0x0314),
+	MFP_ADDR(GSIM_UCLK, 0x0318),
+	MFP_ADDR(GSIM_UDET, 0x031c),
+	MFP_ADDR(GSIM_nURST, 0x0320),
+
+	MFP_ADDR(PMIC_INT, 0x06c8),
+
+	MFP_ADDR(RDY, 0x0200),
+
+	MFP_ADDR_END,
+};
+
+static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
+	MFP_ADDR(GPIO159, 0x0524),
+	MFP_ADDR(GPIO163, 0x0534),
+	MFP_ADDR(GPIO167, 0x0544),
+	MFP_ADDR(GPIO168, 0x0548),
+	MFP_ADDR(GPIO169, 0x054c),
+	MFP_ADDR(GPIO170, 0x0550),
+	MFP_ADDR(GPIO171, 0x0554),
+	MFP_ADDR(GPIO172, 0x0558),
+	MFP_ADDR(GPIO173, 0x055c),
+
+	MFP_ADDR_END,
+};
+
+void pxa93x_clear_reset_status(unsigned int mask)
+{
+	/* RESET_STATUS_* has a 1:1 mapping with ARSR */
+	ARSR = mask;
+}
+
+/*
+ * Return the current HSIO bus clock frequency
+ */
+static unsigned long clk_pxa93x_hsio_getrate(struct clk *clk)
+{
+	unsigned long acsr;
+	unsigned int hss, hsio_clk;
+
+	acsr = ACSR;
+
+	hss = (acsr >> 14) & 0x3;
+	hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+	return hsio_clk;
+}
+
+void clk_pxa93x_cken_enable(struct clk *clk)
+{
+	unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+	if (clk->cken < 32)
+		CKENA |= mask;
+	else
+		CKENB |= mask;
+}
+
+void clk_pxa93x_cken_disable(struct clk *clk)
+{
+	unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+	if (clk->cken < 32)
+		CKENA &= ~mask;
+	else
+		CKENB &= ~mask;
+}
+
+const struct clkops clk_pxa93x_cken_ops = {
+	.enable		= clk_pxa93x_cken_enable,
+	.disable	= clk_pxa93x_cken_disable,
+};
+
+static const struct clkops clk_pxa93x_hsio_ops = {
+	.enable		= clk_pxa93x_cken_enable,
+	.disable	= clk_pxa93x_cken_disable,
+	.getrate	= clk_pxa93x_hsio_getrate,
+};
+
+static void clk_pout_enable(struct clk *clk)
+{
+	OSCC |= OSCC_PEN;
+}
+
+static void clk_pout_disable(struct clk *clk)
+{
+	OSCC &= ~OSCC_PEN;
+}
+
+static const struct clkops clk_pout_ops = {
+	.enable		= clk_pout_enable,
+	.disable	= clk_pout_disable,
+};
+
+static void clk_dummy_enable(struct clk *clk)
+{
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static const struct clkops clk_dummy_ops = {
+	.enable		= clk_dummy_enable,
+	.disable	= clk_dummy_disable,
+};
+
+static struct clk clk_pxa93x_pout = {
+	.ops		= &clk_pout_ops,
+	.rate		= 13000000,
+	.delay		= 70,
+};
+
+static struct clk clk_dummy = {
+	.ops		= &clk_dummy_ops,
+};
+
+static DEFINE_PXA93_CK(pxa93x_lcd, LCD, &clk_pxa93x_hsio_ops);
+static DEFINE_PXA93_CK(pxa93x_camera, CAMERA, &clk_pxa93x_hsio_ops);
+static DEFINE_PXA93_CKEN(pxa93x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA93_CKEN(pxa93x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA93_CKEN(pxa93x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA93_CKEN(pxa93x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA93_CKEN(pxa93x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_ssp4, SSP4, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_pwm1, PWM1, 13000000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_mmc1, MMC1, 19500000, 0);
+static DEFINE_PXA93_CKEN(pxa93x_mmc2, MMC2, 19500000, 0);
+
+static struct clk_lookup pxa93x_clkregs[] = {
+	INIT_CLKREG(&clk_pxa93x_pout, NULL, "CLK_POUT"),
+	/* Power I2C clock is always on */
+	INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
+	INIT_CLKREG(&clk_pxa93x_lcd, "pxa2xx-fb", NULL),
+	INIT_CLKREG(&clk_pxa93x_camera, NULL, "CAMCLK"),
+	INIT_CLKREG(&clk_pxa93x_ffuart, "pxa2xx-uart.0", NULL),
+	INIT_CLKREG(&clk_pxa93x_btuart, "pxa2xx-uart.1", NULL),
+	INIT_CLKREG(&clk_pxa93x_stuart, "pxa2xx-uart.2", NULL),
+	INIT_CLKREG(&clk_pxa93x_stuart, "pxa2xx-ir", "UARTCLK"),
+	INIT_CLKREG(&clk_pxa93x_i2c, "pxa2xx-i2c.0", NULL),
+	INIT_CLKREG(&clk_pxa93x_keypad, "pxa27x-keypad", NULL),
+	INIT_CLKREG(&clk_pxa93x_ssp1, "pxa27x-ssp.0", NULL),
+	INIT_CLKREG(&clk_pxa93x_ssp2, "pxa27x-ssp.1", NULL),
+	INIT_CLKREG(&clk_pxa93x_ssp3, "pxa27x-ssp.2", NULL),
+	INIT_CLKREG(&clk_pxa93x_ssp4, "pxa27x-ssp.3", NULL),
+	INIT_CLKREG(&clk_pxa93x_pwm0, "pxa27x-pwm.0", NULL),
+	INIT_CLKREG(&clk_pxa93x_pwm1, "pxa27x-pwm.1", NULL),
+};
+
+static struct clk_lookup pxa930_clkregs[] = {
+	INIT_CLKREG(&clk_pxa93x_mmc1, "pxa2xx-mci.0", NULL),
+	INIT_CLKREG(&clk_pxa93x_mmc2, "pxa2xx-mci.1", NULL),
+};
+
+static void pxa_ack_ext_wakeup(unsigned int irq)
+{
+	PECR |= PECR_IS(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_mask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
+	PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_unmask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
+	PECR |= PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static int pxa_set_ext_wakeup_type(unsigned int irq, unsigned int flow_type)
+{
+	if (flow_type & IRQ_TYPE_EDGE_RISING)
+		PWER |= 1 << (irq - IRQ_WAKEUP0);
+
+	if (flow_type & IRQ_TYPE_EDGE_FALLING)
+		PWER |= 1 << (irq - IRQ_WAKEUP0 + 2);
+
+	return 0;
+}
+
+static struct irq_chip pxa_ext_wakeup_chip = {
+	.name		= "WAKEUP",
+	.ack		= pxa_ack_ext_wakeup,
+	.mask		= pxa_mask_ext_wakeup,
+	.unmask		= pxa_unmask_ext_wakeup,
+	.set_type	= pxa_set_ext_wakeup_type,
+};
+
+static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
+{
+	set_irq_chip(IRQ_WAKEUP0, &pxa_ext_wakeup_chip);
+	set_irq_handler(IRQ_WAKEUP0, handle_edge_irq);
+	set_irq_flags(IRQ_WAKEUP0, IRQF_VALID);
+
+	pxa_ext_wakeup_chip.set_wake = fn;
+}
+
+void __init pxa93x_init_irq(void)
+{
+	/* enable CP6 access */
+	u32 value;
+	__asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
+	value |= (1 << 6);
+	__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
+
+	pxa_init_irq(96, NULL);
+	pxa_init_ext_wakeup_irq(NULL);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
+}
+
+/*
+ * device registration specific to PXA93x.
+ */
+
+void __init pxa93x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+	pxa_register_device(&pxa3xx_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+	&sa1100_device_rtc,
+	&pxa_device_rtc,
+	&pxa27x_device_ssp1,
+	&pxa27x_device_ssp2,
+	&pxa27x_device_ssp3,
+	&pxa3xx_device_ssp4,
+	&pxa27x_device_pwm0,
+	&pxa27x_device_pwm1,
+};
+
+static int __init pxa93x_init(void)
+{
+	int ret = 0;
+
+	if (cpu_is_pxa93x()) {
+		mfp_init_base(io_p2v(MFPR_BASE));
+		mfp_init_addr(pxa930_mfp_addr_map);
+
+		if (cpu_is_pxa935())
+			mfp_init_addr(pxa935_mfp_addr_map);
+
+		reset_status = ARSR;
+
+		/*
+		 * clear RDH bit every time after reset
+		 *
+		 * Note: the last 3 bits DxS are write-1-to-clear so carefully
+		 * preserve them here in case they will be referenced later
+		 */
+		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+
+		clkdev_add_table(pxa93x_clkregs, ARRAY_SIZE(pxa93x_clkregs));
+		if (cpu_is_pxa930())
+			clkdev_add_table(pxa930_clkregs,
+				ARRAY_SIZE(pxa930_clkregs));
+
+		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+			return ret;
+
+		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+	}
+
+	return ret;
+}
+
+postcore_initcall(pxa93x_init);
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index c1ca8cb..4a166ce 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -598,7 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
 	/* Maintainer: Eric Miao <eric.miao@marvell.com> */
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa3xx_map_io,
-	.init_irq       = pxa3xx_init_irq,
+	.init_irq       = pxa93x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = saar_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
index 232b731..ebee414 100644
--- a/arch/arm/mach-pxa/smemc.c
+++ b/arch/arm/mach-pxa/smemc.c
@@ -59,13 +59,11 @@ static int __init smemc_init(void)
 {
 	int ret = 0;
 
-	if (cpu_is_pxa3xx()) {
-		ret = sysdev_class_register(&smemc_sysclass);
-		if (ret)
-			return ret;
+	ret = sysdev_class_register(&smemc_sysclass);
+	if (ret)
+		return ret;
 
-		ret = sysdev_register(&smemc_sysdev);
-	}
+	ret = sysdev_register(&smemc_sysdev);
 
 	return ret;
 }
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 9cecf83..15ac912 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -491,7 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
 	/* Maintainer: Eric Miao <eric.miao@marvell.com> */
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa3xx_map_io,
-	.init_irq       = pxa3xx_init_irq,
+	.init_irq       = pxa93x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = tavorevb_init,
 MACHINE_END
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 4aacdd1..4ac2fd9 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -6,6 +6,7 @@ obj-y	:= dma.o
 
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_PXA3xx)		+= mfp.o
+obj-$(CONFIG_PXA93x)		+= mfp.o
 obj-$(CONFIG_ARCH_MMP)		+= mfp.o
 
 obj-$(CONFIG_HAVE_PWM)		+= pwm.o
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
index 9e604c8..a3a2a65 100644
--- a/arch/arm/plat-pxa/include/plat/mfp.h
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -423,7 +423,7 @@ typedef unsigned long mfp_cfg_t;
 	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
 	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
 
-#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x) || defined(CONFIG_ARCH_MMP)
 /*
  * each MFP pin will have a MFPR register, since the offset of the
  * register varies between processors, the processor specific code
@@ -470,6 +470,6 @@ void mfp_write(int mfp, unsigned long mfpr_val);
 void mfp_config(unsigned long *mfp_cfgs, int num);
 void mfp_config_run(void);
 void mfp_config_lpm(void);
-#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
+#endif /* CONFIG_PXA3xx || CONFIG_PXA93x || CONFIG_ARCH_MMP */
 
 #endif /* __ASM_PLAT_MFP_H */
-- 
1.5.6.5

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

* [PATCH 04/11] ARM: pxa: update to read ICHP
  2010-11-12  7:17   ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Haojian Zhuang
@ 2010-11-12  7:17     ` Haojian Zhuang
  2010-11-12  7:17       ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
  2010-11-12  8:34       ` [PATCH 04/11] ARM: pxa: update to read ICHP Eric Miao
  2010-11-12  8:07     ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Eric Miao
  1 sibling, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

ICHP records the highest priority interrupt occured. In PXA27x/PXA3xx, we
can read ICHP via cooprocessor. In PJ4, we can only read ICHP via bus
register. So use the same method to read ICHP via bus register.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-pxa/include/mach/entry-macro.S |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S
index a73bc86..91457dd 100644
--- a/arch/arm/mach-pxa/include/mach/entry-macro.S
+++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
@@ -41,11 +41,15 @@
 		b	1001f
 1002:
 		@ Core Generation 2 (PXA27x) or Core Generation 3 (PXA3xx)
-		mrc	p6, 0, \irqstat, c5, c0, 0	@ ICHP
+		@ or Core PJ4
+		mov	\base, #io_p2v(0x40000000)	@ IIR Ctl = 0x40d00000
+		add	\base, \base, #0x00d00000
+		ldr	\irqstat, [\base, #0x18]	@ ICHP offset
 		tst	\irqstat, #0x80000000
 		beq	1001f
 		bic	\irqstat, \irqstat, #0x80000000
 		mov	\irqnr, \irqstat, lsr #16
 		add	\irqnr, \irqnr, #(PXA_IRQ(0))
+
 1001:
 		.endm
-- 
1.5.6.5

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

* [PATCH 05/11] ARM: pxa: support pxa95x
  2010-11-12  7:17     ` [PATCH 04/11] ARM: pxa: update to read ICHP Haojian Zhuang
@ 2010-11-12  7:17       ` Haojian Zhuang
  2010-11-12  7:17         ` [PATCH 06/11] ARM: pxa: support saarb platform Haojian Zhuang
  2010-11-12  8:50         ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
  2010-11-12  8:34       ` [PATCH 04/11] ARM: pxa: update to read ICHP Eric Miao
  1 sibling, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

The core of PXA955 is PJ4. Add new PJ4 support. And add new macro
CONFIG_PXA95x.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/Kconfig                          |    4 +-
 arch/arm/mach-pxa/Kconfig                 |   12 +-
 arch/arm/mach-pxa/Makefile                |    1 +
 arch/arm/mach-pxa/clock.h                 |   20 ++
 arch/arm/mach-pxa/devices.c               |  292 ++++++++++---------
 arch/arm/mach-pxa/generic.h               |    7 +
 arch/arm/mach-pxa/include/mach/hardware.h |   29 ++-
 arch/arm/mach-pxa/include/mach/irqs.h     |    1 +
 arch/arm/mach-pxa/pxa95x.c                |  452 +++++++++++++++++++++++++++++
 arch/arm/mm/Kconfig                       |    8 +-
 arch/arm/plat-pxa/Makefile                |    1 +
 arch/arm/plat-pxa/include/plat/mfp.h      |    5 +-
 12 files changed, 670 insertions(+), 162 deletions(-)
 create mode 100644 arch/arm/mach-pxa/pxa95x.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a19a526..d78a03c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -999,8 +999,8 @@ source arch/arm/mm/Kconfig
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
-	default y if PXA27x || PXA3xx || ARCH_MMP
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
+	default y if PXA27x || PXA3xx || PXA93x || PXA95x || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 84123d4..d9424ff 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -657,11 +657,17 @@ config CPU_PXA935
 	help
 	  PXA935 (codename Tavor-P65)
 
-config CPU_PXA950
+config PXA95x
 	bool
-	select CPU_PXA930
+	select CPU_PJ4
+	help
+	  Select code specific to PXA95x variants
+
+config CPU_PXA955
+	bool
+	select PXA95x
 	help
-	  PXA950 (codename Tavor-PV2)
+	  PXA955 (codename MG1)
 
 config PXA_SHARP_C7xx
 	bool
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index ebdb899..1642f6c 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PXA25x)		+= mfp-pxa2xx.o pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)		+= mfp-pxa2xx.o pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)		+= mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
 obj-$(CONFIG_PXA93x)		+= mfp-pxa3xx.o pxa93x.o smemc.o
+obj-$(CONFIG_PXA95x)		+= mfp-pxa3xx.o pxa95x.o smemc.o
 obj-$(CONFIG_CPU_PXA300)	+= pxa300.o
 obj-$(CONFIG_CPU_PXA320)	+= pxa320.o
 
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index 0d824eb..5018b2c 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -87,3 +87,23 @@ extern void clk_pxa93x_cken_enable(struct clk *);
 extern void clk_pxa93x_cken_disable(struct clk *);
 #endif
 
+#ifdef CONFIG_PXA95x
+#define DEFINE_PXA95_CKEN(_name, _cken, _rate, _delay)	\
+struct clk clk_##_name = {				\
+		.ops	= &clk_pxa95x_cken_ops,		\
+		.rate	= _rate,			\
+		.cken	= CKEN_##_cken,			\
+		.delay	= _delay,			\
+	}
+
+#define DEFINE_PXA95_CK(_name, _cken, _ops)		\
+struct clk clk_##_name = {				\
+		.ops	= _ops,				\
+		.cken	= CKEN_##_cken,			\
+	}
+
+extern const struct clkops clk_pxa95x_cken_ops;
+extern void clk_pxa95x_cken_enable(struct clk *);
+extern void clk_pxa95x_cken_disable(struct clk *);
+#endif
+
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 881ccc3..9c0aba3 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -342,27 +342,6 @@ struct platform_device pxa27x_device_i2c_power = {
 };
 #endif
 
-#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
-static struct resource pxa3xx_resources_i2c_power[] = {
-	{
-		.start  = 0x40f500c0,
-		.end    = 0x40f500d3,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_PWRI2C,
-		.end	= IRQ_PWRI2C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device pxa3xx_device_i2c_power = {
-	.name		= "pxa3xx-pwri2c",
-	.id		= 1,
-	.resource	= pxa3xx_resources_i2c_power,
-	.num_resources	= ARRAY_SIZE(pxa3xx_resources_i2c_power),
-};
-#endif
-
 static struct resource pxai2s_resources[] = {
 	{
 		.start	= 0x40400000,
@@ -633,32 +612,6 @@ struct platform_device pxa25x_device_assp = {
 #endif /* CONFIG_PXA25x */
 
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
-
-static struct resource pxa27x_resource_keypad[] = {
-	[0] = {
-		.start	= 0x41500000,
-		.end	= 0x4150004c,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_KEYPAD,
-		.end	= IRQ_KEYPAD,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device pxa27x_device_keypad = {
-	.name		= "pxa27x-keypad",
-	.id		= -1,
-	.resource	= pxa27x_resource_keypad,
-	.num_resources	= ARRAY_SIZE(pxa27x_resource_keypad),
-};
-
-void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
-{
-	pxa_register_device(&pxa27x_device_keypad, info);
-}
-
 static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
 
 static struct resource pxa27x_resource_ohci[] = {
@@ -690,6 +643,66 @@ void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
 	pxa_register_device(&pxa27x_device_ohci, info);
 }
 
+static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_camera[] = {
+	[0] = {
+		.start	= 0x50000000,
+		.end	= 0x50000fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_CAMERA,
+		.end	= IRQ_CAMERA,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pxa27x_device_camera = {
+	.name		= "pxa27x-camera",
+	.id		= 0, /* This is used to put cameras on this interface */
+	.dev		= {
+		.dma_mask      		= &pxa27x_dma_mask_camera,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxa27x_resource_camera),
+	.resource	= pxa27x_resource_camera,
+};
+
+void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
+{
+	pxa_register_device(&pxa27x_device_camera, info);
+}
+#endif	/* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA93x */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)		\
+	|| defined(CONFIG_PXA93x) || defined(CONFIG_PXA95x)
+
+static struct resource pxa27x_resource_keypad[] = {
+	[0] = {
+		.start	= 0x41500000,
+		.end	= 0x4150004c,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_KEYPAD,
+		.end	= IRQ_KEYPAD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa27x_device_keypad = {
+	.name		= "pxa27x-keypad",
+	.id		= -1,
+	.resource	= pxa27x_resource_keypad,
+	.num_resources	= ARRAY_SIZE(pxa27x_resource_keypad),
+};
+
+void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
+{
+	pxa_register_device(&pxa27x_device_keypad, info);
+}
+
 static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
 
 static struct resource pxa27x_resource_ssp1[] = {
@@ -833,79 +846,9 @@ struct platform_device pxa27x_device_pwm1 = {
 	.resource	= pxa27x_resource_pwm1,
 	.num_resources	= ARRAY_SIZE(pxa27x_resource_pwm1),
 };
-
-static struct resource pxa27x_resource_camera[] = {
-	[0] = {
-		.start	= 0x50000000,
-		.end	= 0x50000fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_CAMERA,
-		.end	= IRQ_CAMERA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32);
-
-static struct platform_device pxa27x_device_camera = {
-	.name		= "pxa27x-camera",
-	.id		= 0, /* This is used to put cameras on this interface */
-	.dev		= {
-		.dma_mask      		= &pxa27x_dma_mask_camera,
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(pxa27x_resource_camera),
-	.resource	= pxa27x_resource_camera,
-};
-
-void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
-{
-	pxa_register_device(&pxa27x_device_camera, info);
-}
 #endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA93x */
 
 #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
-static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
-
-static struct resource pxa3xx_resource_ssp4[] = {
-	[0] = {
-		.start	= 0x41a00000,
-		.end	= 0x41a0003f,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_SSP4,
-		.end	= IRQ_SSP4,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* DRCMR for RX */
-		.start	= 2,
-		.end	= 2,
-		.flags	= IORESOURCE_DMA,
-	},
-	[3] = {
-		/* DRCMR for TX */
-		.start	= 3,
-		.end	= 3,
-		.flags	= IORESOURCE_DMA,
-	},
-};
-
-struct platform_device pxa3xx_device_ssp4 = {
-	/* PXA3xx SSP is basically equivalent to PXA27x */
-	.name		= "pxa27x-ssp",
-	.id		= 3,
-	.dev		= {
-		.dma_mask = &pxa3xx_ssp4_dma_mask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource	= pxa3xx_resource_ssp4,
-	.num_resources	= ARRAY_SIZE(pxa3xx_resource_ssp4),
-};
-
 static struct resource pxa3xx_resources_mci2[] = {
 	[0] = {
 		.start	= 0x42000000,
@@ -984,6 +927,92 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
 	pxa_register_device(&pxa3xx_device_mci3, info);
 }
 
+static struct resource pxa3xx_resources_gcu[] = {
+	{
+		.start	= 0x54000000,
+		.end	= 0x54000fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_GCU,
+		.end	= IRQ_GCU,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device pxa3xx_device_gcu = {
+	.name		= "pxa3xx-gcu",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(pxa3xx_resources_gcu),
+	.resource	= pxa3xx_resources_gcu,
+	.dev		= {
+		.dma_mask = &pxa3xx_gcu_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+};
+#endif /* CONFIG_PXA3xx || CONFIG_PXA93x */
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x) || defined(CONFIG_PXA95x)
+static struct resource pxa3xx_resources_i2c_power[] = {
+	{
+		.start  = 0x40f500c0,
+		.end    = 0x40f500d3,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_PWRI2C,
+		.end	= IRQ_PWRI2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa3xx_device_i2c_power = {
+	.name		= "pxa3xx-pwri2c",
+	.id		= 1,
+	.resource	= pxa3xx_resources_i2c_power,
+	.num_resources	= ARRAY_SIZE(pxa3xx_resources_i2c_power),
+};
+
+static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa3xx_resource_ssp4[] = {
+	[0] = {
+		.start	= 0x41a00000,
+		.end	= 0x41a0003f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP4,
+		.end	= IRQ_SSP4,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 2,
+		.end	= 2,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 3,
+		.end	= 3,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa3xx_device_ssp4 = {
+	/* PXA3xx SSP is basically equivalent to PXA27x */
+	.name		= "pxa27x-ssp",
+	.id		= 3,
+	.dev		= {
+		.dma_mask = &pxa3xx_ssp4_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa3xx_resource_ssp4,
+	.num_resources	= ARRAY_SIZE(pxa3xx_resource_ssp4),
+};
+
 static struct resource pxa3xx_resources_nand[] = {
 	[0] = {
 		.start	= 0x43100000,
@@ -1026,34 +1055,7 @@ void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info)
 {
 	pxa_register_device(&pxa3xx_device_nand, info);
 }
-
-static struct resource pxa3xx_resources_gcu[] = {
-	{
-		.start	= 0x54000000,
-		.end	= 0x54000fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= IRQ_GCU,
-		.end	= IRQ_GCU,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device pxa3xx_device_gcu = {
-	.name		= "pxa3xx-gcu",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(pxa3xx_resources_gcu),
-	.resource	= pxa3xx_resources_gcu,
-	.dev		= {
-		.dma_mask = &pxa3xx_gcu_dmamask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-};
-
-#endif /* CONFIG_PXA3xx || CONFIG_PXA93x */
+#endif	/* CONFIG_PXA3xx || CONFIG_PXA93x || CONFIG_PXA95x */
 
 /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
  * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 7dec811..8d6b066 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -21,6 +21,7 @@ extern void __init pxa26x_init_irq(void);
 extern void __init pxa27x_init_irq(void);
 extern void __init pxa3xx_init_irq(void);
 extern void __init pxa93x_init_irq(void);
+extern void __init pxa95x_init_irq(void);
 
 extern void __init pxa_map_io(void);
 extern void __init pxa25x_map_io(void);
@@ -63,6 +64,12 @@ extern unsigned pxa3xx_get_clk_frequency_khz(int);
 #define pxa3xx_get_clk_frequency_khz(x)		(0)
 #endif
 
+#ifdef CONFIG_PXA95x
+extern void pxa95x_clear_reset_status(unsigned int);
+#else
+static inline void pxa95x_clear_reset_status(unsigned int mask) {}
+#endif
+
 extern struct sysdev_class pxa_irq_sysclass;
 extern struct sysdev_class pxa_gpio_sysclass;
 extern struct sysdev_class pxa2xx_mfp_sysclass;
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index 59f145a..704922d 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -186,14 +186,14 @@
 #define __cpu_is_pxa935(id)	(0)
 #endif
 
-#ifdef CONFIG_CPU_PXA950
-#define __cpu_is_pxa950(id)                             \
-	({                                              \
-		unsigned int _id = (id) >> 4 & 0xfff;	\
-		_id == 0x697;				\
+#ifdef CONFIG_CPU_PXA955
+#define __cpu_is_pxa955(id)                             	\
+	({                                              	\
+		unsigned int _id = (id) >> 4 & 0xfff;		\
+		_id == 0x581 || _id == 0xc08 || _id == 0xb76;	\
 	 })
 #else
-#define __cpu_is_pxa950(id)	(0)
+#define __cpu_is_pxa955(id)	(0)
 #endif
 
 #define cpu_is_pxa210()					\
@@ -246,10 +246,10 @@
 		__cpu_is_pxa935(read_cpuid_id());	\
 	 })
 
-#define cpu_is_pxa950()					\
+#define cpu_is_pxa955()					\
 	({						\
-		__cpu_is_pxa950(read_cpuid_id());	\
-	 })
+		__cpu_is_pxa955(read_cpuid_id());	\
+	})
 
 
 /*
@@ -288,6 +288,11 @@
 #define __cpu_is_pxa93x(id)	(0)
 #endif
 
+#define __cpu_is_pxa95x(id)				\
+	({						\
+		__cpu_is_pxa955(id);			\
+	})
+
 #define cpu_is_pxa2xx()					\
 	({						\
 		__cpu_is_pxa2xx(read_cpuid_id());	\
@@ -302,6 +307,12 @@
 	({						\
 		__cpu_is_pxa93x(read_cpuid_id());	\
 	 })
+
+#define cpu_is_pxa95x()					\
+	({						\
+		__cpu_is_pxa95x(read_cpuid_id());	\
+	})
+
 /*
  * return current memory and LCD clock frequency in units of 10kHz
  */
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index cb7ee26..a4285fc 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -84,6 +84,7 @@
 #define IRQ_PXA935_MMC0	PXA_IRQ(72)	/* MMC0 Controller (PXA935) */
 #define IRQ_PXA935_MMC1	PXA_IRQ(73)	/* MMC1 Controller (PXA935) */
 #define IRQ_PXA935_MMC2	PXA_IRQ(74)	/* MMC2 Controller (PXA935) */
+#define IRQ_PXA955_MMC3	PXA_IRQ(75)	/* MMC3 Controller (PXA955) */
 #define IRQ_U2P		PXA_IRQ(93)	/* USB PHY D+/D- Lines (PXA935) */
 
 #define PXA_GPIO_IRQ_BASE	PXA_IRQ(96)
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
new file mode 100644
index 0000000..b540280
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -0,0 +1,452 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa95x.c
+ *
+ * code specific to pxa95x aka MG
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/pxa930.h>
+#include <mach/reset.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/regs-intc.h>
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK	13000000
+
+/* Ring Oscillator Clock: 60MHz */
+#define RO_CLK		60000000
+
+#define ACCR_D0CS	(1 << 26)
+#define ACCR_PCCE	(1 << 11)
+
+#define PECR_IE(n)	((1 << ((n) * 2)) << 28)
+#define PECR_IS(n)	((1 << ((n) * 2)) << 29)
+
+/* crystal frequency to static memory controller multiplier (SMCFS) */
+static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
+
+static struct mfp_addr_map pxa95x_mfp_addr_map[] __initdata = {
+
+	MFP_ADDR(GPIO0, 0x02e0),
+	MFP_ADDR(GPIO1, 0x02dc),
+	MFP_ADDR(GPIO2, 0x02e8),
+	MFP_ADDR(GPIO3, 0x02d8),
+	MFP_ADDR(GPIO4, 0x02e4),
+	MFP_ADDR(GPIO5, 0x02ec),
+	MFP_ADDR(GPIO6, 0x02f8),
+	MFP_ADDR(GPIO7, 0x02fc),
+	MFP_ADDR(GPIO8, 0x0300),
+	MFP_ADDR(GPIO9, 0x02d4),
+	MFP_ADDR(GPIO10, 0x02f4),
+	MFP_ADDR(GPIO11, 0x02f0),
+	MFP_ADDR(GPIO12, 0x0304),
+	MFP_ADDR(GPIO13, 0x0310),
+	MFP_ADDR(GPIO14, 0x0308),
+	MFP_ADDR(GPIO15, 0x030c),
+	MFP_ADDR(GPIO16, 0x04e8),
+	MFP_ADDR(GPIO17, 0x04f4),
+	MFP_ADDR(GPIO18, 0x04f8),
+	MFP_ADDR(GPIO19, 0x04fc),
+	MFP_ADDR(GPIO20, 0x0518),
+	MFP_ADDR(GPIO21, 0x051c),
+	MFP_ADDR(GPIO22, 0x04ec),
+	MFP_ADDR(GPIO23, 0x0500),
+	MFP_ADDR(GPIO24, 0x04f0),
+	MFP_ADDR(GPIO25, 0x0504),
+	MFP_ADDR(GPIO26, 0x0510),
+	MFP_ADDR(GPIO27, 0x0514),
+	MFP_ADDR(GPIO28, 0x0520),
+	MFP_ADDR(GPIO29, 0x0600),
+	MFP_ADDR(GPIO30, 0x0618),
+	MFP_ADDR(GPIO31, 0x0610),
+	MFP_ADDR(GPIO32, 0x060c),
+	MFP_ADDR(GPIO33, 0x061c),
+	MFP_ADDR(GPIO34, 0x0620),
+	MFP_ADDR(GPIO35, 0x0628),
+	MFP_ADDR(GPIO36, 0x062c),
+	MFP_ADDR(GPIO37, 0x0630),
+	MFP_ADDR(GPIO38, 0x0634),
+	MFP_ADDR(GPIO39, 0x0638),
+	MFP_ADDR(GPIO40, 0x063c),
+	MFP_ADDR(GPIO41, 0x0614),
+	MFP_ADDR(GPIO42, 0x0624),
+	MFP_ADDR(GPIO43, 0x0608),
+	MFP_ADDR(GPIO44, 0x0604),
+	MFP_ADDR(GPIO45, 0x050c),
+	MFP_ADDR(GPIO46, 0x0508),
+	MFP_ADDR(GPIO47, 0x02bc),
+	MFP_ADDR(GPIO48, 0x02b4),
+	MFP_ADDR(GPIO49, 0x02b8),
+	MFP_ADDR(GPIO50, 0x02c8),
+	MFP_ADDR(GPIO51, 0x02c0),
+	MFP_ADDR(GPIO52, 0x02c4),
+	MFP_ADDR(GPIO53, 0x02d0),
+	MFP_ADDR(GPIO54, 0x02cc),
+	MFP_ADDR(GPIO55, 0x029c),
+	MFP_ADDR(GPIO56, 0x02a0),
+	MFP_ADDR(GPIO57, 0x0294),
+	MFP_ADDR(GPIO58, 0x0298),
+	MFP_ADDR(GPIO59, 0x02a4),
+	MFP_ADDR(GPIO60, 0x02a8),
+	MFP_ADDR(GPIO61, 0x02b0),
+	MFP_ADDR(GPIO62, 0x02ac),
+	MFP_ADDR(GPIO63, 0x0640),
+	MFP_ADDR(GPIO64, 0x065c),
+	MFP_ADDR(GPIO65, 0x0648),
+	MFP_ADDR(GPIO66, 0x0644),
+	MFP_ADDR(GPIO67, 0x0674),
+	MFP_ADDR(GPIO68, 0x0658),
+	MFP_ADDR(GPIO69, 0x0654),
+	MFP_ADDR(GPIO70, 0x0660),
+	MFP_ADDR(GPIO71, 0x0668),
+	MFP_ADDR(GPIO72, 0x0664),
+	MFP_ADDR(GPIO73, 0x0650),
+	MFP_ADDR(GPIO74, 0x066c),
+	MFP_ADDR(GPIO75, 0x064c),
+	MFP_ADDR(GPIO76, 0x0670),
+	MFP_ADDR(GPIO77, 0x0678),
+	MFP_ADDR(GPIO78, 0x067c),
+	MFP_ADDR(GPIO79, 0x0694),
+	MFP_ADDR(GPIO80, 0x069c),
+	MFP_ADDR(GPIO81, 0x06a0),
+	MFP_ADDR(GPIO82, 0x06a4),
+	MFP_ADDR(GPIO83, 0x0698),
+	MFP_ADDR(GPIO84, 0x06bc),
+	MFP_ADDR(GPIO85, 0x06b4),
+	MFP_ADDR(GPIO86, 0x06b0),
+	MFP_ADDR(GPIO87, 0x06c0),
+	MFP_ADDR(GPIO88, 0x06c4),
+	MFP_ADDR(GPIO89, 0x06ac),
+	MFP_ADDR(GPIO90, 0x0680),
+	MFP_ADDR(GPIO91, 0x0684),
+	MFP_ADDR(GPIO92, 0x0688),
+	MFP_ADDR(GPIO93, 0x0690),
+	MFP_ADDR(GPIO94, 0x068c),
+	MFP_ADDR(GPIO95, 0x06a8),
+	MFP_ADDR(GPIO96, 0x06b8),
+	MFP_ADDR(GPIO97, 0x0410),
+	MFP_ADDR(GPIO98, 0x0418),
+	MFP_ADDR(GPIO99, 0x041c),
+	MFP_ADDR(GPIO100, 0x0414),
+	MFP_ADDR(GPIO101, 0x0408),
+	MFP_ADDR(GPIO102, 0x0324),
+	MFP_ADDR(GPIO103, 0x040c),
+	MFP_ADDR(GPIO104, 0x0400),
+	MFP_ADDR(GPIO105, 0x0328),
+	MFP_ADDR(GPIO106, 0x0404),
+
+	MFP_ADDR(GPIO159, 0x0524),
+	MFP_ADDR(GPIO163, 0x0534),
+	MFP_ADDR(GPIO167, 0x0544),
+	MFP_ADDR(GPIO168, 0x0548),
+	MFP_ADDR(GPIO169, 0x054c),
+	MFP_ADDR(GPIO170, 0x0550),
+	MFP_ADDR(GPIO171, 0x0554),
+	MFP_ADDR(GPIO172, 0x0558),
+	MFP_ADDR(GPIO173, 0x055c),
+
+	MFP_ADDR(nXCVREN, 0x0204),
+	MFP_ADDR(DF_CLE_nOE, 0x020c),
+	MFP_ADDR(DF_nADV1_ALE, 0x0218),
+	MFP_ADDR(DF_SCLK_E, 0x0214),
+	MFP_ADDR(DF_SCLK_S, 0x0210),
+	MFP_ADDR(nBE0, 0x021c),
+	MFP_ADDR(nBE1, 0x0220),
+	MFP_ADDR(DF_nADV2_ALE, 0x0224),
+	MFP_ADDR(DF_INT_RnB, 0x0228),
+	MFP_ADDR(DF_nCS0, 0x022c),
+	MFP_ADDR(DF_nCS1, 0x0230),
+	MFP_ADDR(nLUA, 0x0254),
+	MFP_ADDR(nLLA, 0x0258),
+	MFP_ADDR(DF_nWE, 0x0234),
+	MFP_ADDR(DF_nRE_nOE, 0x0238),
+	MFP_ADDR(DF_ADDR0, 0x024c),
+	MFP_ADDR(DF_ADDR1, 0x0250),
+	MFP_ADDR(DF_ADDR2, 0x025c),
+	MFP_ADDR(DF_ADDR3, 0x0260),
+	MFP_ADDR(DF_IO0, 0x023c),
+	MFP_ADDR(DF_IO1, 0x0240),
+	MFP_ADDR(DF_IO2, 0x0244),
+	MFP_ADDR(DF_IO3, 0x0248),
+	MFP_ADDR(DF_IO4, 0x0264),
+	MFP_ADDR(DF_IO5, 0x0268),
+	MFP_ADDR(DF_IO6, 0x026c),
+	MFP_ADDR(DF_IO7, 0x0270),
+	MFP_ADDR(DF_IO8, 0x0274),
+	MFP_ADDR(DF_IO9, 0x0278),
+	MFP_ADDR(DF_IO10, 0x027c),
+	MFP_ADDR(DF_IO11, 0x0280),
+	MFP_ADDR(DF_IO12, 0x0284),
+	MFP_ADDR(DF_IO13, 0x0288),
+	MFP_ADDR(DF_IO14, 0x028c),
+	MFP_ADDR(DF_IO15, 0x0290),
+
+	MFP_ADDR(GSIM_UIO, 0x0314),
+	MFP_ADDR(GSIM_UCLK, 0x0318),
+	MFP_ADDR(GSIM_UDET, 0x031c),
+	MFP_ADDR(GSIM_nURST, 0x0320),
+
+	MFP_ADDR(PMIC_INT, 0x06c8),
+
+	MFP_ADDR(RDY, 0x0200),
+
+	MFP_ADDR_END,
+};
+
+void pxa95x_clear_reset_status(unsigned int mask)
+{
+	/* RESET_STATUS_* has a 1:1 mapping with ARSR */
+	ARSR = mask;
+}
+
+/*
+ * Return the current HSIO bus clock frequency
+ */
+static unsigned long clk_pxa95x_hsio_getrate(struct clk *clk)
+{
+	unsigned long acsr;
+	unsigned int hss, hsio_clk;
+
+	acsr = ACSR;
+
+	hss = (acsr >> 14) & 0x3;
+	hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+	return hsio_clk;
+}
+
+void clk_pxa95x_cken_enable(struct clk *clk)
+{
+	unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+	if (clk->cken < 32)
+		CKENA |= mask;
+	else
+		CKENB |= mask;
+}
+
+void clk_pxa95x_cken_disable(struct clk *clk)
+{
+	unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+	if (clk->cken < 32)
+		CKENA &= ~mask;
+	else
+		CKENB &= ~mask;
+}
+
+const struct clkops clk_pxa95x_cken_ops = {
+	.enable		= clk_pxa95x_cken_enable,
+	.disable	= clk_pxa95x_cken_disable,
+};
+
+static const struct clkops clk_pxa95x_hsio_ops = {
+	.enable		= clk_pxa95x_cken_enable,
+	.disable	= clk_pxa95x_cken_disable,
+	.getrate	= clk_pxa95x_hsio_getrate,
+};
+
+static void clk_pout_enable(struct clk *clk)
+{
+	OSCC |= OSCC_PEN;
+}
+
+static void clk_pout_disable(struct clk *clk)
+{
+	OSCC &= ~OSCC_PEN;
+}
+
+static const struct clkops clk_pout_ops = {
+	.enable		= clk_pout_enable,
+	.disable	= clk_pout_disable,
+};
+
+static void clk_dummy_enable(struct clk *clk)
+{
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static const struct clkops clk_dummy_ops = {
+	.enable		= clk_dummy_enable,
+	.disable	= clk_dummy_disable,
+};
+
+static struct clk clk_pxa95x_pout = {
+	.ops		= &clk_pout_ops,
+	.rate		= 13000000,
+	.delay		= 70,
+};
+
+static struct clk clk_dummy = {
+	.ops		= &clk_dummy_ops,
+};
+
+static DEFINE_PXA95_CK(pxa95x_lcd, LCD, &clk_pxa95x_hsio_ops);
+static DEFINE_PXA95_CKEN(pxa95x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA95_CKEN(pxa95x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA95_CKEN(pxa95x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA95_CKEN(pxa95x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA95_CKEN(pxa95x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA95_CKEN(pxa95x_pwm1, PWM1, 13000000, 0);
+
+static struct clk_lookup pxa95x_clkregs[] = {
+	INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
+	/* Power I2C clock is always on */
+	INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
+	INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
+	INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
+	INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
+	INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-uart.2", NULL),
+	INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-ir", "UARTCLK"),
+	INIT_CLKREG(&clk_pxa95x_i2c, "pxa2xx-i2c.0", NULL),
+	INIT_CLKREG(&clk_pxa95x_keypad, "pxa27x-keypad", NULL),
+	INIT_CLKREG(&clk_pxa95x_ssp1, "pxa27x-ssp.0", NULL),
+	INIT_CLKREG(&clk_pxa95x_ssp2, "pxa27x-ssp.1", NULL),
+	INIT_CLKREG(&clk_pxa95x_ssp3, "pxa27x-ssp.2", NULL),
+	INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL),
+	INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
+	INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
+};
+
+static void pxa_ack_ext_wakeup(unsigned int irq)
+{
+	PECR |= PECR_IS(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_mask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
+	PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_unmask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
+	PECR |= PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static int pxa_set_ext_wakeup_type(unsigned int irq, unsigned int flow_type)
+{
+	if (flow_type & IRQ_TYPE_EDGE_RISING)
+		PWER |= 1 << (irq - IRQ_WAKEUP0);
+
+	if (flow_type & IRQ_TYPE_EDGE_FALLING)
+		PWER |= 1 << (irq - IRQ_WAKEUP0 + 2);
+
+	return 0;
+}
+
+static struct irq_chip pxa_ext_wakeup_chip = {
+	.name		= "WAKEUP",
+	.ack		= pxa_ack_ext_wakeup,
+	.mask		= pxa_mask_ext_wakeup,
+	.unmask		= pxa_unmask_ext_wakeup,
+	.set_type	= pxa_set_ext_wakeup_type,
+};
+
+static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
+{
+	set_irq_chip(IRQ_WAKEUP0, &pxa_ext_wakeup_chip);
+	set_irq_handler(IRQ_WAKEUP0, handle_edge_irq);
+	set_irq_flags(IRQ_WAKEUP0, IRQF_VALID);
+
+	pxa_ext_wakeup_chip.set_wake = fn;
+}
+
+void __init pxa95x_init_irq(void)
+{
+	/* enable CP6 access */
+	u32 value;
+	__asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
+	value |= (1 << 6);
+	__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
+
+	pxa_init_irq(96, NULL);
+	pxa_init_ext_wakeup_irq(NULL);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
+}
+
+/*
+ * device registration specific to PXA93x.
+ */
+
+void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+	pxa_register_device(&pxa3xx_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+	&sa1100_device_rtc,
+	&pxa_device_rtc,
+	&pxa27x_device_ssp1,
+	&pxa27x_device_ssp2,
+	&pxa27x_device_ssp3,
+	&pxa3xx_device_ssp4,
+	&pxa27x_device_pwm0,
+	&pxa27x_device_pwm1,
+};
+
+static int __init pxa95x_init(void)
+{
+	int ret = 0;
+
+	if (cpu_is_pxa95x()) {
+		mfp_init_base(io_p2v(MFPR_BASE));
+		mfp_init_addr(pxa95x_mfp_addr_map);
+
+		reset_status = ARSR;
+
+		/*
+		 * clear RDH bit every time after reset
+		 *
+		 * Note: the last 3 bits DxS are write-1-to-clear so carefully
+		 * preserve them here in case they will be referenced later
+		 */
+		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+
+		clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs));
+
+		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+			return ret;
+
+		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+	}
+
+	return ret;
+}
+
+postcore_initcall(pxa95x_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4414a01..a099efe 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -382,6 +382,12 @@ config CPU_FEROCEON_OLD_ID
 	  for which the CPU ID is equal to the ARM926 ID.
 	  Relevant for Feroceon-1850 and early Feroceon-2850.
 
+# Marvell PJ4
+config CPU_PJ4
+	bool
+	select CPU_V7
+	select ARM_THUMBEE
+
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE
@@ -789,7 +795,7 @@ config CACHE_PL310
 
 config CACHE_TAUROS2
 	bool "Enable the Tauros2 L2 cache controller"
-	depends on (ARCH_DOVE || ARCH_MMP)
+	depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
 	default y
 	select OUTER_CACHE
 	help
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 4ac2fd9..bcdd9ce 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -7,6 +7,7 @@ obj-y	:= dma.o
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_PXA3xx)		+= mfp.o
 obj-$(CONFIG_PXA93x)		+= mfp.o
+obj-$(CONFIG_PXA95x)		+= mfp.o
 obj-$(CONFIG_ARCH_MMP)		+= mfp.o
 
 obj-$(CONFIG_HAVE_PWM)		+= pwm.o
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
index a3a2a65..bd7bbf8 100644
--- a/arch/arm/plat-pxa/include/plat/mfp.h
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -423,7 +423,8 @@ typedef unsigned long mfp_cfg_t;
 	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
 	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
 
-#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x) || defined(CONFIG_ARCH_MMP)
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)			\
+	|| defined(CONFIG_PXA95x) || defined(CONFIG_ARCH_MMP)
 /*
  * each MFP pin will have a MFPR register, since the offset of the
  * register varies between processors, the processor specific code
@@ -470,6 +471,6 @@ void mfp_write(int mfp, unsigned long mfpr_val);
 void mfp_config(unsigned long *mfp_cfgs, int num);
 void mfp_config_run(void);
 void mfp_config_lpm(void);
-#endif /* CONFIG_PXA3xx || CONFIG_PXA93x || CONFIG_ARCH_MMP */
+#endif /* CONFIG_PXA3xx || CONFIG_PXA93x || CONFIG_PXA95x || CONFIG_ARCH_MMP */
 
 #endif /* __ASM_PLAT_MFP_H */
-- 
1.5.6.5

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

* [PATCH 06/11] ARM: pxa: support saarb platform
  2010-11-12  7:17       ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
@ 2010-11-12  7:17         ` Haojian Zhuang
  2010-11-12  7:17           ` [PATCH 07/11] ARM: mmp: select CPU_PJ4 Haojian Zhuang
  2010-11-12  8:50         ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
  1 sibling, 1 reply; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

Saarb platform is a handheld platform that supports Marvell PXA955 silicon.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-pxa/Kconfig  |    5 ++
 arch/arm/mach-pxa/Makefile |    1 +
 arch/arm/mach-pxa/pxa95x.c |    3 -
 arch/arm/mach-pxa/saarb.c  |  114 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-pxa/saarb.c

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index d9424ff..d972a2c 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -50,6 +50,11 @@ config MACH_SAAR
 	select CPU_PXA930
 	select CPU_PXA935
 
+config MACH_SAARB
+	bool "PXA955 Handheld Platform (aka SAARB)"
+	depends on !(CPU_XSCALE || CPU_XSC3)
+	select CPU_PXA955
+
 comment "Third Party Dev Platforms (sorted by vendor name)"
 
 config ARCH_PXA_IDP
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 1642f6c..ba83cfb 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_MACH_LITTLETON)	+= littleton.o
 obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
 obj-$(CONFIG_MACH_TAVOREVB3)	+= tavorevb3.o
 obj-$(CONFIG_MACH_SAAR)		+= saar.o
+obj-$(CONFIG_MACH_SAARB)	+= saarb.o
 
 # 3rd Party Dev Platforms
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
index b540280..af4e40f 100644
--- a/arch/arm/mach-pxa/pxa95x.c
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -45,9 +45,6 @@
 #define PECR_IE(n)	((1 << ((n) * 2)) << 28)
 #define PECR_IS(n)	((1 << ((n) * 2)) << 29)
 
-/* crystal frequency to static memory controller multiplier (SMCFS) */
-static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
-
 /* crystal frequency to HSIO bus frequency multiplier (HSS) */
 static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
 
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
new file mode 100644
index 0000000..e497922
--- /dev/null
+++ b/arch/arm/mach-pxa/saarb.c
@@ -0,0 +1,114 @@
+/*
+ *  linux/arch/arm/mach-pxa/saarb.c
+ *
+ *  Support for the Marvell Handheld Platform (aka SAARB)
+ *
+ *  Copyright (C) 2007-2010 Marvell International Ltd.
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/mfp-pxa930.h>
+#include <mach/gpio.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+
+#define SAARB_NR_IRQS	(IRQ_BOARD_START + 40)
+
+static struct pm860x_touch_pdata saarb_touch = {
+	.gpadc_prebias	= 1,
+	.slot_cycle	= 1,
+	.tsi_prebias	= 6,
+	.pen_prebias	= 16,
+	.pen_prechg	= 2,
+	.res_x		= 300,
+};
+
+static struct pm860x_backlight_pdata saarb_backlight[] = {
+	{
+		.id	= PM8606_ID_BACKLIGHT,
+		.iset	= PM8606_WLED_CURRENT(24),
+		.flags	= PM8606_BACKLIGHT1,
+	},
+	{},
+};
+
+static struct pm860x_led_pdata saarb_led[] = {
+	{
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED1_RED,
+	}, {
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED1_GREEN,
+	}, {
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED1_BLUE,
+	}, {
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED2_RED,
+	}, {
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED2_GREEN,
+	}, {
+		.id	= PM8606_ID_LED,
+		.iset	= PM8606_LED_CURRENT(12),
+		.flags	= PM8606_LED2_BLUE,
+	},
+};
+
+static struct pm860x_platform_data saarb_pm8607_info = {
+	.touch		= &saarb_touch,
+	.backlight	= &saarb_backlight[0],
+	.led		= &saarb_led[0],
+	.companion_addr	= 0x10,
+	.irq_mode	= 0,
+	.irq_base	= IRQ_BOARD_START,
+
+	.i2c_port	= GI2C_PORT,
+};
+
+static struct i2c_board_info saarb_i2c_info[] = {
+	{
+		.type		= "88PM860x",
+		.addr		= 0x34,
+		.platform_data	= &saarb_pm8607_info,
+		.irq		= gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+	},
+};
+
+static void __init saarb_init(void)
+{
+	pxa_set_ffuart_info(NULL);
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(saarb_i2c_info));
+}
+
+MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)")
+	.boot_params    = 0xa0000100,
+	.map_io         = pxa_map_io,
+	.nr_irqs	= SAARB_NR_IRQS,
+	.init_irq       = pxa95x_init_irq,
+	.timer          = &pxa_timer,
+	.init_machine   = saarb_init,
+MACHINE_END
+
-- 
1.5.6.5

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

* [PATCH 07/11] ARM: mmp: select CPU_PJ4
  2010-11-12  7:17         ` [PATCH 06/11] ARM: pxa: support saarb platform Haojian Zhuang
@ 2010-11-12  7:17           ` Haojian Zhuang
  2010-11-12  7:17             ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
  0 siblings, 1 reply; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

Since CPU_PJ4 is shared between PXA95x and MMP2, select CPU_PJ4 in MMP2
configuration.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
---
 arch/arm/mach-mmp/Kconfig |    5 +++--
 arch/arm/mm/Kconfig       |    2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 0711d3b..8b7a053 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -39,6 +39,7 @@ config MACH_TTC_DKB
 
 config MACH_FLINT
 	bool "Marvell's Flint Development Platform"
+	depends on !(CPU_MOHAWK)
 	select CPU_MMP2
 	help
 	  Say 'Y' here if you want to support the Marvell MMP2-based
@@ -49,6 +50,7 @@ config MACH_FLINT
 
 config MACH_MARVELL_JASPER
 	bool "Marvell's Jasper Development Platform"
+	depends on !(CPU_MOHAWK)
 	select CPU_MMP2
 	help
 	  Say 'Y' here if you want to support the Marvell MMP2-base
@@ -80,8 +82,7 @@ config CPU_PXA910
 
 config CPU_MMP2
 	bool
-	select CPU_V6
-	select CPU_32v6K
+	select CPU_PJ4
 	help
 	  Select code specific to MMP2. MMP2 is ARMv6 compatible.
 endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index a099efe..163f4b1 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -795,7 +795,7 @@ config CACHE_PL310
 
 config CACHE_TAUROS2
 	bool "Enable the Tauros2 L2 cache controller"
-	depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
+	depends on (ARCH_DOVE || CPU_PJ4)
 	default y
 	select OUTER_CACHE
 	help
-- 
1.5.6.5

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

* [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset
  2010-11-12  7:17           ` [PATCH 07/11] ARM: mmp: select CPU_PJ4 Haojian Zhuang
@ 2010-11-12  7:17             ` Haojian Zhuang
  2010-11-12  7:17               ` [PATCH 09/11] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
  2011-01-09 22:49               ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Marek Vasut
  0 siblings, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
---
 arch/arm/mach-pxa/include/mach/regs-intc.h |    4 -
 arch/arm/mach-pxa/irq.c                    |  122 ++++++++++++++++++----------
 2 files changed, 80 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h
index 68464ce..662288e 100644
--- a/arch/arm/mach-pxa/include/mach/regs-intc.h
+++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
@@ -27,8 +27,4 @@
 #define ICFP3		__REG(0x40D0013C)  /* Interrupt Controller FIQ Pending Register 3 */
 #define ICPR3		__REG(0x40D00140)  /* Interrupt Controller Pending Register 3 */
 
-#define IPR(x)		__REG(0x40D0001C + (x < 32 ? (x << 2)		\
-				: (x < 64 ? (0x94 + ((x - 32) << 2))	\
-				: (0x128 + ((x - 64) << 2)))))
-
 #endif /* __ASM_MACH_REGS_INTC_H */
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index b5cafe2..54e91c9 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -16,20 +16,31 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
+#include <mach/irqs.h>
 #include <mach/gpio.h>
-#include <mach/regs-intc.h>
 
 #include "generic.h"
 
-#define MAX_INTERNAL_IRQS	128
+#define IRQ_BASE		(void __iomem *)io_p2v(0x40d00000)
+
+#define ICIP			(0x000)
+#define ICMR			(0x004)
+#define ICLR			(0x008)
+#define ICFR			(0x00c)
+#define ICPR			(0x010)
+#define ICCR			(0x014)
+#define ICHP			(0x018)
+#define IPR(i)			(((i) < 32) ? (0x01c + ((i) << 2)) :		\
+				((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) :	\
+				      (0x144 + (((i) - 64) << 2)))
+#define IPR_VALID		(1 << 31)
+#define IRQ_BIT(n)		(((n) - PXA_IRQ(0)) & 0x1f)
 
-#define IRQ_BIT(n)	(((n) - PXA_IRQ(0)) & 0x1f)
-#define _ICMR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
-#define _ICLR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
+#define MAX_INTERNAL_IRQS	128
 
 /*
  * This is for peripheral IRQs internal to the PXA chip.
@@ -44,12 +55,20 @@ static inline int cpu_has_ipr(void)
 
 static void pxa_mask_irq(unsigned int irq)
 {
-	_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
+	void __iomem *base = get_irq_chip_data(irq);
+	uint32_t icmr = __raw_readl(base + ICMR);
+
+	icmr &= ~(1 << IRQ_BIT(irq));
+	__raw_writel(icmr, base + ICMR);
 }
 
 static void pxa_unmask_irq(unsigned int irq)
 {
-	_ICMR(irq) |= 1 << IRQ_BIT(irq);
+	void __iomem *base = get_irq_chip_data(irq);
+	uint32_t icmr = __raw_readl(base + ICMR);
+
+	icmr |= 1 << IRQ_BIT(irq);
+	__raw_writel(icmr, base + ICMR);
 }
 
 static struct irq_chip pxa_internal_irq_chip = {
@@ -91,12 +110,16 @@ static void pxa_ack_low_gpio(unsigned int irq)
 
 static void pxa_mask_low_gpio(unsigned int irq)
 {
-	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	desc->chip->mask(irq);
 }
 
 static void pxa_unmask_low_gpio(unsigned int irq)
 {
-	ICMR |= 1 << (irq - PXA_IRQ(0));
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	desc->chip->unmask(irq);
 }
 
 static struct irq_chip pxa_low_gpio_chip = {
@@ -125,33 +148,45 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn)
 	pxa_low_gpio_chip.set_wake = fn;
 }
 
+static inline void __iomem *irq_base(int i)
+{
+	static unsigned long phys_base[] = {
+		0x40d00000,
+		0x40d0009c,
+		0x40d00130,
+	};
+
+	return (void __iomem *)io_p2v(phys_base[i >> 5]);
+}
+
 void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 {
-	int irq, i;
+	int irq, i, n;
 
 	BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
 
 	pxa_internal_irq_nr = irq_nr;
 
-	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
-		_ICMR(irq) = 0;	/* disable all IRQs */
-		_ICLR(irq) = 0;	/* all IRQs are IRQ, not FIQ */
-	}
-
-	/* initialize interrupt priority */
-	if (cpu_has_ipr()) {
-		for (i = 0; i < irq_nr; i++)
-			IPR(i) = i | (1 << 31);
+	for (n = 0; n < irq_nr; n += 32) {
+		void __iomem *base = irq_base(n);
+
+		__raw_writel(0, base + ICMR);	/* disable all IRQs */
+		__raw_writel(0, base + ICLR);	/* all IRQs are IRQ, not FIQ */
+		for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
+			/* initialize interrupt priority */
+			if (cpu_has_ipr())
+				__raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
+
+			irq = PXA_IRQ(i);
+			set_irq_chip(irq, &pxa_internal_irq_chip);
+			set_irq_chip_data(irq, base);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID);
+		}
 	}
 
 	/* only unmasked interrupts kick us out of idle */
-	ICCR = 1;
-
-	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
-		set_irq_chip(irq, &pxa_internal_irq_chip);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+	__raw_writel(1, irq_base(0) + ICCR);
 
 	pxa_internal_irq_chip.set_wake = fn;
 	pxa_init_low_gpio_irq(fn);
@@ -163,16 +198,18 @@ static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
 
 static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 {
-	int i, irq = PXA_IRQ(0);
+	int i;
+
+	for (i = 0; i < pxa_internal_irq_nr; i += 32) {
+		void __iomem *base = irq_base(i);
 
-	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
-		saved_icmr[i] = _ICMR(irq);
-		_ICMR(irq) = 0;
+		saved_icmr[i] = __raw_readl(base + ICMR);
+		__raw_writel(0, base + ICMR);
 	}
 
 	if (cpu_has_ipr()) {
 		for (i = 0; i < pxa_internal_irq_nr; i++)
-			saved_ipr[i] = IPR(i);
+			saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
 	}
 
 	return 0;
@@ -180,19 +217,20 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
 
 static int pxa_irq_resume(struct sys_device *dev)
 {
-	int i, irq = PXA_IRQ(0);
+	int i;
 
-	if (cpu_has_ipr()) {
-		for (i = 0; i < pxa_internal_irq_nr; i++)
-			IPR(i) = saved_ipr[i];
-	}
+	for (i = 0; i < pxa_internal_irq_nr; i += 32) {
+		void __iomem *base = irq_base(i);
 
-	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
-		_ICMR(irq) = saved_icmr[i];
-		_ICLR(irq) = 0;
+		__raw_writel(saved_icmr[i], base + ICMR);
+		__raw_writel(0, base + ICLR);
 	}
 
-	ICCR = 1;
+	if (!cpu_is_pxa25x())
+		for (i = 0; i < pxa_internal_irq_nr; i++)
+			__raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
+
+	__raw_writel(1, IRQ_BASE + ICCR);
 	return 0;
 }
 #else
-- 
1.5.6.5

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

* [PATCH 09/11] ARM: pxa: auto compute shift and mult of timer
  2010-11-12  7:17             ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
@ 2010-11-12  7:17               ` Haojian Zhuang
  2010-11-12  7:17                 ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
  2011-01-09 22:49               ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Marek Vasut
  1 sibling, 1 reply; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

Use auto-computed shift and mult of timer with new API
clocksource_calc_mult_shift()/clockevents_calc_mult_shift().

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Nicolas Pitre <nico@fluxnic.net>
---
 arch/arm/mach-pxa/time.c |    9 ++-------
 1 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 293e40a..dd96128 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -111,7 +111,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 static struct clock_event_device ckevt_pxa_osmr0 = {
 	.name		= "osmr0",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
 	.rating		= 200,
 	.set_next_event	= pxa_osmr0_set_next_event,
 	.set_mode	= pxa_osmr0_set_mode,
@@ -127,7 +126,6 @@ static struct clocksource cksrc_pxa_oscr0 = {
 	.rating         = 200,
 	.read           = pxa_read_oscr,
 	.mask           = CLOCKSOURCE_MASK(32),
-	.shift          = 20,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -147,17 +145,14 @@ static void __init pxa_timer_init(void)
 
 	set_oscr2ns_scale(clock_tick_rate);
 
-	ckevt_pxa_osmr0.mult =
-		div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+	clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
+	clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
 	ckevt_pxa_osmr0.max_delta_ns =
 		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
 	ckevt_pxa_osmr0.min_delta_ns =
 		clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
 	ckevt_pxa_osmr0.cpumask = cpumask_of(0);
 
-	cksrc_pxa_oscr0.mult =
-		clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
-
 	setup_irq(IRQ_OST0, &pxa_ost0_irq);
 
 	clocksource_register(&cksrc_pxa_oscr0);
-- 
1.5.6.5

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

* [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source
  2010-11-12  7:17               ` [PATCH 09/11] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
@ 2010-11-12  7:17                 ` Haojian Zhuang
  2010-11-12  7:17                   ` [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
  2010-11-12 17:50                   ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
  0 siblings, 2 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

PXA silicons are using 3MHz timer as default clock source. But it'll be stopped
counting in low power mode. Although 32KHz timer is slow, it can continue
counting in low power mode. While low power mode is implemented as idle,
stopped timer can't be accepted.

Add 32KHz timer as an alternative clock source. User can switch clock source
on demand.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Nicolas Pitre <nico@fluxnic.net>
---
 arch/arm/mach-pxa/include/mach/regs-ost.h |    2 +
 arch/arm/mach-pxa/time.c                  |  217 +++++++++++++++++++++++------
 2 files changed, 174 insertions(+), 45 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h
index a3e5f86..ac01d5c 100644
--- a/arch/arm/mach-pxa/include/mach/regs-ost.h
+++ b/arch/arm/mach-pxa/include/mach/regs-ost.h
@@ -19,6 +19,7 @@
 #define OWER		__REG(0x40A00018)  /* OS Timer Watchdog Enable Register */
 #define OIER		__REG(0x40A0001C)  /* OS Timer Interrupt Enable Register */
 
+#define OSSR_M4		(1 << 4)	/* Match status channel 4 */
 #define OSSR_M3		(1 << 3)	/* Match status channel 3 */
 #define OSSR_M2		(1 << 2)	/* Match status channel 2 */
 #define OSSR_M1		(1 << 1)	/* Match status channel 1 */
@@ -26,6 +27,7 @@
 
 #define OWER_WME	(1 << 0)	/* Watchdog Match Enable */
 
+#define OIER_E4		(1 << 4)	/* Interrupt enable channel 4 */
 #define OIER_E3		(1 << 3)	/* Interrupt enable channel 3 */
 #define OIER_E2		(1 << 2)	/* Interrupt enable channel 2 */
 #define OIER_E1		(1 << 1)	/* Interrupt enable channel 1 */
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index dd96128..d033995 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -7,6 +7,10 @@
  * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
  * by MontaVista Software, Inc.  (Nico, your code rocks!)
  *
+ * Support 32KHz timer as alternative timer. Copyright (c) 2010 by
+ * Marvell International Inc.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.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.
@@ -18,12 +22,21 @@
 #include <linux/clockchips.h>
 #include <linux/sched.h>
 #include <linux/cnt32_to_63.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include <asm/div64.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <mach/regs-ost.h>
 
+#define OSCR2NS_SCALE_FACTOR	10
+#define MIN_OSCR_DELTA		16
+#define PXA_CLOCK_32K		32768
+
+static struct clock_event_device ckevt_pxa;
+static atomic_t active_oscr0, active_32k;
+
 /*
  * This is PXA's sched_clock implementation. This has a resolution
  * of at least 308 ns and a maximum value of 208 days.
@@ -33,8 +46,6 @@
  * calls to sched_clock() which should always be the case in practice.
  */
 
-#define OSCR2NS_SCALE_FACTOR 10
-
 static unsigned long oscr2ns_scale;
 
 static void __init set_oscr2ns_scale(unsigned long oscr_rate)
@@ -53,15 +64,28 @@ static void __init set_oscr2ns_scale(unsigned long oscr_rate)
 
 unsigned long long sched_clock(void)
 {
-	unsigned long long v = cnt32_to_63(OSCR);
-	return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
+	unsigned long long v;
+
+	if (atomic_read(&active_32k) && !atomic_read(&active_oscr0)) {
+		/*
+		 * 32KHz timer is current clock source
+		 * 32768 / x = (10 ^ 9) / nsec
+		 * nsec = (10^9) / 32768 = (10^9) >> 15 = (5^9) >> 6
+		 */
+		v = (unsigned long long)OSCR4 * (5 ^ 9) >> 6;
+	} else {
+		v = cnt32_to_63(OSCR);
+		v = (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
+	}
+	return v;
 }
 
+static inline int cpu_has_32khz_timer(void)
+{
+	return !cpu_is_pxa25x();
+}
 
-#define MIN_OSCR_DELTA 16
-
-static irqreturn_t
-pxa_ost0_interrupt(int irq, void *dev_id)
+static irqreturn_t pxa_ost0_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *c = dev_id;
 
@@ -73,33 +97,80 @@ pxa_ost0_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int
-pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
+static struct irqaction pxa_ost0_irq = {
+	.name		= "ost0",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= pxa_ost0_interrupt,
+	.dev_id		= &ckevt_pxa,
+};
+
+static irqreturn_t pxa_32k_interrupt(int irq, void *dev_id)
 {
-	unsigned long next, oscr;
+	struct clock_event_device *c = dev_id;
 
-	OIER |= OIER_E0;
-	next = OSCR + delta;
-	OSMR0 = next;
-	oscr = OSCR;
+	OIER &= ~OIER_E4;
+	OSSR = OSSR_M4;
+	c->event_handler(c);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction pxa_ost4_irq = {
+	.name		= "ost4",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= pxa_32k_interrupt,
+	.dev_id		= &ckevt_pxa,
+};
 
-	return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+static int pxa_set_next_event(unsigned long delta,
+			      struct clock_event_device *dev)
+{
+	unsigned long next, oscr, oscr4;
+
+	if (atomic_read(&active_oscr0) && atomic_read(&active_32k)) {
+		OIER |= OIER_E0;
+		next = OSCR + (MIN_OSCR_DELTA << 1);
+		OSMR0 = next;
+		oscr = OSCR;
+		return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+	} else if (atomic_read(&active_32k)) {
+		OIER |= OIER_E4;
+		next = OSCR4 + delta;
+		OSMR4 = next;
+		oscr4 = OSCR4;
+		return (signed)(next - oscr4) <= MIN_OSCR_DELTA ? -ETIME : 0;
+	} else {
+		OIER |= OIER_E0;
+		next = OSCR + delta;
+		OSMR0 = next;
+		oscr = OSCR;
+		return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+	}
 }
 
-static void
-pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+static void pxa_set_mode(enum clock_event_mode mode,
+			 struct clock_event_device *dev)
 {
 	switch (mode) {
 	case CLOCK_EVT_MODE_ONESHOT:
-		OIER &= ~OIER_E0;
-		OSSR = OSSR_M0;
+		if (likely(atomic_read(&active_oscr0))) {
+			OIER &= ~OIER_E0;
+			OSSR = OSSR_M0;
+		} else {
+			OIER &= ~OIER_E4;
+			OSSR = OSSR_M4;
+		}
 		break;
 
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		/* initializing, released, or preparing for suspend */
-		OIER &= ~OIER_E0;
-		OSSR = OSSR_M0;
+		if (likely(atomic_read(&active_oscr0))) {
+			OIER &= ~OIER_E0;
+			OSSR = OSSR_M0;
+		} else {
+			OIER &= ~OIER_E4;
+			OSSR = OSSR_M4;
+		}
 		break;
 
 	case CLOCK_EVT_MODE_RESUME:
@@ -108,12 +179,12 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 	}
 }
 
-static struct clock_event_device ckevt_pxa_osmr0 = {
-	.name		= "osmr0",
+static struct clock_event_device ckevt_pxa = {
+	.name		= "osmr",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
 	.rating		= 200,
-	.set_next_event	= pxa_osmr0_set_next_event,
-	.set_mode	= pxa_osmr0_set_mode,
+	.set_next_event	= pxa_set_next_event,
+	.set_mode	= pxa_set_mode,
 };
 
 static cycle_t pxa_read_oscr(struct clocksource *cs)
@@ -121,42 +192,98 @@ static cycle_t pxa_read_oscr(struct clocksource *cs)
 	return OSCR;
 }
 
+static int pxa_ost0_enable(struct clocksource *cs)
+{
+	atomic_set(&active_oscr0, 1);
+	clockevents_calc_mult_shift(&ckevt_pxa, get_clock_tick_rate(), 4);
+	return 0;
+}
+
+static void pxa_ost0_disable(struct clocksource *cs)
+{
+	atomic_dec(&active_oscr0);
+}
+
 static struct clocksource cksrc_pxa_oscr0 = {
-	.name           = "oscr0",
-	.rating         = 200,
-	.read           = pxa_read_oscr,
-	.mask           = CLOCKSOURCE_MASK(32),
+	.name		= "oscr0",
+	.rating		= 200,
+	.read		= pxa_read_oscr,
+	.enable		= pxa_ost0_enable,
+	.disable	= pxa_ost0_disable,
+	.mask		= CLOCKSOURCE_MASK(32),
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static struct irqaction pxa_ost0_irq = {
-	.name		= "ost0",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= pxa_ost0_interrupt,
-	.dev_id		= &ckevt_pxa_osmr0,
+static cycle_t pxa_32k_read(struct clocksource *cs)
+{
+	return OSCR4;
+}
+
+static int pxa_32k_enable(struct clocksource *cs)
+{
+	atomic_set(&active_32k, 1);
+	clockevents_calc_mult_shift(&ckevt_pxa, PXA_CLOCK_32K, 4);
+	return 0;
+}
+
+static void pxa_32k_disable(struct clocksource *cs)
+{
+	atomic_dec(&active_32k);
+}
+
+static struct clocksource cksrc_pxa_32k = {
+	.name		= "oscr4",
+	.rating		= 150,
+	.read		= pxa_32k_read,
+	.enable		= pxa_32k_enable,
+	.disable	= pxa_32k_disable,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+/*
+ * The rating of OSCR0 _must_ be large than the rating of OSCR4.
+ * So default timer is OSCR0.
+ *
+ * While PXA SoC enters into low power mode, OSCR0 will stop. So using OSCR4
+ * as timer is alternative choice.
+ *
+ * While PXA SoC needs accurate timer, OSCR0 is the best choice.
+ */
 static void __init pxa_timer_init(void)
 {
 	unsigned long clock_tick_rate = get_clock_tick_rate();
 
 	OIER = 0;
-	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
+	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3 | OSSR_M4;
 
 	set_oscr2ns_scale(clock_tick_rate);
 
-	clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
-	clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
-	ckevt_pxa_osmr0.max_delta_ns =
-		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
-	ckevt_pxa_osmr0.min_delta_ns =
-		clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
-	ckevt_pxa_osmr0.cpumask = cpumask_of(0);
+	atomic_set(&active_oscr0, 0);
+	atomic_set(&active_32k, 0);
 
-	setup_irq(IRQ_OST0, &pxa_ost0_irq);
+	if (cpu_has_32khz_timer()) {
+		OMCR4 = 0xc1;		/* match OSCR4 & periodic timer */
+		OSMR4 = 0;
+		OSCR4 = 1;
+
+		clocksource_calc_mult_shift(&cksrc_pxa_32k, PXA_CLOCK_32K, 4);
+		setup_irq(IRQ_OST_4_11, &pxa_ost4_irq);
+		clocksource_register(&cksrc_pxa_32k);
+	}
 
+	clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
+	setup_irq(IRQ_OST0, &pxa_ost0_irq);
 	clocksource_register(&cksrc_pxa_oscr0);
-	clockevents_register_device(&ckevt_pxa_osmr0);
+
+	clockevents_calc_mult_shift(&ckevt_pxa, clock_tick_rate, 4);
+	ckevt_pxa.max_delta_ns =
+		clockevent_delta2ns(0x7fffffff, &ckevt_pxa);
+	ckevt_pxa.min_delta_ns =
+		clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa) + 1;
+	ckevt_pxa.cpumask = cpumask_of(0);
+
+	clockevents_register_device(&ckevt_pxa);
 }
 
 #ifdef CONFIG_PM
-- 
1.5.6.5

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

* [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4
  2010-11-12  7:17                 ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
@ 2010-11-12  7:17                   ` Haojian Zhuang
  2010-11-12 18:43                     ` Nicolas Pitre
  2010-11-12 17:50                   ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
  1 sibling, 1 reply; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

iwmmxt is used in XScale, XScale3, Mohawk and PJ4 core. But the instructions
of accessing CP0 and CP1 is changed in PJ4. Append more files to support
iwmmxt in PJ4 core.

Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Nicolas Pitre <nico@fluxnic.net>
---
 arch/arm/kernel/Makefile        |   14 +-
 arch/arm/kernel/iwmmxt.S        |  317 --------------------------------------
 arch/arm/kernel/pj4-cp0.c       |  180 ++++++++++++++++++++++
 arch/arm/kernel/pj4-iwmmxt.S    |  319 +++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/xscale-iwmmxt.S |  317 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 825 insertions(+), 322 deletions(-)
 delete mode 100644 arch/arm/kernel/iwmmxt.S
 create mode 100644 arch/arm/kernel/pj4-cp0.c
 create mode 100644 arch/arm/kernel/pj4-iwmmxt.S
 create mode 100644 arch/arm/kernel/xscale-iwmmxt.S

diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5b9b268..af5cd47 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -47,13 +47,17 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
 AFLAGS_crunch-bits.o		:= -Wa,-mcpu=ep9312
 
-obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
-obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
-obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
-obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
+ifeq ($(CONFIG_IWMMXT),y)
+  obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o xscale-iwmmxt.o
+  obj-$(CONFIG_CPU_XSC3)	+= xscale-cp0.o xscale-iwmmxt.o
+  obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o xscale-iwmmxt.o
+  AFLAGS_xscale-iwmmxt.o	:= -Wa,-mcpu=iwmmxt+iwmmxt2
+
+  obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o pj4-iwmmxt.o
+  AFLAGS_pj4-iwmmxt.o		:= -Wa,-mcpu=iwmmxt+iwmmxt2
+endif
 obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
-AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
   obj-y		+= io.o
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
deleted file mode 100644
index b63b528..0000000
--- a/arch/arm/kernel/iwmmxt.S
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- *  linux/arch/arm/kernel/iwmmxt.S
- *
- *  XScale iWMMXt (Concan) context switching and handling
- *
- *  Initial code:
- *  Copyright (c) 2003, Intel Corporation
- *
- *  Full lazy switching support, optimizations and more, by Nicolas Pitre
-*   Copyright (c) 2003-2004, MontaVista Software, Inc.
- *
- * 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 <asm/ptrace.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-
-#define MMX_WR0		 	(0x00)
-#define MMX_WR1		 	(0x08)
-#define MMX_WR2		 	(0x10)
-#define MMX_WR3			(0x18)
-#define MMX_WR4		 	(0x20)
-#define MMX_WR5		 	(0x28)
-#define MMX_WR6		 	(0x30)
-#define MMX_WR7		 	(0x38)
-#define MMX_WR8		 	(0x40)
-#define MMX_WR9		 	(0x48)
-#define MMX_WR10		(0x50)
-#define MMX_WR11		(0x58)
-#define MMX_WR12		(0x60)
-#define MMX_WR13		(0x68)
-#define MMX_WR14		(0x70)
-#define MMX_WR15		(0x78)
-#define MMX_WCSSF		(0x80)
-#define MMX_WCASF		(0x84)
-#define MMX_WCGR0		(0x88)
-#define MMX_WCGR1		(0x8C)
-#define MMX_WCGR2		(0x90)
-#define MMX_WCGR3		(0x94)
-
-#define MMX_SIZE		(0x98)
-
-	.text
-
-/*
- * Lazy switching of Concan coprocessor context
- *
- * r10 = struct thread_info pointer
- * r9  = ret_from_exception
- * lr  = undefined instr exit
- *
- * called from prefetch exception handler with interrupts disabled
- */
-
-ENTRY(iwmmxt_task_enable)
-
-	mrc	p15, 0, r2, c15, c1, 0
-	tst	r2, #0x3			@ CP0 and CP1 accessible?
-	movne	pc, lr				@ if so no business here
-	orr	r2, r2, #0x3			@ enable access to CP0 and CP1
-	mcr	p15, 0, r2, c15, c1, 0
-
-	ldr	r3, =concan_owner
-	add	r0, r10, #TI_IWMMXT_STATE	@ get task Concan save area
-	ldr	r2, [sp, #60]			@ current task pc value
-	ldr	r1, [r3]			@ get current Concan owner
-	str	r0, [r3]			@ this task now owns Concan regs
-	sub	r2, r2, #4			@ adjust pc back
-	str	r2, [sp, #60]
-
-	mrc	p15, 0, r2, c2, c0, 0
-	mov	r2, r2				@ cpwait
-
-	teq	r1, #0				@ test for last ownership
-	mov	lr, r9				@ normal exit from exception
-	beq	concan_load			@ no owner, skip save
-
-concan_save:
-
-	tmrc	r2, wCon
-
-	@ CUP? wCx
-	tst	r2, #0x1
-	beq 	1f
-
-concan_dump:
-
-	wstrw	wCSSF, [r1, #MMX_WCSSF]
-	wstrw	wCASF, [r1, #MMX_WCASF]
-	wstrw	wCGR0, [r1, #MMX_WCGR0]
-	wstrw	wCGR1, [r1, #MMX_WCGR1]
-	wstrw	wCGR2, [r1, #MMX_WCGR2]
-	wstrw	wCGR3, [r1, #MMX_WCGR3]
-
-1:	@ MUP? wRn
-	tst	r2, #0x2
-	beq	2f
-
-	wstrd	wR0,  [r1, #MMX_WR0]
-	wstrd	wR1,  [r1, #MMX_WR1]
-	wstrd	wR2,  [r1, #MMX_WR2]
-	wstrd	wR3,  [r1, #MMX_WR3]
-	wstrd	wR4,  [r1, #MMX_WR4]
-	wstrd	wR5,  [r1, #MMX_WR5]
-	wstrd	wR6,  [r1, #MMX_WR6]
-	wstrd	wR7,  [r1, #MMX_WR7]
-	wstrd	wR8,  [r1, #MMX_WR8]
-	wstrd	wR9,  [r1, #MMX_WR9]
-	wstrd	wR10, [r1, #MMX_WR10]
-	wstrd	wR11, [r1, #MMX_WR11]
-	wstrd	wR12, [r1, #MMX_WR12]
-	wstrd	wR13, [r1, #MMX_WR13]
-	wstrd	wR14, [r1, #MMX_WR14]
-	wstrd	wR15, [r1, #MMX_WR15]
-
-2:	teq	r0, #0				@ anything to load?
-	moveq	pc, lr
-
-concan_load:
-
-	@ Load wRn
-	wldrd	wR0,  [r0, #MMX_WR0]
-	wldrd	wR1,  [r0, #MMX_WR1]
-	wldrd	wR2,  [r0, #MMX_WR2]
-	wldrd	wR3,  [r0, #MMX_WR3]
-	wldrd	wR4,  [r0, #MMX_WR4]
-	wldrd	wR5,  [r0, #MMX_WR5]
-	wldrd	wR6,  [r0, #MMX_WR6]
-	wldrd	wR7,  [r0, #MMX_WR7]
-	wldrd	wR8,  [r0, #MMX_WR8]
-	wldrd	wR9,  [r0, #MMX_WR9]
-	wldrd	wR10, [r0, #MMX_WR10]
-	wldrd	wR11, [r0, #MMX_WR11]
-	wldrd	wR12, [r0, #MMX_WR12]
-	wldrd	wR13, [r0, #MMX_WR13]
-	wldrd	wR14, [r0, #MMX_WR14]
-	wldrd	wR15, [r0, #MMX_WR15]
-
-	@ Load wCx
-	wldrw	wCSSF, [r0, #MMX_WCSSF]
-	wldrw	wCASF, [r0, #MMX_WCASF]
-	wldrw	wCGR0, [r0, #MMX_WCGR0]
-	wldrw	wCGR1, [r0, #MMX_WCGR1]
-	wldrw	wCGR2, [r0, #MMX_WCGR2]
-	wldrw	wCGR3, [r0, #MMX_WCGR3]
-
-	@ clear CUP/MUP (only if r1 != 0)
-	teq	r1, #0
-	mov 	r2, #0
-	moveq	pc, lr
-	tmcr	wCon, r2
-	mov	pc, lr
-
-/*
- * Back up Concan regs to save area and disable access to them
- * (mainly for gdb or sleep mode usage)
- *
- * r0 = struct thread_info pointer of target task or NULL for any
- */
-
-ENTRY(iwmmxt_task_disable)
-
-	stmfd	sp!, {r4, lr}
-
-	mrs	ip, cpsr
-	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
-	msr	cpsr_c, r2
-
-	ldr	r3, =concan_owner
-	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
-	ldr	r1, [r3]			@ get current Concan owner
-	teq	r1, #0				@ any current owner?
-	beq	1f				@ no: quit
-	teq	r0, #0				@ any owner?
-	teqne	r1, r2				@ or specified one?
-	bne	1f				@ no: quit
-
-	mrc	p15, 0, r4, c15, c1, 0
-	orr	r4, r4, #0x3			@ enable access to CP0 and CP1
-	mcr	p15, 0, r4, c15, c1, 0
-	mov	r0, #0				@ nothing to load
-	str	r0, [r3]			@ no more current owner
-	mrc	p15, 0, r2, c2, c0, 0
-	mov	r2, r2				@ cpwait
-	bl	concan_save
-
-	bic	r4, r4, #0x3			@ disable access to CP0 and CP1
-	mcr	p15, 0, r4, c15, c1, 0
-	mrc	p15, 0, r2, c2, c0, 0
-	mov	r2, r2				@ cpwait
-
-1:	msr	cpsr_c, ip			@ restore interrupt mode
-	ldmfd	sp!, {r4, pc}
-
-/*
- * Copy Concan state to given memory address
- *
- * r0 = struct thread_info pointer of target task
- * r1 = memory address where to store Concan state
- *
- * this is called mainly in the creation of signal stack frames
- */
-
-ENTRY(iwmmxt_task_copy)
-
-	mrs	ip, cpsr
-	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
-	msr	cpsr_c, r2
-
-	ldr	r3, =concan_owner
-	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
-	ldr	r3, [r3]			@ get current Concan owner
-	teq	r2, r3				@ does this task own it...
-	beq	1f
-
-	@ current Concan values are in the task save area
-	msr	cpsr_c, ip			@ restore interrupt mode
-	mov	r0, r1
-	mov	r1, r2
-	mov	r2, #MMX_SIZE
-	b	memcpy
-
-1:	@ this task owns Concan regs -- grab a copy from there
-	mov	r0, #0				@ nothing to load
-	mov	r2, #3				@ save all regs
-	mov	r3, lr				@ preserve return address
-	bl	concan_dump
-	msr	cpsr_c, ip			@ restore interrupt mode
-	mov	pc, r3
-
-/*
- * Restore Concan state from given memory address
- *
- * r0 = struct thread_info pointer of target task
- * r1 = memory address where to get Concan state from
- *
- * this is used to restore Concan state when unwinding a signal stack frame
- */
-
-ENTRY(iwmmxt_task_restore)
-
-	mrs	ip, cpsr
-	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
-	msr	cpsr_c, r2
-
-	ldr	r3, =concan_owner
-	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
-	ldr	r3, [r3]			@ get current Concan owner
-	bic	r2, r2, #0x7			@ 64-bit alignment
-	teq	r2, r3				@ does this task own it...
-	beq	1f
-
-	@ this task doesn't own Concan regs -- use its save area
-	msr	cpsr_c, ip			@ restore interrupt mode
-	mov	r0, r2
-	mov	r2, #MMX_SIZE
-	b	memcpy
-
-1:	@ this task owns Concan regs -- load them directly
-	mov	r0, r1
-	mov	r1, #0				@ don't clear CUP/MUP
-	mov	r3, lr				@ preserve return address
-	bl	concan_load
-	msr	cpsr_c, ip			@ restore interrupt mode
-	mov	pc, r3
-
-/*
- * Concan handling on task switch
- *
- * r0 = next thread_info pointer
- *
- * Called only from the iwmmxt notifier with task preemption disabled.
- */
-ENTRY(iwmmxt_task_switch)
-
-	mrc	p15, 0, r1, c15, c1, 0
-	tst	r1, #0x3			@ CP0 and CP1 accessible?
-	bne	1f				@ yes: block them for next task
-
-	ldr	r2, =concan_owner
-	add	r3, r0, #TI_IWMMXT_STATE	@ get next task Concan save area
-	ldr	r2, [r2]			@ get current Concan owner
-	teq	r2, r3				@ next task owns it?
-	movne	pc, lr				@ no: leave Concan disabled
-
-1:	eor	r1, r1, #3			@ flip Concan access
-	mcr	p15, 0, r1, c15, c1, 0
-
-	mrc	p15, 0, r1, c2, c0, 0
-	sub	pc, lr, r1, lsr #32		@ cpwait and return
-
-/*
- * Remove Concan ownership of given task
- *
- * r0 = struct thread_info pointer
- */
-ENTRY(iwmmxt_task_release)
-
-	mrs	r2, cpsr
-	orr	ip, r2, #PSR_I_BIT		@ disable interrupts
-	msr	cpsr_c, ip
-	ldr	r3, =concan_owner
-	add	r0, r0, #TI_IWMMXT_STATE	@ get task Concan save area
-	ldr	r1, [r3]			@ get current Concan owner
-	eors	r0, r0, r1			@ if equal...
-	streq	r0, [r3]			@ then clear ownership
-	msr	cpsr_c, r2			@ restore interrupts
-	mov	pc, lr
-
-	.data
-concan_owner:
-	.word	0
-
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
new file mode 100644
index 0000000..6d5ee12
--- /dev/null
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/kernel/pj4-cp0.c
+ *
+ * XScale DSP and iWMMXt coprocessor context switching and handling
+ *
+ * Copyright (c) 2010 Marvell International Inc.
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/thread_notify.h>
+
+static inline void dsp_save_state(u32 *state)
+{
+	__asm__ __volatile__ (
+		"mrrc	p0, 0, %0, %1, c0\n"
+		: "=r" (state[0]), "=r" (state[1]));
+}
+
+static inline void dsp_load_state(u32 *state)
+{
+	__asm__ __volatile__ (
+		"mcrr	p0, 0, %0, %1, c0\n"
+		: : "r" (state[0]), "r" (state[1]));
+}
+
+static int dsp_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+	struct thread_info *thread = t;
+
+	switch (cmd) {
+	case THREAD_NOTIFY_FLUSH:
+		thread->cpu_context.extra[0] = 0;
+		thread->cpu_context.extra[1] = 0;
+		break;
+
+	case THREAD_NOTIFY_SWITCH:
+		dsp_save_state(current_thread_info()->cpu_context.extra);
+		dsp_load_state(thread->cpu_context.extra);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block dsp_notifier_block = {
+	.notifier_call	= dsp_do,
+};
+
+
+#ifdef CONFIG_IWMMXT
+static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+	struct thread_info *thread = t;
+
+	switch (cmd) {
+	case THREAD_NOTIFY_FLUSH:
+		/*
+		 * flush_thread() zeroes thread->fpstate, so no need
+		 * to do anything here.
+		 *
+		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
+		 * initialised state information on the first fault.
+		 */
+
+	case THREAD_NOTIFY_EXIT:
+		iwmmxt_task_release(thread);
+		break;
+
+	case THREAD_NOTIFY_SWITCH:
+		iwmmxt_task_switch(thread);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block iwmmxt_notifier_block = {
+	.notifier_call	= iwmmxt_do,
+};
+#endif
+
+
+static u32 __init pj4_cp_access_read(void)
+{
+	u32 value;
+
+	__asm__ __volatile__ (
+		"mrc	p15, 0, %0, c1, c0, 2\n\t"
+		: "=r" (value));
+	return value;
+}
+
+static void __init pj4_cp_access_write(u32 value)
+{
+	u32 temp;
+
+	__asm__ __volatile__ (
+		"mcr	p15, 0, %1, c1, c0, 2\n\t"
+		"mrc	p15, 0, %0, c1, c0, 2\n\t"
+		"mov	%0, %0\n\t"
+		"sub	pc, pc, #4\n\t"
+		: "=r" (temp) : "r" (value));
+}
+
+/*
+ * Detect whether we have a MAC coprocessor (40 bit register) or an
+ * iWMMXt coprocessor (64 bit registers) by loading 00000100:00000000
+ * into a coprocessor register and reading it back, and checking
+ * whether the upper word survived intact.
+ */
+static int __init cpu_has_iwmmxt(void)
+{
+	u32 lo;
+	u32 hi;
+
+	/*
+	 * This sequence is interpreted by the DSP coprocessor as:
+	 *	mar	acc0, %2, %3
+	 *	mra	%0, %1, acc0
+	 *
+	 * And by the iWMMXt coprocessor as:
+	 *	tmcrr	wR0, %2, %3
+	 *	tmrrc	%0, %1, wR0
+	 */
+	__asm__ __volatile__ (
+		"mcrr	p0, 0, %2, %3, c0\n"
+		"mrrc	p0, 0, %0, %1, c0\n"
+		: "=r" (lo), "=r" (hi)
+		: "r" (0), "r" (0x100));
+
+	return !!hi;
+}
+
+
+/*
+ * If we detect that the CPU has iWMMXt (and CONFIG_IWMMXT=y), we
+ * disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
+ * switch code handle iWMMXt context switching.  If on the other
+ * hand the CPU has a DSP coprocessor, we keep access to CP0 enabled
+ * all the time, and save/restore acc0 on context switch in non-lazy
+ * fashion.
+ */
+static int __init pj4_cp0_init(void)
+{
+	u32 cp_access;
+
+	cp_access = pj4_cp_access_read() & ~0xf;
+	pj4_cp_access_write(cp_access | 0xf);
+
+	if (cpu_has_iwmmxt()) {
+#ifndef CONFIG_IWMMXT
+		printk(KERN_WARNING "CAUTION: XScale iWMMXt coprocessor "
+			"detected, but kernel support is missing.\n");
+#else
+		printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n");
+		elf_hwcap |= HWCAP_IWMMXT;
+		thread_register_notifier(&iwmmxt_notifier_block);
+#endif
+	} else {
+		printk(KERN_INFO "XScale DSP coprocessor detected.\n");
+		thread_register_notifier(&dsp_notifier_block);
+		cp_access |= 1;
+	}
+
+	pj4_cp_access_write(cp_access);
+
+	return 0;
+}
+
+late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/pj4-iwmmxt.S b/arch/arm/kernel/pj4-iwmmxt.S
new file mode 100644
index 0000000..db500f3
--- /dev/null
+++ b/arch/arm/kernel/pj4-iwmmxt.S
@@ -0,0 +1,319 @@
+/*
+ *  linux/arch/arm/kernel/pj4-iwmmxt.S
+ *
+ *  PJ4 iWMMXt (Concan) context switching and handling
+ *
+ *  Initial code:
+ *  Copyright (c) 2003, Intel Corporation
+ *
+ *  Full lazy switching support, optimizations and more, by Nicolas Pitre
+ *  Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ *  Copyright (c) 2010 Marvell International Inc.
+ *
+ * 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 <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#define MMX_WR0		 	(0x00)
+#define MMX_WR1		 	(0x08)
+#define MMX_WR2		 	(0x10)
+#define MMX_WR3			(0x18)
+#define MMX_WR4		 	(0x20)
+#define MMX_WR5		 	(0x28)
+#define MMX_WR6		 	(0x30)
+#define MMX_WR7		 	(0x38)
+#define MMX_WR8		 	(0x40)
+#define MMX_WR9		 	(0x48)
+#define MMX_WR10		(0x50)
+#define MMX_WR11		(0x58)
+#define MMX_WR12		(0x60)
+#define MMX_WR13		(0x68)
+#define MMX_WR14		(0x70)
+#define MMX_WR15		(0x78)
+#define MMX_WCSSF		(0x80)
+#define MMX_WCASF		(0x84)
+#define MMX_WCGR0		(0x88)
+#define MMX_WCGR1		(0x8C)
+#define MMX_WCGR2		(0x90)
+#define MMX_WCGR3		(0x94)
+
+#define MMX_SIZE		(0x98)
+
+	.text
+
+/*
+ * Lazy switching of Concan coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9  = ret_from_exception
+ * lr  = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+
+ENTRY(iwmmxt_task_enable)
+
+	mrc	p15, 0, r2, c1, c0, 2
+	tst	r2, #0xf			@ CP0 and CP1 accessible?
+	movne	pc, lr				@ if so no business here
+	orr	r2, r2, #0xf			@ enable access to CP0 and CP1
+	mcr	p15, 0, r2, c1, c0, 2
+
+	ldr	r3, =concan_owner
+	add	r0, r10, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r2, [sp, #60]			@ current task pc value
+	ldr	r1, [r3]			@ get current Concan owner
+	str	r0, [r3]			@ this task now owns Concan regs
+	sub	r2, r2, #4			@ adjust pc back
+	str	r2, [sp, #60]
+
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+
+	teq	r1, #0				@ test for last ownership
+	mov	lr, r9				@ normal exit from exception
+	beq	concan_load			@ no owner, skip save
+
+concan_save:
+
+	tmrc	r2, wCon
+
+	@ CUP? wCx
+	tst	r2, #0x1
+	beq 	1f
+
+concan_dump:
+
+	wstrw	wCSSF, [r1, #MMX_WCSSF]
+	wstrw	wCASF, [r1, #MMX_WCASF]
+	wstrw	wCGR0, [r1, #MMX_WCGR0]
+	wstrw	wCGR1, [r1, #MMX_WCGR1]
+	wstrw	wCGR2, [r1, #MMX_WCGR2]
+	wstrw	wCGR3, [r1, #MMX_WCGR3]
+
+1:	@ MUP? wRn
+	tst	r2, #0x2
+	beq	2f
+
+	wstrd	wR0,  [r1, #MMX_WR0]
+	wstrd	wR1,  [r1, #MMX_WR1]
+	wstrd	wR2,  [r1, #MMX_WR2]
+	wstrd	wR3,  [r1, #MMX_WR3]
+	wstrd	wR4,  [r1, #MMX_WR4]
+	wstrd	wR5,  [r1, #MMX_WR5]
+	wstrd	wR6,  [r1, #MMX_WR6]
+	wstrd	wR7,  [r1, #MMX_WR7]
+	wstrd	wR8,  [r1, #MMX_WR8]
+	wstrd	wR9,  [r1, #MMX_WR9]
+	wstrd	wR10, [r1, #MMX_WR10]
+	wstrd	wR11, [r1, #MMX_WR11]
+	wstrd	wR12, [r1, #MMX_WR12]
+	wstrd	wR13, [r1, #MMX_WR13]
+	wstrd	wR14, [r1, #MMX_WR14]
+	wstrd	wR15, [r1, #MMX_WR15]
+
+2:	teq	r0, #0				@ anything to load?
+	moveq	pc, lr
+
+concan_load:
+
+	@ Load wRn
+	wldrd	wR0,  [r0, #MMX_WR0]
+	wldrd	wR1,  [r0, #MMX_WR1]
+	wldrd	wR2,  [r0, #MMX_WR2]
+	wldrd	wR3,  [r0, #MMX_WR3]
+	wldrd	wR4,  [r0, #MMX_WR4]
+	wldrd	wR5,  [r0, #MMX_WR5]
+	wldrd	wR6,  [r0, #MMX_WR6]
+	wldrd	wR7,  [r0, #MMX_WR7]
+	wldrd	wR8,  [r0, #MMX_WR8]
+	wldrd	wR9,  [r0, #MMX_WR9]
+	wldrd	wR10, [r0, #MMX_WR10]
+	wldrd	wR11, [r0, #MMX_WR11]
+	wldrd	wR12, [r0, #MMX_WR12]
+	wldrd	wR13, [r0, #MMX_WR13]
+	wldrd	wR14, [r0, #MMX_WR14]
+	wldrd	wR15, [r0, #MMX_WR15]
+
+	@ Load wCx
+	wldrw	wCSSF, [r0, #MMX_WCSSF]
+	wldrw	wCASF, [r0, #MMX_WCASF]
+	wldrw	wCGR0, [r0, #MMX_WCGR0]
+	wldrw	wCGR1, [r0, #MMX_WCGR1]
+	wldrw	wCGR2, [r0, #MMX_WCGR2]
+	wldrw	wCGR3, [r0, #MMX_WCGR3]
+
+	@ clear CUP/MUP (only if r1 != 0)
+	teq	r1, #0
+	mov 	r2, #0
+	moveq	pc, lr
+	tmcr	wCon, r2
+	mov	pc, lr
+
+/*
+ * Back up Concan regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+
+ENTRY(iwmmxt_task_disable)
+
+	stmfd	sp!, {r4, lr}
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r1, [r3]			@ get current Concan owner
+	teq	r1, #0				@ any current owner?
+	beq	1f				@ no: quit
+	teq	r0, #0				@ any owner?
+	teqne	r1, r2				@ or specified one?
+	bne	1f				@ no: quit
+
+	mrc	p15, 0, r4, c1, c0, 2
+	orr	r4, r4, #0xf			@ enable access to CP0 and CP1
+	mcr	p15, 0, r4, c1, c0, 2
+	mov	r0, #0				@ nothing to load
+	str	r0, [r3]			@ no more current owner
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+	bl	concan_save
+
+	bic	r4, r4, #0xf			@ disable access to CP0 and CP1
+	mcr	p15, 0, r4, c1, c0, 2
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+
+1:	msr	cpsr_c, ip			@ restore interrupt mode
+	ldmfd	sp!, {r4, pc}
+
+/*
+ * Copy Concan state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store Concan state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+
+ENTRY(iwmmxt_task_copy)
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r3, [r3]			@ get current Concan owner
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ current Concan values are in the task save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r1
+	mov	r1, r2
+	mov	r2, #MMX_SIZE
+	b	memcpy
+
+1:	@ this task owns Concan regs -- grab a copy from there
+	mov	r0, #0				@ nothing to load
+	mov	r2, #3				@ save all regs
+	mov	r3, lr				@ preserve return address
+	bl	concan_dump
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
+
+/*
+ * Restore Concan state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get Concan state from
+ *
+ * this is used to restore Concan state when unwinding a signal stack frame
+ */
+
+ENTRY(iwmmxt_task_restore)
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r3, [r3]			@ get current Concan owner
+	bic	r2, r2, #0x7			@ 64-bit alignment
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ this task doesn't own Concan regs -- use its save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r2
+	mov	r2, #MMX_SIZE
+	b	memcpy
+
+1:	@ this task owns Concan regs -- load them directly
+	mov	r0, r1
+	mov	r1, #0				@ don't clear CUP/MUP
+	mov	r3, lr				@ preserve return address
+	bl	concan_load
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
+
+/*
+ * Concan handling on task switch
+ *
+ * r0 = next thread_info pointer
+ *
+ * Called only from the iwmmxt notifier with task preemption disabled.
+ */
+ENTRY(iwmmxt_task_switch)
+
+	mrc	p15, 0, r1, c1, c0, 2
+	tst	r1, #0xf			@ CP0 and CP1 accessible?
+	bne	1f				@ yes: block them for next task
+
+	ldr	r2, =concan_owner
+	add	r3, r0, #TI_IWMMXT_STATE	@ get next task Concan save area
+	ldr	r2, [r2]			@ get current Concan owner
+	teq	r2, r3				@ next task owns it?
+	movne	pc, lr				@ no: leave Concan disabled
+
+1:	eor	r1, r1, #0xf			@ flip Concan access
+	mcr	p15, 0, r1, c1, c0, 2
+
+	mrc	p15, 0, r1, c2, c0, 0
+	sub	pc, lr, r1, lsr #32		@ cpwait and return
+
+/*
+ * Remove Concan ownership of given task
+ *
+ * r0 = struct thread_info pointer
+ */
+ENTRY(iwmmxt_task_release)
+
+	mrs	r2, cpsr
+	orr	ip, r2, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, ip
+	ldr	r3, =concan_owner
+	add	r0, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r1, [r3]			@ get current Concan owner
+	eors	r0, r0, r1			@ if equal...
+	streq	r0, [r3]			@ then clear ownership
+	msr	cpsr_c, r2			@ restore interrupts
+	mov	pc, lr
+
+	.data
+concan_owner:
+	.word	0
+
diff --git a/arch/arm/kernel/xscale-iwmmxt.S b/arch/arm/kernel/xscale-iwmmxt.S
new file mode 100644
index 0000000..b63b528
--- /dev/null
+++ b/arch/arm/kernel/xscale-iwmmxt.S
@@ -0,0 +1,317 @@
+/*
+ *  linux/arch/arm/kernel/iwmmxt.S
+ *
+ *  XScale iWMMXt (Concan) context switching and handling
+ *
+ *  Initial code:
+ *  Copyright (c) 2003, Intel Corporation
+ *
+ *  Full lazy switching support, optimizations and more, by Nicolas Pitre
+*   Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ * 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 <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#define MMX_WR0		 	(0x00)
+#define MMX_WR1		 	(0x08)
+#define MMX_WR2		 	(0x10)
+#define MMX_WR3			(0x18)
+#define MMX_WR4		 	(0x20)
+#define MMX_WR5		 	(0x28)
+#define MMX_WR6		 	(0x30)
+#define MMX_WR7		 	(0x38)
+#define MMX_WR8		 	(0x40)
+#define MMX_WR9		 	(0x48)
+#define MMX_WR10		(0x50)
+#define MMX_WR11		(0x58)
+#define MMX_WR12		(0x60)
+#define MMX_WR13		(0x68)
+#define MMX_WR14		(0x70)
+#define MMX_WR15		(0x78)
+#define MMX_WCSSF		(0x80)
+#define MMX_WCASF		(0x84)
+#define MMX_WCGR0		(0x88)
+#define MMX_WCGR1		(0x8C)
+#define MMX_WCGR2		(0x90)
+#define MMX_WCGR3		(0x94)
+
+#define MMX_SIZE		(0x98)
+
+	.text
+
+/*
+ * Lazy switching of Concan coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9  = ret_from_exception
+ * lr  = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+
+ENTRY(iwmmxt_task_enable)
+
+	mrc	p15, 0, r2, c15, c1, 0
+	tst	r2, #0x3			@ CP0 and CP1 accessible?
+	movne	pc, lr				@ if so no business here
+	orr	r2, r2, #0x3			@ enable access to CP0 and CP1
+	mcr	p15, 0, r2, c15, c1, 0
+
+	ldr	r3, =concan_owner
+	add	r0, r10, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r2, [sp, #60]			@ current task pc value
+	ldr	r1, [r3]			@ get current Concan owner
+	str	r0, [r3]			@ this task now owns Concan regs
+	sub	r2, r2, #4			@ adjust pc back
+	str	r2, [sp, #60]
+
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+
+	teq	r1, #0				@ test for last ownership
+	mov	lr, r9				@ normal exit from exception
+	beq	concan_load			@ no owner, skip save
+
+concan_save:
+
+	tmrc	r2, wCon
+
+	@ CUP? wCx
+	tst	r2, #0x1
+	beq 	1f
+
+concan_dump:
+
+	wstrw	wCSSF, [r1, #MMX_WCSSF]
+	wstrw	wCASF, [r1, #MMX_WCASF]
+	wstrw	wCGR0, [r1, #MMX_WCGR0]
+	wstrw	wCGR1, [r1, #MMX_WCGR1]
+	wstrw	wCGR2, [r1, #MMX_WCGR2]
+	wstrw	wCGR3, [r1, #MMX_WCGR3]
+
+1:	@ MUP? wRn
+	tst	r2, #0x2
+	beq	2f
+
+	wstrd	wR0,  [r1, #MMX_WR0]
+	wstrd	wR1,  [r1, #MMX_WR1]
+	wstrd	wR2,  [r1, #MMX_WR2]
+	wstrd	wR3,  [r1, #MMX_WR3]
+	wstrd	wR4,  [r1, #MMX_WR4]
+	wstrd	wR5,  [r1, #MMX_WR5]
+	wstrd	wR6,  [r1, #MMX_WR6]
+	wstrd	wR7,  [r1, #MMX_WR7]
+	wstrd	wR8,  [r1, #MMX_WR8]
+	wstrd	wR9,  [r1, #MMX_WR9]
+	wstrd	wR10, [r1, #MMX_WR10]
+	wstrd	wR11, [r1, #MMX_WR11]
+	wstrd	wR12, [r1, #MMX_WR12]
+	wstrd	wR13, [r1, #MMX_WR13]
+	wstrd	wR14, [r1, #MMX_WR14]
+	wstrd	wR15, [r1, #MMX_WR15]
+
+2:	teq	r0, #0				@ anything to load?
+	moveq	pc, lr
+
+concan_load:
+
+	@ Load wRn
+	wldrd	wR0,  [r0, #MMX_WR0]
+	wldrd	wR1,  [r0, #MMX_WR1]
+	wldrd	wR2,  [r0, #MMX_WR2]
+	wldrd	wR3,  [r0, #MMX_WR3]
+	wldrd	wR4,  [r0, #MMX_WR4]
+	wldrd	wR5,  [r0, #MMX_WR5]
+	wldrd	wR6,  [r0, #MMX_WR6]
+	wldrd	wR7,  [r0, #MMX_WR7]
+	wldrd	wR8,  [r0, #MMX_WR8]
+	wldrd	wR9,  [r0, #MMX_WR9]
+	wldrd	wR10, [r0, #MMX_WR10]
+	wldrd	wR11, [r0, #MMX_WR11]
+	wldrd	wR12, [r0, #MMX_WR12]
+	wldrd	wR13, [r0, #MMX_WR13]
+	wldrd	wR14, [r0, #MMX_WR14]
+	wldrd	wR15, [r0, #MMX_WR15]
+
+	@ Load wCx
+	wldrw	wCSSF, [r0, #MMX_WCSSF]
+	wldrw	wCASF, [r0, #MMX_WCASF]
+	wldrw	wCGR0, [r0, #MMX_WCGR0]
+	wldrw	wCGR1, [r0, #MMX_WCGR1]
+	wldrw	wCGR2, [r0, #MMX_WCGR2]
+	wldrw	wCGR3, [r0, #MMX_WCGR3]
+
+	@ clear CUP/MUP (only if r1 != 0)
+	teq	r1, #0
+	mov 	r2, #0
+	moveq	pc, lr
+	tmcr	wCon, r2
+	mov	pc, lr
+
+/*
+ * Back up Concan regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+
+ENTRY(iwmmxt_task_disable)
+
+	stmfd	sp!, {r4, lr}
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r1, [r3]			@ get current Concan owner
+	teq	r1, #0				@ any current owner?
+	beq	1f				@ no: quit
+	teq	r0, #0				@ any owner?
+	teqne	r1, r2				@ or specified one?
+	bne	1f				@ no: quit
+
+	mrc	p15, 0, r4, c15, c1, 0
+	orr	r4, r4, #0x3			@ enable access to CP0 and CP1
+	mcr	p15, 0, r4, c15, c1, 0
+	mov	r0, #0				@ nothing to load
+	str	r0, [r3]			@ no more current owner
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+	bl	concan_save
+
+	bic	r4, r4, #0x3			@ disable access to CP0 and CP1
+	mcr	p15, 0, r4, c15, c1, 0
+	mrc	p15, 0, r2, c2, c0, 0
+	mov	r2, r2				@ cpwait
+
+1:	msr	cpsr_c, ip			@ restore interrupt mode
+	ldmfd	sp!, {r4, pc}
+
+/*
+ * Copy Concan state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store Concan state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+
+ENTRY(iwmmxt_task_copy)
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r3, [r3]			@ get current Concan owner
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ current Concan values are in the task save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r1
+	mov	r1, r2
+	mov	r2, #MMX_SIZE
+	b	memcpy
+
+1:	@ this task owns Concan regs -- grab a copy from there
+	mov	r0, #0				@ nothing to load
+	mov	r2, #3				@ save all regs
+	mov	r3, lr				@ preserve return address
+	bl	concan_dump
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
+
+/*
+ * Restore Concan state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get Concan state from
+ *
+ * this is used to restore Concan state when unwinding a signal stack frame
+ */
+
+ENTRY(iwmmxt_task_restore)
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =concan_owner
+	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r3, [r3]			@ get current Concan owner
+	bic	r2, r2, #0x7			@ 64-bit alignment
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ this task doesn't own Concan regs -- use its save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r2
+	mov	r2, #MMX_SIZE
+	b	memcpy
+
+1:	@ this task owns Concan regs -- load them directly
+	mov	r0, r1
+	mov	r1, #0				@ don't clear CUP/MUP
+	mov	r3, lr				@ preserve return address
+	bl	concan_load
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
+
+/*
+ * Concan handling on task switch
+ *
+ * r0 = next thread_info pointer
+ *
+ * Called only from the iwmmxt notifier with task preemption disabled.
+ */
+ENTRY(iwmmxt_task_switch)
+
+	mrc	p15, 0, r1, c15, c1, 0
+	tst	r1, #0x3			@ CP0 and CP1 accessible?
+	bne	1f				@ yes: block them for next task
+
+	ldr	r2, =concan_owner
+	add	r3, r0, #TI_IWMMXT_STATE	@ get next task Concan save area
+	ldr	r2, [r2]			@ get current Concan owner
+	teq	r2, r3				@ next task owns it?
+	movne	pc, lr				@ no: leave Concan disabled
+
+1:	eor	r1, r1, #3			@ flip Concan access
+	mcr	p15, 0, r1, c15, c1, 0
+
+	mrc	p15, 0, r1, c2, c0, 0
+	sub	pc, lr, r1, lsr #32		@ cpwait and return
+
+/*
+ * Remove Concan ownership of given task
+ *
+ * r0 = struct thread_info pointer
+ */
+ENTRY(iwmmxt_task_release)
+
+	mrs	r2, cpsr
+	orr	ip, r2, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, ip
+	ldr	r3, =concan_owner
+	add	r0, r0, #TI_IWMMXT_STATE	@ get task Concan save area
+	ldr	r1, [r3]			@ get current Concan owner
+	eors	r0, r0, r1			@ if equal...
+	streq	r0, [r3]			@ then clear ownership
+	msr	cpsr_c, r2			@ restore interrupts
+	mov	pc, lr
+
+	.data
+concan_owner:
+	.word	0
+
-- 
1.5.6.5

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

* [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx
  2010-11-12  7:17 [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
  2010-11-12  7:17 ` [PATCH 02/11] ARM: pxa: redefine irqs.h Haojian Zhuang
@ 2010-11-12  8:00 ` Eric Miao
  2010-11-16 14:24   ` Eric Miao
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Miao @ 2010-11-12  8:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> PXA300/PXA310/PXA320/PXA930/PXA935 are sharing one cpu family id.
> It's a little confusion on cpu_is_pxa3xx().
>
> Now reduce the scope of cpu_is_pxa3xx(). Make it focusing on
> PXA300/PXA310/PXA320. PXA930/PXA935 is coverd by cpu_is_pxa93x().
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>

Applied.

> ---
> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 26 +++++++++-----------------
> ?1 files changed, 9 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
> index ca188cd..59f145a 100644
> --- a/arch/arm/mach-pxa/include/mach/hardware.h
> +++ b/arch/arm/mach-pxa/include/mach/hardware.h
> @@ -145,53 +145,44 @@
> ?#define __cpu_is_pxa27x(id) ? ?(0)
> ?#endif
>
> -#ifdef CONFIG_CPU_PXA300
> +#ifdef CONFIG_PXA3xx
> ?#define __cpu_is_pxa300(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> ? ? ? ? ? ? ? ?_id == 0x688; ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? })
> -#else
> -#define __cpu_is_pxa300(id) ? ?(0)
> -#endif
>
> -#ifdef CONFIG_CPU_PXA310
> ?#define __cpu_is_pxa310(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> ? ? ? ? ? ? ? ?_id == 0x689; ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? })
> -#else
> -#define __cpu_is_pxa310(id) ? ?(0)
> -#endif
>
> -#ifdef CONFIG_CPU_PXA320
> ?#define __cpu_is_pxa320(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> ? ? ? ? ? ? ? ?_id == 0x603 || _id == 0x682; ? ? ? ? ? \
> ? ? ? ? })
> ?#else
> +#define __cpu_is_pxa300(id) ? ?(0)
> +#define __cpu_is_pxa310(id) ? ?(0)
> ?#define __cpu_is_pxa320(id) ? ?(0)
> ?#endif
>
> -#ifdef CONFIG_CPU_PXA930
> +#ifdef CONFIG_PXA93x
> ?#define __cpu_is_pxa930(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> ? ? ? ? ? ? ? ?_id == 0x683; ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? })
> -#else
> -#define __cpu_is_pxa930(id) ? ?(0)
> -#endif
>
> -#ifdef CONFIG_CPU_PXA935
> ?#define __cpu_is_pxa935(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> ? ? ? ? ? ? ? ?_id == 0x693; ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? })
> ?#else
> +#define __cpu_is_pxa930(id) ? ?(0)
> ?#define __cpu_is_pxa935(id) ? ?(0)
> ?#endif
>
> @@ -264,7 +255,7 @@
> ?/*
> ?* CPUID Core Generation Bit
> ?* <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
> - * == 0x3 for pxa300/pxa310/pxa320
> + * == 0x3 for pxa300/pxa310/pxa320 and pxa930/pxa935
> ?*/
> ?#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
> ?#define __cpu_is_pxa2xx(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> @@ -279,8 +270,9 @@
> ?#ifdef CONFIG_PXA3xx
> ?#define __cpu_is_pxa3xx(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> - ? ? ? ? ? ? ? unsigned int _id = (id) >> 13 & 0x7; ? ?\
> - ? ? ? ? ? ? ? _id == 0x3; ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? __cpu_is_pxa300(id) ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? ? ? ? ? || __cpu_is_pxa310(id) ? ? ? ? ?\
> + ? ? ? ? ? ? ? ? ? ? ? || __cpu_is_pxa320(id); ? ? ? ? \
> ? ? ? ? })
> ?#else
> ?#define __cpu_is_pxa3xx(id) ? ?(0)
> --
> 1.5.6.5
>
>

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

* [PATCH 02/11] ARM: pxa: redefine irqs.h
  2010-11-12  7:17 ` [PATCH 02/11] ARM: pxa: redefine irqs.h Haojian Zhuang
  2010-11-12  7:17   ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Haojian Zhuang
@ 2010-11-12  8:02   ` Eric Miao
  1 sibling, 0 replies; 23+ messages in thread
From: Eric Miao @ 2010-11-12  8:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> A lot of componets of PXA93x are shared with PXA3xx. From CPUID, they belong
> to same family. But it's confustion that code of PXA93x is depend on PXA3xx
> by default.
>
> Now clean the scope of both PXA3xx and PXA93X. Only PXA300/PXA310/PXA320 is
> family member of PXA3xx. Only PXA930/PXA935 is family member of PXA93x. Remove
> the code dependany on IRQ definition.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>

Applied.

> ---
> ?arch/arm/mach-pxa/include/mach/irqs.h | ? 47 ++++++++++-----------------------
> ?arch/arm/mach-pxa/irq.c ? ? ? ? ? ? ? | ? 11 +++++--
> ?2 files changed, 22 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
> index d372caa..cb7ee26 100644
> --- a/arch/arm/mach-pxa/include/mach/irqs.h
> +++ b/arch/arm/mach-pxa/include/mach/irqs.h
> @@ -21,16 +21,14 @@
>
> ?#define PXA_IRQ(x) ? ? (PXA_ISA_IRQ_NUM + (x))
>
> -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
> ?#define IRQ_SSP3 ? ? ? PXA_IRQ(0) ? ? ?/* SSP3 service request */
> ?#define IRQ_MSL ? ? ? ? ? ? ? ?PXA_IRQ(1) ? ? ?/* MSL Interface interrupt */
> -#define IRQ_USBH2 ? ? ?PXA_IRQ(2) ? ? ?/* USB Host interrupt 1 (OHCI) */
> -#define IRQ_USBH1 ? ? ?PXA_IRQ(3) ? ? ?/* USB Host interrupt 2 (non-OHCI) */
> +#define IRQ_USBH2 ? ? ?PXA_IRQ(2) ? ? ?/* USB Host interrupt 1 (OHCI,PXA27x) */
> +#define IRQ_USBH1 ? ? ?PXA_IRQ(3) ? ? ?/* USB Host interrupt 2 (non-OHCI,PXA27x) */
> ?#define IRQ_KEYPAD ? ? PXA_IRQ(4) ? ? ?/* Key pad controller */
> -#define IRQ_MEMSTK ? ? PXA_IRQ(5) ? ? ?/* Memory Stick interrupt */
> +#define IRQ_MEMSTK ? ? PXA_IRQ(5) ? ? ?/* Memory Stick interrupt (PXA27x) */
> +#define IRQ_ACIPC0 ? ? PXA_IRQ(5) ? ? ?/* AP-CP Communication (PXA930) */
> ?#define IRQ_PWRI2C ? ? PXA_IRQ(6) ? ? ?/* Power I2C interrupt */
> -#endif
> -
> ?#define IRQ_HWUART ? ? PXA_IRQ(7) ? ? ?/* HWUART Transmit/Receive/Error (PXA26x) */
> ?#define IRQ_OST_4_11 ? PXA_IRQ(7) ? ? ?/* OS timer 4-11 matches (PXA27x) */
> ?#define ? ? ? ?IRQ_GPIO0 ? ? ? PXA_IRQ(8) ? ? ?/* GPIO0 Edge Detect */
> @@ -38,7 +36,8 @@
> ?#define ? ? ? ?IRQ_GPIO_2_x ? ?PXA_IRQ(10) ? ? /* GPIO[2-x] Edge Detect */
> ?#define ? ? ? ?IRQ_USB ? ? ? ? PXA_IRQ(11) ? ? /* USB Service */
> ?#define ? ? ? ?IRQ_PMU ? ? ? ? PXA_IRQ(12) ? ? /* Performance Monitoring Unit */
> -#define ? ? ? ?IRQ_I2S ? ? ? ? PXA_IRQ(13) ? ? /* I2S Interrupt */
> +#define ? ? ? ?IRQ_I2S ? ? ? ? PXA_IRQ(13) ? ? /* I2S Interrupt (PXA27x) */
> +#define IRQ_SSP4 ? ? ? PXA_IRQ(13) ? ? /* SSP4 service request (PXA3xx) */
> ?#define ? ? ? ?IRQ_AC97 ? ? ? ?PXA_IRQ(14) ? ? /* AC97 Interrupt */
> ?#define IRQ_ASSP ? ? ? PXA_IRQ(15) ? ? /* Audio SSP Service Request (PXA25x) */
> ?#define IRQ_USIM ? ? ? PXA_IRQ(15) ? ? /* Smart Card interface interrupt (PXA27x) */
> @@ -47,6 +46,7 @@
> ?#define ? ? ? ?IRQ_LCD ? ? ? ? PXA_IRQ(17) ? ? /* LCD Controller Service Request */
> ?#define ? ? ? ?IRQ_I2C ? ? ? ? PXA_IRQ(18) ? ? /* I2C Service Request */
> ?#define ? ? ? ?IRQ_ICP ? ? ? ? PXA_IRQ(19) ? ? /* ICP Transmit/Receive/Error */
> +#define IRQ_ACIPC2 ? ? PXA_IRQ(19) ? ? /* AP-CP Communication (PXA930) */
> ?#define ? ? ? ?IRQ_STUART ? ? ?PXA_IRQ(20) ? ? /* STUART Transmit/Receive/Error */
> ?#define ? ? ? ?IRQ_BTUART ? ? ?PXA_IRQ(21) ? ? /* BTUART Transmit/Receive/Error */
> ?#define ? ? ? ?IRQ_FFUART ? ? ?PXA_IRQ(22) ? ? /* FFUART Transmit/Receive/Error*/
> @@ -60,19 +60,17 @@
> ?#define ? ? ? ?IRQ_RTC1Hz ? ? ?PXA_IRQ(30) ? ? /* RTC HZ Clock Tick */
> ?#define ? ? ? ?IRQ_RTCAlrm ? ? PXA_IRQ(31) ? ? /* RTC Alarm */
>
> -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
> ?#define IRQ_TPM ? ? ? ? ? ? ? ?PXA_IRQ(32) ? ? /* TPM interrupt */
> ?#define IRQ_CAMERA ? ? PXA_IRQ(33) ? ? /* Camera Interface */
> -#endif
> -
> -#ifdef CONFIG_PXA3xx
> -#define IRQ_SSP4 ? ? ? PXA_IRQ(13) ? ? /* SSP4 service request */
> ?#define IRQ_CIR ? ? ? ? ? ? ? ?PXA_IRQ(34) ? ? /* Consumer IR */
> ?#define IRQ_COMM_WDT ? PXA_IRQ(35) ? ? /* Comm WDT interrupt */
> ?#define IRQ_TSI ? ? ? ? ? ? ? ?PXA_IRQ(36) ? ? /* Touch Screen Interface (PXA320) */
> +#define IRQ_ENHROT ? ? PXA_IRQ(37) ? ? /* Enhanced Rotary (PXA930) */
> ?#define IRQ_USIM2 ? ? ?PXA_IRQ(38) ? ? /* USIM2 Controller */
> -#define IRQ_GCU ? ? ? ? ? ? ? ?PXA_IRQ(39) ? ? /* Graphics Controller */
> +#define IRQ_GCU ? ? ? ? ? ? ? ?PXA_IRQ(39) ? ? /* Graphics Controller (PXA3xx) */
> +#define IRQ_ACIPC1 ? ? PXA_IRQ(40) ? ? /* AP-CP Communication (PXA930) */
> ?#define IRQ_MMC2 ? ? ? PXA_IRQ(41) ? ? /* MMC2 Controller */
> +#define IRQ_TRKBALL ? ?PXA_IRQ(43) ? ? /* Track Ball (PXA930) */
> ?#define IRQ_1WIRE ? ? ?PXA_IRQ(44) ? ? /* 1-Wire Controller */
> ?#define IRQ_NAND ? ? ? PXA_IRQ(45) ? ? /* NAND Controller */
> ?#define IRQ_USB2 ? ? ? PXA_IRQ(46) ? ? /* USB 2.0 Device Controller */
> @@ -80,30 +78,13 @@
> ?#define IRQ_WAKEUP1 ? ?PXA_IRQ(50) ? ? /* EXT_WAKEUP1 */
> ?#define IRQ_DMEMC ? ? ?PXA_IRQ(51) ? ? /* Dynamic Memory Controller */
> ?#define IRQ_MMC3 ? ? ? PXA_IRQ(55) ? ? /* MMC3 Controller (PXA310) */
> -#endif
>
> -#ifdef CONFIG_CPU_PXA935
> ?#define IRQ_U2O ? ? ? ? ? ? ? ?PXA_IRQ(64) ? ? /* USB OTG 2.0 Controller (PXA935) */
> ?#define IRQ_U2H ? ? ? ? ? ? ? ?PXA_IRQ(65) ? ? /* USB Host 2.0 Controller (PXA935) */
> -
> -#define IRQ_MMC3_PXA935 ? ? ? ?PXA_IRQ(72) ? ? /* MMC3 Controller (PXA935) */
> -#define IRQ_MMC4_PXA935 ? ? ? ?PXA_IRQ(73) ? ? /* MMC4 Controller (PXA935) */
> -#define IRQ_MMC5_PXA935 ? ? ? ?PXA_IRQ(74) ? ? /* MMC5 Controller (PXA935) */
> -
> +#define IRQ_PXA935_MMC0 ? ? ? ?PXA_IRQ(72) ? ? /* MMC0 Controller (PXA935) */
> +#define IRQ_PXA935_MMC1 ? ? ? ?PXA_IRQ(73) ? ? /* MMC1 Controller (PXA935) */
> +#define IRQ_PXA935_MMC2 ? ? ? ?PXA_IRQ(74) ? ? /* MMC2 Controller (PXA935) */
> ?#define IRQ_U2P ? ? ? ? ? ? ? ?PXA_IRQ(93) ? ? /* USB PHY D+/D- Lines (PXA935) */
> -#endif
> -
> -#ifdef CONFIG_CPU_PXA930
> -#define IRQ_ENHROT ? ? PXA_IRQ(37) ? ? /* Enhanced Rotary (PXA930) */
> -#define IRQ_ACIPC0 ? ? PXA_IRQ(5)
> -#define IRQ_ACIPC1 ? ? PXA_IRQ(40)
> -#define IRQ_ACIPC2 ? ? PXA_IRQ(19)
> -#define IRQ_TRKBALL ? ?PXA_IRQ(43) ? ? /* Track Ball */
> -#endif
> -
> -#ifdef CONFIG_CPU_PXA950
> -#define IRQ_GC500 ? ? ?PXA_IRQ(70) ? ? /* Graphics Controller (PXA950) */
> -#endif
>
> ?#define PXA_GPIO_IRQ_BASE ? ? ?PXA_IRQ(96)
> ?#define PXA_GPIO_IRQ_NUM ? ? ? (192)
> diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
> index 1beb40f..b5cafe2 100644
> --- a/arch/arm/mach-pxa/irq.c
> +++ b/arch/arm/mach-pxa/irq.c
> @@ -37,6 +37,11 @@
>
> ?static int pxa_internal_irq_nr;
>
> +static inline int cpu_has_ipr(void)
> +{
> + ? ? ? return !cpu_is_pxa25x();
> +}
> +
> ?static void pxa_mask_irq(unsigned int irq)
> ?{
> ? ? ? ?_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
> @@ -134,7 +139,7 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
> ? ? ? ?}
>
> ? ? ? ?/* initialize interrupt priority */
> - ? ? ? if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
> + ? ? ? if (cpu_has_ipr()) {
> ? ? ? ? ? ? ? ?for (i = 0; i < irq_nr; i++)
> ? ? ? ? ? ? ? ? ? ? ? ?IPR(i) = i | (1 << 31);
> ? ? ? ?}
> @@ -165,7 +170,7 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
> ? ? ? ? ? ? ? ?_ICMR(irq) = 0;
> ? ? ? ?}
>
> - ? ? ? if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
> + ? ? ? if (cpu_has_ipr()) {
> ? ? ? ? ? ? ? ?for (i = 0; i < pxa_internal_irq_nr; i++)
> ? ? ? ? ? ? ? ? ? ? ? ?saved_ipr[i] = IPR(i);
> ? ? ? ?}
> @@ -177,7 +182,7 @@ static int pxa_irq_resume(struct sys_device *dev)
> ?{
> ? ? ? ?int i, irq = PXA_IRQ(0);
>
> - ? ? ? if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
> + ? ? ? if (cpu_has_ipr()) {
> ? ? ? ? ? ? ? ?for (i = 0; i < pxa_internal_irq_nr; i++)
> ? ? ? ? ? ? ? ? ? ? ? ?IPR(i) = saved_ipr[i];
> ? ? ? ?}
> --
> 1.5.6.5
>
>

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

* [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx
  2010-11-12  7:17   ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Haojian Zhuang
  2010-11-12  7:17     ` [PATCH 04/11] ARM: pxa: update to read ICHP Haojian Zhuang
@ 2010-11-12  8:07     ` Eric Miao
  2010-11-12  8:47       ` Haojian Zhuang
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Miao @ 2010-11-12  8:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> In order to avoid confusion, seperate pxa93x from pxa3xx.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> ---
> ?arch/arm/mach-pxa/Kconfig ? ? ? ? ? ?| ? 18 +-
> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? | ? ?2 +-
> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ?| ? 20 ++
> ?arch/arm/mach-pxa/devices.c ? ? ? ? ?| ? 10 +-
> ?arch/arm/mach-pxa/generic.c ? ? ? ? ?| ? ?8 +-
> ?arch/arm/mach-pxa/generic.h ? ? ? ? ?| ? ?3 +-
> ?arch/arm/mach-pxa/mfp-pxa3xx.c ? ? ? | ? ?5 +-
> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? | ? ?9 -
> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? | ?206 ---------------
> ?arch/arm/mach-pxa/pxa93x.c ? ? ? ? ? | ?471 ++++++++++++++++++++++++++++++++++
> ?arch/arm/mach-pxa/saar.c ? ? ? ? ? ? | ? ?2 +-
> ?arch/arm/mach-pxa/smemc.c ? ? ? ? ? ?| ? 10 +-
> ?arch/arm/mach-pxa/tavorevb.c ? ? ? ? | ? ?2 +-
> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? | ? ?1 +
> ?arch/arm/plat-pxa/include/plat/mfp.h | ? ?4 +-
> ?15 files changed, 525 insertions(+), 246 deletions(-)
> ?delete mode 100644 arch/arm/mach-pxa/pxa930.c
> ?create mode 100644 arch/arm/mach-pxa/pxa93x.c
>
> diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
> index dd235ec..84123d4 100644
> --- a/arch/arm/mach-pxa/Kconfig
> +++ b/arch/arm/mach-pxa/Kconfig
> @@ -37,18 +37,18 @@ config MACH_LITTLETON
> ? ? ? ?select CPU_PXA310
>
> ?config MACH_TAVOREVB
> - ? ? ? bool "PXA930 Evaluation Board (aka TavorEVB)"
> - ? ? ? select PXA3xx
> + ? ? ? bool "PXA935 Evaluation Board (aka TavorEVB)"
> ? ? ? ?select CPU_PXA930
> + ? ? ? select CPU_PXA935
>
> ?config MACH_TAVOREVB3
> ? ? ? ?bool "PXA95x Development Platform (aka TavorEVB III)"
> ? ? ? ?select CPU_PXA950
>
> ?config MACH_SAAR
> - ? ? ? bool "PXA930 Handheld Platform (aka SAAR)"
> - ? ? ? select PXA3xx
> + ? ? ? bool "PXA935 Handheld Platform (aka SAAR)"
> ? ? ? ?select CPU_PXA930
> + ? ? ? select CPU_PXA935
>
> ?comment "Third Party Dev Platforms (sorted by vendor name)"
>
> @@ -639,15 +639,21 @@ config CPU_PXA320
> ? ? ? ?help
> ? ? ? ? ?PXA320 (codename Monahans-P)
>
> +config PXA93x
> + ? ? ? bool
> + ? ? ? select CPU_XSC3
> + ? ? ? help
> + ? ? ? ? Select code specific to PXA93x variants
> +
> ?config CPU_PXA930
> ? ? ? ?bool
> - ? ? ? select PXA3xx
> + ? ? ? select PXA93x
> ? ? ? ?help
> ? ? ? ? ?PXA930 (codename Tavor-P)
>
> ?config CPU_PXA935
> ? ? ? ?bool
> - ? ? ? select CPU_PXA930
> + ? ? ? select PXA93x
> ? ? ? ?help
> ? ? ? ? ?PXA935 (codename Tavor-P65)
>
> diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
> index e2f89c2..ebdb899 100644
> --- a/arch/arm/mach-pxa/Makefile
> +++ b/arch/arm/mach-pxa/Makefile
> @@ -19,9 +19,9 @@ endif
> ?obj-$(CONFIG_PXA25x) ? ? ? ? ? += mfp-pxa2xx.o pxa2xx.o pxa25x.o
> ?obj-$(CONFIG_PXA27x) ? ? ? ? ? += mfp-pxa2xx.o pxa2xx.o pxa27x.o
> ?obj-$(CONFIG_PXA3xx) ? ? ? ? ? += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
> +obj-$(CONFIG_PXA93x) ? ? ? ? ? += mfp-pxa3xx.o pxa93x.o smemc.o
> ?obj-$(CONFIG_CPU_PXA300) ? ? ? += pxa300.o
> ?obj-$(CONFIG_CPU_PXA320) ? ? ? += pxa320.o
> -obj-$(CONFIG_CPU_PXA930) ? ? ? += pxa930.o
>
> ?# NOTE: keep the order of boards in accordance to their order in Kconfig
>
> diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
> index d848874..0d824eb 100644
> --- a/arch/arm/mach-pxa/clock.h
> +++ b/arch/arm/mach-pxa/clock.h
> @@ -67,3 +67,23 @@ extern void clk_pxa3xx_cken_enable(struct clk *);
> ?extern void clk_pxa3xx_cken_disable(struct clk *);
> ?#endif
>
> +#ifdef CONFIG_PXA93x
> +#define DEFINE_PXA93_CKEN(_name, _cken, _rate, _delay) \
> +struct clk clk_##_name = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .ops ? ?= &clk_pxa93x_cken_ops, ? ? ? ? \
> + ? ? ? ? ? ? ? .rate ? = _rate, ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? .cken ? = CKEN_##_cken, ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .delay ?= _delay, ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? }
> +
> +#define DEFINE_PXA93_CK(_name, _cken, _ops) ? ? ? ? ? ?\
> +struct clk clk_##_name = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .ops ? ?= _ops, ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .cken ? = CKEN_##_cken, ? ? ? ? ? ? ? ? \
> + ? ? ? }
> +
> +extern const struct clkops clk_pxa93x_cken_ops;
> +extern void clk_pxa93x_cken_enable(struct clk *);
> +extern void clk_pxa93x_cken_disable(struct clk *);
> +#endif
> +
> diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
> index aaa1166..881ccc3 100644
> --- a/arch/arm/mach-pxa/devices.c
> +++ b/arch/arm/mach-pxa/devices.c
> @@ -342,7 +342,7 @@ struct platform_device pxa27x_device_i2c_power = {
> ?};
> ?#endif
>
> -#ifdef CONFIG_PXA3xx
> +#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
> ?static struct resource pxa3xx_resources_i2c_power[] = {
> ? ? ? ?{
> ? ? ? ? ? ? ? ?.start ?= 0x40f500c0,
> @@ -632,7 +632,7 @@ struct platform_device pxa25x_device_assp = {
> ?};
> ?#endif /* CONFIG_PXA25x */
>
> -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
> +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
>
> ?static struct resource pxa27x_resource_keypad[] = {
> ? ? ? ?[0] = {
> @@ -864,9 +864,9 @@ void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
> ?{
> ? ? ? ?pxa_register_device(&pxa27x_device_camera, info);
> ?}
> -#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
> +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA93x */
>
> -#ifdef CONFIG_PXA3xx
> +#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x)
> ?static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
>
> ?static struct resource pxa3xx_resource_ssp4[] = {
> @@ -1053,7 +1053,7 @@ struct platform_device pxa3xx_device_gcu = {
> ? ? ? ?},
> ?};
>
> -#endif /* CONFIG_PXA3xx */
> +#endif /* CONFIG_PXA3xx || CONFIG_PXA93x */
>
> ?/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
> ?* See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
> diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
> index d4ce8f9..84e2cc3 100644
> --- a/arch/arm/mach-pxa/generic.c
> +++ b/arch/arm/mach-pxa/generic.c
> @@ -29,6 +29,7 @@
> ?#include <mach/reset.h>
> ?#include <mach/gpio.h>
> ?#include <mach/smemc.h>
> +#include <mach/pxa3xx-regs.h>
>
> ?#include "generic.h"
>
> @@ -36,9 +37,10 @@ void clear_reset_status(unsigned int mask)
> ?{
> ? ? ? ?if (cpu_is_pxa2xx())
> ? ? ? ? ? ? ? ?pxa2xx_clear_reset_status(mask);
> -
> - ? ? ? if (cpu_is_pxa3xx())
> - ? ? ? ? ? ? ? pxa3xx_clear_reset_status(mask);
> + ? ? ? else {
> + ? ? ? ? ? ? ? /* RESET_STATUS_* has a 1:1 mapping with ARSR */
> + ? ? ? ? ? ? ? ARSR = mask;
> + ? ? ? }
> ?}
>
> ?unsigned long get_clock_tick_rate(void)
> diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
> index d2e8bc3..7dec811 100644
> --- a/arch/arm/mach-pxa/generic.h
> +++ b/arch/arm/mach-pxa/generic.h
> @@ -20,6 +20,7 @@ extern void __init pxa26x_init_irq(void);
> ?#endif
> ?extern void __init pxa27x_init_irq(void);
> ?extern void __init pxa3xx_init_irq(void);
> +extern void __init pxa93x_init_irq(void);
>
> ?extern void __init pxa_map_io(void);
> ?extern void __init pxa25x_map_io(void);
> @@ -58,10 +59,8 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
>
> ?#ifdef CONFIG_PXA3xx
> ?extern unsigned pxa3xx_get_clk_frequency_khz(int);
> -extern void pxa3xx_clear_reset_status(unsigned int);
> ?#else
> ?#define pxa3xx_get_clk_frequency_khz(x) ? ? ? ? ? ? ? ?(0)
> -static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
> ?#endif
>
> ?extern struct sysdev_class pxa_irq_sysclass;
> diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c
> index 7a270ee..1bb58a3 100644
> --- a/arch/arm/mach-pxa/mfp-pxa3xx.c
> +++ b/arch/arm/mach-pxa/mfp-pxa3xx.c
> @@ -62,9 +62,6 @@ struct sysdev_class pxa3xx_mfp_sysclass = {
>
> ?static int __init mfp_init_devicefs(void)
> ?{
> - ? ? ? if (cpu_is_pxa3xx())
> - ? ? ? ? ? ? ? return sysdev_class_register(&pxa3xx_mfp_sysclass);
> -
> - ? ? ? return 0;
> + ? ? ? return sysdev_class_register(&pxa3xx_mfp_sysclass);
> ?}
> ?postcore_initcall(mfp_init_devicefs);
> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
> index dc658ad..8957466 100644
> --- a/arch/arm/mach-pxa/pxa3xx.c
> +++ b/arch/arm/mach-pxa/pxa3xx.c
> @@ -50,9 +50,6 @@
> ?#define PECR_IE(n) ? ? ((1 << ((n) * 2)) << 28)
> ?#define PECR_IS(n) ? ? ((1 << ((n) * 2)) << 29)
>
> -/* crystal frequency to static memory controller multiplier (SMCFS) */
> -static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
> -
> ?/* crystal frequency to HSIO bus frequency multiplier (HSS) */
> ?static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
>
> @@ -100,12 +97,6 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
> ? ? ? ?return CLK / 1000;
> ?}
>
> -void pxa3xx_clear_reset_status(unsigned int mask)
> -{
> - ? ? ? /* RESET_STATUS_* has a 1:1 mapping with ARSR */
> - ? ? ? ARSR = mask;
> -}
> -
> ?/*
> ?* Return the current AC97 clock frequency.
> ?*/
> diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
> deleted file mode 100644
> index 7d29dd3..0000000
> --- a/arch/arm/mach-pxa/pxa930.c
> +++ /dev/null
> @@ -1,206 +0,0 @@
> -/*
> - * linux/arch/arm/mach-pxa/pxa930.c
> - *
> - * Code specific to PXA930
> - *
> - * Copyright (C) 2007-2008 Marvell Internation Ltd.
> - *
> - * 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/module.h>
> -#include <linux/kernel.h>
> -#include <linux/platform_device.h>
> -#include <linux/irq.h>
> -#include <linux/dma-mapping.h>
> -
> -#include <mach/pxa930.h>
> -
> -static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
> -
> - ? ? ? MFP_ADDR(GPIO0, 0x02e0),
> - ? ? ? MFP_ADDR(GPIO1, 0x02dc),
> - ? ? ? MFP_ADDR(GPIO2, 0x02e8),
> - ? ? ? MFP_ADDR(GPIO3, 0x02d8),
> - ? ? ? MFP_ADDR(GPIO4, 0x02e4),
> - ? ? ? MFP_ADDR(GPIO5, 0x02ec),
> - ? ? ? MFP_ADDR(GPIO6, 0x02f8),
> - ? ? ? MFP_ADDR(GPIO7, 0x02fc),
> - ? ? ? MFP_ADDR(GPIO8, 0x0300),
> - ? ? ? MFP_ADDR(GPIO9, 0x02d4),
> - ? ? ? MFP_ADDR(GPIO10, 0x02f4),
> - ? ? ? MFP_ADDR(GPIO11, 0x02f0),
> - ? ? ? MFP_ADDR(GPIO12, 0x0304),
> - ? ? ? MFP_ADDR(GPIO13, 0x0310),
> - ? ? ? MFP_ADDR(GPIO14, 0x0308),
> - ? ? ? MFP_ADDR(GPIO15, 0x030c),
> - ? ? ? MFP_ADDR(GPIO16, 0x04e8),
> - ? ? ? MFP_ADDR(GPIO17, 0x04f4),
> - ? ? ? MFP_ADDR(GPIO18, 0x04f8),
> - ? ? ? MFP_ADDR(GPIO19, 0x04fc),
> - ? ? ? MFP_ADDR(GPIO20, 0x0518),
> - ? ? ? MFP_ADDR(GPIO21, 0x051c),
> - ? ? ? MFP_ADDR(GPIO22, 0x04ec),
> - ? ? ? MFP_ADDR(GPIO23, 0x0500),
> - ? ? ? MFP_ADDR(GPIO24, 0x04f0),
> - ? ? ? MFP_ADDR(GPIO25, 0x0504),
> - ? ? ? MFP_ADDR(GPIO26, 0x0510),
> - ? ? ? MFP_ADDR(GPIO27, 0x0514),
> - ? ? ? MFP_ADDR(GPIO28, 0x0520),
> - ? ? ? MFP_ADDR(GPIO29, 0x0600),
> - ? ? ? MFP_ADDR(GPIO30, 0x0618),
> - ? ? ? MFP_ADDR(GPIO31, 0x0610),
> - ? ? ? MFP_ADDR(GPIO32, 0x060c),
> - ? ? ? MFP_ADDR(GPIO33, 0x061c),
> - ? ? ? MFP_ADDR(GPIO34, 0x0620),
> - ? ? ? MFP_ADDR(GPIO35, 0x0628),
> - ? ? ? MFP_ADDR(GPIO36, 0x062c),
> - ? ? ? MFP_ADDR(GPIO37, 0x0630),
> - ? ? ? MFP_ADDR(GPIO38, 0x0634),
> - ? ? ? MFP_ADDR(GPIO39, 0x0638),
> - ? ? ? MFP_ADDR(GPIO40, 0x063c),
> - ? ? ? MFP_ADDR(GPIO41, 0x0614),
> - ? ? ? MFP_ADDR(GPIO42, 0x0624),
> - ? ? ? MFP_ADDR(GPIO43, 0x0608),
> - ? ? ? MFP_ADDR(GPIO44, 0x0604),
> - ? ? ? MFP_ADDR(GPIO45, 0x050c),
> - ? ? ? MFP_ADDR(GPIO46, 0x0508),
> - ? ? ? MFP_ADDR(GPIO47, 0x02bc),
> - ? ? ? MFP_ADDR(GPIO48, 0x02b4),
> - ? ? ? MFP_ADDR(GPIO49, 0x02b8),
> - ? ? ? MFP_ADDR(GPIO50, 0x02c8),
> - ? ? ? MFP_ADDR(GPIO51, 0x02c0),
> - ? ? ? MFP_ADDR(GPIO52, 0x02c4),
> - ? ? ? MFP_ADDR(GPIO53, 0x02d0),
> - ? ? ? MFP_ADDR(GPIO54, 0x02cc),
> - ? ? ? MFP_ADDR(GPIO55, 0x029c),
> - ? ? ? MFP_ADDR(GPIO56, 0x02a0),
> - ? ? ? MFP_ADDR(GPIO57, 0x0294),
> - ? ? ? MFP_ADDR(GPIO58, 0x0298),
> - ? ? ? MFP_ADDR(GPIO59, 0x02a4),
> - ? ? ? MFP_ADDR(GPIO60, 0x02a8),
> - ? ? ? MFP_ADDR(GPIO61, 0x02b0),
> - ? ? ? MFP_ADDR(GPIO62, 0x02ac),
> - ? ? ? MFP_ADDR(GPIO63, 0x0640),
> - ? ? ? MFP_ADDR(GPIO64, 0x065c),
> - ? ? ? MFP_ADDR(GPIO65, 0x0648),
> - ? ? ? MFP_ADDR(GPIO66, 0x0644),
> - ? ? ? MFP_ADDR(GPIO67, 0x0674),
> - ? ? ? MFP_ADDR(GPIO68, 0x0658),
> - ? ? ? MFP_ADDR(GPIO69, 0x0654),
> - ? ? ? MFP_ADDR(GPIO70, 0x0660),
> - ? ? ? MFP_ADDR(GPIO71, 0x0668),
> - ? ? ? MFP_ADDR(GPIO72, 0x0664),
> - ? ? ? MFP_ADDR(GPIO73, 0x0650),
> - ? ? ? MFP_ADDR(GPIO74, 0x066c),
> - ? ? ? MFP_ADDR(GPIO75, 0x064c),
> - ? ? ? MFP_ADDR(GPIO76, 0x0670),
> - ? ? ? MFP_ADDR(GPIO77, 0x0678),
> - ? ? ? MFP_ADDR(GPIO78, 0x067c),
> - ? ? ? MFP_ADDR(GPIO79, 0x0694),
> - ? ? ? MFP_ADDR(GPIO80, 0x069c),
> - ? ? ? MFP_ADDR(GPIO81, 0x06a0),
> - ? ? ? MFP_ADDR(GPIO82, 0x06a4),
> - ? ? ? MFP_ADDR(GPIO83, 0x0698),
> - ? ? ? MFP_ADDR(GPIO84, 0x06bc),
> - ? ? ? MFP_ADDR(GPIO85, 0x06b4),
> - ? ? ? MFP_ADDR(GPIO86, 0x06b0),
> - ? ? ? MFP_ADDR(GPIO87, 0x06c0),
> - ? ? ? MFP_ADDR(GPIO88, 0x06c4),
> - ? ? ? MFP_ADDR(GPIO89, 0x06ac),
> - ? ? ? MFP_ADDR(GPIO90, 0x0680),
> - ? ? ? MFP_ADDR(GPIO91, 0x0684),
> - ? ? ? MFP_ADDR(GPIO92, 0x0688),
> - ? ? ? MFP_ADDR(GPIO93, 0x0690),
> - ? ? ? MFP_ADDR(GPIO94, 0x068c),
> - ? ? ? MFP_ADDR(GPIO95, 0x06a8),
> - ? ? ? MFP_ADDR(GPIO96, 0x06b8),
> - ? ? ? MFP_ADDR(GPIO97, 0x0410),
> - ? ? ? MFP_ADDR(GPIO98, 0x0418),
> - ? ? ? MFP_ADDR(GPIO99, 0x041c),
> - ? ? ? MFP_ADDR(GPIO100, 0x0414),
> - ? ? ? MFP_ADDR(GPIO101, 0x0408),
> - ? ? ? MFP_ADDR(GPIO102, 0x0324),
> - ? ? ? MFP_ADDR(GPIO103, 0x040c),
> - ? ? ? MFP_ADDR(GPIO104, 0x0400),
> - ? ? ? MFP_ADDR(GPIO105, 0x0328),
> - ? ? ? MFP_ADDR(GPIO106, 0x0404),
> -
> - ? ? ? MFP_ADDR(nXCVREN, 0x0204),
> - ? ? ? MFP_ADDR(DF_CLE_nOE, 0x020c),
> - ? ? ? MFP_ADDR(DF_nADV1_ALE, 0x0218),
> - ? ? ? MFP_ADDR(DF_SCLK_E, 0x0214),
> - ? ? ? MFP_ADDR(DF_SCLK_S, 0x0210),
> - ? ? ? MFP_ADDR(nBE0, 0x021c),
> - ? ? ? MFP_ADDR(nBE1, 0x0220),
> - ? ? ? MFP_ADDR(DF_nADV2_ALE, 0x0224),
> - ? ? ? MFP_ADDR(DF_INT_RnB, 0x0228),
> - ? ? ? MFP_ADDR(DF_nCS0, 0x022c),
> - ? ? ? MFP_ADDR(DF_nCS1, 0x0230),
> - ? ? ? MFP_ADDR(nLUA, 0x0254),
> - ? ? ? MFP_ADDR(nLLA, 0x0258),
> - ? ? ? MFP_ADDR(DF_nWE, 0x0234),
> - ? ? ? MFP_ADDR(DF_nRE_nOE, 0x0238),
> - ? ? ? MFP_ADDR(DF_ADDR0, 0x024c),
> - ? ? ? MFP_ADDR(DF_ADDR1, 0x0250),
> - ? ? ? MFP_ADDR(DF_ADDR2, 0x025c),
> - ? ? ? MFP_ADDR(DF_ADDR3, 0x0260),
> - ? ? ? MFP_ADDR(DF_IO0, 0x023c),
> - ? ? ? MFP_ADDR(DF_IO1, 0x0240),
> - ? ? ? MFP_ADDR(DF_IO2, 0x0244),
> - ? ? ? MFP_ADDR(DF_IO3, 0x0248),
> - ? ? ? MFP_ADDR(DF_IO4, 0x0264),
> - ? ? ? MFP_ADDR(DF_IO5, 0x0268),
> - ? ? ? MFP_ADDR(DF_IO6, 0x026c),
> - ? ? ? MFP_ADDR(DF_IO7, 0x0270),
> - ? ? ? MFP_ADDR(DF_IO8, 0x0274),
> - ? ? ? MFP_ADDR(DF_IO9, 0x0278),
> - ? ? ? MFP_ADDR(DF_IO10, 0x027c),
> - ? ? ? MFP_ADDR(DF_IO11, 0x0280),
> - ? ? ? MFP_ADDR(DF_IO12, 0x0284),
> - ? ? ? MFP_ADDR(DF_IO13, 0x0288),
> - ? ? ? MFP_ADDR(DF_IO14, 0x028c),
> - ? ? ? MFP_ADDR(DF_IO15, 0x0290),
> -
> - ? ? ? MFP_ADDR(GSIM_UIO, 0x0314),
> - ? ? ? MFP_ADDR(GSIM_UCLK, 0x0318),
> - ? ? ? MFP_ADDR(GSIM_UDET, 0x031c),
> - ? ? ? MFP_ADDR(GSIM_nURST, 0x0320),
> -
> - ? ? ? MFP_ADDR(PMIC_INT, 0x06c8),
> -
> - ? ? ? MFP_ADDR(RDY, 0x0200),
> -
> - ? ? ? MFP_ADDR_END,
> -};
> -
> -static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
> - ? ? ? MFP_ADDR(GPIO159, 0x0524),
> - ? ? ? MFP_ADDR(GPIO163, 0x0534),
> - ? ? ? MFP_ADDR(GPIO167, 0x0544),
> - ? ? ? MFP_ADDR(GPIO168, 0x0548),
> - ? ? ? MFP_ADDR(GPIO169, 0x054c),
> - ? ? ? MFP_ADDR(GPIO170, 0x0550),
> - ? ? ? MFP_ADDR(GPIO171, 0x0554),
> - ? ? ? MFP_ADDR(GPIO172, 0x0558),
> - ? ? ? MFP_ADDR(GPIO173, 0x055c),
> -
> - ? ? ? MFP_ADDR_END,
> -};
> -
> -static int __init pxa930_init(void)
> -{
> - ? ? ? if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
> - ? ? ? ? ? ? ? mfp_init_base(io_p2v(MFPR_BASE));
> - ? ? ? ? ? ? ? mfp_init_addr(pxa930_mfp_addr_map);
> - ? ? ? }
> -
> - ? ? ? if (cpu_is_pxa935())
> - ? ? ? ? ? ? ? mfp_init_addr(pxa935_mfp_addr_map);
> -
> - ? ? ? return 0;
> -}
> -
> -core_initcall(pxa930_init);
> diff --git a/arch/arm/mach-pxa/pxa93x.c b/arch/arm/mach-pxa/pxa93x.c
> new file mode 100644
> index 0000000..dc7fa9f
> --- /dev/null
> +++ b/arch/arm/mach-pxa/pxa93x.c
> @@ -0,0 +1,471 @@
> +/*
> + * linux/arch/arm/mach-pxa/pxa93x.c
> + *
> + * code specific to pxa93x aka Tavor
> + *
> + * Copyright (C) 2006 Marvell International Ltd.
> + *
> + * 2007-09-02: eric miao <eric.miao@marvell.com>
> + * ? ? ? ? ? ? initial version
> + *
> + * 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/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/pm.h>
> +#include <linux/platform_device.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/sysdev.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/gpio.h>
> +#include <mach/pxa3xx-regs.h>
> +#include <mach/pxa930.h>
> +#include <mach/reset.h>
> +#include <mach/pm.h>
> +#include <mach/dma.h>
> +#include <mach/regs-intc.h>
> +#include <plat/i2c.h>
> +
> +#include "generic.h"
> +#include "devices.h"
> +#include "clock.h"
> +
> +/* Crystal clock: 13MHz */
> +#define BASE_CLK ? ? ? 13000000
> +
> +/* Ring Oscillator Clock: 60MHz */
> +#define RO_CLK ? ? ? ? 60000000
> +
> +#define ACCR_D0CS ? ? ?(1 << 26)
> +#define ACCR_PCCE ? ? ?(1 << 11)
> +
> +#define PECR_IE(n) ? ? ((1 << ((n) * 2)) << 28)
> +#define PECR_IS(n) ? ? ((1 << ((n) * 2)) << 29)
> +
> +/* crystal frequency to HSIO bus frequency multiplier (HSS) */
> +static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
> +
> +static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
> +
> + ? ? ? MFP_ADDR(GPIO0, 0x02e0),
> + ? ? ? MFP_ADDR(GPIO1, 0x02dc),
> + ? ? ? MFP_ADDR(GPIO2, 0x02e8),
> + ? ? ? MFP_ADDR(GPIO3, 0x02d8),
> + ? ? ? MFP_ADDR(GPIO4, 0x02e4),
> + ? ? ? MFP_ADDR(GPIO5, 0x02ec),
> + ? ? ? MFP_ADDR(GPIO6, 0x02f8),
> + ? ? ? MFP_ADDR(GPIO7, 0x02fc),
> + ? ? ? MFP_ADDR(GPIO8, 0x0300),
> + ? ? ? MFP_ADDR(GPIO9, 0x02d4),
> + ? ? ? MFP_ADDR(GPIO10, 0x02f4),
> + ? ? ? MFP_ADDR(GPIO11, 0x02f0),
> + ? ? ? MFP_ADDR(GPIO12, 0x0304),
> + ? ? ? MFP_ADDR(GPIO13, 0x0310),
> + ? ? ? MFP_ADDR(GPIO14, 0x0308),
> + ? ? ? MFP_ADDR(GPIO15, 0x030c),
> + ? ? ? MFP_ADDR(GPIO16, 0x04e8),
> + ? ? ? MFP_ADDR(GPIO17, 0x04f4),
> + ? ? ? MFP_ADDR(GPIO18, 0x04f8),
> + ? ? ? MFP_ADDR(GPIO19, 0x04fc),
> + ? ? ? MFP_ADDR(GPIO20, 0x0518),
> + ? ? ? MFP_ADDR(GPIO21, 0x051c),
> + ? ? ? MFP_ADDR(GPIO22, 0x04ec),
> + ? ? ? MFP_ADDR(GPIO23, 0x0500),
> + ? ? ? MFP_ADDR(GPIO24, 0x04f0),
> + ? ? ? MFP_ADDR(GPIO25, 0x0504),
> + ? ? ? MFP_ADDR(GPIO26, 0x0510),
> + ? ? ? MFP_ADDR(GPIO27, 0x0514),
> + ? ? ? MFP_ADDR(GPIO28, 0x0520),
> + ? ? ? MFP_ADDR(GPIO29, 0x0600),
> + ? ? ? MFP_ADDR(GPIO30, 0x0618),
> + ? ? ? MFP_ADDR(GPIO31, 0x0610),
> + ? ? ? MFP_ADDR(GPIO32, 0x060c),
> + ? ? ? MFP_ADDR(GPIO33, 0x061c),
> + ? ? ? MFP_ADDR(GPIO34, 0x0620),
> + ? ? ? MFP_ADDR(GPIO35, 0x0628),
> + ? ? ? MFP_ADDR(GPIO36, 0x062c),
> + ? ? ? MFP_ADDR(GPIO37, 0x0630),
> + ? ? ? MFP_ADDR(GPIO38, 0x0634),
> + ? ? ? MFP_ADDR(GPIO39, 0x0638),
> + ? ? ? MFP_ADDR(GPIO40, 0x063c),
> + ? ? ? MFP_ADDR(GPIO41, 0x0614),
> + ? ? ? MFP_ADDR(GPIO42, 0x0624),
> + ? ? ? MFP_ADDR(GPIO43, 0x0608),
> + ? ? ? MFP_ADDR(GPIO44, 0x0604),
> + ? ? ? MFP_ADDR(GPIO45, 0x050c),
> + ? ? ? MFP_ADDR(GPIO46, 0x0508),
> + ? ? ? MFP_ADDR(GPIO47, 0x02bc),
> + ? ? ? MFP_ADDR(GPIO48, 0x02b4),
> + ? ? ? MFP_ADDR(GPIO49, 0x02b8),
> + ? ? ? MFP_ADDR(GPIO50, 0x02c8),
> + ? ? ? MFP_ADDR(GPIO51, 0x02c0),
> + ? ? ? MFP_ADDR(GPIO52, 0x02c4),
> + ? ? ? MFP_ADDR(GPIO53, 0x02d0),
> + ? ? ? MFP_ADDR(GPIO54, 0x02cc),
> + ? ? ? MFP_ADDR(GPIO55, 0x029c),
> + ? ? ? MFP_ADDR(GPIO56, 0x02a0),
> + ? ? ? MFP_ADDR(GPIO57, 0x0294),
> + ? ? ? MFP_ADDR(GPIO58, 0x0298),
> + ? ? ? MFP_ADDR(GPIO59, 0x02a4),
> + ? ? ? MFP_ADDR(GPIO60, 0x02a8),
> + ? ? ? MFP_ADDR(GPIO61, 0x02b0),
> + ? ? ? MFP_ADDR(GPIO62, 0x02ac),
> + ? ? ? MFP_ADDR(GPIO63, 0x0640),
> + ? ? ? MFP_ADDR(GPIO64, 0x065c),
> + ? ? ? MFP_ADDR(GPIO65, 0x0648),
> + ? ? ? MFP_ADDR(GPIO66, 0x0644),
> + ? ? ? MFP_ADDR(GPIO67, 0x0674),
> + ? ? ? MFP_ADDR(GPIO68, 0x0658),
> + ? ? ? MFP_ADDR(GPIO69, 0x0654),
> + ? ? ? MFP_ADDR(GPIO70, 0x0660),
> + ? ? ? MFP_ADDR(GPIO71, 0x0668),
> + ? ? ? MFP_ADDR(GPIO72, 0x0664),
> + ? ? ? MFP_ADDR(GPIO73, 0x0650),
> + ? ? ? MFP_ADDR(GPIO74, 0x066c),
> + ? ? ? MFP_ADDR(GPIO75, 0x064c),
> + ? ? ? MFP_ADDR(GPIO76, 0x0670),
> + ? ? ? MFP_ADDR(GPIO77, 0x0678),
> + ? ? ? MFP_ADDR(GPIO78, 0x067c),
> + ? ? ? MFP_ADDR(GPIO79, 0x0694),
> + ? ? ? MFP_ADDR(GPIO80, 0x069c),
> + ? ? ? MFP_ADDR(GPIO81, 0x06a0),
> + ? ? ? MFP_ADDR(GPIO82, 0x06a4),
> + ? ? ? MFP_ADDR(GPIO83, 0x0698),
> + ? ? ? MFP_ADDR(GPIO84, 0x06bc),
> + ? ? ? MFP_ADDR(GPIO85, 0x06b4),
> + ? ? ? MFP_ADDR(GPIO86, 0x06b0),
> + ? ? ? MFP_ADDR(GPIO87, 0x06c0),
> + ? ? ? MFP_ADDR(GPIO88, 0x06c4),
> + ? ? ? MFP_ADDR(GPIO89, 0x06ac),
> + ? ? ? MFP_ADDR(GPIO90, 0x0680),
> + ? ? ? MFP_ADDR(GPIO91, 0x0684),
> + ? ? ? MFP_ADDR(GPIO92, 0x0688),
> + ? ? ? MFP_ADDR(GPIO93, 0x0690),
> + ? ? ? MFP_ADDR(GPIO94, 0x068c),
> + ? ? ? MFP_ADDR(GPIO95, 0x06a8),
> + ? ? ? MFP_ADDR(GPIO96, 0x06b8),
> + ? ? ? MFP_ADDR(GPIO97, 0x0410),
> + ? ? ? MFP_ADDR(GPIO98, 0x0418),
> + ? ? ? MFP_ADDR(GPIO99, 0x041c),
> + ? ? ? MFP_ADDR(GPIO100, 0x0414),
> + ? ? ? MFP_ADDR(GPIO101, 0x0408),
> + ? ? ? MFP_ADDR(GPIO102, 0x0324),
> + ? ? ? MFP_ADDR(GPIO103, 0x040c),
> + ? ? ? MFP_ADDR(GPIO104, 0x0400),
> + ? ? ? MFP_ADDR(GPIO105, 0x0328),
> + ? ? ? MFP_ADDR(GPIO106, 0x0404),
> +
> + ? ? ? MFP_ADDR(nXCVREN, 0x0204),
> + ? ? ? MFP_ADDR(DF_CLE_nOE, 0x020c),
> + ? ? ? MFP_ADDR(DF_nADV1_ALE, 0x0218),
> + ? ? ? MFP_ADDR(DF_SCLK_E, 0x0214),
> + ? ? ? MFP_ADDR(DF_SCLK_S, 0x0210),
> + ? ? ? MFP_ADDR(nBE0, 0x021c),
> + ? ? ? MFP_ADDR(nBE1, 0x0220),
> + ? ? ? MFP_ADDR(DF_nADV2_ALE, 0x0224),
> + ? ? ? MFP_ADDR(DF_INT_RnB, 0x0228),
> + ? ? ? MFP_ADDR(DF_nCS0, 0x022c),
> + ? ? ? MFP_ADDR(DF_nCS1, 0x0230),
> + ? ? ? MFP_ADDR(nLUA, 0x0254),
> + ? ? ? MFP_ADDR(nLLA, 0x0258),
> + ? ? ? MFP_ADDR(DF_nWE, 0x0234),
> + ? ? ? MFP_ADDR(DF_nRE_nOE, 0x0238),
> + ? ? ? MFP_ADDR(DF_ADDR0, 0x024c),
> + ? ? ? MFP_ADDR(DF_ADDR1, 0x0250),
> + ? ? ? MFP_ADDR(DF_ADDR2, 0x025c),
> + ? ? ? MFP_ADDR(DF_ADDR3, 0x0260),
> + ? ? ? MFP_ADDR(DF_IO0, 0x023c),
> + ? ? ? MFP_ADDR(DF_IO1, 0x0240),
> + ? ? ? MFP_ADDR(DF_IO2, 0x0244),
> + ? ? ? MFP_ADDR(DF_IO3, 0x0248),
> + ? ? ? MFP_ADDR(DF_IO4, 0x0264),
> + ? ? ? MFP_ADDR(DF_IO5, 0x0268),
> + ? ? ? MFP_ADDR(DF_IO6, 0x026c),
> + ? ? ? MFP_ADDR(DF_IO7, 0x0270),
> + ? ? ? MFP_ADDR(DF_IO8, 0x0274),
> + ? ? ? MFP_ADDR(DF_IO9, 0x0278),
> + ? ? ? MFP_ADDR(DF_IO10, 0x027c),
> + ? ? ? MFP_ADDR(DF_IO11, 0x0280),
> + ? ? ? MFP_ADDR(DF_IO12, 0x0284),
> + ? ? ? MFP_ADDR(DF_IO13, 0x0288),
> + ? ? ? MFP_ADDR(DF_IO14, 0x028c),
> + ? ? ? MFP_ADDR(DF_IO15, 0x0290),
> +
> + ? ? ? MFP_ADDR(GSIM_UIO, 0x0314),
> + ? ? ? MFP_ADDR(GSIM_UCLK, 0x0318),
> + ? ? ? MFP_ADDR(GSIM_UDET, 0x031c),
> + ? ? ? MFP_ADDR(GSIM_nURST, 0x0320),
> +
> + ? ? ? MFP_ADDR(PMIC_INT, 0x06c8),
> +
> + ? ? ? MFP_ADDR(RDY, 0x0200),
> +
> + ? ? ? MFP_ADDR_END,
> +};
> +
> +static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
> + ? ? ? MFP_ADDR(GPIO159, 0x0524),
> + ? ? ? MFP_ADDR(GPIO163, 0x0534),
> + ? ? ? MFP_ADDR(GPIO167, 0x0544),
> + ? ? ? MFP_ADDR(GPIO168, 0x0548),
> + ? ? ? MFP_ADDR(GPIO169, 0x054c),
> + ? ? ? MFP_ADDR(GPIO170, 0x0550),
> + ? ? ? MFP_ADDR(GPIO171, 0x0554),
> + ? ? ? MFP_ADDR(GPIO172, 0x0558),
> + ? ? ? MFP_ADDR(GPIO173, 0x055c),
> +
> + ? ? ? MFP_ADDR_END,
> +};
> +
> +void pxa93x_clear_reset_status(unsigned int mask)
> +{
> + ? ? ? /* RESET_STATUS_* has a 1:1 mapping with ARSR */
> + ? ? ? ARSR = mask;
> +}

This is not necessary now.

> +
> +/*
> + * Return the current HSIO bus clock frequency
> + */
> +static unsigned long clk_pxa93x_hsio_getrate(struct clk *clk)
> +{
> + ? ? ? unsigned long acsr;
> + ? ? ? unsigned int hss, hsio_clk;
> +
> + ? ? ? acsr = ACSR;
> +
> + ? ? ? hss = (acsr >> 14) & 0x3;
> + ? ? ? hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
> +
> + ? ? ? return hsio_clk;
> +}

Provided that the AP side is exactly same as PXA3xx, I'm still not
convinced that PXA93x should be separated as a family.

> +
> +void clk_pxa93x_cken_enable(struct clk *clk)
> +{
> + ? ? ? unsigned long mask = 1ul << (clk->cken & 0x1f);
> +
> + ? ? ? if (clk->cken < 32)
> + ? ? ? ? ? ? ? CKENA |= mask;
> + ? ? ? else
> + ? ? ? ? ? ? ? CKENB |= mask;
> +}
> +
> +void clk_pxa93x_cken_disable(struct clk *clk)
> +{
> + ? ? ? unsigned long mask = 1ul << (clk->cken & 0x1f);
> +
> + ? ? ? if (clk->cken < 32)
> + ? ? ? ? ? ? ? CKENA &= ~mask;
> + ? ? ? else
> + ? ? ? ? ? ? ? CKENB &= ~mask;
> +}
> +
> +const struct clkops clk_pxa93x_cken_ops = {
> + ? ? ? .enable ? ? ? ? = clk_pxa93x_cken_enable,
> + ? ? ? .disable ? ? ? ?= clk_pxa93x_cken_disable,
> +};
> +
> +static const struct clkops clk_pxa93x_hsio_ops = {
> + ? ? ? .enable ? ? ? ? = clk_pxa93x_cken_enable,
> + ? ? ? .disable ? ? ? ?= clk_pxa93x_cken_disable,
> + ? ? ? .getrate ? ? ? ?= clk_pxa93x_hsio_getrate,
> +};
> +
> +static void clk_pout_enable(struct clk *clk)
> +{
> + ? ? ? OSCC |= OSCC_PEN;
> +}
> +
> +static void clk_pout_disable(struct clk *clk)
> +{
> + ? ? ? OSCC &= ~OSCC_PEN;
> +}
> +
> +static const struct clkops clk_pout_ops = {
> + ? ? ? .enable ? ? ? ? = clk_pout_enable,
> + ? ? ? .disable ? ? ? ?= clk_pout_disable,
> +};
> +
> +static void clk_dummy_enable(struct clk *clk)
> +{
> +}
> +
> +static void clk_dummy_disable(struct clk *clk)
> +{
> +}
> +
> +static const struct clkops clk_dummy_ops = {
> + ? ? ? .enable ? ? ? ? = clk_dummy_enable,
> + ? ? ? .disable ? ? ? ?= clk_dummy_disable,
> +};
> +
> +static struct clk clk_pxa93x_pout = {
> + ? ? ? .ops ? ? ? ? ? ?= &clk_pout_ops,
> + ? ? ? .rate ? ? ? ? ? = 13000000,
> + ? ? ? .delay ? ? ? ? ?= 70,
> +};
> +
> +static struct clk clk_dummy = {
> + ? ? ? .ops ? ? ? ? ? ?= &clk_dummy_ops,
> +};
> +
> +static DEFINE_PXA93_CK(pxa93x_lcd, LCD, &clk_pxa93x_hsio_ops);
> +static DEFINE_PXA93_CK(pxa93x_camera, CAMERA, &clk_pxa93x_hsio_ops);
> +static DEFINE_PXA93_CKEN(pxa93x_ffuart, FFUART, 14857000, 1);
> +static DEFINE_PXA93_CKEN(pxa93x_btuart, BTUART, 14857000, 1);
> +static DEFINE_PXA93_CKEN(pxa93x_stuart, STUART, 14857000, 1);
> +static DEFINE_PXA93_CKEN(pxa93x_i2c, I2C, 32842000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_keypad, KEYPAD, 32768, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_ssp1, SSP1, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_ssp2, SSP2, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_ssp3, SSP3, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_ssp4, SSP4, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_pwm0, PWM0, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_pwm1, PWM1, 13000000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_mmc1, MMC1, 19500000, 0);
> +static DEFINE_PXA93_CKEN(pxa93x_mmc2, MMC2, 19500000, 0);
> +
> +static struct clk_lookup pxa93x_clkregs[] = {
> + ? ? ? INIT_CLKREG(&clk_pxa93x_pout, NULL, "CLK_POUT"),
> + ? ? ? /* Power I2C clock is always on */
> + ? ? ? INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_lcd, "pxa2xx-fb", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_camera, NULL, "CAMCLK"),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_ffuart, "pxa2xx-uart.0", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_btuart, "pxa2xx-uart.1", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_stuart, "pxa2xx-uart.2", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_stuart, "pxa2xx-ir", "UARTCLK"),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_i2c, "pxa2xx-i2c.0", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_keypad, "pxa27x-keypad", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_ssp1, "pxa27x-ssp.0", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_ssp2, "pxa27x-ssp.1", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_ssp3, "pxa27x-ssp.2", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_ssp4, "pxa27x-ssp.3", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_pwm0, "pxa27x-pwm.0", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_pwm1, "pxa27x-pwm.1", NULL),
> +};
> +
> +static struct clk_lookup pxa930_clkregs[] = {
> + ? ? ? INIT_CLKREG(&clk_pxa93x_mmc1, "pxa2xx-mci.0", NULL),
> + ? ? ? INIT_CLKREG(&clk_pxa93x_mmc2, "pxa2xx-mci.1", NULL),
> +};
> +
> +static void pxa_ack_ext_wakeup(unsigned int irq)
> +{
> + ? ? ? PECR |= PECR_IS(irq - IRQ_WAKEUP0);
> +}
> +
> +static void pxa_mask_ext_wakeup(unsigned int irq)
> +{
> + ? ? ? ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
> + ? ? ? PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
> +}
> +
> +static void pxa_unmask_ext_wakeup(unsigned int irq)
> +{
> + ? ? ? ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
> + ? ? ? PECR |= PECR_IE(irq - IRQ_WAKEUP0);
> +}
> +
> +static int pxa_set_ext_wakeup_type(unsigned int irq, unsigned int flow_type)
> +{
> + ? ? ? if (flow_type & IRQ_TYPE_EDGE_RISING)
> + ? ? ? ? ? ? ? PWER |= 1 << (irq - IRQ_WAKEUP0);
> +
> + ? ? ? if (flow_type & IRQ_TYPE_EDGE_FALLING)
> + ? ? ? ? ? ? ? PWER |= 1 << (irq - IRQ_WAKEUP0 + 2);
> +
> + ? ? ? return 0;
> +}
> +
> +static struct irq_chip pxa_ext_wakeup_chip = {
> + ? ? ? .name ? ? ? ? ? = "WAKEUP",
> + ? ? ? .ack ? ? ? ? ? ?= pxa_ack_ext_wakeup,
> + ? ? ? .mask ? ? ? ? ? = pxa_mask_ext_wakeup,
> + ? ? ? .unmask ? ? ? ? = pxa_unmask_ext_wakeup,
> + ? ? ? .set_type ? ? ? = pxa_set_ext_wakeup_type,
> +};
> +
> +static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
> +{
> + ? ? ? set_irq_chip(IRQ_WAKEUP0, &pxa_ext_wakeup_chip);
> + ? ? ? set_irq_handler(IRQ_WAKEUP0, handle_edge_irq);
> + ? ? ? set_irq_flags(IRQ_WAKEUP0, IRQF_VALID);
> +
> + ? ? ? pxa_ext_wakeup_chip.set_wake = fn;
> +}
> +
> +void __init pxa93x_init_irq(void)
> +{
> + ? ? ? /* enable CP6 access */
> + ? ? ? u32 value;
> + ? ? ? __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
> + ? ? ? value |= (1 << 6);
> + ? ? ? __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
> +
> + ? ? ? pxa_init_irq(96, NULL);
> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
> +}
> +
> +/*
> + * device registration specific to PXA93x.
> + */
> +
> +void __init pxa93x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
> +{
> + ? ? ? pxa_register_device(&pxa3xx_device_i2c_power, info);
> +}
> +
> +static struct platform_device *devices[] __initdata = {
> + ? ? ? &sa1100_device_rtc,
> + ? ? ? &pxa_device_rtc,
> + ? ? ? &pxa27x_device_ssp1,
> + ? ? ? &pxa27x_device_ssp2,
> + ? ? ? &pxa27x_device_ssp3,
> + ? ? ? &pxa3xx_device_ssp4,
> + ? ? ? &pxa27x_device_pwm0,
> + ? ? ? &pxa27x_device_pwm1,
> +};
> +
> +static int __init pxa93x_init(void)
> +{
> + ? ? ? int ret = 0;
> +
> + ? ? ? if (cpu_is_pxa93x()) {
> + ? ? ? ? ? ? ? mfp_init_base(io_p2v(MFPR_BASE));
> + ? ? ? ? ? ? ? mfp_init_addr(pxa930_mfp_addr_map);
> +
> + ? ? ? ? ? ? ? if (cpu_is_pxa935())
> + ? ? ? ? ? ? ? ? ? ? ? mfp_init_addr(pxa935_mfp_addr_map);
> +
> + ? ? ? ? ? ? ? reset_status = ARSR;
> +
> + ? ? ? ? ? ? ? /*
> + ? ? ? ? ? ? ? ?* clear RDH bit every time after reset
> + ? ? ? ? ? ? ? ?*
> + ? ? ? ? ? ? ? ?* Note: the last 3 bits DxS are write-1-to-clear so carefully
> + ? ? ? ? ? ? ? ?* preserve them here in case they will be referenced later
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
> +
> + ? ? ? ? ? ? ? clkdev_add_table(pxa93x_clkregs, ARRAY_SIZE(pxa93x_clkregs));
> + ? ? ? ? ? ? ? if (cpu_is_pxa930())
> + ? ? ? ? ? ? ? ? ? ? ? clkdev_add_table(pxa930_clkregs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ARRAY_SIZE(pxa930_clkregs));
> +
> + ? ? ? ? ? ? ? if ((ret = pxa_init_dma(IRQ_DMA, 32)))
> + ? ? ? ? ? ? ? ? ? ? ? return ret;
> +
> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
> + ? ? ? }
> +
> + ? ? ? return ret;
> +}
> +
> +postcore_initcall(pxa93x_init);
> diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
> index c1ca8cb..4a166ce 100644
> --- a/arch/arm/mach-pxa/saar.c
> +++ b/arch/arm/mach-pxa/saar.c
> @@ -598,7 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
> ? ? ? ?/* Maintainer: Eric Miao <eric.miao@marvell.com> */
> ? ? ? ?.boot_params ? ?= 0xa0000100,
> ? ? ? ?.map_io ? ? ? ? = pxa3xx_map_io,
> - ? ? ? .init_irq ? ? ? = pxa3xx_init_irq,
> + ? ? ? .init_irq ? ? ? = pxa93x_init_irq,
> ? ? ? ?.timer ? ? ? ? ?= &pxa_timer,
> ? ? ? ?.init_machine ? = saar_init,
> ?MACHINE_END
> diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
> index 232b731..ebee414 100644
> --- a/arch/arm/mach-pxa/smemc.c
> +++ b/arch/arm/mach-pxa/smemc.c
> @@ -59,13 +59,11 @@ static int __init smemc_init(void)
> ?{
> ? ? ? ?int ret = 0;
>
> - ? ? ? if (cpu_is_pxa3xx()) {
> - ? ? ? ? ? ? ? ret = sysdev_class_register(&smemc_sysclass);
> - ? ? ? ? ? ? ? if (ret)
> - ? ? ? ? ? ? ? ? ? ? ? return ret;
> + ? ? ? ret = sysdev_class_register(&smemc_sysclass);
> + ? ? ? if (ret)
> + ? ? ? ? ? ? ? return ret;
>
> - ? ? ? ? ? ? ? ret = sysdev_register(&smemc_sysdev);
> - ? ? ? }
> + ? ? ? ret = sysdev_register(&smemc_sysdev);
>
> ? ? ? ?return ret;
> ?}
> diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
> index 9cecf83..15ac912 100644
> --- a/arch/arm/mach-pxa/tavorevb.c
> +++ b/arch/arm/mach-pxa/tavorevb.c
> @@ -491,7 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
> ? ? ? ?/* Maintainer: Eric Miao <eric.miao@marvell.com> */
> ? ? ? ?.boot_params ? ?= 0xa0000100,
> ? ? ? ?.map_io ? ? ? ? = pxa3xx_map_io,
> - ? ? ? .init_irq ? ? ? = pxa3xx_init_irq,
> + ? ? ? .init_irq ? ? ? = pxa93x_init_irq,
> ? ? ? ?.timer ? ? ? ? ?= &pxa_timer,
> ? ? ? ?.init_machine ? = tavorevb_init,
> ?MACHINE_END
> diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
> index 4aacdd1..4ac2fd9 100644
> --- a/arch/arm/plat-pxa/Makefile
> +++ b/arch/arm/plat-pxa/Makefile
> @@ -6,6 +6,7 @@ obj-y ? := dma.o
>
> ?obj-$(CONFIG_GENERIC_GPIO) ? ? += gpio.o
> ?obj-$(CONFIG_PXA3xx) ? ? ? ? ? += mfp.o
> +obj-$(CONFIG_PXA93x) ? ? ? ? ? += mfp.o
> ?obj-$(CONFIG_ARCH_MMP) ? ? ? ? += mfp.o
>
> ?obj-$(CONFIG_HAVE_PWM) ? ? ? ? += pwm.o
> diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
> index 9e604c8..a3a2a65 100644
> --- a/arch/arm/plat-pxa/include/plat/mfp.h
> +++ b/arch/arm/plat-pxa/include/plat/mfp.h
> @@ -423,7 +423,7 @@ typedef unsigned long mfp_cfg_t;
> ? ? ? ?((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
> ? ? ? ? (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
>
> -#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
> +#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA93x) || defined(CONFIG_ARCH_MMP)
> ?/*
> ?* each MFP pin will have a MFPR register, since the offset of the
> ?* register varies between processors, the processor specific code
> @@ -470,6 +470,6 @@ void mfp_write(int mfp, unsigned long mfpr_val);
> ?void mfp_config(unsigned long *mfp_cfgs, int num);
> ?void mfp_config_run(void);
> ?void mfp_config_lpm(void);
> -#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
> +#endif /* CONFIG_PXA3xx || CONFIG_PXA93x || CONFIG_ARCH_MMP */
>
> ?#endif /* __ASM_PLAT_MFP_H */
> --
> 1.5.6.5
>
>

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

* [PATCH 04/11] ARM: pxa: update to read ICHP
  2010-11-12  7:17     ` [PATCH 04/11] ARM: pxa: update to read ICHP Haojian Zhuang
  2010-11-12  7:17       ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
@ 2010-11-12  8:34       ` Eric Miao
  2010-11-12  8:53         ` Haojian Zhuang
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Miao @ 2010-11-12  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> ICHP records the highest priority interrupt occured. In PXA27x/PXA3xx, we
> can read ICHP via cooprocessor. In PJ4, we can only read ICHP via bus
> register. So use the same method to read ICHP via bus register.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> ---
> ?arch/arm/mach-pxa/include/mach/entry-macro.S | ? ?6 +++++-
> ?1 files changed, 5 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S
> index a73bc86..91457dd 100644
> --- a/arch/arm/mach-pxa/include/mach/entry-macro.S
> +++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
> @@ -41,11 +41,15 @@
> ? ? ? ? ? ? ? ?b ? ? ? 1001f
> ?1002:
> ? ? ? ? ? ? ? ?@ Core Generation 2 (PXA27x) or Core Generation 3 (PXA3xx)
> - ? ? ? ? ? ? ? mrc ? ? p6, 0, \irqstat, c5, c0, 0 ? ? ?@ ICHP
> + ? ? ? ? ? ? ? @ or Core PJ4
> + ? ? ? ? ? ? ? mov ? ? \base, #io_p2v(0x40000000) ? ? ?@ IIR Ctl = 0x40d00000
> + ? ? ? ? ? ? ? add ? ? \base, \base, #0x00d00000
> + ? ? ? ? ? ? ? ldr ? ? \irqstat, [\base, #0x18] ? ? ? ?@ ICHP offset

Accessing from co-processor is supposed to be faster than MMIO.

BTW, this could be addressed by MULTI_IRQ_HANDLER as in patch:

http://www.spinics.net/lists/arm-kernel/msg88817.html

Once it gets merged.

> ? ? ? ? ? ? ? ?tst ? ? \irqstat, #0x80000000
> ? ? ? ? ? ? ? ?beq ? ? 1001f
> ? ? ? ? ? ? ? ?bic ? ? \irqstat, \irqstat, #0x80000000
> ? ? ? ? ? ? ? ?mov ? ? \irqnr, \irqstat, lsr #16
> ? ? ? ? ? ? ? ?add ? ? \irqnr, \irqnr, #(PXA_IRQ(0))
> +
> ?1001:
> ? ? ? ? ? ? ? ?.endm
> --
> 1.5.6.5
>
>

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

* [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx
  2010-11-12  8:07     ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Eric Miao
@ 2010-11-12  8:47       ` Haojian Zhuang
  0 siblings, 0 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  8:47 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2010?11?12? 4:08 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org
>Subject: Re: [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx
>
>On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
><haojian.zhuang@marvell.com> wrote:
>> In order to avoid confusion, seperate pxa93x from pxa3xx.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>> Cc: Eric Miao <eric.y.miao@gmail.com>
>> +void pxa93x_clear_reset_status(unsigned int mask)
>> +{
>> + ? ? ? /* RESET_STATUS_* has a 1:1 mapping with ARSR */
>> + ? ? ? ARSR = mask;
>> +}
>
>This is not necessary now.
>
Thanks. It's fixed now.

>> +
>> +/*
>> + * Return the current HSIO bus clock frequency
>> + */
>> +static unsigned long clk_pxa93x_hsio_getrate(struct clk *clk)
>> +{
>> + ? ? ? unsigned long acsr;
>> + ? ? ? unsigned int hss, hsio_clk;
>> +
>> + ? ? ? acsr = ACSR;
>> +
>> + ? ? ? hss = (acsr >> 14) & 0x3;
>> + ? ? ? hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
>> +
>> + ? ? ? return hsio_clk;
>> +}
>
>Provided that the AP side is exactly same as PXA3xx, I'm still not
>convinced that PXA93x should be separated as a family.
>
Yes, HSIO is nearly same. But DVFM operation is different. And using separated file can avoid too much cpu id checking.

Changelog:
1. Remove pxa93x_clear_reset_status() implementation in pxa93x.c
2. Remove pxa93x_clear_reset_status() definition in generic.h

Thanks
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-ARM-pxa-split-pxa93x-from-pxa3xx.patch
Type: application/octet-stream
Size: 29158 bytes
Desc: 0003-ARM-pxa-split-pxa93x-from-pxa3xx.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101112/2c788260/attachment-0001.obj>

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

* [PATCH 05/11] ARM: pxa: support pxa95x
  2010-11-12  7:17       ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
  2010-11-12  7:17         ` [PATCH 06/11] ARM: pxa: support saarb platform Haojian Zhuang
@ 2010-11-12  8:50         ` Haojian Zhuang
  1 sibling, 0 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  8:50 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Haojian Zhuang [mailto:haojian.zhuang at marvell.com]
>Sent: 2010?11?12? 3:18 PM
>To: linux-arm-kernel at lists.infradead.org
>Cc: Haojian Zhuang; Eric Miao
>Subject: [PATCH 05/11] ARM: pxa: support pxa95x
>
>The core of PXA955 is PJ4. Add new PJ4 support. And add new macro
>CONFIG_PXA95x.
>
>Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>Cc: Eric Miao <eric.y.miao@gmail.com>
>---

Changelog:
1. Remove pxa95x_clear_reset_status() in pxa95x.c
2. Remove pxa95x_clear_reset_status() definition in generic.h

Thanks
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-ARM-pxa-support-pxa95x.patch
Type: application/octet-stream
Size: 28875 bytes
Desc: 0005-ARM-pxa-support-pxa95x.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101112/b430ec9b/attachment-0001.obj>

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

* [PATCH 04/11] ARM: pxa: update to read ICHP
  2010-11-12  8:34       ` [PATCH 04/11] ARM: pxa: update to read ICHP Eric Miao
@ 2010-11-12  8:53         ` Haojian Zhuang
  0 siblings, 0 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-12  8:53 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2010?11?12? 4:35 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org
>Subject: Re: [PATCH 04/11] ARM: pxa: update to read ICHP
>
>On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
><haojian.zhuang@marvell.com> wrote:
>> ICHP records the highest priority interrupt occured. In PXA27x/PXA3xx, we
>> can read ICHP via cooprocessor. In PJ4, we can only read ICHP via bus
>> register. So use the same method to read ICHP via bus register.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>> Cc: Eric Miao <eric.y.miao@gmail.com>
>> ---
>> ?arch/arm/mach-pxa/include/mach/entry-macro.S | ? ?6 +++++-
>> ?1 files changed, 5 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-
>pxa/include/mach/entry-macro.S
>> index a73bc86..91457dd 100644
>> --- a/arch/arm/mach-pxa/include/mach/entry-macro.S
>> +++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
>> @@ -41,11 +41,15 @@
>> ? ? ? ? ? ? ? ?b ? ? ? 1001f
>> ?1002:
>> ? ? ? ? ? ? ? ?@ Core Generation 2 (PXA27x) or Core Generation 3 (PXA3xx)
>> - ? ? ? ? ? ? ? mrc ? ? p6, 0, \irqstat, c5, c0, 0 ? ? ?@ ICHP
>> + ? ? ? ? ? ? ? @ or Core PJ4
>> + ? ? ? ? ? ? ? mov ? ? \base, #io_p2v(0x40000000) ? ? ?@ IIR Ctl = 0x40d00000
>> + ? ? ? ? ? ? ? add ? ? \base, \base, #0x00d00000
>> + ? ? ? ? ? ? ? ldr ? ? \irqstat, [\base, #0x18] ? ? ? ?@ ICHP offset
>
>Accessing from co-processor is supposed to be faster than MMIO.
>
>BTW, this could be addressed by MULTI_IRQ_HANDLER as in patch:
>
>http://www.spinics.net/lists/arm-kernel/msg88817.html
>
>Once it gets merged.
>
No problem. I can reformat this patch for MULTI_IRQ_HANDLER after it merged. You can skip this patch from current patch series since it won't impact old silicons.

Thanks
Haojian

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

* [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source
  2010-11-12  7:17                 ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
  2010-11-12  7:17                   ` [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
@ 2010-11-12 17:50                   ` Nicolas Pitre
  2010-11-16  5:07                     ` Haojian Zhuang
  1 sibling, 1 reply; 23+ messages in thread
From: Nicolas Pitre @ 2010-11-12 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 12 Nov 2010, Haojian Zhuang wrote:

> PXA silicons are using 3MHz timer as default clock source. But it'll be stopped
> counting in low power mode. Although 32KHz timer is slow, it can continue
> counting in low power mode. While low power mode is implemented as idle,
> stopped timer can't be accepted.
> 
> Add 32KHz timer as an alternative clock source. User can switch clock source
> on demand.

Why are you doing this?  What's wrong with  having timers stopped when 
in sleep mode?  I don't think a 32K timer is precise enough for 
runtime usage in general.

What you should do instead is to use the 32KHz timer to readjust OSCR 
when the CPU comes out of sleep mode.


Nicolas

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

* [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4
  2010-11-12  7:17                   ` [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
@ 2010-11-12 18:43                     ` Nicolas Pitre
  0 siblings, 0 replies; 23+ messages in thread
From: Nicolas Pitre @ 2010-11-12 18:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 12 Nov 2010, Haojian Zhuang wrote:

> iwmmxt is used in XScale, XScale3, Mohawk and PJ4 core. But the instructions
> of accessing CP0 and CP1 is changed in PJ4. Append more files to support
> iwmmxt in PJ4 core.
> 
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> Cc: Nicolas Pitre <nico@fluxnic.net>

Comments below.

>  delete mode 100644 arch/arm/kernel/iwmmxt.S
>  create mode 100644 arch/arm/kernel/pj4-iwmmxt.S
>  create mode 100644 arch/arm/kernel/xscale-iwmmxt.S

According to your previous patch, the changes needed to iwmmxt.S were 
minimal.  Please don't duplicate the whole file just for this.

In retrospective I think I still prefer the #ifdef's for this file.  
Eventually we could use some dynamic kernel patching (we're getting 
good at it) when we'll want to support XScale and PJ4 with the same 
kernel binary.

So what you could do to make the code cleaner in iwmmxt.S is:

[...]
#if defined(CONFIG_CPU_PJ4)
#define PJ4(code...) code
#define XSC(code...)
#else
#define PJ4(code...)
#define XSC(code...) code
#endif

[...]

ENTRY(iwmmxt_task_switch)

   XSC(	mrc	p15, 0, r1, c15, c1, 0	)
   PJ4(	mrc	p15, 0, r1, c1, c0, 2	)
	@ CP0 and CP1 accessible?
   XSC(	tst	r1, #0x3		)
   PJ4(	tst	r1, #0xf		)	
        bne     1f                              @ yes: block them for next task
[...]

This way the code is pretty readable, and that paves the way for a 
future dynamic patching capability.

> --- /dev/null
> +++ b/arch/arm/kernel/pj4-cp0.c
> @@ -0,0 +1,180 @@
> +/*
> + * linux/arch/arm/kernel/pj4-cp0.c
> + *
> + * XScale DSP and iWMMXt coprocessor context switching and handling
> + *
> + * Copyright (c) 2010 Marvell International Inc.
> + *
> + * 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/module.h>
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/signal.h>
> +#include <linux/sched.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <asm/thread_notify.h>
> +
> +static inline void dsp_save_state(u32 *state)
> +{

Do you really need this?  The "dsp" stuff was to support early XScale 
versions which had only an accumulator and not the full iwmmx support.  
Therefore you should only keep the appropriate iwmmxt notifier block and 
get 
rid of the "dsp" one.

[...]
> +/*
> + * Detect whether we have a MAC coprocessor (40 bit register) or an
> + * iWMMXt coprocessor (64 bit registers) by loading 00000100:00000000
> + * into a coprocessor register and reading it back, and checking
> + * whether the upper word survived intact.
> + */
> +static int __init cpu_has_iwmmxt(void)
> +{

And obviously you don't need this anymore either.

> +/*
> + * If we detect that the CPU has iWMMXt (and CONFIG_IWMMXT=y), we
> + * disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
> + * switch code handle iWMMXt context switching.  If on the other
> + * hand the CPU has a DSP coprocessor, we keep access to CP0 enabled
> + * all the time, and save/restore acc0 on context switch in non-lazy
> + * fashion.
> + */
> +static int __init pj4_cp0_init(void)
> +{

The first case described in the comment above should be unconditional 
with a 
PJ4, obviously.  Therefore this code and comment need to be reworked as 
well.


Nicolas

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

* [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source
  2010-11-12 17:50                   ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
@ 2010-11-16  5:07                     ` Haojian Zhuang
  0 siblings, 0 replies; 23+ messages in thread
From: Haojian Zhuang @ 2010-11-16  5:07 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Nicolas Pitre [mailto:nico at fluxnic.net]
>Sent: 2010?11?13? 1:50 AM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org; Eric Miao
>Subject: Re: [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source
>
>On Fri, 12 Nov 2010, Haojian Zhuang wrote:
>
>> PXA silicons are using 3MHz timer as default clock source. But it'll be stopped
>> counting in low power mode. Although 32KHz timer is slow, it can continue
>> counting in low power mode. While low power mode is implemented as idle,
>> stopped timer can't be accepted.
>>
>> Add 32KHz timer as an alternative clock source. User can switch clock source
>> on demand.
>
>Why are you doing this?  What's wrong with  having timers stopped when
>in sleep mode?  I don't think a 32K timer is precise enough for
>runtime usage in general.
>
>What you should do instead is to use the 32KHz timer to readjust OSCR
>when the CPU comes out of sleep mode.
>
>
>Nicolas

Hi Nicolas,

It's not suspend mode. It's idle mode. System will enter idle frequently and time shouldn't stop counting in idle time.

If we use 32KHz timer to compensate OSCR, the drifts on OSCR will be larger and larger. Because 32KHz time isn't precise. System time is based on our timer. I don't think this solution could be acceptable.

If we only use 32KHz timer, it can't meet precise time requirement in performance test.

So I use both clock source. While we need to get a precise time usage for performance calculating, we can switch clock source to fast clock. While we need to keep system to save power, we shouldn't care precise time at this time. We have to choose one in this scenario.

Thanks
Haojian

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

* [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx
  2010-11-12  8:00 ` [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Eric Miao
@ 2010-11-16 14:24   ` Eric Miao
  0 siblings, 0 replies; 23+ messages in thread
From: Eric Miao @ 2010-11-16 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 12, 2010 at 4:00 PM, Eric Miao <eric.y.miao@gmail.com> wrote:
> On Fri, Nov 12, 2010 at 3:17 PM, Haojian Zhuang
> <haojian.zhuang@marvell.com> wrote:
>> PXA300/PXA310/PXA320/PXA930/PXA935 are sharing one cpu family id.
>> It's a little confusion on cpu_is_pxa3xx().
>>
>> Now reduce the scope of cpu_is_pxa3xx(). Make it focusing on
>> PXA300/PXA310/PXA320. PXA930/PXA935 is coverd by cpu_is_pxa93x().
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
>> Cc: Eric Miao <eric.y.miao@gmail.com>
>
> Applied.
>

Dropped as we discussed. Waiting for your new submission.

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

* [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset
  2010-11-12  7:17             ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
  2010-11-12  7:17               ` [PATCH 09/11] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
@ 2011-01-09 22:49               ` Marek Vasut
  1 sibling, 0 replies; 23+ messages in thread
From: Marek Vasut @ 2011-01-09 22:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 12 November 2010 08:17:37 Haojian Zhuang wrote:
> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>


I think there's something wrong with this patch. It crashes my ZipitZ2 (no crash 
with this patch reverted). I'll investigate a bit and keep you informed, but see 
below.

> ---
>  arch/arm/mach-pxa/include/mach/regs-intc.h |    4 -
>  arch/arm/mach-pxa/irq.c                    |  122
> ++++++++++++++++++---------- 2 files changed, 80 insertions(+), 46
> deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h
> b/arch/arm/mach-pxa/include/mach/regs-intc.h index 68464ce..662288e 100644
> --- a/arch/arm/mach-pxa/include/mach/regs-intc.h
> +++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
> @@ -27,8 +27,4 @@
>  #define ICFP3		__REG(0x40D0013C)  /* Interrupt Controller FIQ Pending
> Register 3 */ #define ICPR3		__REG(0x40D00140)  /* Interrupt Controller
> Pending Register 3 */
> 
> -#define IPR(x)		__REG(0x40D0001C + (x < 32 ? (x << 2)		\
> -				: (x < 64 ? (0x94 + ((x - 32) << 2))	\
> -				: (0x128 + ((x - 64) << 2)))))
> -
>  #endif /* __ASM_MACH_REGS_INTC_H */
> diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
> index b5cafe2..54e91c9 100644
> --- a/arch/arm/mach-pxa/irq.c
> +++ b/arch/arm/mach-pxa/irq.c
> @@ -16,20 +16,31 @@
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
>  #include <linux/sysdev.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> 
>  #include <mach/hardware.h>
> -#include <asm/irq.h>
> -#include <asm/mach/irq.h>
> +#include <mach/irqs.h>
>  #include <mach/gpio.h>
> -#include <mach/regs-intc.h>
> 
>  #include "generic.h"
> 
> -#define MAX_INTERNAL_IRQS	128
> +#define IRQ_BASE		(void __iomem *)io_p2v(0x40d00000)
> +
> +#define ICIP			(0x000)
> +#define ICMR			(0x004)
> +#define ICLR			(0x008)
> +#define ICFR			(0x00c)
> +#define ICPR			(0x010)
> +#define ICCR			(0x014)
> +#define ICHP			(0x018)
> +#define IPR(i)			(((i) < 32) ? (0x01c + ((i) << 2)) :		\
> +				((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) :	\
> +				      (0x144 + (((i) - 64) << 2)))
> +#define IPR_VALID		(1 << 31)
> +#define IRQ_BIT(n)		(((n) - PXA_IRQ(0)) & 0x1f)
> 
> -#define IRQ_BIT(n)	(((n) - PXA_IRQ(0)) & 0x1f)
> -#define _ICMR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
> -#define _ICLR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
> +#define MAX_INTERNAL_IRQS	128
> 
>  /*
>   * This is for peripheral IRQs internal to the PXA chip.
> @@ -44,12 +55,20 @@ static inline int cpu_has_ipr(void)
> 
>  static void pxa_mask_irq(unsigned int irq)
>  {
> -	_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
> +	void __iomem *base = get_irq_chip_data(irq);
> +	uint32_t icmr = __raw_readl(base + ICMR);
> +
> +	icmr &= ~(1 << IRQ_BIT(irq));
> +	__raw_writel(icmr, base + ICMR);
>  }
> 
>  static void pxa_unmask_irq(unsigned int irq)
>  {
> -	_ICMR(irq) |= 1 << IRQ_BIT(irq);
> +	void __iomem *base = get_irq_chip_data(irq);
> +	uint32_t icmr = __raw_readl(base + ICMR);
> +
> +	icmr |= 1 << IRQ_BIT(irq);
> +	__raw_writel(icmr, base + ICMR);
>  }
> 
>  static struct irq_chip pxa_internal_irq_chip = {
> @@ -91,12 +110,16 @@ static void pxa_ack_low_gpio(unsigned int irq)
> 
>  static void pxa_mask_low_gpio(unsigned int irq)
>  {
> -	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
> +	struct irq_desc *desc = irq_to_desc(irq);
> +
> +	desc->chip->mask(irq);
>  }
> 
>  static void pxa_unmask_low_gpio(unsigned int irq)
>  {
> -	ICMR |= 1 << (irq - PXA_IRQ(0));
> +	struct irq_desc *desc = irq_to_desc(irq);
> +
> +	desc->chip->unmask(irq);
>  }
> 
>  static struct irq_chip pxa_low_gpio_chip = {
> @@ -125,33 +148,45 @@ static void __init pxa_init_low_gpio_irq(set_wake_t
> fn) pxa_low_gpio_chip.set_wake = fn;
>  }
> 
> +static inline void __iomem *irq_base(int i)
> +{
> +	static unsigned long phys_base[] = {
> +		0x40d00000,
> +		0x40d0009c,
> +		0x40d00130,
> +	};
> +
> +	return (void __iomem *)io_p2v(phys_base[i >> 5]);
> +}
> +
>  void __init pxa_init_irq(int irq_nr, set_wake_t fn)
>  {
> -	int irq, i;
> +	int irq, i, n;
> 
>  	BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
> 
>  	pxa_internal_irq_nr = irq_nr;
> 
> -	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
> -		_ICMR(irq) = 0;	/* disable all IRQs */
> -		_ICLR(irq) = 0;	/* all IRQs are IRQ, not FIQ */
> -	}
> -
> -	/* initialize interrupt priority */
> -	if (cpu_has_ipr()) {
> -		for (i = 0; i < irq_nr; i++)
> -			IPR(i) = i | (1 << 31);
> +	for (n = 0; n < irq_nr; n += 32) {
> +		void __iomem *base = irq_base(n);
> +
> +		__raw_writel(0, base + ICMR);	/* disable all IRQs */
> +		__raw_writel(0, base + ICLR);	/* all IRQs are IRQ, not FIQ */
> +		for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
> +			/* initialize interrupt priority */
> +			if (cpu_has_ipr())
> +				__raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
> +
> +			irq = PXA_IRQ(i);
> +			set_irq_chip(irq, &pxa_internal_irq_chip);
> +			set_irq_chip_data(irq, base);
> +			set_irq_handler(irq, handle_level_irq);
> +			set_irq_flags(irq, IRQF_VALID);
> +		}
>  	}
> 
>  	/* only unmasked interrupts kick us out of idle */
> -	ICCR = 1;
> -
> -	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
> -		set_irq_chip(irq, &pxa_internal_irq_chip);
> -		set_irq_handler(irq, handle_level_irq);
> -		set_irq_flags(irq, IRQF_VALID);
> -	}
> +	__raw_writel(1, irq_base(0) + ICCR);
> 
>  	pxa_internal_irq_chip.set_wake = fn;
>  	pxa_init_low_gpio_irq(fn);
> @@ -163,16 +198,18 @@ static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
> 
>  static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
>  {
> -	int i, irq = PXA_IRQ(0);
> +	int i;
> +
> +	for (i = 0; i < pxa_internal_irq_nr; i += 32) {
> +		void __iomem *base = irq_base(i);
> 
> -	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
> -		saved_icmr[i] = _ICMR(irq);
> -		_ICMR(irq) = 0;
> +		saved_icmr[i] = __raw_readl(base + ICMR);
> +		__raw_writel(0, base + ICMR);
>  	}
> 
>  	if (cpu_has_ipr()) {
>  		for (i = 0; i < pxa_internal_irq_nr; i++)
> -			saved_ipr[i] = IPR(i);
> +			saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
>  	}
> 
>  	return 0;
> @@ -180,19 +217,20 @@ static int pxa_irq_suspend(struct sys_device *dev,
> pm_message_t state)
> 
>  static int pxa_irq_resume(struct sys_device *dev)
>  {
> -	int i, irq = PXA_IRQ(0);
> +	int i;
> 
> -	if (cpu_has_ipr()) {
> -		for (i = 0; i < pxa_internal_irq_nr; i++)
> -			IPR(i) = saved_ipr[i];
> -	}
> +	for (i = 0; i < pxa_internal_irq_nr; i += 32) {
> +		void __iomem *base = irq_base(i);
> 
> -	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
> -		_ICMR(irq) = saved_icmr[i];
> -		_ICLR(irq) = 0;
> +		__raw_writel(saved_icmr[i], base + ICMR);

eg. here, it just so does out-of-bounds access (saved_icmr[32] is wrong).

> +		__raw_writel(0, base + ICLR);
>  	}
> 
> -	ICCR = 1;
> +	if (!cpu_is_pxa25x())
> +		for (i = 0; i < pxa_internal_irq_nr; i++)
> +			__raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
> +
> +	__raw_writel(1, IRQ_BASE + ICCR);
>  	return 0;
>  }
>  #else

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

end of thread, other threads:[~2011-01-09 22:49 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-12  7:17 [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
2010-11-12  7:17 ` [PATCH 02/11] ARM: pxa: redefine irqs.h Haojian Zhuang
2010-11-12  7:17   ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Haojian Zhuang
2010-11-12  7:17     ` [PATCH 04/11] ARM: pxa: update to read ICHP Haojian Zhuang
2010-11-12  7:17       ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
2010-11-12  7:17         ` [PATCH 06/11] ARM: pxa: support saarb platform Haojian Zhuang
2010-11-12  7:17           ` [PATCH 07/11] ARM: mmp: select CPU_PJ4 Haojian Zhuang
2010-11-12  7:17             ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
2010-11-12  7:17               ` [PATCH 09/11] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
2010-11-12  7:17                 ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
2010-11-12  7:17                   ` [PATCH 11/11] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
2010-11-12 18:43                     ` Nicolas Pitre
2010-11-12 17:50                   ` [PATCH 10/11] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
2010-11-16  5:07                     ` Haojian Zhuang
2011-01-09 22:49               ` [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset Marek Vasut
2010-11-12  8:50         ` [PATCH 05/11] ARM: pxa: support pxa95x Haojian Zhuang
2010-11-12  8:34       ` [PATCH 04/11] ARM: pxa: update to read ICHP Eric Miao
2010-11-12  8:53         ` Haojian Zhuang
2010-11-12  8:07     ` [PATCH 03/11] ARM: pxa: split pxa93x from pxa3xx Eric Miao
2010-11-12  8:47       ` Haojian Zhuang
2010-11-12  8:02   ` [PATCH 02/11] ARM: pxa: redefine irqs.h Eric Miao
2010-11-12  8:00 ` [PATCH 01/11] ARM: pxa: redefine the cpu_is_pxa3xx Eric Miao
2010-11-16 14:24   ` Eric Miao

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.