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

After introducing pxa930/pxa935 and new silicons, original cpuid rules
of XScale generation 3 can't fit new silicons. Now redefine the rule
of PXA3xx.

Only PXA300/PXA310/PXA320/PXA930/PXA935 are family members of PXA3xx.
PXA930/PXA935 are family members of PXA93x. PXA93x can be considered
as PXA3xx + CP.

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 |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index ca188cd..e480d1e 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -264,7 +264,6 @@
 /*
  * CPUID Core Generation Bit
  * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
- * == 0x3 for pxa300/pxa310/pxa320
  */
 #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
 #define __cpu_is_pxa2xx(id)				\
@@ -279,8 +278,10 @@
 #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)		\
+			|| __cpu_is_pxa93x(id);		\
 	 })
 #else
 #define __cpu_is_pxa3xx(id)	(0)
@@ -289,8 +290,8 @@
 #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
 #define __cpu_is_pxa93x(id)				\
 	({						\
-		unsigned int _id = (id) >> 4 & 0xfff;	\
-		_id == 0x683 || _id == 0x693;		\
+		__cpu_is_pxa930(id)			\
+			|| __cpu_is_pxa935(id);		\
 	 })
 #else
 #define __cpu_is_pxa93x(id)	(0)
-- 
1.5.6.5

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

* [PATCH 2/9] ARM: pxa: redefine irqs.h
  2010-11-17 11:03 [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
@ 2010-11-17 11:03 ` Haojian Zhuang
  2010-11-17 11:03   ` [PATCH 3/9] ARM: pxa: support pxa95x Haojian Zhuang
  2010-11-18 14:03   ` [PATCH 2/9] ARM: pxa: redefine irqs.h Eric Miao
  2010-11-18 14:01 ` [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx Eric Miao
  1 sibling, 2 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Define all IRQs in irqs.h. If some IRQs are sharing one IRQ number, define
them together. If some IRQs are sharing same name with different IRQ number,
define different IRQ.

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] 27+ messages in thread

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-17 11:03 ` [PATCH 2/9] ARM: pxa: redefine irqs.h Haojian Zhuang
@ 2010-11-17 11:03   ` Haojian Zhuang
  2010-11-17 11:03     ` [PATCH 4/9] ARM: pxa: support saarb platform Haojian Zhuang
  2010-11-19  8:45     ` [PATCH 3/9] ARM: pxa: support pxa95x Eric Miao
  2010-11-18 14:03   ` [PATCH 2/9] ARM: pxa: redefine irqs.h Eric Miao
  1 sibling, 2 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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/mach-pxa/Kconfig                 |   12 +-
 arch/arm/mach-pxa/Makefile                |    1 +
 arch/arm/mach-pxa/clock.h                 |   20 ++
 arch/arm/mach-pxa/devices.c               |  267 +++++++++---------
 arch/arm/mach-pxa/generic.c               |    8 +-
 arch/arm/mach-pxa/generic.h               |    3 +-
 arch/arm/mach-pxa/include/mach/hardware.h |   34 ++-
 arch/arm/mach-pxa/include/mach/irqs.h     |    1 +
 arch/arm/mach-pxa/pxa3xx.c                |    9 -
 arch/arm/mach-pxa/pxa930.c                |    2 +-
 arch/arm/mach-pxa/pxa95x.c                |  437 +++++++++++++++++++++++++++++
 arch/arm/mm/Kconfig                       |    6 +
 arch/arm/plat-pxa/Makefile                |    1 +
 arch/arm/plat-pxa/include/plat/mfp.h      |    4 +-
 14 files changed, 643 insertions(+), 162 deletions(-)
 create mode 100644 arch/arm/mach-pxa/pxa95x.c

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index dd235ec..d407659 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -651,11 +651,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)
+	  PXA950 (codename MG1)
 
 config PXA_SHARP_C7xx
 	bool
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index e2f89c2..b8cd0e7 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -19,6 +19,7 @@ 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_PXA95x)		+= mfp-pxa3xx.o pxa95x.o smemc.o
 obj-$(CONFIG_CPU_PXA300)	+= pxa300.o
 obj-$(CONFIG_CPU_PXA320)	+= pxa320.o
 obj-$(CONFIG_CPU_PXA930)	+= pxa930.o
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index d848874..c6c4460 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_PXA95x
+#define DEFINE_MG_CKEN(_name, _cken, _rate, _delay)	\
+struct clk clk_##_name = {				\
+		.ops	= &clk_pxa95x_cken_ops,		\
+		.rate	= _rate,			\
+		.cken	= CKEN_##_cken,			\
+		.delay	= _delay,			\
+	}
+
+#define DEFINE_MG_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 aaa1166..0975597 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
 
-#ifdef CONFIG_PXA3xx
-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,30 +612,35 @@ struct platform_device pxa25x_device_assp = {
 #endif /* CONFIG_PXA25x */
 
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-
-static struct resource pxa27x_resource_keypad[] = {
+static struct resource pxa27x_resource_camera[] = {
 	[0] = {
-		.start	= 0x41500000,
-		.end	= 0x4150004c,
+		.start	= 0x50000000,
+		.end	= 0x50000fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= IRQ_KEYPAD,
-		.end	= IRQ_KEYPAD,
+		.start	= IRQ_CAMERA,
+		.end	= IRQ_CAMERA,
 		.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),
+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_keypad_info(struct pxa27x_keypad_platform_data *info)
+void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
 {
-	pxa_register_device(&pxa27x_device_keypad, info);
+	pxa_register_device(&pxa27x_device_camera, info);
 }
 
 static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
@@ -689,6 +673,33 @@ void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
 {
 	pxa_register_device(&pxa27x_device_ohci, info);
 }
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || 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);
 
@@ -833,79 +844,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 */
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x */
 
 #ifdef CONFIG_PXA3xx
-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 +925,54 @@ 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 */
+
+#if defined(CONFIG_PXA3xx) || 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 struct resource pxa3xx_resources_nand[] = {
 	[0] = {
 		.start	= 0x43100000,
@@ -1009,6 +998,45 @@ static struct resource pxa3xx_resources_nand[] = {
 	},
 };
 
+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 u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
 
 struct platform_device pxa3xx_device_nand = {
@@ -1026,34 +1054,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 */
+#endif	/* CONFIG_PXA3xx || 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.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..ffcd00c 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 pxa95x_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/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index e480d1e..6957ba5 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -195,14 +195,15 @@
 #define __cpu_is_pxa935(id)	(0)
 #endif
 
-#ifdef CONFIG_CPU_PXA950
-#define __cpu_is_pxa950(id)                             \
-	({                                              \
+#ifdef CONFIG_CPU_PXA955
+#define __cpu_is_pxa955(id)				\
+	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
-		_id == 0x697;				\
-	 })
+		_id == 0x581 || _id == 0xc08		\
+			|| _id == 0xb76;		\
+	})
 #else
-#define __cpu_is_pxa950(id)	(0)
+#define __cpu_is_pxa955(id)	(0)
 #endif
 
 #define cpu_is_pxa210()					\
@@ -255,10 +256,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());	\
+	})
 
 
 /*
@@ -297,6 +298,15 @@
 #define __cpu_is_pxa93x(id)	(0)
 #endif
 
+#ifdef CONFIG_PXA95x
+#define __cpu_is_pxa95x(id)				\
+	({						\
+		__cpu_is_pxa955(id);			\
+	})
+#else
+#define __cpu_is_pxa95x(id)	(0)
+#endif
+
 #define cpu_is_pxa2xx()					\
 	({						\
 		__cpu_is_pxa2xx(read_cpuid_id());	\
@@ -311,6 +321,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/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
index 7d29dd3..8aeacf9 100644
--- a/arch/arm/mach-pxa/pxa930.c
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
 
 static int __init pxa930_init(void)
 {
-	if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
+	if (cpu_is_pxa93x()) {
 		mfp_init_base(io_p2v(MFPR_BASE));
 		mfp_init_addr(pxa930_mfp_addr_map);
 	}
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
new file mode 100644
index 0000000..580dd52
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -0,0 +1,437 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa95x.c
+ *
+ * code specific to PXA95x aka MGx
+ *
+ * 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 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,
+};
+
+/*
+ * 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_MG_CK(pxa95x_lcd, LCD, &clk_pxa95x_hsio_ops);
+static DEFINE_MG_CKEN(pxa95x_ffuart, FFUART, 14857000, 1);
+static DEFINE_MG_CKEN(pxa95x_btuart, BTUART, 14857000, 1);
+static DEFINE_MG_CKEN(pxa95x_stuart, STUART, 14857000, 1);
+static DEFINE_MG_CKEN(pxa95x_i2c, I2C, 32842000, 0);
+static DEFINE_MG_CKEN(pxa95x_keypad, KEYPAD, 32768, 0);
+static DEFINE_MG_CKEN(pxa95x_ssp1, SSP1, 13000000, 0);
+static DEFINE_MG_CKEN(pxa95x_ssp2, SSP2, 13000000, 0);
+static DEFINE_MG_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
+static DEFINE_MG_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
+static DEFINE_MG_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
+static DEFINE_MG_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)
+{
+	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..ede1763 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
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 4aacdd1..3aca5ba 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_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 9e604c8..75f6564 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_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 +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_PXA95x || CONFIG_ARCH_MMP */
 
 #endif /* __ASM_PLAT_MFP_H */
-- 
1.5.6.5

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

* [PATCH 4/9] ARM: pxa: support saarb platform
  2010-11-17 11:03   ` [PATCH 3/9] ARM: pxa: support pxa95x Haojian Zhuang
@ 2010-11-17 11:03     ` Haojian Zhuang
  2010-11-17 11:03       ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Haojian Zhuang
  2010-11-19  8:45     ` [PATCH 3/9] ARM: pxa: support pxa95x Eric Miao
  1 sibling, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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>
---
 arch/arm/mach-pxa/Kconfig  |    5 ++
 arch/arm/mach-pxa/Makefile |    1 +
 arch/arm/mach-pxa/saarb.c  |  114 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 0 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 d407659..34ec1fb 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -50,6 +50,11 @@ config MACH_SAAR
 	select PXA3xx
 	select CPU_PXA930
 
+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 b8cd0e7..e6b6643 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/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] 27+ messages in thread

* [PATCH 5/9] ARM: mmp: select CPU_PJ4
  2010-11-17 11:03     ` [PATCH 4/9] ARM: pxa: support saarb platform Haojian Zhuang
@ 2010-11-17 11:03       ` Haojian Zhuang
  2010-11-17 11:03         ` [PATCH 6/9] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
  2010-11-17 13:13         ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Sergei Shtylyov
  0 siblings, 2 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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 |    7 ++++---
 arch/arm/mm/Kconfig       |    2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 0711d3b..ab39b1e 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.
+	  Select code specific to MMP2. MMP2 is ARMv7 compatible.
 endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ede1763..a099efe 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)
+	depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
 	default y
 	select OUTER_CACHE
 	help
-- 
1.5.6.5

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

* [PATCH 6/9] ARM: pxa: sanitize IRQ registers access based on offset
  2010-11-17 11:03       ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Haojian Zhuang
@ 2010-11-17 11:03         ` Haojian Zhuang
  2010-11-17 11:03           ` [PATCH 7/9] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
  2010-11-17 13:13         ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Sergei Shtylyov
  1 sibling, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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] 27+ messages in thread

* [PATCH 7/9] ARM: pxa: auto compute shift and mult of timer
  2010-11-17 11:03         ` [PATCH 6/9] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
@ 2010-11-17 11:03           ` Haojian Zhuang
  2010-11-17 11:03             ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
  0 siblings, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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] 27+ messages in thread

* [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source
  2010-11-17 11:03           ` [PATCH 7/9] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
@ 2010-11-17 11:03             ` Haojian Zhuang
  2010-11-17 11:03               ` [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
  2010-11-17 15:23               ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
  0 siblings, 2 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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..4edd597 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		= "accurate",
+	.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		= "32k",
+	.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] 27+ messages in thread

* [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
  2010-11-17 11:03             ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
@ 2010-11-17 11:03               ` Haojian Zhuang
  2010-11-17 11:09                 ` Haojian Zhuang
  2010-11-17 15:29                 ` Nicolas Pitre
  2010-11-17 15:23               ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
  1 sibling, 2 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:03 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/Kconfig         |    4 +-
 arch/arm/kernel/Makefile |    1 +
 arch/arm/kernel/iwmmxt.S |   55 +++++++++++++++++++++++++++++++++++-----------
 3 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a19a526..b0f25b0 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 || 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/kernel/Makefile b/arch/arm/kernel/Makefile
index 5b9b268..b0f11fa 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -50,6 +50,7 @@ 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_CPU_PJ4)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index b63b528..7fa3bb0 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -19,6 +19,14 @@
 #include <asm/thread_info.h>
 #include <asm/asm-offsets.h>
 
+#if defined(CONFIG_CPU_PJ4)
+#define PJ4(code...)		code
+#define XSC(code...)
+#else
+#define PJ4(code...)
+#define XSC(code...)		code
+#endif
+
 #define MMX_WR0		 	(0x00)
 #define MMX_WR1		 	(0x08)
 #define MMX_WR2		 	(0x10)
@@ -58,11 +66,17 @@
 
 ENTRY(iwmmxt_task_enable)
 
-	mrc	p15, 0, r2, c15, c1, 0
-	tst	r2, #0x3			@ CP0 and CP1 accessible?
+	XSC(mrc	p15, 0, r2, c15, c1, 0)
+	PJ4(mrc p15, 0, r2, c1, c0, 2)
+	@ CP0 and CP1 accessible?
+	XSC(tst	r2, #0x3)
+	PJ4(tst	r2, #0xf)
 	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
+	@ enable access to CP0 and CP1
+	XSC(orr	r2, r2, #0x3)
+	XSC(mcr	p15, 0, r2, c15, c1, 0)
+	PJ4(orr	r2, r2, #0xf)
+	PJ4(mcr	p15, 0, r2, c1, c0, 2)
 
 	ldr	r3, =concan_owner
 	add	r0, r10, #TI_IWMMXT_STATE	@ get task Concan save area
@@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable)
 	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
+	@ enable access to CP0 and CP1
+	XSC(mrc	p15, 0, r4, c15, c1, 0)
+	XSC(orr	r4, r4, #0xf)
+	XSC(mcr	p15, 0, r4, c15, c1, 0)
+	PJ4(mrc p15, 0, r4, c1, c0, 2)
+	PJ4(orr	r4, r4, #0x3)
+	PJ4(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, #0x3			@ disable access to CP0 and CP1
-	mcr	p15, 0, r4, c15, c1, 0
+	@ disable access to CP0 and CP1
+	XSC(bic	r4, r4, #0x3)
+	XSC(mcr	p15, 0, r4, c15, c1, 0)
+	PJ4(bic	r4, r4, #0xf)
+	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+
 	mrc	p15, 0, r2, c2, c0, 0
 	mov	r2, r2				@ cpwait
 
@@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore)
  */
 ENTRY(iwmmxt_task_switch)
 
-	mrc	p15, 0, r1, c15, c1, 0
-	tst	r1, #0x3			@ CP0 and CP1 accessible?
+	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
 
 	ldr	r2, =concan_owner
@@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch)
 	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
+1:	@ flip Conan access
+	XSC(eor	r1, r1, #0x3)
+	XSC(mcr	p15, 0, r1, c15, c1, 0)
+	PJ4(eor r1, r1, #0xf)
+	PJ4(mcr	p15, 0, r1, c1, c0, 2)
 
 	mrc	p15, 0, r1, c2, c0, 0
 	sub	pc, lr, r1, lsr #32		@ cpwait and return
-- 
1.5.6.5

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

* [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
  2010-11-17 11:03               ` [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
@ 2010-11-17 11:09                 ` Haojian Zhuang
  2010-11-17 15:55                   ` Nicolas Pitre
  2010-11-17 15:29                 ` Nicolas Pitre
  1 sibling, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-17 11:09 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Haojian Zhuang [mailto:haojian.zhuang at marvell.com]
>Sent: 2010?11?17? 7:04 PM
>To: linux-arm-kernel at lists.infradead.org
>Cc: Haojian Zhuang; Zhou Zhu; Eric Miao; Nicolas Pitre
>Subject: [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
>
>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/Kconfig         |    4 +-
> arch/arm/kernel/Makefile |    1 +
> arch/arm/kernel/iwmmxt.S |   55 +++++++++++++++++++++++++++++++++++-------
>----
> 3 files changed, 45 insertions(+), 15 deletions(-)
>

Changelog:
1. Append missing pj4-cp0.c.

Thanks
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0009-ARM-pxa-add-iwmmx-support-for-PJ4.patch
Type: application/octet-stream
Size: 6981 bytes
Desc: 0009-ARM-pxa-add-iwmmx-support-for-PJ4.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101117/8ddac871/attachment.obj>

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

* [PATCH 5/9] ARM: mmp: select CPU_PJ4
  2010-11-17 11:03       ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Haojian Zhuang
  2010-11-17 11:03         ` [PATCH 6/9] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
@ 2010-11-17 13:13         ` Sergei Shtylyov
  2010-11-18  3:12           ` Haojian Zhuang
  1 sibling, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2010-11-17 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hello.

On 17-11-2010 14:03, Haojian Zhuang wrote:

> 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>
[...]

> diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
> index 0711d3b..ab39b1e 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)

    () not needed.

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

    Likewise...

WBR, Sergei

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

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

On Wed, 17 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.

Do you need to do this for sched_clock() too?  The clock source API is 
for reliable clock, but sched_clock is not as strict and requires a fast 
and lightweight implementation instead.  And the clock source API and 
sched_clock() don't have to be based on the same timer.

> 
> 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..4edd597 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		= "accurate",
> +	.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		= "32k",
> +	.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	[flat|nested] 27+ messages in thread

* [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
  2010-11-17 11:03               ` [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
  2010-11-17 11:09                 ` Haojian Zhuang
@ 2010-11-17 15:29                 ` Nicolas Pitre
  1 sibling, 0 replies; 27+ messages in thread
From: Nicolas Pitre @ 2010-11-17 15:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 17 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>


Did you forget to do "git add pj4-cp0.c"?  It is missing from your 
patch.


Nicolas

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

* [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
  2010-11-17 11:09                 ` Haojian Zhuang
@ 2010-11-17 15:55                   ` Nicolas Pitre
  2010-11-18  3:09                     ` Haojian Zhuang
  0 siblings, 1 reply; 27+ messages in thread
From: Nicolas Pitre @ 2010-11-17 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 17 Nov 2010, Haojian Zhuang wrote:

> 
> 
> >-----Original Message-----
> >From: Haojian Zhuang [mailto:haojian.zhuang at marvell.com]
> >Sent: 2010?11?17? 7:04 PM
> >To: linux-arm-kernel at lists.infradead.org
> >Cc: Haojian Zhuang; Zhou Zhu; Eric Miao; Nicolas Pitre
> >Subject: [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
> >
> >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/Kconfig         |    4 +-
> > arch/arm/kernel/Makefile |    1 +
> > arch/arm/kernel/iwmmxt.S |   55 +++++++++++++++++++++++++++++++++++-------
> >----
> > 3 files changed, 45 insertions(+), 15 deletions(-)
> >
> 
> Changelog:
> 1. Append missing pj4-cp0.c.

OK... some more comments there:

+static int __init pj4_cp0_init(void)
+{
+       u32 cp_access;
+
+       cp_access = pj4_cp_access_read() & ~0xf;
+       pj4_cp_access_write(cp_access | 0xf);

You clear all first 4 bits just to set them all again.  Isn't the first 
mask redundant?

+       printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n");

You are not really detecting anything here, and this is not for XScale 
either.  What about ""PJ4 iWMMXt coprocessor enabled.\n" instead?

+       elf_hwcap |= HWCAP_IWMMXT;
+       thread_register_notifier(&iwmmxt_notifier_block);
+
+       pj4_cp_access_write(cp_access);

And here you are clearing access to the coprocessor.  There is nothing 
that required access to it from the moment it was set at the beginning 
of the function, so maybe you should have only cleared it at the 
beginning instead.


Nicolas

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

* [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
  2010-11-17 15:55                   ` Nicolas Pitre
@ 2010-11-18  3:09                     ` Haojian Zhuang
  2010-11-18 18:27                       ` Nicolas Pitre
  0 siblings, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-18  3:09 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Nicolas Pitre [mailto:nico at fluxnic.net]
>Sent: 2010?11?17? 11:56 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org; Zhou Zhu; Eric Miao
>Subject: RE: [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
>
>On Wed, 17 Nov 2010, Haojian Zhuang wrote:
>
>>
>>
>> >-----Original Message-----
>> >From: Haojian Zhuang [mailto:haojian.zhuang at marvell.com]
>> >Sent: 2010?11?17? 7:04 PM
>> >To: linux-arm-kernel at lists.infradead.org
>> >Cc: Haojian Zhuang; Zhou Zhu; Eric Miao; Nicolas Pitre
>> >Subject: [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4
>> >
>> >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/Kconfig         |    4 +-
>> > arch/arm/kernel/Makefile |    1 +
>> > arch/arm/kernel/iwmmxt.S |   55 +++++++++++++++++++++++++++++++++++----
>---
>> >----
>> > 3 files changed, 45 insertions(+), 15 deletions(-)
>> >
>>
>> Changelog:
>> 1. Append missing pj4-cp0.c.
>
>OK... some more comments there:
>
>+static int __init pj4_cp0_init(void)
>+{
>+       u32 cp_access;
>+
>+       cp_access = pj4_cp_access_read() & ~0xf;
>+       pj4_cp_access_write(cp_access | 0xf);
>
>You clear all first 4 bits just to set them all again.  Isn't the first
>mask redundant?
>
>+       printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n");
>
>You are not really detecting anything here, and this is not for XScale
>either.  What about ""PJ4 iWMMXt coprocessor enabled.\n" instead?
>
>+       elf_hwcap |= HWCAP_IWMMXT;
>+       thread_register_notifier(&iwmmxt_notifier_block);
>+
>+       pj4_cp_access_write(cp_access);
>
>And here you are clearing access to the coprocessor.  There is nothing
>that required access to it from the moment it was set at the beginning
>of the function, so maybe you should have only cleared it at the
>beginning instead.
>
>
>Nicolas

Thanks for your comments. Now it's fixed in attachment.

Best Regards
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0009-ARM-pxa-add-iwmmx-support-for-PJ4.patch
Type: application/octet-stream
Size: 6921 bytes
Desc: 0009-ARM-pxa-add-iwmmx-support-for-PJ4.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101117/2edb37e3/attachment-0001.obj>

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

* [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source
  2010-11-17 15:23               ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
@ 2010-11-18  3:11                 ` Haojian Zhuang
  0 siblings, 0 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-18  3:11 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Nicolas Pitre [mailto:nico at fluxnic.net]
>Sent: 2010?11?17? 11:23 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org; Eric Miao
>Subject: Re: [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source
>
>On Wed, 17 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.
>
>Do you need to do this for sched_clock() too?  The clock source API is
>for reliable clock, but sched_clock is not as strict and requires a fast
>and lightweight implementation instead.  And the clock source API and
>sched_clock() don't have to be based on the same timer.
>

Thanks for your comments. Now it's fixed in attachment.

Best Regards
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0008-ARM-pxa-add-32KHz-timer-as-clock-source.patch
Type: application/octet-stream
Size: 9969 bytes
Desc: 0008-ARM-pxa-add-32KHz-timer-as-clock-source.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101117/604137fe/attachment.obj>

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

* [PATCH 5/9] ARM: mmp: select CPU_PJ4
  2010-11-17 13:13         ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Sergei Shtylyov
@ 2010-11-18  3:12           ` Haojian Zhuang
  0 siblings, 0 replies; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-18  3:12 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Sergei Shtylyov [mailto:sshtylyov at mvista.com]
>Sent: 2010?11?17? 9:14 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org; Eric Miao
>Subject: Re: [PATCH 5/9] ARM: mmp: select CPU_PJ4
>
>Hello.
>
>On 17-11-2010 14:03, Haojian Zhuang wrote:
>
>> 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>
>[...]
>
>> diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
>> index 0711d3b..ab39b1e 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)
>
>    () not needed.
>

Thanks. Now it's fixed in attachment.

Best Regards
Haojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-ARM-mmp-select-CPU_PJ4.patch
Type: application/octet-stream
Size: 1759 bytes
Desc: 0005-ARM-mmp-select-CPU_PJ4.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101117/56eb32e0/attachment.obj>

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

* [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx
  2010-11-17 11:03 [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
  2010-11-17 11:03 ` [PATCH 2/9] ARM: pxa: redefine irqs.h Haojian Zhuang
@ 2010-11-18 14:01 ` Eric Miao
  1 sibling, 0 replies; 27+ messages in thread
From: Eric Miao @ 2010-11-18 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> After introducing pxa930/pxa935 and new silicons, original cpuid rules
> of XScale generation 3 can't fit new silicons. Now redefine the rule
> of PXA3xx.
>
> Only PXA300/PXA310/PXA320/PXA930/PXA935 are family members of PXA3xx.
> PXA930/PXA935 are family members of PXA93x. PXA93x can be considered
> as PXA3xx + CP.
>
> 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 | ? 11 ++++++-----
> ?1 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
> index ca188cd..e480d1e 100644
> --- a/arch/arm/mach-pxa/include/mach/hardware.h
> +++ b/arch/arm/mach-pxa/include/mach/hardware.h
> @@ -264,7 +264,6 @@
> ?/*
> ?* CPUID Core Generation Bit
> ?* <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
> - * == 0x3 for pxa300/pxa310/pxa320
> ?*/
> ?#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
> ?#define __cpu_is_pxa2xx(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> @@ -279,8 +278,10 @@
> ?#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) ? ? ? ? ?\
> + ? ? ? ? ? ? ? ? ? ? ? || __cpu_is_pxa93x(id); ? ? ? ? \
> ? ? ? ? })
> ?#else
> ?#define __cpu_is_pxa3xx(id) ? ?(0)
> @@ -289,8 +290,8 @@
> ?#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
> ?#define __cpu_is_pxa93x(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> - ? ? ? ? ? ? ? unsigned int _id = (id) >> 4 & 0xfff; ? \
> - ? ? ? ? ? ? ? _id == 0x683 || _id == 0x693; ? ? ? ? ? \
> + ? ? ? ? ? ? ? __cpu_is_pxa930(id) ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? ? ? ? ? || __cpu_is_pxa935(id); ? ? ? ? \
> ? ? ? ? })
> ?#else
> ?#define __cpu_is_pxa93x(id) ? ?(0)
> --
> 1.5.6.5
>
>

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

* [PATCH 2/9] ARM: pxa: redefine irqs.h
  2010-11-17 11:03 ` [PATCH 2/9] ARM: pxa: redefine irqs.h Haojian Zhuang
  2010-11-17 11:03   ` [PATCH 3/9] ARM: pxa: support pxa95x Haojian Zhuang
@ 2010-11-18 14:03   ` Eric Miao
  1 sibling, 0 replies; 27+ messages in thread
From: Eric Miao @ 2010-11-18 14:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> Define all IRQs in irqs.h. If some IRQs are sharing one IRQ number, define
> them together. If some IRQs are sharing same name with different IRQ number,
> define different IRQ.
>
> 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] 27+ messages in thread

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

On Wed, 17 Nov 2010, Haojian Zhuang wrote:
[...]
> >that required access to it from the moment it was set at the beginning
> >of the function, so maybe you should have only cleared it at the
> >beginning instead.
> >
> >
> >Nicolas
> 
> Thanks for your comments. Now it's fixed in attachment.

Acked-by: Nicolas Pitre <nico@fluxnic.net>


Nicolas

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-17 11:03   ` [PATCH 3/9] ARM: pxa: support pxa95x Haojian Zhuang
  2010-11-17 11:03     ` [PATCH 4/9] ARM: pxa: support saarb platform Haojian Zhuang
@ 2010-11-19  8:45     ` Eric Miao
  2010-11-19  9:16       ` Haojian Zhuang
  1 sibling, 1 reply; 27+ messages in thread
From: Eric Miao @ 2010-11-19  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
<haojian.zhuang@marvell.com> wrote:
> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437 +++++++++++++++++++++++++++++
> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
> ?14 files changed, 643 insertions(+), 162 deletions(-)
> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>
> diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
> index dd235ec..d407659 100644
> --- a/arch/arm/mach-pxa/Kconfig
> +++ b/arch/arm/mach-pxa/Kconfig
> @@ -651,11 +651,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)
> + ? ? ? ? PXA950 (codename MG1)
>
> ?config PXA_SHARP_C7xx
> ? ? ? ?bool
> diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
> index e2f89c2..b8cd0e7 100644
> --- a/arch/arm/mach-pxa/Makefile
> +++ b/arch/arm/mach-pxa/Makefile
> @@ -19,6 +19,7 @@ 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_PXA95x) ? ? ? ? ? += mfp-pxa3xx.o pxa95x.o smemc.o
> ?obj-$(CONFIG_CPU_PXA300) ? ? ? += pxa300.o
> ?obj-$(CONFIG_CPU_PXA320) ? ? ? += pxa320.o
> ?obj-$(CONFIG_CPU_PXA930) ? ? ? += pxa930.o
> diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
> index d848874..c6c4460 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_PXA95x
> +#define DEFINE_MG_CKEN(_name, _cken, _rate, _delay) ? ?\
> +struct clk clk_##_name = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .ops ? ?= &clk_pxa95x_cken_ops, ? ? ? ? \
> + ? ? ? ? ? ? ? .rate ? = _rate, ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? .cken ? = CKEN_##_cken, ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .delay ?= _delay, ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? }
> +
> +#define DEFINE_MG_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 aaa1166..0975597 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
>
> -#ifdef CONFIG_PXA3xx
> -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,30 +612,35 @@ struct platform_device pxa25x_device_assp = {
> ?#endif /* CONFIG_PXA25x */
>
> ?#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
> -
> -static struct resource pxa27x_resource_keypad[] = {
> +static struct resource pxa27x_resource_camera[] = {
> ? ? ? ?[0] = {
> - ? ? ? ? ? ? ? .start ?= 0x41500000,
> - ? ? ? ? ? ? ? .end ? ?= 0x4150004c,
> + ? ? ? ? ? ? ? .start ?= 0x50000000,
> + ? ? ? ? ? ? ? .end ? ?= 0x50000fff,
> ? ? ? ? ? ? ? ?.flags ?= IORESOURCE_MEM,
> ? ? ? ?},
> ? ? ? ?[1] = {
> - ? ? ? ? ? ? ? .start ?= IRQ_KEYPAD,
> - ? ? ? ? ? ? ? .end ? ?= IRQ_KEYPAD,
> + ? ? ? ? ? ? ? .start ?= IRQ_CAMERA,
> + ? ? ? ? ? ? ? .end ? ?= IRQ_CAMERA,
> ? ? ? ? ? ? ? ?.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),
> +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_keypad_info(struct pxa27x_keypad_platform_data *info)
> +void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
> ?{
> - ? ? ? pxa_register_device(&pxa27x_device_keypad, info);
> + ? ? ? pxa_register_device(&pxa27x_device_camera, info);
> ?}
>
> ?static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
> @@ -689,6 +673,33 @@ void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
> ?{
> ? ? ? ?pxa_register_device(&pxa27x_device_ohci, info);
> ?}
> +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
> +
> +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || 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);
>
> @@ -833,79 +844,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 */
> +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x */
>
> ?#ifdef CONFIG_PXA3xx
> -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 +925,54 @@ 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 */
> +
> +#if defined(CONFIG_PXA3xx) || 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 struct resource pxa3xx_resources_nand[] = {
> ? ? ? ?[0] = {
> ? ? ? ? ? ? ? ?.start ?= 0x43100000,
> @@ -1009,6 +998,45 @@ static struct resource pxa3xx_resources_nand[] = {
> ? ? ? ?},
> ?};
>
> +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 u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
>
> ?struct platform_device pxa3xx_device_nand = {
> @@ -1026,34 +1054,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 */
> +#endif /* CONFIG_PXA3xx || 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.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..ffcd00c 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 pxa95x_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/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
> index e480d1e..6957ba5 100644
> --- a/arch/arm/mach-pxa/include/mach/hardware.h
> +++ b/arch/arm/mach-pxa/include/mach/hardware.h
> @@ -195,14 +195,15 @@
> ?#define __cpu_is_pxa935(id) ? ?(0)
> ?#endif
>
> -#ifdef CONFIG_CPU_PXA950
> -#define __cpu_is_pxa950(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> - ? ? ? ({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> +#ifdef CONFIG_CPU_PXA955
> +#define __cpu_is_pxa955(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?unsigned int _id = (id) >> 4 & 0xfff; ? \
> - ? ? ? ? ? ? ? _id == 0x697; ? ? ? ? ? ? ? ? ? ? ? ? ? \
> - ? ? ? ?})
> + ? ? ? ? ? ? ? _id == 0x581 || _id == 0xc08 ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? ? ? ? ? || _id == 0xb76; ? ? ? ? ? ? ? ?\
> + ? ? ? })
> ?#else
> -#define __cpu_is_pxa950(id) ? ?(0)
> +#define __cpu_is_pxa955(id) ? ?(0)
> ?#endif
>
> ?#define cpu_is_pxa210() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> @@ -255,10 +256,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()); ? ? ? \
> + ? ? ? })
>
>
> ?/*
> @@ -297,6 +298,15 @@
> ?#define __cpu_is_pxa93x(id) ? ?(0)
> ?#endif
>
> +#ifdef CONFIG_PXA95x
> +#define __cpu_is_pxa95x(id) ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? __cpu_is_pxa955(id); ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? })
> +#else
> +#define __cpu_is_pxa95x(id) ? ?(0)
> +#endif
> +
> ?#define cpu_is_pxa2xx() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ?({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?__cpu_is_pxa2xx(read_cpuid_id()); ? ? ? \
> @@ -311,6 +321,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/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
> index 7d29dd3..8aeacf9 100644
> --- a/arch/arm/mach-pxa/pxa930.c
> +++ b/arch/arm/mach-pxa/pxa930.c
> @@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
>
> ?static int __init pxa930_init(void)
> ?{
> - ? ? ? if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
> + ? ? ? if (cpu_is_pxa93x()) {
> ? ? ? ? ? ? ? ?mfp_init_base(io_p2v(MFPR_BASE));
> ? ? ? ? ? ? ? ?mfp_init_addr(pxa930_mfp_addr_map);
> ? ? ? ?}
> diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
> new file mode 100644
> index 0000000..580dd52
> --- /dev/null
> +++ b/arch/arm/mach-pxa/pxa95x.c
> @@ -0,0 +1,437 @@
> +/*
> + * linux/arch/arm/mach-pxa/pxa95x.c
> + *
> + * code specific to PXA95x aka MGx
> + *
> + * 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 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,
> +};
> +
> +/*
> + * 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_MG_CK(pxa95x_lcd, LCD, &clk_pxa95x_hsio_ops);
> +static DEFINE_MG_CKEN(pxa95x_ffuart, FFUART, 14857000, 1);
> +static DEFINE_MG_CKEN(pxa95x_btuart, BTUART, 14857000, 1);
> +static DEFINE_MG_CKEN(pxa95x_stuart, STUART, 14857000, 1);
> +static DEFINE_MG_CKEN(pxa95x_i2c, I2C, 32842000, 0);
> +static DEFINE_MG_CKEN(pxa95x_keypad, KEYPAD, 32768, 0);
> +static DEFINE_MG_CKEN(pxa95x_ssp1, SSP1, 13000000, 0);
> +static DEFINE_MG_CKEN(pxa95x_ssp2, SSP2, 13000000, 0);
> +static DEFINE_MG_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
> +static DEFINE_MG_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
> +static DEFINE_MG_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
> +static DEFINE_MG_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)
> +{

No enabling of CP6 is needed for pxa95x?

> + ? ? ? 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;
> +

No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
subsystems are just same.

> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
> + ? ? ? }
> +
> + ? ? ? return ret;
> +}

I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
difference
is the missing of pxa3xx_init_pm(), which is due to the difference of the power
management. Instead of duplicating so much code, another better way out is:

1) remove pxa3xx_init_pm() from pxa3xx_init()
2) remove pxa3xx_init() from postcore_init()
3) change pxa3xx_init() to pxa3xx_common_init()
4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
well as pxa3xx_init_pm()
5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
pm initialization
  (e.g. pxa95x_init_pm)


Otherwise looks OK.

> +
> +postcore_initcall(pxa95x_init);
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 4414a01..ede1763 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
> diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
> index 4aacdd1..3aca5ba 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_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 9e604c8..75f6564 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_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 +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_PXA95x || CONFIG_ARCH_MMP */
>
> ?#endif /* __ASM_PLAT_MFP_H */
> --
> 1.5.6.5
>
>

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-19  8:45     ` [PATCH 3/9] ARM: pxa: support pxa95x Eric Miao
@ 2010-11-19  9:16       ` Haojian Zhuang
  2010-11-22  1:08         ` Eric Miao
  0 siblings, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-19  9:16 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2010?11?19? 4:45 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org
>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>
>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
><haojian.zhuang@marvell.com> wrote:
>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>+++++++++++++++++++++++++++++
>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>
>> +void __init pxa95x_init_irq(void)
>> +{
>
>No enabling of CP6 is needed for pxa95x?
>
Yes, PXA95x can't support to access interrupt registers via co-processors.

>> + ? ? ? pxa_init_irq(96, NULL);
>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>> +}
>> +
>> +
>> +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;
>> +
>
>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>subsystems are just same.
>
I don't want to support PM feature now. So I remove them in current patch.

>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>> + ? ? ? }
>> +
>> + ? ? ? return ret;
>> +}
>
>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>difference
>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>management. Instead of duplicating so much code, another better way out is:
>
>1) remove pxa3xx_init_pm() from pxa3xx_init()
>2) remove pxa3xx_init() from postcore_init()
>3) change pxa3xx_init() to pxa3xx_common_init()
>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>well as pxa3xx_init_pm()
>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>pm initialization
>  (e.g. pxa95x_init_pm)
>
The name of pxa3xx_init() and pxa3xx_common_init() is very confusion. PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image now. Actually I failed to compile them together.

Thanks
Haojian

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-19  9:16       ` Haojian Zhuang
@ 2010-11-22  1:08         ` Eric Miao
  2010-11-22  4:18           ` Haojian Zhuang
  0 siblings, 1 reply; 27+ messages in thread
From: Eric Miao @ 2010-11-22  1:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 19, 2010 at 5:16 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>
>
>>-----Original Message-----
>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>Sent: 2010?11?19? 4:45 PM
>>To: Haojian Zhuang
>>Cc: linux-arm-kernel at lists.infradead.org
>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>
>>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
>><haojian.zhuang@marvell.com> wrote:
>>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>>+++++++++++++++++++++++++++++
>>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>>
>>> +void __init pxa95x_init_irq(void)
>>> +{
>>
>>No enabling of CP6 is needed for pxa95x?
>>
> Yes, PXA95x can't support to access interrupt registers via co-processors.
>
>>> + ? ? ? pxa_init_irq(96, NULL);
>>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>>> +}
>>> +
>>> +
>>> +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;
>>> +
>>
>>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>>subsystems are just same.
>>
> I don't want to support PM feature now. So I remove them in current patch.
>
>>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>>> + ? ? ? }
>>> +
>>> + ? ? ? return ret;
>>> +}
>>
>>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>>difference
>>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>>management. Instead of duplicating so much code, another better way out is:
>>
>>1) remove pxa3xx_init_pm() from pxa3xx_init()
>>2) remove pxa3xx_init() from postcore_init()
>>3) change pxa3xx_init() to pxa3xx_common_init()
>>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>>well as pxa3xx_init_pm()
>>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>>pm initialization
>> ?(e.g. pxa95x_init_pm)
>>
> The name of pxa3xx_init() and pxa3xx_common_init() is very confusion.

I know it's a bit confusing. But they are sharing the same code, and it's
only a matter of naming issue. Like many drivers we have, they are called
'pxa2xx-*' but actually able to support pxa3xx, pxa9xx and even pxa168.

> PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image now. Actually I failed to compile them together.
>

Nah, it's not a hard requirement to build them together. It's about reducing
code duplication.

My idea would be to separate clock and pm into separate files, making them
more self-contained driver-like, instead of hardcoding them into pxa3xx.c.
So in the end, the pxa95x_init() will be something like below:

static int __init pxa95x_init(void)
{
	if (cpu_is_pxa95x()) {
		pxa_init_dma(IRQ_DMA, 32);
		pxa3xx_init_pm();
		pxa3xx_init_clock();
		clkdev_add_table(ARRAY_AND_SIZE(pxa95x_clkregs));

		for_each(p, pxa95x_sysdevs)
			sysdev_register(p);

		platform_add_devices(ARRAY_AND_SIZE(pxa95x_devices));
	}
}

So it reads like pxa95x is using the same subsystem as pxa3xx PM
and clock, and if there are any subtle differences to handle, we can
just change the API, and let know the difference through parameters,
just like pxa_init_dma().

Let me know if you think this is better and acceptable.

> Thanks
> Haojian
>

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-22  1:08         ` Eric Miao
@ 2010-11-22  4:18           ` Haojian Zhuang
  2010-11-22  6:59             ` Eric Miao
  0 siblings, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-22  4:18 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2010?11?22? 9:08 AM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org
>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>
>On Fri, Nov 19, 2010 at 5:16 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>
>>
>>>-----Original Message-----
>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>Sent: 2010?11?19? 4:45 PM
>>>To: Haojian Zhuang
>>>Cc: linux-arm-kernel at lists.infradead.org
>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>
>>>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
>>><haojian.zhuang@marvell.com> wrote:
>>>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>>>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>>>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>>>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>>>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>>>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>>>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>>>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>>>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>>>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>>>+++++++++++++++++++++++++++++
>>>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>>>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>>>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>>>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>>>
>>>> +void __init pxa95x_init_irq(void)
>>>> +{
>>>
>>>No enabling of CP6 is needed for pxa95x?
>>>
>> Yes, PXA95x can't support to access interrupt registers via co-processors.
>>
>>>> + ? ? ? pxa_init_irq(96, NULL);
>>>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>>>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>>>> +}
>>>> +
>>>> +
>>>> +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;
>>>> +
>>>
>>>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>>>subsystems are just same.
>>>
>> I don't want to support PM feature now. So I remove them in current patch.
>>
>>>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>>>> + ? ? ? }
>>>> +
>>>> + ? ? ? return ret;
>>>> +}
>>>
>>>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>>>difference
>>>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>>>management. Instead of duplicating so much code, another better way out is:
>>>
>>>1) remove pxa3xx_init_pm() from pxa3xx_init()
>>>2) remove pxa3xx_init() from postcore_init()
>>>3) change pxa3xx_init() to pxa3xx_common_init()
>>>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>>>well as pxa3xx_init_pm()
>>>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>>>pm initialization
>>> ?(e.g. pxa95x_init_pm)
>>>
>> The name of pxa3xx_init() and pxa3xx_common_init() is very confusion.
>
>I know it's a bit confusing. But they are sharing the same code, and it's
>only a matter of naming issue. Like many drivers we have, they are called
>'pxa2xx-*' but actually able to support pxa3xx, pxa9xx and even pxa168.
>
>> PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image now.
>Actually I failed to compile them together.
>>
>
>Nah, it's not a hard requirement to build them together. It's about reducing
>code duplication.
>
>My idea would be to separate clock and pm into separate files, making them
>more self-contained driver-like, instead of hardcoding them into pxa3xx.c.
>So in the end, the pxa95x_init() will be something like below:
>
>static int __init pxa95x_init(void)
>{
>	if (cpu_is_pxa95x()) {
>		pxa_init_dma(IRQ_DMA, 32);
>		pxa3xx_init_pm();
>		pxa3xx_init_clock();
>		clkdev_add_table(ARRAY_AND_SIZE(pxa95x_clkregs));
>
>		for_each(p, pxa95x_sysdevs)
>			sysdev_register(p);
>
>		platform_add_devices(ARRAY_AND_SIZE(pxa95x_devices));
>	}
>}
>
>So it reads like pxa95x is using the same subsystem as pxa3xx PM
>and clock, and if there are any subtle differences to handle, we can
>just change the API, and let know the difference through parameters,
>just like pxa_init_dma().
>
>Let me know if you think this is better and acceptable.

I don't agree invoking pxa3xx_init_pm() and pxa3xx_init_clock() in pxa95x.c. It's based on two reasons of naming confusion and force building pxa3xx.c for pxa95x.

If we want to share code, I suggest to move the sharing code into generic.c. So pxa95x.c will call xsc3_init_pm()/xsc3_init_clock() or common_init_pm()/common_init_clock(). What's your opinion?

Now we move PXA300/PXA310/PXA320/PXA930/PXA935 into pxa3xx family. So we shouldn't invoke pxa3xx_xxx() functions in other family. Otherwise, it's hard to be understood and maintained.

Thanks
Haojian

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-22  4:18           ` Haojian Zhuang
@ 2010-11-22  6:59             ` Eric Miao
  2010-11-23  4:11               ` Haojian Zhuang
  0 siblings, 1 reply; 27+ messages in thread
From: Eric Miao @ 2010-11-22  6:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 22, 2010 at 12:18 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>
>
>>-----Original Message-----
>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>Sent: 2010?11?22? 9:08 AM
>>To: Haojian Zhuang
>>Cc: linux-arm-kernel at lists.infradead.org
>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>
>>On Fri, Nov 19, 2010 at 5:16 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>>
>>>
>>>>-----Original Message-----
>>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>>Sent: 2010?11?19? 4:45 PM
>>>>To: Haojian Zhuang
>>>>Cc: linux-arm-kernel at lists.infradead.org
>>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>>
>>>>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
>>>><haojian.zhuang@marvell.com> wrote:
>>>>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>>>>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>>>>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>>>>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>>>>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>>>>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>>>>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>>>>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>>>>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>>>>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>>>>+++++++++++++++++++++++++++++
>>>>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>>>>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>>>>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>>>>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>>>>
>>>>> +void __init pxa95x_init_irq(void)
>>>>> +{
>>>>
>>>>No enabling of CP6 is needed for pxa95x?
>>>>
>>> Yes, PXA95x can't support to access interrupt registers via co-processors.
>>>
>>>>> + ? ? ? pxa_init_irq(96, NULL);
>>>>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>>>>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>>>>> +}
>>>>> +
>>>>> +
>>>>> +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;
>>>>> +
>>>>
>>>>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>>>>subsystems are just same.
>>>>
>>> I don't want to support PM feature now. So I remove them in current patch.
>>>
>>>>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>>>>> + ? ? ? }
>>>>> +
>>>>> + ? ? ? return ret;
>>>>> +}
>>>>
>>>>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>>>>difference
>>>>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>>>>management. Instead of duplicating so much code, another better way out is:
>>>>
>>>>1) remove pxa3xx_init_pm() from pxa3xx_init()
>>>>2) remove pxa3xx_init() from postcore_init()
>>>>3) change pxa3xx_init() to pxa3xx_common_init()
>>>>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>>>>well as pxa3xx_init_pm()
>>>>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>>>>pm initialization
>>>> ?(e.g. pxa95x_init_pm)
>>>>
>>> The name of pxa3xx_init() and pxa3xx_common_init() is very confusion.
>>
>>I know it's a bit confusing. But they are sharing the same code, and it's
>>only a matter of naming issue. Like many drivers we have, they are called
>>'pxa2xx-*' but actually able to support pxa3xx, pxa9xx and even pxa168.
>>
>>> PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image now.
>>Actually I failed to compile them together.
>>>
>>
>>Nah, it's not a hard requirement to build them together. It's about reducing
>>code duplication.
>>
>>My idea would be to separate clock and pm into separate files, making them
>>more self-contained driver-like, instead of hardcoding them into pxa3xx.c.
>>So in the end, the pxa95x_init() will be something like below:
>>
>>static int __init pxa95x_init(void)
>>{
>> ? ? ? if (cpu_is_pxa95x()) {
>> ? ? ? ? ? ? ? pxa_init_dma(IRQ_DMA, 32);
>> ? ? ? ? ? ? ? pxa3xx_init_pm();
>> ? ? ? ? ? ? ? pxa3xx_init_clock();
>> ? ? ? ? ? ? ? clkdev_add_table(ARRAY_AND_SIZE(pxa95x_clkregs));
>>
>> ? ? ? ? ? ? ? for_each(p, pxa95x_sysdevs)
>> ? ? ? ? ? ? ? ? ? ? ? sysdev_register(p);
>>
>> ? ? ? ? ? ? ? platform_add_devices(ARRAY_AND_SIZE(pxa95x_devices));
>> ? ? ? }
>>}
>>
>>So it reads like pxa95x is using the same subsystem as pxa3xx PM
>>and clock, and if there are any subtle differences to handle, we can
>>just change the API, and let know the difference through parameters,
>>just like pxa_init_dma().
>>
>>Let me know if you think this is better and acceptable.
>
> I don't agree invoking pxa3xx_init_pm() and pxa3xx_init_clock() in pxa95x.c. It's based on two reasons of naming confusion and force building pxa3xx.c for pxa95x.
>
> If we want to share code, I suggest to move the sharing code into generic.c. So pxa95x.c will call xsc3_init_pm()/xsc3_init_clock() or common_init_pm()/common_init_clock(). What's your opinion?
>

Now that's also confusing, cuz pxa95x is using PJ4. So a trade-off
would be for the naming to stick to the first SoC it appears. E.g.
pxa27x_keypad.c, where the keypad controller first appears on pxa27x,
but we are later re-using this on pxa3xx and pxa93x, and we are adding
device named "pxa27x-keypad" on pxa3xx and pxa93x, do you find
this approach acceptable?

Regarding the naming confusion that Marvell created, I don't have any
other better idea.

> Now we move PXA300/PXA310/PXA320/PXA930/PXA935 into pxa3xx family. So we shouldn't invoke pxa3xx_xxx() functions in other family. Otherwise, it's hard to be understood and maintained.
>

If we treat things like clock, power management, and so on, as normal
devices, you probably won't feel too upset about the naming then. If we
tear the SoC apart, we'll finally end up in a list of components as:

Core: PJ4
IRQ: re-using legacy pxa3xx
GPIO: reusing pxa3xx
PM: specific to pxa95x
CLOCK: reusing pxa3xx
MEM: specific to pxa95x

(just for illustration purpose only), and so on.

I do respect your opinions. So please let me know your concerns.

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-22  6:59             ` Eric Miao
@ 2010-11-23  4:11               ` Haojian Zhuang
  2010-11-23  6:13                 ` Eric Miao
  0 siblings, 1 reply; 27+ messages in thread
From: Haojian Zhuang @ 2010-11-23  4:11 UTC (permalink / raw)
  To: linux-arm-kernel



>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2010?11?22? 2:59 PM
>To: Haojian Zhuang
>Cc: linux-arm-kernel at lists.infradead.org
>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>
>On Mon, Nov 22, 2010 at 12:18 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>
>>
>>>-----Original Message-----
>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>Sent: 2010?11?22? 9:08 AM
>>>To: Haojian Zhuang
>>>Cc: linux-arm-kernel at lists.infradead.org
>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>
>>>On Fri, Nov 19, 2010 at 5:16 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>>>
>>>>
>>>>>-----Original Message-----
>>>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>>>Sent: 2010?11?19? 4:45 PM
>>>>>To: Haojian Zhuang
>>>>>Cc: linux-arm-kernel at lists.infradead.org
>>>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>>>
>>>>>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
>>>>><haojian.zhuang@marvell.com> wrote:
>>>>>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>>>>>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>>>>>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>>>>>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>>>>>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>>>>>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>>>>>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>>>>>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>>>>>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>>>>>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>>>>>+++++++++++++++++++++++++++++
>>>>>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>>>>>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>>>>>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>>>>>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>>>>>
>>>>>> +void __init pxa95x_init_irq(void)
>>>>>> +{
>>>>>
>>>>>No enabling of CP6 is needed for pxa95x?
>>>>>
>>>> Yes, PXA95x can't support to access interrupt registers via co-processors.
>>>>
>>>>>> + ? ? ? pxa_init_irq(96, NULL);
>>>>>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>>>>>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>>>>>> +}
>>>>>> +
>>>>>> +
>>>>>> +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;
>>>>>> +
>>>>>
>>>>>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>>>>>subsystems are just same.
>>>>>
>>>> I don't want to support PM feature now. So I remove them in current patch.
>>>>
>>>>>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>>>>>> + ? ? ? }
>>>>>> +
>>>>>> + ? ? ? return ret;
>>>>>> +}
>>>>>
>>>>>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>>>>>difference
>>>>>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>>>>>management. Instead of duplicating so much code, another better way out is:
>>>>>
>>>>>1) remove pxa3xx_init_pm() from pxa3xx_init()
>>>>>2) remove pxa3xx_init() from postcore_init()
>>>>>3) change pxa3xx_init() to pxa3xx_common_init()
>>>>>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>>>>>well as pxa3xx_init_pm()
>>>>>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>>>>>pm initialization
>>>>> ?(e.g. pxa95x_init_pm)
>>>>>
>>>> The name of pxa3xx_init() and pxa3xx_common_init() is very confusion.
>>>
>>>I know it's a bit confusing. But they are sharing the same code, and it's
>>>only a matter of naming issue. Like many drivers we have, they are called
>>>'pxa2xx-*' but actually able to support pxa3xx, pxa9xx and even pxa168.
>>>
>>>> PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image
>now.
>>>Actually I failed to compile them together.
>>>>
>>>
>>>Nah, it's not a hard requirement to build them together. It's about reducing
>>>code duplication.
>>>
>>>My idea would be to separate clock and pm into separate files, making them
>>>more self-contained driver-like, instead of hardcoding them into pxa3xx.c.
>>>So in the end, the pxa95x_init() will be something like below:
>>>
>>>static int __init pxa95x_init(void)
>>>{
>>> ? ? ? if (cpu_is_pxa95x()) {
>>> ? ? ? ? ? ? ? pxa_init_dma(IRQ_DMA, 32);
>>> ? ? ? ? ? ? ? pxa3xx_init_pm();
>>> ? ? ? ? ? ? ? pxa3xx_init_clock();
>>> ? ? ? ? ? ? ? clkdev_add_table(ARRAY_AND_SIZE(pxa95x_clkregs));
>>>
>>> ? ? ? ? ? ? ? for_each(p, pxa95x_sysdevs)
>>> ? ? ? ? ? ? ? ? ? ? ? sysdev_register(p);
>>>
>>> ? ? ? ? ? ? ? platform_add_devices(ARRAY_AND_SIZE(pxa95x_devices));
>>> ? ? ? }
>>>}
>>>
>>>So it reads like pxa95x is using the same subsystem as pxa3xx PM
>>>and clock, and if there are any subtle differences to handle, we can
>>>just change the API, and let know the difference through parameters,
>>>just like pxa_init_dma().
>>>
>>>Let me know if you think this is better and acceptable.
>>
>> I don't agree invoking pxa3xx_init_pm() and pxa3xx_init_clock() in pxa95x.c. It's based
>on two reasons of naming confusion and force building pxa3xx.c for pxa95x.
>>
>> If we want to share code, I suggest to move the sharing code into generic.c. So
>pxa95x.c will call xsc3_init_pm()/xsc3_init_clock() or
>common_init_pm()/common_init_clock(). What's your opinion?
>>
>
>Now that's also confusing, cuz pxa95x is using PJ4. So a trade-off
>would be for the naming to stick to the first SoC it appears. E.g.
>pxa27x_keypad.c, where the keypad controller first appears on pxa27x,
>but we are later re-using this on pxa3xx and pxa93x, and we are adding
>device named "pxa27x-keypad" on pxa3xx and pxa93x, do you find
>this approach acceptable?
>
>Regarding the naming confusion that Marvell created, I don't have any
>other better idea.
>
>> Now we move PXA300/PXA310/PXA320/PXA930/PXA935 into pxa3xx family. So we
>shouldn't invoke pxa3xx_xxx() functions in other family. Otherwise, it's hard to be
>understood and maintained.
>>
>
>If we treat things like clock, power management, and so on, as normal
>devices, you probably won't feel too upset about the naming then. If we
>tear the SoC apart, we'll finally end up in a list of components as:
>
>Core: PJ4
>IRQ: re-using legacy pxa3xx
>GPIO: reusing pxa3xx
>PM: specific to pxa95x
>CLOCK: reusing pxa3xx
>MEM: specific to pxa95x
>
CLOCK: There is no problem after seperate clock code from pxa3xx.c to independent clock file. My original concern is focused on calling APIs what are in pxa3xx.c from pxa95x.c.
MFP: a bit different on register bits definition. So suggest to move some operation from common head file to mfp-pxa3xx.c and create pxa95x_mfp_class. Because there's always a bit difference among silicons on MFP (drive setting and low power setting) whatever it belongs to PXA series or MMP series. And we can share some code in same c file for both pxa3xx and pxa95x.
MEM: which MEM do you mean? ISRAM allocation or SMEMC/DMEMC map region?

Thanks
Haojian

>(just for illustration purpose only), and so on.
>
>I do respect your opinions. So please let me know your concerns.

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

* [PATCH 3/9] ARM: pxa: support pxa95x
  2010-11-23  4:11               ` Haojian Zhuang
@ 2010-11-23  6:13                 ` Eric Miao
  0 siblings, 0 replies; 27+ messages in thread
From: Eric Miao @ 2010-11-23  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 23, 2010 at 12:11 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>
>
>>-----Original Message-----
>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>Sent: 2010?11?22? 2:59 PM
>>To: Haojian Zhuang
>>Cc: linux-arm-kernel at lists.infradead.org
>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>
>>On Mon, Nov 22, 2010 at 12:18 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>>
>>>
>>>>-----Original Message-----
>>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>>Sent: 2010?11?22? 9:08 AM
>>>>To: Haojian Zhuang
>>>>Cc: linux-arm-kernel at lists.infradead.org
>>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>>
>>>>On Fri, Nov 19, 2010 at 5:16 PM, Haojian Zhuang <hzhuang1@marvell.com> wrote:
>>>>>
>>>>>
>>>>>>-----Original Message-----
>>>>>>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>>>>>>Sent: 2010?11?19? 4:45 PM
>>>>>>To: Haojian Zhuang
>>>>>>Cc: linux-arm-kernel at lists.infradead.org
>>>>>>Subject: Re: [PATCH 3/9] ARM: pxa: support pxa95x
>>>>>>
>>>>>>On Wed, Nov 17, 2010 at 7:03 PM, Haojian Zhuang
>>>>>><haojian.zhuang@marvell.com> wrote:
>>>>>>> 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/mach-pxa/Kconfig ? ? ? ? ? ? ? ? | ? 12 +-
>>>>>>> ?arch/arm/mach-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>>>> ?arch/arm/mach-pxa/clock.h ? ? ? ? ? ? ? ? | ? 20 ++
>>>>>>> ?arch/arm/mach-pxa/devices.c ? ? ? ? ? ? ? | ?267 +++++++++---------
>>>>>>> ?arch/arm/mach-pxa/generic.c ? ? ? ? ? ? ? | ? ?8 +-
>>>>>>> ?arch/arm/mach-pxa/generic.h ? ? ? ? ? ? ? | ? ?3 +-
>>>>>>> ?arch/arm/mach-pxa/include/mach/hardware.h | ? 34 ++-
>>>>>>> ?arch/arm/mach-pxa/include/mach/irqs.h ? ? | ? ?1 +
>>>>>>> ?arch/arm/mach-pxa/pxa3xx.c ? ? ? ? ? ? ? ?| ? ?9 -
>>>>>>> ?arch/arm/mach-pxa/pxa930.c ? ? ? ? ? ? ? ?| ? ?2 +-
>>>>>>> ?arch/arm/mach-pxa/pxa95x.c ? ? ? ? ? ? ? ?| ?437
>>>>>>+++++++++++++++++++++++++++++
>>>>>>> ?arch/arm/mm/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +
>>>>>>> ?arch/arm/plat-pxa/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
>>>>>>> ?arch/arm/plat-pxa/include/plat/mfp.h ? ? ?| ? ?4 +-
>>>>>>> ?14 files changed, 643 insertions(+), 162 deletions(-)
>>>>>>> ?create mode 100644 arch/arm/mach-pxa/pxa95x.c
>>>>>>>
>>>>>>> +void __init pxa95x_init_irq(void)
>>>>>>> +{
>>>>>>
>>>>>>No enabling of CP6 is needed for pxa95x?
>>>>>>
>>>>> Yes, PXA95x can't support to access interrupt registers via co-processors.
>>>>>
>>>>>>> + ? ? ? pxa_init_irq(96, NULL);
>>>>>>> + ? ? ? pxa_init_ext_wakeup_irq(NULL);
>>>>>>> + ? ? ? pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
>>>>>>> +}
>>>>>>> +
>>>>>>> +
>>>>>>> +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;
>>>>>>> +
>>>>>>
>>>>>>No need to register pxa3xx_sysdev[]? My understanding is the IRQ/MFP/GPIO
>>>>>>subsystems are just same.
>>>>>>
>>>>> I don't want to support PM feature now. So I remove them in current patch.
>>>>>
>>>>>>> + ? ? ? ? ? ? ? ret = platform_add_devices(devices, ARRAY_SIZE(devices));
>>>>>>> + ? ? ? }
>>>>>>> +
>>>>>>> + ? ? ? return ret;
>>>>>>> +}
>>>>>>
>>>>>>I'm afraid the above duplicates most part of pxa3xx.c, the only subtle
>>>>>>difference
>>>>>>is the missing of pxa3xx_init_pm(), which is due to the difference of the power
>>>>>>management. Instead of duplicating so much code, another better way out is:
>>>>>>
>>>>>>1) remove pxa3xx_init_pm() from pxa3xx_init()
>>>>>>2) remove pxa3xx_init() from postcore_init()
>>>>>>3) change pxa3xx_init() to pxa3xx_common_init()
>>>>>>4) in pxa300_init() and pxa320_init(), call pxa3xx_common_init() as
>>>>>>well as pxa3xx_init_pm()
>>>>>>5) in pxa95x_init(), call pxa3xx_common_init() and pxa95x's specific
>>>>>>pm initialization
>>>>>> ?(e.g. pxa95x_init_pm)
>>>>>>
>>>>> The name of pxa3xx_init() and pxa3xx_common_init() is very confusion.
>>>>
>>>>I know it's a bit confusing. But they are sharing the same code, and it's
>>>>only a matter of naming issue. Like many drivers we have, they are called
>>>>'pxa2xx-*' but actually able to support pxa3xx, pxa9xx and even pxa168.
>>>>
>>>>> PXA95x is based on ARMv7. I don't prefer to compile it with PXA3xx in one image
>>now.
>>>>Actually I failed to compile them together.
>>>>>
>>>>
>>>>Nah, it's not a hard requirement to build them together. It's about reducing
>>>>code duplication.
>>>>
>>>>My idea would be to separate clock and pm into separate files, making them
>>>>more self-contained driver-like, instead of hardcoding them into pxa3xx.c.
>>>>So in the end, the pxa95x_init() will be something like below:
>>>>
>>>>static int __init pxa95x_init(void)
>>>>{
>>>> ? ? ? if (cpu_is_pxa95x()) {
>>>> ? ? ? ? ? ? ? pxa_init_dma(IRQ_DMA, 32);
>>>> ? ? ? ? ? ? ? pxa3xx_init_pm();
>>>> ? ? ? ? ? ? ? pxa3xx_init_clock();
>>>> ? ? ? ? ? ? ? clkdev_add_table(ARRAY_AND_SIZE(pxa95x_clkregs));
>>>>
>>>> ? ? ? ? ? ? ? for_each(p, pxa95x_sysdevs)
>>>> ? ? ? ? ? ? ? ? ? ? ? sysdev_register(p);
>>>>
>>>> ? ? ? ? ? ? ? platform_add_devices(ARRAY_AND_SIZE(pxa95x_devices));
>>>> ? ? ? }
>>>>}
>>>>
>>>>So it reads like pxa95x is using the same subsystem as pxa3xx PM
>>>>and clock, and if there are any subtle differences to handle, we can
>>>>just change the API, and let know the difference through parameters,
>>>>just like pxa_init_dma().
>>>>
>>>>Let me know if you think this is better and acceptable.
>>>
>>> I don't agree invoking pxa3xx_init_pm() and pxa3xx_init_clock() in pxa95x.c. It's based
>>on two reasons of naming confusion and force building pxa3xx.c for pxa95x.
>>>
>>> If we want to share code, I suggest to move the sharing code into generic.c. So
>>pxa95x.c will call xsc3_init_pm()/xsc3_init_clock() or
>>common_init_pm()/common_init_clock(). What's your opinion?
>>>
>>
>>Now that's also confusing, cuz pxa95x is using PJ4. So a trade-off
>>would be for the naming to stick to the first SoC it appears. E.g.
>>pxa27x_keypad.c, where the keypad controller first appears on pxa27x,
>>but we are later re-using this on pxa3xx and pxa93x, and we are adding
>>device named "pxa27x-keypad" on pxa3xx and pxa93x, do you find
>>this approach acceptable?
>>
>>Regarding the naming confusion that Marvell created, I don't have any
>>other better idea.
>>
>>> Now we move PXA300/PXA310/PXA320/PXA930/PXA935 into pxa3xx family. So we
>>shouldn't invoke pxa3xx_xxx() functions in other family. Otherwise, it's hard to be
>>understood and maintained.
>>>
>>
>>If we treat things like clock, power management, and so on, as normal
>>devices, you probably won't feel too upset about the naming then. If we
>>tear the SoC apart, we'll finally end up in a list of components as:
>>
>>Core: PJ4
>>IRQ: re-using legacy pxa3xx
>>GPIO: reusing pxa3xx
>>PM: specific to pxa95x
>>CLOCK: reusing pxa3xx
>>MEM: specific to pxa95x
>>
> CLOCK: There is no problem after seperate clock code from pxa3xx.c to independent clock file. My original concern is focused on calling APIs what are in pxa3xx.c from pxa95x.c.
> MFP: a bit different on register bits definition. So suggest to move some operation from common head file to mfp-pxa3xx.c and create pxa95x_mfp_class.

That's completely fine. If necessary I don't mind having a separate
mfp-pxa95x.c for the different parts.

> Because there's always a bit difference among silicons on MFP (drive setting and low power setting) whatever it belongs to PXA series or MMP series. And we can share some code in same c file for both pxa3xx and pxa95x.
> MEM: which MEM do you mean? ISRAM allocation or SMEMC/DMEMC map region?

All of them. So it could be further divided into sub-components, and decide
if they can be shared or not.

>
> Thanks
> Haojian
>
>>(just for illustration purpose only), and so on.
>>
>>I do respect your opinions. So please let me know your concerns.
>
>

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

end of thread, other threads:[~2010-11-23  6:13 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-17 11:03 [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx Haojian Zhuang
2010-11-17 11:03 ` [PATCH 2/9] ARM: pxa: redefine irqs.h Haojian Zhuang
2010-11-17 11:03   ` [PATCH 3/9] ARM: pxa: support pxa95x Haojian Zhuang
2010-11-17 11:03     ` [PATCH 4/9] ARM: pxa: support saarb platform Haojian Zhuang
2010-11-17 11:03       ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Haojian Zhuang
2010-11-17 11:03         ` [PATCH 6/9] ARM: pxa: sanitize IRQ registers access based on offset Haojian Zhuang
2010-11-17 11:03           ` [PATCH 7/9] ARM: pxa: auto compute shift and mult of timer Haojian Zhuang
2010-11-17 11:03             ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Haojian Zhuang
2010-11-17 11:03               ` [PATCH 9/9] ARM: pxa: add iwmmx support for PJ4 Haojian Zhuang
2010-11-17 11:09                 ` Haojian Zhuang
2010-11-17 15:55                   ` Nicolas Pitre
2010-11-18  3:09                     ` Haojian Zhuang
2010-11-18 18:27                       ` Nicolas Pitre
2010-11-17 15:29                 ` Nicolas Pitre
2010-11-17 15:23               ` [PATCH 8/9] ARM: pxa: add 32KHz timer as clock source Nicolas Pitre
2010-11-18  3:11                 ` Haojian Zhuang
2010-11-17 13:13         ` [PATCH 5/9] ARM: mmp: select CPU_PJ4 Sergei Shtylyov
2010-11-18  3:12           ` Haojian Zhuang
2010-11-19  8:45     ` [PATCH 3/9] ARM: pxa: support pxa95x Eric Miao
2010-11-19  9:16       ` Haojian Zhuang
2010-11-22  1:08         ` Eric Miao
2010-11-22  4:18           ` Haojian Zhuang
2010-11-22  6:59             ` Eric Miao
2010-11-23  4:11               ` Haojian Zhuang
2010-11-23  6:13                 ` Eric Miao
2010-11-18 14:03   ` [PATCH 2/9] ARM: pxa: redefine irqs.h Eric Miao
2010-11-18 14:01 ` [PATCH 1/9] ARM: pxa: redefine the cpu_is_pxa3xx 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.