Skip to contentSkip to conversation

update irqchip, clocksource, clk for mmp

PATCH Superseded Haojian Zhuang 2 participants 13 messages Jun 4, 2013 – Jun 11, 2013

Subsystems (7)

v4 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v4 cover update irqchip, clocksource, clk for mmp

Changelog:
v4:
1. Remove .init_irq in mmp & mmp2 DT machine descriptor.
2. Use an argument to replace TIMER_PHYS_BASE. Now transfer virtual address directly.
3. Merge 10th & 11th patches together. Remove the redundant changes on drivers/clocksource/Kconfig & drivers/clocksource/Makefile.

v3:
1. Don't use include/linux/irqchip/mmp.h since we don't need to move <mach/irqs.h> to <include/linux/irqchip/mmp.h>.
2. Move timer-mmp driver into clocksource directory & support clocksource.
3. Support clksrc in mmp & parse all clock from DTS.

v2:
1. Avoid to include <mach/irqs.h>. Move the head file into ? ?include/linux/irqchip directory.
2. Avoid to include <mach/pm-pxa910.h> & <mach/pm-mmp2.h>.

#1 lore raw

PATCH v4 1/10 irqchip: move mmp irq driver

Move irq-mmp driver from mach-mmp directory into irqchip directory.

---
 arch/arm/mach-mmp/Makefile                           | 2 +-
 arch/arm/mach-mmp/common.h                           | 1 -
 arch/arm/mach-mmp/include/mach/pxa168.h              | 1 +
 arch/arm/mach-mmp/include/mach/pxa910.h              | 1 +
 arch/arm/mach-mmp/pxa910.c                           | 1 +
 drivers/irqchip/Makefile                             | 1 +
 arch/arm/mach-mmp/irq.c => drivers/irqchip/irq-mmp.c | 2 --
 7 files changed, 5 insertions(+), 4 deletions(-)
 rename arch/arm/mach-mmp/irq.c => drivers/irqchip/irq-mmp.c (99%)
arch/arm/mach-mmp/Makefile +1 -1
index 095c155..9b702a1 100644
@@ -2,7 +2,7 @@
 # Makefile for Marvell's PXA168 processors line
 #
 
-obj-y				+= common.o devices.o time.o irq.o
+obj-y				+= common.o devices.o time.o
 
 # SoC support
 obj-$(CONFIG_CPU_PXA168)	+= pxa168.o
arch/arm/mach-mmp/common.h +0 -1
index 0bdc50b..9c1c9be 100644
@@ -2,7 +2,6 @@
 
 extern void timer_init(int irq);
 
-extern void __init icu_init_irq(void);
 extern void __init mmp_map_io(void);
 extern void mmp_restart(char, const char *);
 extern void __init pxa168_clk_init(void);
arch/arm/mach-mmp/include/mach/pxa168.h +1 -0
index 7ed1df2..e01dc2a 100644
@@ -2,6 +2,7 @@
 #define __ASM_MACH_PXA168_H
 
 extern void pxa168_timer_init(void);
+extern void __init icu_init_irq(void);
 extern void __init pxa168_init_irq(void);
 extern void pxa168_restart(char, const char *);
 extern void pxa168_clear_keypad_wakeup(void);
arch/arm/mach-mmp/include/mach/pxa910.h +1 -0
index b914afa..9225320 100644
@@ -2,6 +2,7 @@
 #define __ASM_MACH_PXA910_H
 
 extern void pxa910_timer_init(void);
+extern void __init icu_init_irq(void);
 extern void __init pxa910_init_irq(void);
 
 #include <linux/i2c.h>
arch/arm/mach-mmp/pxa910.c +1 -0
index ce6393a..a586742 100644
@@ -23,6 +23,7 @@
 #include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/devices.h>
+#include <mach/pxa910.h>
 
 #include "common.h"
 
drivers/irqchip/Makefile +1 -0
index cda4cb5..542d47e 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ARCH_MMP)			+= irq-mmp.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
 obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
drivers/irqchip/irq-mmp.c renamed from arch/arm/mach-mmp/irq.c +0 -2
similarity index 99%
rename from arch/arm/mach-mmp/irq.c
rename to drivers/irqchip/irq-mmp.c
index 3c71246..dab6def 100644
@@ -30,8 +30,6 @@
 #include <mach/pm-pxa910.h>
 #endif
 
-#include "common.h"
-
 #define MAX_ICU_NR		16
 
 struct icu_chip_data {
Signature · 1 line
1.8.1.2
#2 lore raw

PATCH v4 2/10 irqchip: mmp: support irqchip

In reply to Haojian Zhuang

Support IRQCHIP on irq-mmp driver.

---
 arch/arm/mach-mmp/mmp-dt.c  |   8 +-
 arch/arm/mach-mmp/mmp2-dt.c |   8 +-
 drivers/irqchip/irq-mmp.c   | 238 +++++++++++++++++++++++---------------------
 3 files changed, 126 insertions(+), 128 deletions(-)
arch/arm/mach-mmp/mmp-dt.c +1 -7
index b37915d..cca529c 100644
@@ -9,17 +9,13 @@
  *  publishhed by the Free Software Foundation.
  */
 
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/of_irq.h>
+#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/irqs.h>
 
 #include "common.h"
 
-extern void __init mmp_dt_irq_init(void);
 extern void __init mmp_dt_init_timer(void);
 
 static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = {
@@ -64,7 +60,6 @@ static const char *mmp_dt_board_compat[] __initdata = {
 
 DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_irq	= mmp_dt_irq_init,
 	.init_time	= mmp_dt_init_timer,
 	.init_machine	= pxa168_dt_init,
 	.dt_compat	= mmp_dt_board_compat,
@@ -72,7 +67,6 @@ MACHINE_END
 
 DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_irq	= mmp_dt_irq_init,
 	.init_time	= mmp_dt_init_timer,
 	.init_machine	= pxa910_dt_init,
 	.dt_compat	= mmp_dt_board_compat,
arch/arm/mach-mmp/mmp2-dt.c +1 -7
index 4ac2567..023cb45 100644
@@ -10,18 +10,13 @@
  */
 
 #include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/of_irq.h>
+#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/irqs.h>
-#include <mach/regs-apbc.h>
 
 #include "common.h"
 
-extern void __init mmp_dt_irq_init(void);
 extern void __init mmp_dt_init_timer(void);
 
 static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = {
@@ -49,7 +44,6 @@ static const char *mmp2_dt_board_compat[] __initdata = {
 
 DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_irq	= mmp_dt_irq_init,
 	.init_time	= mmp_dt_init_timer,
 	.init_machine	= mmp2_dt_init,
 	.dt_compat	= mmp2_dt_board_compat,
drivers/irqchip/irq-mmp.c +124 -114

268 lines not on this page · raw message

Signature · 1 line
1.8.1.2
#3 lore raw

PATCH v4 3/10 irqchip: mmp: support MULTI_IRQ_HANDLER

In reply to Haojian Zhuang

Support CONFIG_MULTI_IRQ_HANDLER in ARCH_MMP. So remove entry-macro.S.

---
 arch/arm/Kconfig                             |  1 +
 arch/arm/mach-mmp/include/mach/entry-macro.S | 26 -----------------
 drivers/irqchip/irq-mmp.c                    | 42 +++++++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 27 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/include/mach/entry-macro.S
arch/arm/Kconfig +1 -0
index d423d58..d6ba351 100644
@@ -549,6 +549,7 @@ config ARCH_MMP
 	select GENERIC_CLOCKEVENTS
 	select GPIO_PXA
 	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER
 	select NEED_MACH_GPIO_H
 	select PINCTRL
 	select PLAT_PXA
arch/arm/mach-mmp/include/mach/entry-macro.S deleted +0 -26
deleted file mode 100644
index bd152e2..0000000
@@ -1,26 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/entry-macro.S
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <asm/irq.h>
-#include <mach/regs-icu.h>
-
-	.macro	get_irqnr_preamble, base, tmp
-	mrc	p15, 0, \tmp, c0, c0, 0		@ CPUID
-	and	\tmp, \tmp, #0xff00
-	cmp	\tmp, #0x5800
-	ldr	\base, =mmp_icu_base
-	ldr	\base, [\base, #0]
-	addne	\base, \base, #0x10c		@ PJ1 AP INT SEL register
-	addeq	\base, \base, #0x104		@ PJ4 IRQ SEL register
-	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\tmp, [\base, #0]
-	and	\irqnr, \tmp, #0x3f
-	tst	\tmp, #(1 << 6)
-	.endm
drivers/irqchip/irq-mmp.c +41 -1

90 lines not on this page · raw message

Signature · 1 line
1.8.1.2
#4 lore raw

PATCH v4 4/10 ARM: mmp: avoid to include head file in mach-mmp

In reply to Haojian Zhuang

pxa910_set_wake() & mmp2_set_wake() are both declared in head files of arch/arm/mach-mmp/include/mach directory. If we include these head files in irq-mmp driver, it blocks the multiplatform build. So adjust the code.

---
 arch/arm/mach-mmp/mmp2.c    |  4 ++++
 arch/arm/mach-mmp/pxa910.c  |  4 ++++
 drivers/irqchip/irq-mmp.c   | 15 +--------------
 include/linux/irqchip/mmp.h |  6 ++++++
 4 files changed, 15 insertions(+), 14 deletions(-)
 create mode 100644 include/linux/irqchip/mmp.h
arch/arm/mach-mmp/mmp2.c +4 -0
index c7592f1..09fbe7d 100644
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip/mmp.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware/cache-tauros2.h>
@@ -26,6 +28,7 @@
 #include <mach/mfp.h>
 #include <mach/devices.h>
 #include <mach/mmp2.h>
+#include <mach/pm-mmp2.h>
 
 #include "common.h"
 
@@ -94,6 +97,7 @@ void mmp2_clear_pmic_int(void)
 void __init mmp2_init_irq(void)
 {
 	mmp2_init_icu();
+	icu_irq_chip.irq_set_wake = mmp2_set_wake;
 }
 
 static int __init mmp2_init(void)
arch/arm/mach-mmp/pxa910.c +4 -0
index a586742..96e125b 100644
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip/mmp.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware/cache-tauros2.h>
@@ -23,6 +25,7 @@
 #include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/devices.h>
+#include <mach/pm-pxa910.h>
 #include <mach/pxa910.h>
 
 #include "common.h"
@@ -80,6 +83,7 @@ static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata =
 void __init pxa910_init_irq(void)
 {
 	icu_init_irq();
+	icu_irq_chip.irq_set_wake = pxa910_set_wake;
 }
 
 static int __init pxa910_init(void)
drivers/irqchip/irq-mmp.c +1 -14
index 84d51ff..1f81432 100644
@@ -26,13 +26,6 @@
 
 #include <mach/irqs.h>
 
-#ifdef CONFIG_CPU_MMP2
-#include <mach/pm-mmp2.h>
-#endif
-#ifdef CONFIG_CPU_PXA910
-#include <mach/pm-pxa910.h>
-#endif
-
 #include "irqchip.h"
 
 #define MAX_ICU_NR		16
@@ -132,7 +125,7 @@ static void icu_unmask_irq(struct irq_data *d)
 	}
 }
 
-static struct irq_chip icu_irq_chip = {
+struct irq_chip icu_irq_chip = {
 	.name		= "icu_irq",
 	.irq_mask	= icu_mask_irq,
 	.irq_mask_ack	= icu_mask_ack_irq,
@@ -251,9 +244,6 @@ void __init icu_init_irq(void)
 	}
 	irq_set_default_host(icu_data[0].domain);
 	set_handle_irq(mmp_handle_irq);
-#ifdef CONFIG_CPU_PXA910
-	icu_irq_chip.irq_set_wake = pxa910_set_wake;
-#endif
 }
 
 /* MMP2 (ARMv7) */
@@ -358,9 +348,6 @@ void __init mmp2_init_icu(void)
 	}
 	irq_set_default_host(icu_data[0].domain);
 	set_handle_irq(mmp2_handle_irq);
-#ifdef CONFIG_CPU_MMP2
-	icu_irq_chip.irq_set_wake = mmp2_set_wake;
-#endif
 }
 
 #ifdef CONFIG_OF
include/linux/irqchip/mmp.h new file +6 -0
new file mode 100644
index 0000000..c78a892
@@ -0,0 +1,6 @@
+#ifndef	__IRQCHIP_MMP_H
+#define	__IRQCHIP_MMP_H
+
+extern struct irq_chip icu_irq_chip;
+
+#endif	/* __IRQCHIP_MMP_H */
Signature · 1 line
1.8.1.2
#5 lore raw

PATCH v4 5/10 irqchip: mmp: avoid to include irqs head file

In reply to Haojian Zhuang

Since <mach/irqs.h> in irq-mmp.c blocks the multiplatform build, remove it instead.

---
 drivers/irqchip/irq-mmp.c | 45 +++++++++++++++++++++------------------------
 1 file changed, 21 insertions(+), 24 deletions(-)
drivers/irqchip/irq-mmp.c +21 -24
index 1f81432..2cb7cd0 100644
@@ -24,8 +24,6 @@
 #include <asm/exception.h>
 #include <asm/mach/irq.h>
 
-#include <mach/irqs.h>
-
 #include "irqchip.h"
 
 #define MAX_ICU_NR		16
@@ -249,7 +247,7 @@ void __init icu_init_irq(void)
 /* MMP2 (ARMv7) */
 void __init mmp2_init_icu(void)
 {
-	int irq;
+	int irq, end;
 
 	max_icu_nr = 8;
 	mmp_icu_base = ioremap(0xd4282000, 0x1000);
@@ -263,11 +261,12 @@ void __init mmp2_init_icu(void)
 						   &icu_data[0]);
 	icu_data[1].reg_status = mmp_icu_base + 0x150;
 	icu_data[1].reg_mask = mmp_icu_base + 0x168;
-	icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE;
-	icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE;
+	icu_data[1].clr_mfp_irq_base = icu_data[0].virq_base +
+				icu_data[0].nr_irqs;
+	icu_data[1].clr_mfp_hwirq = 1;		/* offset to IRQ_MMP2_PMIC_BASE */
 	icu_data[1].nr_irqs = 2;
 	icu_data[1].cascade_irq = 4;
-	icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE;
+	icu_data[1].virq_base = icu_data[0].virq_base + icu_data[0].nr_irqs;
 	icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs,
 						   icu_data[1].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -276,7 +275,7 @@ void __init mmp2_init_icu(void)
 	icu_data[2].reg_mask = mmp_icu_base + 0x16c;
 	icu_data[2].nr_irqs = 2;
 	icu_data[2].cascade_irq = 5;
-	icu_data[2].virq_base = IRQ_MMP2_RTC_BASE;
+	icu_data[2].virq_base = icu_data[1].virq_base + icu_data[1].nr_irqs;
 	icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs,
 						   icu_data[2].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -285,7 +284,7 @@ void __init mmp2_init_icu(void)
 	icu_data[3].reg_mask = mmp_icu_base + 0x17c;
 	icu_data[3].nr_irqs = 3;
 	icu_data[3].cascade_irq = 9;
-	icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE;
+	icu_data[3].virq_base = icu_data[2].virq_base + icu_data[2].nr_irqs;
 	icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs,
 						   icu_data[3].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -294,7 +293,7 @@ void __init mmp2_init_icu(void)
 	icu_data[4].reg_mask = mmp_icu_base + 0x170;
 	icu_data[4].nr_irqs = 5;
 	icu_data[4].cascade_irq = 17;
-	icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE;
+	icu_data[4].virq_base = icu_data[3].virq_base + icu_data[3].nr_irqs;
 	icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs,
 						   icu_data[4].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -303,7 +302,7 @@ void __init mmp2_init_icu(void)
 	icu_data[5].reg_mask = mmp_icu_base + 0x174;
 	icu_data[5].nr_irqs = 15;
 	icu_data[5].cascade_irq = 35;
-	icu_data[5].virq_base = IRQ_MMP2_MISC_BASE;
+	icu_data[5].virq_base = icu_data[4].virq_base + icu_data[4].nr_irqs;
 	icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs,
 						   icu_data[5].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -312,7 +311,7 @@ void __init mmp2_init_icu(void)
 	icu_data[6].reg_mask = mmp_icu_base + 0x178;
 	icu_data[6].nr_irqs = 2;
 	icu_data[6].cascade_irq = 51;
-	icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE;
+	icu_data[6].virq_base = icu_data[5].virq_base + icu_data[5].nr_irqs;
 	icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs,
 						   icu_data[6].virq_base, 0,
 						   &irq_domain_simple_ops,
@@ -321,28 +320,26 @@ void __init mmp2_init_icu(void)
 	icu_data[7].reg_mask = mmp_icu_base + 0x184;
 	icu_data[7].nr_irqs = 2;
 	icu_data[7].cascade_irq = 55;
-	icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE;
+	icu_data[7].virq_base = icu_data[6].virq_base + icu_data[6].nr_irqs;
 	icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs,
 						   icu_data[7].virq_base, 0,
 						   &irq_domain_simple_ops,
 						   &icu_data[7]);
-	for (irq = 0; irq < IRQ_MMP2_MUX_END; irq++) {
+	end = icu_data[7].virq_base + icu_data[7].nr_irqs;
+	for (irq = 0; irq < end; irq++) {
 		icu_mask_irq(irq_get_irq_data(irq));
-		switch (irq) {
-		case IRQ_MMP2_PMIC_MUX:
-		case IRQ_MMP2_RTC_MUX:
-		case IRQ_MMP2_KEYPAD_MUX:
-		case IRQ_MMP2_TWSI_MUX:
-		case IRQ_MMP2_MISC_MUX:
-		case IRQ_MMP2_MIPI_HSI1_MUX:
-		case IRQ_MMP2_MIPI_HSI0_MUX:
+		if (irq == icu_data[1].cascade_irq ||
+		    irq == icu_data[2].cascade_irq ||
+		    irq == icu_data[3].cascade_irq ||
+		    irq == icu_data[4].cascade_irq ||
+		    irq == icu_data[5].cascade_irq ||
+		    irq == icu_data[6].cascade_irq ||
+		    irq == icu_data[7].cascade_irq) {
 			irq_set_chip(irq, &icu_irq_chip);
 			irq_set_chained_handler(irq, icu_mux_irq_demux);
-			break;
-		default:
+		} else {
 			irq_set_chip_and_handler(irq, &icu_irq_chip,
 						 handle_level_irq);
-			break;
 		}
 		set_irq_flags(irq, IRQF_VALID);
 	}
Signature · 1 line
1.8.1.2
#6 lore raw

PATCH v4 6/10 clocksource: mmp: move mmp timer driver

In reply to Haojian Zhuang

Move timer-mmp driver from mach-mmp to clocksource directory.

---
 arch/arm/mach-mmp/Makefile                                  | 2 +-
 drivers/clocksource/Makefile                                | 1 +
 arch/arm/mach-mmp/time.c => drivers/clocksource/timer-mmp.c | 2 --
 3 files changed, 2 insertions(+), 3 deletions(-)
 rename arch/arm/mach-mmp/time.c => drivers/clocksource/timer-mmp.c (99%)
arch/arm/mach-mmp/Makefile +1 -1
index 9b702a1..5d4ccc6 100644
@@ -2,7 +2,7 @@
 # Makefile for Marvell's PXA168 processors line
 #
 
-obj-y				+= common.o devices.o time.o
+obj-y				+= common.o devices.o
 
 # SoC support
 obj-$(CONFIG_CPU_PXA168)	+= pxa168.o
drivers/clocksource/Makefile +1 -0
index 8d979c7..f6aa3b6 100644
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
 obj-$(CONFIG_ARCH_MARCO)	+= timer-marco.o
+obj-$(CONFIG_ARCH_MMP)		+= timer-mmp.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs_timer.o
 obj-$(CONFIG_ARCH_PRIMA2)	+= timer-prima2.o
 obj-$(CONFIG_SUN4I_TIMER)	+= sun4i_timer.o
drivers/clocksource/timer-mmp.c renamed from arch/arm/mach-mmp/time.c +0 -2
similarity index 99%
rename from arch/arm/mach-mmp/time.c
rename to drivers/clocksource/timer-mmp.c
index 86a18b3..553e3de 100644
@@ -37,8 +37,6 @@
 #include <mach/cputype.h>
 #include <asm/mach/time.h>
 
-#include "clock.h"
-
 #define TIMERS_VIRT_BASE	TIMERS1_VIRT_BASE
 
 #define MAX_DELTA		(0xfffffffe)
Signature · 1 line
1.8.1.2
#7 lore raw

PATCH v4 7/10 ARM: mmp: move timer registers into driver

In reply to Haojian Zhuang

Move the definition of timer registers into timer-mmp driver. And map timer registers in driver.

---
 arch/arm/mach-mmp/common.h                   |  2 +-
 arch/arm/mach-mmp/include/mach/addr-map.h    |  3 ++
 arch/arm/mach-mmp/include/mach/regs-timers.h | 44 ----------------------------
 arch/arm/mach-mmp/mmp2.c                     |  2 +-
 arch/arm/mach-mmp/pxa168.c                   |  2 +-
 arch/arm/mach-mmp/pxa910.c                   |  2 +-
 drivers/clocksource/timer-mmp.c              | 37 ++++++++++++++++++-----
 7 files changed, 37 insertions(+), 55 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/include/mach/regs-timers.h
arch/arm/mach-mmp/common.h +1 -1
index 9c1c9be..2fc9390 100644
@@ -1,6 +1,6 @@
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 
-extern void timer_init(int irq);
+extern void timer_init(void __iomem *base, int irq);
 
 extern void __init mmp_map_io(void);
 extern void mmp_restart(char, const char *);
arch/arm/mach-mmp/include/mach/addr-map.h +3 -0
index f88a44c..169c280 100644
@@ -43,4 +43,7 @@
 #define CIU_VIRT_BASE		(AXI_VIRT_BASE + 0x82c00)
 #define CIU_REG(x)		(CIU_VIRT_BASE + (x))
 
+#define TIMER1_VIRT_BASE	(APB_VIRT_BASE + 0x14000)
+#define TIMER2_VIRT_BASE	(APB_VIRT_BASE + 0x16000)
+
 #endif /* __ASM_MACH_ADDR_MAP_H */
arch/arm/mach-mmp/include/mach/regs-timers.h deleted +0 -44

44 lines not on this page · raw message

arch/arm/mach-mmp/mmp2.c +1 -1
index 09fbe7d..f26ea9d 100644
@@ -131,7 +131,7 @@ void __init mmp2_timer_init(void)
 	clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
 	__raw_writel(clk_rst, APBC_TIMERS);
 
-	timer_init(IRQ_MMP2_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_MMP2_TIMER1);
 }
 
 /* on-chip devices */
arch/arm/mach-mmp/pxa168.c +1 -1
index a30dcf3..2bdec91 100644
@@ -78,7 +78,7 @@ void __init pxa168_timer_init(void)
 	/* 3.25MHz, bus/functional clock enabled, release reset */
 	__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-	timer_init(IRQ_PXA168_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_PXA168_TIMER1);
 }
 
 void pxa168_clear_keypad_wakeup(void)
arch/arm/mach-mmp/pxa910.c +1 -1
index 96e125b..df379c2 100644
@@ -112,7 +112,7 @@ void __init pxa910_timer_init(void)
 	__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
 	__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-	timer_init(IRQ_PXA910_AP1_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_PXA910_AP1_TIMER1);
 }
 
 /* on-chip devices */
drivers/clocksource/timer-mmp.c +30 -7
index 553e3de..bfd0997 100644
@@ -30,19 +30,39 @@
 #include <linux/of_irq.h>
 
 #include <asm/sched_clock.h>
-#include <mach/addr-map.h>
-#include <mach/regs-timers.h>
-#include <mach/regs-apbc.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <asm/mach/time.h>
 
-#define TIMERS_VIRT_BASE	TIMERS1_VIRT_BASE
+#define TMR_CCR		(0x0000)
+#define TMR_TN_MM(n, m)	(0x0004 + ((n) << 3) + (((n) + (m)) << 2))
+#define TMR_CR(n)	(0x0028 + ((n) << 2))
+#define TMR_SR(n)	(0x0034 + ((n) << 2))
+#define TMR_IER(n)	(0x0040 + ((n) << 2))
+#define TMR_PLVR(n)	(0x004c + ((n) << 2))
+#define TMR_PLCR(n)	(0x0058 + ((n) << 2))
+#define TMR_WMER	(0x0064)
+#define TMR_WMR		(0x0068)
+#define TMR_WVR		(0x006c)
+#define TMR_WSR		(0x0070)
+#define TMR_ICR(n)	(0x0074 + ((n) << 2))
+#define TMR_WICR	(0x0080)
+#define TMR_CER		(0x0084)
+#define TMR_CMR		(0x0088)
+#define TMR_ILR(n)	(0x008c + ((n) << 2))
+#define TMR_WCR		(0x0098)
+#define TMR_WFAR	(0x009c)
+#define TMR_WSAR	(0x00A0)
+#define TMR_CVWR(n)	(0x00A4 + ((n) << 2))
+
+#define TMR_CCR_CS_0(x)	(((x) & 0x3) << 0)
+#define TMR_CCR_CS_1(x)	(((x) & 0x7) << 2)
+#define TMR_CCR_CS_2(x)	(((x) & 0x3) << 5)
 
 #define MAX_DELTA		(0xfffffffe)
 #define MIN_DELTA		(16)
 
-static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+static void __iomem *mmp_timer_base;
 
 /*
  * FIXME: the timer needs some delay to stablize the counter capture
@@ -189,8 +209,11 @@ static struct irqaction timer_irq = {
 	.dev_id		= &ckevt,
 };
 
-void __init timer_init(int irq)
+void __init timer_init(void __iomem *base, int irq)
 {
+	BUG_ON(!base);
+	mmp_timer_base = base;
+
 	timer_config();
 
 	setup_sched_clock(mmp_read_sched_clock, 32, CLOCK_TICK_RATE);
@@ -231,7 +254,7 @@ void __init mmp_dt_init_timer(void)
 		ret = -ENOMEM;
 		goto out;
 	}
-	timer_init(irq);
+	timer_init(mmp_timer_base, irq);
 	return;
 out:
 	pr_err("Failed to get timer from device tree with error:%d\n", ret);
Signature · 1 line
1.8.1.2
#8 lore raw

PATCH v4 8/10 ARM: pxa: init dma debugfs in late level

In reply to Haojian Zhuang

Remove pxa_init_dma() from core_initcall level since it's unncecssary for DT mode. But dma debugfs is also included in pxa_init_dma(). So only initiliaze dma debugfs in late_initcall level.

---
 arch/arm/mach-mmp/mmp2.c   |  2 +-
 arch/arm/mach-mmp/pxa168.c |  2 +-
 arch/arm/mach-mmp/pxa910.c |  2 +-
 arch/arm/plat-pxa/dma.c    | 30 ++++++++++++++++++++----------
 4 files changed, 23 insertions(+), 13 deletions(-)
arch/arm/mach-mmp/mmp2.c +1 -1
index f26ea9d..a0abfd7 100644
@@ -114,7 +114,6 @@ static int __init mmp2_init(void)
 
 	return 0;
 }
-postcore_initcall(mmp2_init);
 
 #define APBC_TIMERS	APBC_REG(0x024)
 
@@ -122,6 +121,7 @@ void __init mmp2_timer_init(void)
 {
 	unsigned long clk_rst;
 
+	mmp2_init();
 	__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
 
 	/*
arch/arm/mach-mmp/pxa168.c +1 -1
index 2bdec91..345a493 100644
@@ -61,7 +61,6 @@ static int __init pxa168_init(void)
 
 	return 0;
 }
-postcore_initcall(pxa168_init);
 
 /* system timer - clock enabled, 3.25MHz */
 #define TIMER_CLK_RST	(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
@@ -69,6 +68,7 @@ postcore_initcall(pxa168_init);
 
 void __init pxa168_timer_init(void)
 {
+	pxa168_init();
 	/* this is early, we have to initialize the CCU registers by
 	 * ourselves instead of using clk_* API. Clock rate is defined
 	 * by APBC_TIMERS_CLK_RST (3.25MHz) and enabled free-running
arch/arm/mach-mmp/pxa910.c +1 -1
index df379c2..1a84800 100644
@@ -100,7 +100,6 @@ static int __init pxa910_init(void)
 
 	return 0;
 }
-postcore_initcall(pxa910_init);
 
 /* system timer - clock enabled, 3.25MHz */
 #define TIMER_CLK_RST	(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
@@ -108,6 +107,7 @@ postcore_initcall(pxa910_init);
 
 void __init pxa910_timer_init(void)
 {
+	pxa910_init();
 	/* reset and configure */
 	__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
 	__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
arch/arm/plat-pxa/dma.c +20 -10
index 79ef102..6c5472b 100644
@@ -228,36 +228,46 @@ err_state:
 	return NULL;
 }
 
-static void pxa_dma_init_debugfs(void)
+static int __init pxa_dma_init_debugfs(void)
 {
-	int i;
+	int i, ret;
 	struct dentry *chandir;
 
 	dbgfs_root = debugfs_create_dir(DMA_DEBUG_NAME, NULL);
-	if (IS_ERR(dbgfs_root) || !dbgfs_root)
+	if (IS_ERR(dbgfs_root) || !dbgfs_root) {
+		ret = -EINVAL;
 		goto err_root;
+	}
 
 	dbgfs_state = debugfs_create_file("state", 0400, dbgfs_root, NULL,
 					  &dbg_fops_state);
-	if (!dbgfs_state)
+	if (!dbgfs_state) {
+		ret = -EINVAL;
 		goto err_state;
+	}
 
 	dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
 			     GFP_KERNEL);
-	if (!dbgfs_chan)
+	if (!dbgfs_chan) {
+		ret = -ENOMEM;
 		goto err_alloc;
+	}
 
 	chandir = debugfs_create_dir("channels", dbgfs_root);
-	if (!chandir)
+	if (!chandir) {
+		ret = -EINVAL;
 		goto err_chandir;
+	}
 
 	for (i = 0; i < num_dma_channels; i++) {
 		dbgfs_chan[i] = pxa_dma_dbg_alloc_chan(i, chandir);
-		if (!dbgfs_chan[i])
+		if (!dbgfs_chan[i]) {
+			ret = -EINVAL;
 			goto err_chans;
+		}
 	}
 
-	return;
+	return 0;
 err_chans:
 err_chandir:
 	kfree(dbgfs_chan);
@@ -266,7 +276,9 @@ err_state:
 	debugfs_remove_recursive(dbgfs_root);
 err_root:
 	pr_err("pxa_dma: debugfs is not available\n");
+	return ret;
 }
+late_initcall(pxa_dma_init_debugfs);
 
 static void __exit pxa_dma_cleanup_debugfs(void)
 {
@@ -385,7 +397,5 @@ int __init pxa_init_dma(int irq, int num_ch)
 	}
 	num_dma_channels = num_ch;
 
-	pxa_dma_init_debugfs();
-
 	return 0;
 }
Signature · 1 line
1.8.1.2
#9 lore raw

PATCH v4 9/10 clk: mmp: parse clock from dts

In reply to Haojian Zhuang

Parse clock information from DTS file for mach-mmp.

---
 arch/arm/boot/dts/pxa168-aspenite.dts |   3 +
 arch/arm/boot/dts/pxa168-clk.dtsi     | 304 ++++++++++++++++++
 arch/arm/boot/dts/pxa168.dtsi         |  10 +
 arch/arm/boot/dts/pxa910-clk.dtsi     | 569 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/pxa910-dkb.dts      |  11 +
 arch/arm/boot/dts/pxa910.dtsi         |  12 +-
 arch/arm/mach-mmp/mmp-dt.c            |   2 +
 drivers/clk/mmp/Makefile              |   2 +-
 drivers/clk/mmp/clk-mmp.c             | 363 ++++++++++++++++++++++
 9 files changed, 1274 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/pxa168-clk.dtsi
 create mode 100644 arch/arm/boot/dts/pxa910-clk.dtsi
 create mode 100644 drivers/clk/mmp/clk-mmp.c
arch/arm/boot/dts/pxa168-aspenite.dts +3 -0
index e762fac..2597e98 100644
@@ -24,6 +24,9 @@
 
 	soc {
 		apb at d4000000 {
+			timer0: timer at d4014000 {
+				status = "okay";
+			};
 			uart1: uart at d4017000 {
 				status = "okay";
 			};
arch/arm/boot/dts/pxa168-clk.dtsi new file +304 -0

304 lines not on this page · raw message

arch/arm/boot/dts/pxa168.dtsi +10 -0
index 975dad2..250bf2c 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
 	aliases {
@@ -53,12 +54,15 @@
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4014000 0x100>;
 				interrupts = <13>;
+				clocks = <&apbc_timer0_clk>;
+				status = "disabled";
 			};
 
 			uart1: uart at d4017000 {
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4017000 0x1000>;
 				interrupts = <27>;
+				clocks = <&apbc_uart1_clk>;
 				status = "disabled";
 			};
 
@@ -66,6 +70,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4018000 0x1000>;
 				interrupts = <28>;
+				clocks = <&apbc_uart2_clk>;
 				status = "disabled";
 			};
 
@@ -73,6 +78,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4026000 0x1000>;
 				interrupts = <29>;
+				clocks = <&apbc_uart3_clk>;
 				status = "disabled";
 			};
 
@@ -87,6 +93,7 @@
 				interrupt-names = "gpio_mux";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+				clocks = <&apbc_gpio_clk>;
 				ranges;
 
 				gcb0: gpio at d4019000 {
@@ -111,6 +118,7 @@
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
 				mrvl,i2c-fast-mode;
+				clocks = <&apbc_twsi1_clk>;
 				status = "disabled";
 			};
 
@@ -118,6 +126,7 @@
 				compatible = "mrvl,mmp-twsi";
 				reg = <0xd4025000 0x1000>;
 				interrupts = <58>;
+				clocks = <&apbc_twsi2_clk>;
 				status = "disabled";
 			};
 
@@ -126,6 +135,7 @@
 				reg = <0xd4010000 0x1000>;
 				interrupts = <5 6>;
 				interrupt-names = "rtc 1Hz", "rtc alarm";
+				clocks = <&apbc_rtc_clk>;
 				status = "disabled";
 			};
 		};
arch/arm/boot/dts/pxa910-clk.dtsi new file +569 -0

569 lines not on this page · raw message

arch/arm/boot/dts/pxa910-dkb.dts +11 -0
index 595492a..b892ebe 100644
@@ -24,6 +24,17 @@
 
 	soc {
 		apb at d4000000 {
+			pll2: refclk1001mhz {
+				/* Reference clock for internal PLL2 */
+				compatible = "marvell,mmp-fixed-clkrate";
+				#clock-cells = <0>;
+				clocks = <&osc_26m>;
+				clock-frequency = <1001000000>;
+				clock-output-names = "refclk1001mhz";
+			};
+			timer0: timer at d4014000 {
+				status = "okay";
+			};
 			uart1: uart at d4017000 {
 				status = "okay";
 			};
arch/arm/boot/dts/pxa910.dtsi +11 -1
index 0247c62..cd888d3 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
 	aliases {
@@ -44,7 +45,6 @@
 				reg = <0xd4282000 0x1000>;
 				mrvl,intc-nr-irqs = <64>;
 			};
-
 		};
 
 		apb at d4000000 {	/* APB */
@@ -58,12 +58,15 @@
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4014000 0x100>;
 				interrupts = <13>;
+				clocks = <&apbc_timer0_clk>;
+				status = "disabled";
 			};
 
 			timer1: timer at d4016000 {
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4016000 0x100>;
 				interrupts = <29>;
+				clocks = <&apbc_timer1_clk>;
 				status = "disabled";
 			};
 
@@ -71,6 +74,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4017000 0x1000>;
 				interrupts = <27>;
+				clocks = <&apbc_uart1_clk>;
 				status = "disabled";
 			};
 
@@ -78,6 +82,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4018000 0x1000>;
 				interrupts = <28>;
+				clocks = <&apbc_uart2_clk>;
 				status = "disabled";
 			};
 
@@ -85,6 +90,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4036000 0x1000>;
 				interrupts = <59>;
+				clocks = <&apbcp_uart3_clk>;
 				status = "disabled";
 			};
 
@@ -99,6 +105,7 @@
 				interrupt-names = "gpio_mux";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+				clocks = <&apbc_gpio_clk>;
 				ranges;
 
 				gcb0: gpio at d4019000 {
@@ -124,6 +131,7 @@
 				#size-cells = <0>;
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
+				clocks = <&apbc_twsi1_clk>;
 				mrvl,i2c-fast-mode;
 				status = "disabled";
 			};
@@ -134,6 +142,7 @@
 				#size-cells = <0>;
 				reg = <0xd4037000 0x1000>;
 				interrupts = <54>;
+				clocks = <&apbcp_twsi2_clk>;
 				status = "disabled";
 			};
 
@@ -142,6 +151,7 @@
 				reg = <0xd4010000 0x1000>;
 				interrupts = <5 6>;
 				interrupt-names = "rtc 1Hz", "rtc alarm";
+				clocks = <&apbc_rtc_clk>;
 				status = "disabled";
 			};
 		};
arch/arm/mach-mmp/mmp-dt.c +2 -0
index cca529c..f109bf6 100644
@@ -9,6 +9,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -48,6 +49,7 @@ static void __init pxa168_dt_init(void)
 
 static void __init pxa910_dt_init(void)
 {
+	of_clk_init(NULL);
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     pxa910_auxdata_lookup, NULL);
 }
drivers/clk/mmp/Makefile +1 -1
index 392d780..83182e5 100644
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mmp.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
drivers/clk/mmp/clk-mmp.c new file +363 -0

363 lines not on this page · raw message

Signature · 1 line
1.8.1.2
#10 lore raw

PATCH v4 9/10 clk: mmp: parse clock from dts

Quoting Haojian Zhuang (2013-06-03 21:12:51)

Quoted 13 lines

Parse clock information from DTS file for mach-mmp.

---
 arch/arm/boot/dts/pxa168-aspenite.dts |   3 +
 arch/arm/boot/dts/pxa168-clk.dtsi     | 304 ++++++++++++++++++
 arch/arm/boot/dts/pxa168.dtsi         |  10 +
 arch/arm/boot/dts/pxa910-clk.dtsi     | 569 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/pxa910-dkb.dts      |  11 +
 arch/arm/boot/dts/pxa910.dtsi         |  12 +-
 arch/arm/mach-mmp/mmp-dt.c            |   2 +
 drivers/clk/mmp/Makefile              |   2 +-
 drivers/clk/mmp/clk-mmp.c             | 363 ++++++++++++++++++++++

Patch looks mostly good to me. I prefer to break out the DTS changes from the clock driver changes into separate patches.

Also I believe that binding definitions are missing from Documentation/devicetree/bindings/clocks.

Regards,
Mike

Quoted 1,498 lines
 9 files changed, 1274 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/pxa168-clk.dtsi
 create mode 100644 arch/arm/boot/dts/pxa910-clk.dtsi
 create mode 100644 drivers/clk/mmp/clk-mmp.c
arch/arm/boot/dts/pxa168-aspenite.dts +3 -0
index e762fac..2597e98 100644
@@ -24,6 +24,9 @@
 
        soc {
                apb at d4000000 {
+                       timer0: timer at d4014000 {
+                               status = "okay";
+                       };
                        uart1: uart at d4017000 {
                                status = "okay";
                        };
arch/arm/boot/dts/pxa168-clk.dtsi new file +304 -0
new file mode 100644
index 0000000..f9c298df
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (C) 2013
+ *  Author: Haojian Zhuang <[email protected]>
+ *
+ *  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/ "skeleton.dtsi"
+
+/ {
+       soc {
+               apb at d4000000 {  /* APB */
+                       compatible = "mrvl,apb-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd4000000 0x00200000>;
+                       ranges;
+
+                       mpmu: clocks at 50000 {
+                               compatible = "marvell,mmp-mpmu";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xd4050000 0x1100>;
+
+                               osc_32k: osc32khz {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <32768>;
+                                       clock-output-names = "osc32khz";
+                               };
+                               osc_26m: osc26mhz {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <26000000>;
+                                       clock-output-names = "osc26mhz";
+                               };
+                               pll1_312m: refclk312mhz {
+                                       compatible = "marvell,mmp-fixed-clkrate";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_26m>;
+                                       clock-frequency = <312000000>;
+                                       clock-output-names = "refclk312mhz";
+                               };
+                               refclk156m: refclk156mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m>;
+                                       clock-output-names = "refclk156mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk118m: refclk117mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk156m>;
+                                       /* 117.9648MHz */
+                                       clock-output-names = "refclk118mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <6144 8125>;
+                               };
+                               refclk104m: refclk104mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m>;
+                                       clock-output-names = "refclk104mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 3>;
+                               };
+                               refclk59m: refclk59mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk118m>;
+                                       clock-names = "baud_58.98mhz";
+                                       /* 58.9824MHz */
+                                       clock-output-names = "refclk59mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk15m: refclk15mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk156m>;
+                                       clock-names = "baud_14.86mhz";
+                                       /* 14.857MHz */
+                                       clock-output-names = "refclk15mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <2 21>;
+                               };
+                       };
+
+                       apbc: clocks at 15000 {
+                               compatible = "marvell,mmp-apbc";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               #clock-cells = <0>;
+                               reg = <0xd4015000 0x100>;
+
+                               apbc_twsi1_clk: apbc_twsi1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk32m>;
+                                       clock-names = "apbc_twsi1_clk";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x2c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_twsi2_clk: apbc_twsi2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk32m>;
+                                       clock-names = "apbc_twsi2_clk";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x6c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_rtc_clk: apbc_rtc_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_32k>;
+                                       clock-names = "apbc_rtc_clk";
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x28 0x70>;
+                                       marvell,mmp-apbc-power-ctl;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_gpio_clk: apbc_gpio_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk26m>;
+                                       clock-names = "apbc_gpio_clk";
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x8 0x0>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_uart1_mux: apbc_uart1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbc_uart1_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x0 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbc_uart1_clk: apbc_uart1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_uart1_mux>;
+                                       clock-names = "apbc_uart1_clk";
+                                       marvell,mmp-clk-reg = <0x0 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_uart2_mux: apbc_uart2_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbc_uart2_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbc_uart2_clk: apbc_uart2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_uart2_mux>;
+                                       clock-names = "apbc_uart2_clk";
+                                       marvell,mmp-clk-reg = <0x4 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_uart3_mux: apbc_uart3_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbc_uart3_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x70 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbc_uart3_clk: apbc_uart3_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_uart3_mux>;
+                                       clock-names = "apbc_uart3_clk";
+                                       marvell,mmp-clk-reg = <0x70 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm1_mux: apbc_pwm1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm1_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0xc 0x70>;
+                               };
+                               apbc_pwm1_clk: apbc_pwm1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm1_mux>;
+                                       clock-names = "apbc_pwm1_clk";
+                                       marvell,mmp-clk-reg = <0xc 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm2_mux: apbc_pwm2_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm2_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x10 0x70>;
+                               };
+                               apbc_pwm2_clk: apbc_pwm2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm2_mux>;
+                                       clock-names = "apbc_pwm2_clk";
+                                       marvell,mmp-clk-reg = <0x10 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm3_mux: apbc_pwm3_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm3_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x14 0x70>;
+                               };
+                               apbc_pwm3_clk: apbc_pwm3_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm3_mux>;
+                                       clock-names = "apbc_pwm3_clk";
+                                       marvell,mmp-clk-reg = <0x14 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm4_mux: apbc_pwm4_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm4_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x18 0x70>;
+                               };
+                               apbc_pwm4_clk: apbc_pwm4_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm4_mux>;
+                                       clock-names = "apbc_pwm4_clk";
+                                       marvell,mmp-clk-reg = <0x18 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_kpc_mux: apbc_kpc_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_32k &refclk16k &refclk26m>;
+                                       clock-output-names = "apbc_kpc_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20>;
+                                       marvell,mmp-clk-reg = <0x30 0x70>;
+                               };
+                               apbc_kpc_clk: apbc_kpc_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_kpc_mux>;
+                                       clock-names = "apbc_kpc_clk";
+                                       marvell,mmp-clk-reg = <0x30 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_timer0_mux: apbc_timer0_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k &refclk7m &refclk3m>;
+                                       clock-output-names = "apbc_timer0_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x34 0x70>;
+                               };
+                               apbc_timer0_clk: apbc_timer0_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&timer0_mux>;
+                                       clock-names = "apbc_timer0_clk";
+                                       marvell,mmp-clk-reg = <0x34 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                       };
+                       timer0_mux: timer0_mux {
+                               compatible = "marvell,mmp-clkmux";
+                               #clock-cells = <0>;
+                               clocks = <&apbc_timer0_mux &osc_32k>;
+                               clock-output-names = "timer0_mux";
+                               marvell,mmp-clk-sel = <0 0x2>;
+                               marvell,mmp-clk-reg = <0x14000 0x1c>;
+                       };
+               };
+       };
+};
arch/arm/boot/dts/pxa168.dtsi +10 -0
index 975dad2..250bf2c 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
        aliases {
@@ -53,12 +54,15 @@
                                compatible = "mrvl,mmp-timer";
                                reg = <0xd4014000 0x100>;
                                interrupts = <13>;
+                               clocks = <&apbc_timer0_clk>;
+                               status = "disabled";
                        };
 
                        uart1: uart at d4017000 {
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4017000 0x1000>;
                                interrupts = <27>;
+                               clocks = <&apbc_uart1_clk>;
                                status = "disabled";
                        };
 
@@ -66,6 +70,7 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4018000 0x1000>;
                                interrupts = <28>;
+                               clocks = <&apbc_uart2_clk>;
                                status = "disabled";
                        };
 
@@ -73,6 +78,7 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4026000 0x1000>;
                                interrupts = <29>;
+                               clocks = <&apbc_uart3_clk>;
                                status = "disabled";
                        };
 
@@ -87,6 +93,7 @@
                                interrupt-names = "gpio_mux";
                                interrupt-controller;
                                #interrupt-cells = <1>;
+                               clocks = <&apbc_gpio_clk>;
                                ranges;
 
                                gcb0: gpio at d4019000 {
@@ -111,6 +118,7 @@
                                reg = <0xd4011000 0x1000>;
                                interrupts = <7>;
                                mrvl,i2c-fast-mode;
+                               clocks = <&apbc_twsi1_clk>;
                                status = "disabled";
                        };
 
@@ -118,6 +126,7 @@
                                compatible = "mrvl,mmp-twsi";
                                reg = <0xd4025000 0x1000>;
                                interrupts = <58>;
+                               clocks = <&apbc_twsi2_clk>;
                                status = "disabled";
                        };
 
@@ -126,6 +135,7 @@
                                reg = <0xd4010000 0x1000>;
                                interrupts = <5 6>;
                                interrupt-names = "rtc 1Hz", "rtc alarm";
+                               clocks = <&apbc_rtc_clk>;
                                status = "disabled";
                        };
                };
arch/arm/boot/dts/pxa910-clk.dtsi new file +569 -0
new file mode 100644
index 0000000..035697f
@@ -0,0 +1,569 @@
+/*
+ *  Copyright (C) 2013
+ *  Author: Haojian Zhuang <[email protected]>
+ *
+ *  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/ "skeleton.dtsi"
+
+/ {
+       soc {
+               axi at d4200000 {  /* AXI */
+                       compatible = "mrvl,axi-bus", "simple-bus";
+                       reg = <0xd4200000 0x00200000>;
+                       ranges;
+
+                       apmu: clocks at 82800 {
+                               compatible = "marvell,mmp-apmu";
+                               reg = <0xd4282800 0x100>;
+
+                               /*
+                                * Processor clocks: pclk, pdclk, baclk, xpclk
+                                * DDR Controller clocks: dclk
+                                * AXI Fabric clocks: aclk
+                                */
+                               pclk_refclk: refclk_pclk {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&pj1_refclk>;
+                                       clock-output-names = "pclk";
+                                       marvell,mmp-clock-frequency = <104000000 156000000 208000000 312000000 500500000 624000000 806000000 1001000000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x7>;
+                               };
+                               /* pdclk -- DDR Interface clock */
+                               pdclk_refclk: refclk_pdclk {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&pj1_refclk>;
+                                       clock-output-names = "pdclk";
+                                       marvell,mmp-clock-frequency = <78000000 104000000 156000000 201000000 250250000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x38>;
+                               };
+                               /* baclk -- AXI Fabric Bus Interface clock */
+                               baclk_refclk: refclk_baclk {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&pj1_refclk>;
+                                       clock-output-names = "baclk";
+                                       marvell,mmp-clock-frequency = <78000000 104000000 156000000 201000000 250250000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x1c0>;
+                               };
+                               /* xpclk -- L2 interface clock */
+                               xpclk_refclk: refclk_xpclk {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&pj1_refclk>;
+                                       clock-output-names = "xpclk";
+                                       marvell,mmp-clock-frequency = <104000000 156000000 250250000 312000000 403000000 500500000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0xe00>;
+                               };
+                               /* dclk -- DDR Controller clock */
+                               dclk2x_refclk: refclk_dclk2x {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&ddr_refclk>;
+                                       clock-output-names = "dclk2x";
+                                       marvell,mmp-clock-frequency = <208000000 312000000 402000000 500500000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x7000>;
+                               };
+                               dclk_refclk: refclk_dclk {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&dclk2x_refclk>;
+                                       clock-output-names = "dclk";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               /* aclk -- AXI Fabric clock */
+                               aclk_refclk: refclk_aclk {
+                                       compatible = "marvell,mmp-apmu-clkdiv";
+                                       #clock-cells = <0>;
+                                       clocks = <&axi_refclk>;
+                                       clock-output-names = "aclk";
+                                       marvell,mmp-clock-frequency = <104000000 156000000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x38000>;
+                               };
+                       };
+               };
+
+               apb at d4000000 {  /* APB */
+                       compatible = "mrvl,apb-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd4000000 0x00200000>;
+                       ranges;
+
+                       mpmu: clocks at 50000 {
+                               compatible = "marvell,mmp-mpmu";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xd4050000 0x1100>;
+
+                               osc_32k: osc32khz {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <32768>;
+                                       clock-output-names = "osc32khz";
+                               };
+                               osc_26m: osc26mhz {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <26000000>;
+                                       clock-output-names = "osc26mhz";
+                               };
+                               pll1_312m: refclk312mhz {
+                                       compatible = "marvell,mmp-fixed-clkrate";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_26m>;
+                                       clock-frequency = <312000000>;
+                                       clock-output-names = "refclk312mhz";
+                               };
+                               pll1_624m: refclk624mhz {
+                                       compatible = "marvell,mmp-fixed-clkrate";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_26m>;
+                                       clock-frequency = <624000000>;
+                                       clock-output-names = "refclk624mhz";
+                               };
+                               pj1_refclk: refclk_pj1 {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m &pll1_624m &pll2>;
+                                       clock-output-names = "refclk_pj1";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x20000000 0x40000000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x8 0xe0000000>;
+                               };
+                               ddr_refclk: refclk_ddr {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m &pll1_624m &pll2>;
+                                       clock-output-names = "refclk_ddr";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x00800000 0x01000000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x8 0x01800000>;
+                               };
+                               axi_refclk: refclk_axi {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m &pll1_624m>;
+                                       clock-output-names = "refclk_axi";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x00080000>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x8 0x00080000>;
+                               };
+                               refclk156m: refclk156mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m>;
+                                       clock-output-names = "refclk156mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk118m: refclk117mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk156m>;
+                                       /* 117.9648MHz */
+                                       clock-output-names = "refclk118mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <6144 8125>;
+                               };
+                               refclk104m: refclk104mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_312m>;
+                                       clock-output-names = "refclk104mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 3>;
+                               };
+                               refclk59m: refclk59mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk118m>;
+                                       clock-names = "baud_58.98mhz";
+                                       /* 58.9824MHz */
+                                       clock-output-names = "refclk59mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk52m: refclk52mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk104m>;
+                                       clock-output-names = "refclk52mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk48m: refclk48mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&pll1_624m>;
+                                       clock-output-names = "refclk48mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 13>;
+                               };
+                               refclk32m: refclk32mhz@ {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk48m>;
+                                       clock-output-names = "refclk32mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <2 3>;
+                               };
+                               refclk26m: refclk26mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk52m>;
+                                       clock-output-names = "refclk26mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk15m: refclk15mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk156m>;
+                                       clock-names = "baud_14.86mhz";
+                                       /* 14.857MHz */
+                                       clock-output-names = "refclk15mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <2 21>;
+                               };
+                               refclk13m: refclk13mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk26m>;
+                                       clock-output-names = "refclk13mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk7m: refclk7mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m>;
+                                       clock-output-names = "refclk7mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk3m: refclk3mhz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk7m>;
+                                       clock-output-names = "refclk3mhz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                               refclk16k: refclk16khz {
+                                       compatible = "marvell,mmp-fixed-clkfactor";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_32k>;
+                                       clock-output-names = "refclk16khz";
+                                       /* multiple & divider */
+                                       marvell,mmp-fixed-factor = <1 2>;
+                               };
+                       };
+
+                       apbc: clocks at 15000 {
+                               compatible = "marvell,mmp-apbc";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               #clock-cells = <0>;
+                               reg = <0xd4015000 0x100>;
+
+                               apbc_twsi1_clk: apbc_twsi1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk32m>;
+                                       clock-names = "apbc_twsi1_clk";
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x2c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_rtc_clk: apbc_rtc_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_32k>;
+                                       clock-names = "apbc_rtc_clk";
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x28 0x70>;
+                                       marvell,mmp-apbc-power-ctl;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_gpio_clk: apbc_gpio_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk26m>;
+                                       clock-names = "apbc_gpio_clk";
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x8 0x0>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_uart1_mux: apbc_uart1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbc_uart1_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x0 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbc_uart1_clk: apbc_uart1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_uart1_mux>;
+                                       clock-names = "apbc_uart1_clk";
+                                       marvell,mmp-clk-reg = <0x0 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_uart2_mux: apbc_uart2_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbc_uart2_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x4 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbc_uart2_clk: apbc_uart2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_uart2_mux>;
+                                       clock-names = "apbc_uart2_clk";
+                                       marvell,mmp-clk-reg = <0x4 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm1_mux: apbc_pwm1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm1_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0xc 0x70>;
+                               };
+                               apbc_pwm1_clk: apbc_pwm1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm1_mux>;
+                                       clock-names = "apbc_pwm1_clk";
+                                       marvell,mmp-clk-reg = <0xc 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm2_mux: apbc_pwm2_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm2_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x10 0x70>;
+                               };
+                               apbc_pwm2_clk: apbc_pwm2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm2_mux>;
+                                       clock-names = "apbc_pwm2_clk";
+                                       marvell,mmp-clk-reg = <0x10 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm3_mux: apbc_pwm3_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm3_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x14 0x70>;
+                               };
+                               apbc_pwm3_clk: apbc_pwm3_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm3_mux>;
+                                       clock-names = "apbc_pwm3_clk";
+                                       marvell,mmp-clk-reg = <0x14 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_pwm4_mux: apbc_pwm4_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k>;
+                                       clock-output-names = "apbc_pwm4_mux";
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                                       marvell,mmp-clk-reg = <0x18 0x70>;
+                               };
+                               apbc_pwm4_clk: apbc_pwm4_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_pwm4_mux>;
+                                       clock-names = "apbc_pwm4_clk";
+                                       marvell,mmp-clk-reg = <0x18 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_ssp1_mux: apbc_ssp1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk7m &refclk13m &refclk26m &refclk52m>;
+                                       clock-output-names = "apbc_ssp1_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x1c 0x70>;
+                               };
+                               apbc_ssp1_clk: apbc_ssp1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_ssp1_mux>;
+                                       clock-names = "apbc_ssp1_clk";
+                                       marvell,mmp-clk-reg = <0x1c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_ssp2_mux: apbc_ssp2_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk7m &refclk13m &refclk26m &refclk52m>;
+                                       clock-output-names = "apbc_ssp2_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x20 0x70>;
+                               };
+                               apbc_ssp2_clk: apbc_ssp2_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_ssp2_mux>;
+                                       clock-names = "apbc_ssp2_clk";
+                                       marvell,mmp-clk-reg = <0x20 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_ssp3_mux: apbc_ssp3_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk7m &refclk13m &refclk26m &refclk52m>;
+                                       clock-output-names = "apbc_ssp3_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x4c 0x70>;
+                               };
+                               apbc_ssp3_clk: apbc_ssp3_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_ssp3_mux>;
+                                       clock-names = "apbc_ssp3_clk";
+                                       marvell,mmp-clk-reg = <0x4c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_kpc_mux: apbc_kpc_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&osc_32k &refclk16k &refclk26m>;
+                                       clock-output-names = "apbc_kpc_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20>;
+                                       marvell,mmp-clk-reg = <0x30 0x70>;
+                               };
+                               apbc_kpc_clk: apbc_kpc_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbc_kpc_mux>;
+                                       clock-names = "apbc_kpc_clk";
+                                       marvell,mmp-clk-reg = <0x30 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_timer0_mux: apbc_timer0_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k &refclk7m &refclk3m>;
+                                       clock-output-names = "apbc_timer0_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x34 0x70>;
+                               };
+                               apbc_timer0_clk: apbc_timer0_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&timer0_mux>;
+                                       clock-names = "apbc_timer0_clk";
+                                       marvell,mmp-clk-reg = <0x34 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                               apbc_timer1_mux: apbc_timer1_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk13m &osc_32k &refclk7m &refclk3m>;
+                                       clock-output-names = "apbc_timer1_mux";
+                                       marvell,mmp-clk-sel = <0 0x10 0x20 0x30>;
+                                       marvell,mmp-clk-reg = <0x44 0x70>;
+                               };
+                               apbc_timer1_clk: apbc_timer1_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&timer1_mux>;
+                                       clock-names = "apbc_timer1_clk";
+                                       marvell,mmp-clk-reg = <0x44 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                       };
+
+                       apbcp: clocks at 3b000 {
+                               compatible = "marvell,mmp-apbcp";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xd403b000 0x100>;
+
+                               apbcp_twsi2_clk: apbcp_twsi2_clk {
+                                       compatible = "marvell,mmp-apbcp-clock";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk32m>;
+                                       clock-output-names = "apbcp_twsi2_clk";
+                                       marvell,mmp-clk-sel = <0>;
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x28 0x70>;
+                               };
+                               apbcp_uart3_mux: apbcp_uart3_mux {
+                                       compatible = "marvell,mmp-clkmux";
+                                       #clock-cells = <0>;
+                                       clocks = <&refclk59m &refclk15m>;
+                                       clock-output-names = "apbcp_uart3_mux";
+                                       /* register offset & mask */
+                                       marvell,mmp-clk-reg = <0x1c 0x70>;
+                                       /* register value of each item */
+                                       marvell,mmp-clk-sel = <0 0x10>;
+                               };
+                               apbcp_uart3_clk: apbcp_uart3_clk {
+                                       compatible = "marvell,mmp-apbc-clk";
+                                       #clock-cells = <0>;
+                                       clocks = <&apbcp_uart3_mux>;
+                                       clock-names = "apbcp_uart3_clk";
+                                       marvell,mmp-clk-reg = <0x1c 0x70>;
+                                       marvell,mmp-clk-delay = <10>;
+                               };
+                       };
+
+                       timer0_mux: timer0_mux {
+                               compatible = "marvell,mmp-clkmux";
+                               #clock-cells = <0>;
+                               clocks = <&refclk3m &osc_32k &apbc_timer0_mux>;
+                               clock-output-names = "timer0_mux";
+                               marvell,mmp-clk-sel = <0 0x1 0x3>;
+                               marvell,mmp-clk-reg = <0x14000 0x1c>;
+                       };
+
+                       timer1_mux: timer1_mux {
+                               compatible = "marvell,mmp-clkmux";
+                               #clock-cells = <0>;
+                               clocks = <&refclk3m &osc_32k &apbc_timer1_mux>;
+                               clock-output-names = "timer1_mux";
+                               marvell,mmp-clk-sel = <0 0x1 0x3>;
+                               marvell,mmp-clk-reg = <0x16000 0x1c>;
+                       };
+               };
+       };
+};
arch/arm/boot/dts/pxa910-dkb.dts +11 -0
index 595492a..b892ebe 100644
@@ -24,6 +24,17 @@
 
        soc {
                apb at d4000000 {
+                       pll2: refclk1001mhz {
+                               /* Reference clock for internal PLL2 */
+                               compatible = "marvell,mmp-fixed-clkrate";
+                               #clock-cells = <0>;
+                               clocks = <&osc_26m>;
+                               clock-frequency = <1001000000>;
+                               clock-output-names = "refclk1001mhz";
+                       };
+                       timer0: timer at d4014000 {
+                               status = "okay";
+                       };
                        uart1: uart at d4017000 {
                                status = "okay";
                        };
arch/arm/boot/dts/pxa910.dtsi +11 -1
index 0247c62..cd888d3 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
        aliases {
@@ -44,7 +45,6 @@
                                reg = <0xd4282000 0x1000>;
                                mrvl,intc-nr-irqs = <64>;
                        };
-
                };
 
                apb at d4000000 {  /* APB */
@@ -58,12 +58,15 @@
                                compatible = "mrvl,mmp-timer";
                                reg = <0xd4014000 0x100>;
                                interrupts = <13>;
+                               clocks = <&apbc_timer0_clk>;
+                               status = "disabled";
                        };
 
                        timer1: timer at d4016000 {
                                compatible = "mrvl,mmp-timer";
                                reg = <0xd4016000 0x100>;
                                interrupts = <29>;
+                               clocks = <&apbc_timer1_clk>;
                                status = "disabled";
                        };
 
@@ -71,6 +74,7 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4017000 0x1000>;
                                interrupts = <27>;
+                               clocks = <&apbc_uart1_clk>;
                                status = "disabled";
                        };
 
@@ -78,6 +82,7 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4018000 0x1000>;
                                interrupts = <28>;
+                               clocks = <&apbc_uart2_clk>;
                                status = "disabled";
                        };
 
@@ -85,6 +90,7 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4036000 0x1000>;
                                interrupts = <59>;
+                               clocks = <&apbcp_uart3_clk>;
                                status = "disabled";
                        };
 
@@ -99,6 +105,7 @@
                                interrupt-names = "gpio_mux";
                                interrupt-controller;
                                #interrupt-cells = <1>;
+                               clocks = <&apbc_gpio_clk>;
                                ranges;
 
                                gcb0: gpio at d4019000 {
@@ -124,6 +131,7 @@
                                #size-cells = <0>;
                                reg = <0xd4011000 0x1000>;
                                interrupts = <7>;
+                               clocks = <&apbc_twsi1_clk>;
                                mrvl,i2c-fast-mode;
                                status = "disabled";
                        };
@@ -134,6 +142,7 @@
                                #size-cells = <0>;
                                reg = <0xd4037000 0x1000>;
                                interrupts = <54>;
+                               clocks = <&apbcp_twsi2_clk>;
                                status = "disabled";
                        };
 
@@ -142,6 +151,7 @@
                                reg = <0xd4010000 0x1000>;
                                interrupts = <5 6>;
                                interrupt-names = "rtc 1Hz", "rtc alarm";
+                               clocks = <&apbc_rtc_clk>;
                                status = "disabled";
                        };
                };
arch/arm/mach-mmp/mmp-dt.c +2 -0
index cca529c..f109bf6 100644
@@ -9,6 +9,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -48,6 +49,7 @@ static void __init pxa168_dt_init(void)
 
 static void __init pxa910_dt_init(void)
 {
+       of_clk_init(NULL);
        of_platform_populate(NULL, of_default_bus_match_table,
                             pxa910_auxdata_lookup, NULL);
 }
drivers/clk/mmp/Makefile +1 -1
index 392d780..83182e5 100644
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mmp.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
drivers/clk/mmp/clk-mmp.c new file +363 -0
new file mode 100644
index 0000000..7ead432
@@ -0,0 +1,363 @@
+/*
+ * Marvell MMP clock driver
+ *
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+enum {
+       MMP_MPMU = 0,
+       MMP_APMU,
+       MMP_APBC,
+       MMP_APBCP,
+       MMP_APB,
+       MMP_MAX,
+};
+
+static void __iomem *mmp_clk_base[MMP_MAX];
+
+static DEFINE_SPINLOCK(mmp_clk_lock);
+
+static const struct of_device_id mmp_of_match[] = {
+       { .compatible = "marvell,mmp-mpmu", .data = (void *)MMP_MPMU, },
+       { .compatible = "marvell,mmp-apmu", .data = (void *)MMP_APMU, },
+       { .compatible = "marvell,mmp-apbc", .data = (void *)MMP_APBC, },
+       { .compatible = "marvell,mmp-apbcp", .data = (void *)MMP_APBCP, },
+       { .compatible = "mrvl,apb-bus", .data = (void *)MMP_APB, },
+};
+
+void __iomem __init *mmp_init_clocks(struct device_node *np)
+{
+       struct device_node *parent;
+       const struct of_device_id *match;
+       void __iomem *ret = NULL;
+       int i;
+
+       parent = of_get_parent(np);
+       if (!parent)
+               goto out;
+       match = of_match_node(mmp_of_match, parent);
+       if (!match)
+               goto out;
+
+       i = (unsigned int)match->data;
+       switch (i) {
+       case MMP_MPMU:
+       case MMP_APMU:
+       case MMP_APBC:
+       case MMP_APBCP:
+       case MMP_APB:
+               if (!mmp_clk_base[i]) {
+                       ret = of_iomap(parent, 0);
+                       WARN_ON(!ret);
+                       mmp_clk_base[i] = ret;
+               } else {
+                       ret = mmp_clk_base[i];
+               }
+               break;
+       default:
+               goto out;
+       }
+out:
+       return ret;
+}
+
+static void __init mmp_fixed_rate_setup(struct device_node *np)
+{
+       struct clk *clk;
+       const char *clk_name, *parent_name;
+       int rate;
+
+       if (of_property_read_u32(np, "clock-frequency", &rate))
+               return;
+
+       if (of_property_read_string(np, "clock-output-names", &clk_name))
+               return;
+
+       /* this node has only one parent */
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       clk = clk_register_fixed_rate(NULL, clk_name, parent_name, 0, rate);
+       if (IS_ERR(clk))
+               return;
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(mmp_fixed_rate, "marvell,mmp-fixed-clkrate",
+              mmp_fixed_rate_setup);
+
+static void __init mmp_fixed_factor_setup(struct device_node *np)
+{
+       struct clk *clk;
+       const char *clk_name, *output_name, *parent_name;
+       u32 data[2];
+
+       if (of_property_read_u32_array(np, "marvell,mmp-fixed-factor",
+                               &data[0], 2))
+               return;
+       if (of_property_read_string(np, "clock-output-names", &output_name))
+               return;
+
+       /* this node has only one parent */
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       clk = clk_register_fixed_factor(NULL, output_name, parent_name, 0,
+                       data[0], data[1]);
+       if (IS_ERR(clk))
+               return;
+       if (!of_property_read_string(np, "clock-names", &clk_name))
+               clk_register_clkdev(clk, clk_name, NULL);
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(mmp_fixed_factor, "marvell,mmp-fixed-clkfactor",
+              mmp_fixed_factor_setup);
+
+static void __init mmp_apmu_div_setup(struct device_node *np)
+{
+       u32 data[2];
+       u8 shift, width;
+       void __iomem *reg, *base;
+       const char *parent_name, *clk_name;
+       struct clk *clk;
+
+       base = mmp_init_clocks(np);
+       if (!base)
+               return;
+
+       if (of_property_read_u32_array(np, "marvell,mmp-clk-reg", &data[0], 2))
+               return;
+       reg = base + data[0];
+       shift = ffs(data[1]) - 1;
+       width = fls(data[1]) - ffs(data[1]) + 1;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+       if (of_property_read_string(np, "clock-output-names", &clk_name))
+               return;
+
+       clk = clk_register_divider(NULL, clk_name, parent_name,
+                       CLK_SET_RATE_PARENT, reg, shift, width, 0,
+                       &mmp_clk_lock);
+       if (IS_ERR(clk))
+               return;
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       return;
+}
+CLK_OF_DECLARE(mmp_div, "mmp-apmu-clkdiv", mmp_apmu_div_setup);
+
+static int __init mmp_parse_mux(struct device_node *np,
+                               const char **parent_names,
+                               u8 *num_parents,
+                               u32 *clk_sel)
+{
+       int i, cnt, ret;
+
+       /* get the count of items in mux */
+       for (i = 0, cnt = 0; ; i++, cnt++) {
+               /* parent's #clock-cells property is always 0 */
+               if (!of_parse_phandle(np, "clocks", i))
+                       break;
+       }
+
+       for (i = 0; ; i++) {
+               if (!of_clk_get_parent_name(np, i))
+                       break;
+       }
+       *num_parents = i;
+       if (!*num_parents)
+               return -ENOENT;
+
+       clk_sel = kzalloc(sizeof(u32 *) * *num_parents, GFP_KERNEL);
+       if (!clk_sel)
+               return -ENOMEM;
+       ret = of_property_read_u32_array(np, "marvell,mmp-clk-sel", clk_sel, cnt);
+       if (ret)
+               goto err;
+       return 0;
+err:
+       kfree(clk_sel);
+       return ret;
+}
+
+static void __init mmp_mux_setup(struct device_node *np)
+{
+       u32 data[2], *clk_sel, mux_flags = 0;
+       u8 shift, width, num_parents;
+       void __iomem *reg, *base;
+       const char **parent_names;
+       const char *clk_name;
+       struct clk *clk;
+       int i, ret;
+
+       base = mmp_init_clocks(np);
+       if (!base)
+               return;
+       if (of_property_read_string(np, "clock-output-names", &clk_name))
+               return;
+       if (of_property_read_u32_array(np, "marvell,mmp-clk-reg", &data[0], 2))
+               return;
+       ret = mmp_parse_mux(np, parent_names, &num_parents, clk_sel);
+       if (ret)
+               return;
+
+       reg = base + data[0];
+       shift = ffs(data[1]) - 1;
+       width = fls(data[1]) - ffs(data[1]) + 1;
+
+       parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+       if (!parent_names)
+               return;
+
+       for (i = 0; i < num_parents; i++)
+               parent_names[i] = of_clk_get_parent_name(np, i);
+       clk = clk_register_mux(NULL, clk_name, parent_names, num_parents,
+                              CLK_SET_RATE_PARENT, reg, shift, width,
+                              mux_flags, &mmp_clk_lock);
+       if (IS_ERR(clk)) {
+               kfree(parent_names);
+               return;
+       }
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(mmp_mux, "marvell,mmp-clkmux", mmp_mux_setup);
+
+#define APBC_NO_BUS_CTRL       BIT(0)
+#define APBC_POWER_CTRL                BIT(1)
+
+static void __init mmp_apbc_setup(struct device_node *np)
+{
+       u32 data[2], delay, apbc_flags, clkdev;
+       void __iomem *reg, *base;
+       const char **parent_names;
+       const char *clk_name = NULL;
+       struct clk *clk;
+
+       base = mmp_init_clocks(np);
+       if (!base)
+               return;
+
+       if (of_property_read_string(np, "clock-names", &clk_name))
+               clkdev = 1;
+       else {
+               of_property_read_string(np, "clock-output-names", &clk_name);
+               clkdev = 0;
+       }
+
+       if (of_property_read_u32_array(np, "marvell,mmp-clk-reg", &data[0], 2))
+               return;
+       /* If marvell,mmp-clk-delay property isn't defined, set delay as 10us */
+       if (of_property_read_u32(np, "marvell,mmp-clk-delay", &delay))
+               delay = 10;
+       if (of_get_property(np, "marvell,mmp-apbc-power-ctl", NULL))
+               apbc_flags |= APBC_POWER_CTRL;
+
+       reg = base + data[0];
+
+       /* only has the fixed parent */
+       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+       if (!parent_names)
+               return;
+       parent_names[0] = of_clk_get_parent_name(np, 0);
+
+       clk = mmp_clk_register_apbc(clk_name, parent_names[0],
+                                   reg, delay, 0, &mmp_clk_lock);
+       if (IS_ERR(clk)) {
+               kfree(parent_names);
+               return;
+       }
+       if (clkdev)
+               clk_register_clkdev(clk, clk_name, NULL);
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(mmp_apbc, "marvell,mmp-apbc-clk", mmp_apbc_setup);
+
+static void __init mmp_apbcp_setup(struct device_node *np)
+{
+       int i, cnt;
+       u32 *clk_sel, data[2];
+       u8 num_parents, shift, width;
+       void __iomem *reg, *base;
+       const char **parent_names, *clk_name;
+       struct clk *clk;
+
+       base = mmp_init_clocks(np);
+       if (!base)
+               return;
+
+       if (of_property_read_string(np, "clock-output-names", &clk_name))
+               return;
+       /* get the count of items in mux */
+       for (i = 0, cnt = 0; ; i++, cnt++) {
+               /* parent's #clock-cells property is always 0 */
+               if (!of_parse_phandle(np, "clocks", i))
+                       break;
+       }
+
+       for (i = 0; ; i++) {
+               if (!of_clk_get_parent_name(np, i))
+                       break;
+       }
+       num_parents = i;
+       if (!num_parents)
+               return;
+
+       if (of_property_read_u32_array(np, "marvell,mmp-clk-reg", &data[0], 2))
+               return;
+       reg = base + data[0];
+       shift = ffs(data[1]) - 1;
+       width = fls(data[1]) - ffs(data[1]) + 1;
+
+       clk_sel = kzalloc(sizeof(u32 *) * num_parents, GFP_KERNEL);
+       if (!clk_sel)
+               return;
+       if (of_property_read_u32_array(np, "marvell,mmp-clk-sel", clk_sel, cnt))
+               goto err_sel;
+       parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+       if (!parent_names)
+               goto err_sel;
+
+       for (i = 0; i < num_parents; i++)
+               parent_names[i] = of_clk_get_parent_name(np, i);
+       clk = clk_register_mux(NULL, clk_name, parent_names, num_parents, 0,
+                               reg, shift, width, 0, &mmp_clk_lock);
+       if (IS_ERR(clk))
+               goto err_mux;
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       return;
+err_mux:
+       kfree(parent_names);
+err_sel:
+       kfree(clk_sel);
+}
+CLK_OF_DECLARE(mmp_apbcp, "mmp-apbcp-clk", mmp_apbcp_setup);
Signature · 1 line
1.8.1.2
#11 lore raw

PATCH v4 10/10 ARM: mmp: avoid to use cpu_is_xxx in timer

In reply to Haojian Zhuang

Avoid to use cpu_is_xxx() in timer-mmp driver, since it blocks the multiplatform build. Now add mmp2_mode variable for legacy mode. In DT mode, set the right clock rate in DTS file.

---
 arch/arm/Kconfig                      |  1 +
 arch/arm/boot/dts/mmp2-brownstone.dts |  4 ++
 arch/arm/boot/dts/pxa168-aspenite.dts |  1 +
 arch/arm/boot/dts/pxa910-dkb.dts      |  1 +
 arch/arm/mach-mmp/common.h            |  2 +-
 arch/arm/mach-mmp/mmp-dt.c            | 14 ++++---
 arch/arm/mach-mmp/mmp2-dt.c           | 12 ++++--
 arch/arm/mach-mmp/mmp2.c              |  2 +-
 arch/arm/mach-mmp/pxa168.c            |  2 +-
 arch/arm/mach-mmp/pxa910.c            |  2 +-
 drivers/clocksource/timer-mmp.c       | 72 +++++++++++++++++++++--------------
 11 files changed, 72 insertions(+), 41 deletions(-)
arch/arm/Kconfig +1 -0
index d6ba351..324cb62 100644
@@ -545,6 +545,7 @@ config ARCH_MMP
 	depends on MMU
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select CLKSRC_OF if OF
 	select GENERIC_ALLOCATOR
 	select GENERIC_CLOCKEVENTS
 	select GPIO_PXA
arch/arm/boot/dts/mmp2-brownstone.dts +4 -0
index 7f70a39..29c7dc6 100644
@@ -24,6 +24,10 @@
 
 	soc {
 		apb at d4000000 {
+			timer0: timer at d4014000 {
+				clock-frequency = <6500000>;
+				status = "okay";
+			};
 			uart3: uart at d4018000 {
 				status = "okay";
 			};
arch/arm/boot/dts/pxa168-aspenite.dts +1 -0
index 2597e98..9b3d6d9 100644
@@ -25,6 +25,7 @@
 	soc {
 		apb at d4000000 {
 			timer0: timer at d4014000 {
+				clock-frequency = <3250000>;
 				status = "okay";
 			};
 			uart1: uart at d4017000 {
arch/arm/boot/dts/pxa910-dkb.dts +1 -0
index b892ebe..3cd1a85 100644
@@ -33,6 +33,7 @@
 				clock-output-names = "refclk1001mhz";
 			};
 			timer0: timer at d4014000 {
+				clock-frequency = <3250000>;
 				status = "okay";
 			};
 			uart1: uart at d4017000 {
arch/arm/mach-mmp/common.h +1 -1
index 2fc9390..3784ea9 100644
@@ -1,6 +1,6 @@
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 
-extern void timer_init(void __iomem *base, int irq);
+extern void timer_init(void __iomem *base, int irq, int mmp2_mode);
 
 extern void __init mmp_map_io(void);
 extern void mmp_restart(char, const char *);
arch/arm/mach-mmp/mmp-dt.c +9 -5
index f109bf6..8d0253b 100644
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -17,8 +18,6 @@
 
 #include "common.h"
 
-extern void __init mmp_dt_init_timer(void);
-
 static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = {
 	OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
 	OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
@@ -49,7 +48,6 @@ static void __init pxa168_dt_init(void)
 
 static void __init pxa910_dt_init(void)
 {
-	of_clk_init(NULL);
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     pxa910_auxdata_lookup, NULL);
 }
@@ -60,16 +58,22 @@ static const char *mmp_dt_board_compat[] __initdata = {
 	NULL,
 };
 
+static void __init mmp_init_timer(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
 DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_time	= mmp_dt_init_timer,
+	.init_time	= mmp_init_timer,
 	.init_machine	= pxa168_dt_init,
 	.dt_compat	= mmp_dt_board_compat,
 MACHINE_END
 
 DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_time	= mmp_dt_init_timer,
+	.init_time	= mmp_init_timer,
 	.init_machine	= pxa910_dt_init,
 	.dt_compat	= mmp_dt_board_compat,
 MACHINE_END
arch/arm/mach-mmp/mmp2-dt.c +9 -3
index 023cb45..2229d1d 100644
@@ -9,6 +9,8 @@
  *  publishhed by the Free Software Foundation.
  */
 
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <linux/io.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
@@ -17,8 +19,6 @@
 
 #include "common.h"
 
-extern void __init mmp_dt_init_timer(void);
-
 static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = {
 	OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL),
 	OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL),
@@ -37,6 +37,12 @@ static void __init mmp2_dt_init(void)
 			     mmp2_auxdata_lookup, NULL);
 }
 
+static void __init mmp2_init_timer(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
 static const char *mmp2_dt_board_compat[] __initdata = {
 	"mrvl,mmp2-brownstone",
 	NULL,
@@ -44,7 +50,7 @@ static const char *mmp2_dt_board_compat[] __initdata = {
 
 DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
 	.map_io		= mmp_map_io,
-	.init_time	= mmp_dt_init_timer,
+	.init_time	= mmp2_init_timer,
 	.init_machine	= mmp2_dt_init,
 	.dt_compat	= mmp2_dt_board_compat,
 MACHINE_END
arch/arm/mach-mmp/mmp2.c +1 -1
index a0abfd7..d00c0fe 100644
@@ -131,7 +131,7 @@ void __init mmp2_timer_init(void)
 	clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
 	__raw_writel(clk_rst, APBC_TIMERS);
 
-	timer_init(TIMER1_VIRT_BASE, IRQ_MMP2_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_MMP2_TIMER1, 1);
 }
 
 /* on-chip devices */
arch/arm/mach-mmp/pxa168.c +1 -1
index 345a493..f8dfbc6 100644
@@ -78,7 +78,7 @@ void __init pxa168_timer_init(void)
 	/* 3.25MHz, bus/functional clock enabled, release reset */
 	__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-	timer_init(TIMER1_VIRT_BASE, IRQ_PXA168_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_PXA168_TIMER1, 0);
 }
 
 void pxa168_clear_keypad_wakeup(void)
arch/arm/mach-mmp/pxa910.c +1 -1
index 1a84800..0e98bf3 100644
@@ -112,7 +112,7 @@ void __init pxa910_timer_init(void)
 	__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
 	__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-	timer_init(TIMER1_VIRT_BASE, IRQ_PXA910_AP1_TIMER1);
+	timer_init(TIMER1_VIRT_BASE, IRQ_PXA910_AP1_TIMER1, 0);
 }
 
 /* on-chip devices */
drivers/clocksource/timer-mmp.c +43 -29

120 lines not on this page · raw message

Signature · 1 line
1.8.1.2
#12 lore raw

PATCH v5 9/10 clk: mmp: parse clock from dts

In reply to Haojian Zhuang

Parse clock information from DTS file for mach-mmp.

Changelog:
v5:
1. Replace clk_register_mux() by clk_register_mux_table().

---
 arch/arm/boot/dts/pxa168-aspenite.dts |   3 +
 arch/arm/boot/dts/pxa168-clk.dtsi     | 304 ++++++++++++++++++
 arch/arm/boot/dts/pxa168.dtsi         |  10 +
 arch/arm/boot/dts/pxa910-clk.dtsi     | 569 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/pxa910-dkb.dts      |  11 +
 arch/arm/boot/dts/pxa910.dtsi         |  12 +-
 arch/arm/mach-mmp/mmp-dt.c            |   2 +
 drivers/clk/mmp/Makefile              |   2 +-
 drivers/clk/mmp/clk-mmp.c             | 361 +++++++++++++++++++++
 9 files changed, 1272 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/pxa168-clk.dtsi
 create mode 100644 arch/arm/boot/dts/pxa910-clk.dtsi
 create mode 100644 drivers/clk/mmp/clk-mmp.c
arch/arm/boot/dts/pxa168-aspenite.dts +3 -0
index e762fac..2597e98 100644
@@ -24,6 +24,9 @@
 
 	soc {
 		apb at d4000000 {
+			timer0: timer at d4014000 {
+				status = "okay";
+			};
 			uart1: uart at d4017000 {
 				status = "okay";
 			};
arch/arm/boot/dts/pxa168-clk.dtsi new file +304 -0

304 lines not on this page · raw message

arch/arm/boot/dts/pxa168.dtsi +10 -0
index 975dad2..250bf2c 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
 	aliases {
@@ -53,12 +54,15 @@
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4014000 0x100>;
 				interrupts = <13>;
+				clocks = <&apbc_timer0_clk>;
+				status = "disabled";
 			};
 
 			uart1: uart at d4017000 {
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4017000 0x1000>;
 				interrupts = <27>;
+				clocks = <&apbc_uart1_clk>;
 				status = "disabled";
 			};
 
@@ -66,6 +70,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4018000 0x1000>;
 				interrupts = <28>;
+				clocks = <&apbc_uart2_clk>;
 				status = "disabled";
 			};
 
@@ -73,6 +78,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4026000 0x1000>;
 				interrupts = <29>;
+				clocks = <&apbc_uart3_clk>;
 				status = "disabled";
 			};
 
@@ -87,6 +93,7 @@
 				interrupt-names = "gpio_mux";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+				clocks = <&apbc_gpio_clk>;
 				ranges;
 
 				gcb0: gpio at d4019000 {
@@ -111,6 +118,7 @@
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
 				mrvl,i2c-fast-mode;
+				clocks = <&apbc_twsi1_clk>;
 				status = "disabled";
 			};
 
@@ -118,6 +126,7 @@
 				compatible = "mrvl,mmp-twsi";
 				reg = <0xd4025000 0x1000>;
 				interrupts = <58>;
+				clocks = <&apbc_twsi2_clk>;
 				status = "disabled";
 			};
 
@@ -126,6 +135,7 @@
 				reg = <0xd4010000 0x1000>;
 				interrupts = <5 6>;
 				interrupt-names = "rtc 1Hz", "rtc alarm";
+				clocks = <&apbc_rtc_clk>;
 				status = "disabled";
 			};
 		};
arch/arm/boot/dts/pxa910-clk.dtsi new file +569 -0

569 lines not on this page · raw message

arch/arm/boot/dts/pxa910-dkb.dts +11 -0
index 595492a..b892ebe 100644
@@ -24,6 +24,17 @@
 
 	soc {
 		apb at d4000000 {
+			pll2: refclk1001mhz {
+				/* Reference clock for internal PLL2 */
+				compatible = "marvell,mmp-fixed-clkrate";
+				#clock-cells = <0>;
+				clocks = <&osc_26m>;
+				clock-frequency = <1001000000>;
+				clock-output-names = "refclk1001mhz";
+			};
+			timer0: timer at d4014000 {
+				status = "okay";
+			};
 			uart1: uart at d4017000 {
 				status = "okay";
 			};
arch/arm/boot/dts/pxa910.dtsi +11 -1
index 0247c62..cd888d3 100644
@@ -8,6 +8,7 @@
  */
 
 /include/ "skeleton.dtsi"
+/include/ "pxa910-clk.dtsi"
 
 / {
 	aliases {
@@ -44,7 +45,6 @@
 				reg = <0xd4282000 0x1000>;
 				mrvl,intc-nr-irqs = <64>;
 			};
-
 		};
 
 		apb at d4000000 {	/* APB */
@@ -58,12 +58,15 @@
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4014000 0x100>;
 				interrupts = <13>;
+				clocks = <&apbc_timer0_clk>;
+				status = "disabled";
 			};
 
 			timer1: timer at d4016000 {
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4016000 0x100>;
 				interrupts = <29>;
+				clocks = <&apbc_timer1_clk>;
 				status = "disabled";
 			};
 
@@ -71,6 +74,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4017000 0x1000>;
 				interrupts = <27>;
+				clocks = <&apbc_uart1_clk>;
 				status = "disabled";
 			};
 
@@ -78,6 +82,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4018000 0x1000>;
 				interrupts = <28>;
+				clocks = <&apbc_uart2_clk>;
 				status = "disabled";
 			};
 
@@ -85,6 +90,7 @@
 				compatible = "mrvl,mmp-uart";
 				reg = <0xd4036000 0x1000>;
 				interrupts = <59>;
+				clocks = <&apbcp_uart3_clk>;
 				status = "disabled";
 			};
 
@@ -99,6 +105,7 @@
 				interrupt-names = "gpio_mux";
 				interrupt-controller;
 				#interrupt-cells = <1>;
+				clocks = <&apbc_gpio_clk>;
 				ranges;
 
 				gcb0: gpio at d4019000 {
@@ -124,6 +131,7 @@
 				#size-cells = <0>;
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
+				clocks = <&apbc_twsi1_clk>;
 				mrvl,i2c-fast-mode;
 				status = "disabled";
 			};
@@ -134,6 +142,7 @@
 				#size-cells = <0>;
 				reg = <0xd4037000 0x1000>;
 				interrupts = <54>;
+				clocks = <&apbcp_twsi2_clk>;
 				status = "disabled";
 			};
 
@@ -142,6 +151,7 @@
 				reg = <0xd4010000 0x1000>;
 				interrupts = <5 6>;
 				interrupt-names = "rtc 1Hz", "rtc alarm";
+				clocks = <&apbc_rtc_clk>;
 				status = "disabled";
 			};
 		};
arch/arm/mach-mmp/mmp-dt.c +2 -0
index cca529c..f109bf6 100644
@@ -9,6 +9,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -48,6 +49,7 @@ static void __init pxa168_dt_init(void)
 
 static void __init pxa910_dt_init(void)
 {
+	of_clk_init(NULL);
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     pxa910_auxdata_lookup, NULL);
 }
drivers/clk/mmp/Makefile +1 -1
index 392d780..83182e5 100644
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mmp.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
drivers/clk/mmp/clk-mmp.c new file +361 -0

361 lines not on this page · raw message

Signature · 1 line
1.8.1.2