linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* No subject
@ 2013-07-26 10:05 Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 01/11] irqchip: move mmp irq driver Haojian Zhuang
                   ` (10 more replies)
  0 siblings, 11 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v6:
1. Merge clk apbc & apbcp together.
2. Add DT binding document of clock driver.
3. Remove marvell string in properties of clock driver.

v5:
1. Use clk mux table.

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

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

* [PATCH v6 01/11] irqchip: move mmp irq driver
  2013-07-26 10:05 No subject Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-14 21:26   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 02/11] irqchip: mmp: support irqchip Haojian Zhuang
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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%)

diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 095c155..9b702a1 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -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
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index 991d7e9..cf445ba 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -3,7 +3,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(enum reboot_mode, const char *);
 extern void __init pxa168_clk_init(void);
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index 459c2d0..a83ba7c 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -4,6 +4,7 @@
 #include <linux/reboot.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(enum reboot_mode, const char *);
 extern void pxa168_clear_keypad_wakeup(void);
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
index b914afa..9225320 100644
--- a/arch/arm/mach-mmp/include/mach/pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -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>
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index ce6393a..a586742 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -23,6 +23,7 @@
 #include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/devices.h>
+#include <mach/pxa910.h>
 
 #include "common.h"
 
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e65c41a..c452943 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP)			+= irqchip.o
 
 obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2835.o
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos-combiner.o
+obj-$(CONFIG_ARCH_MMP)			+= irq-mmp.o
 obj-$(CONFIG_ARCH_MVEBU)		+= irq-armada-370-xp.o
 obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
diff --git a/arch/arm/mach-mmp/irq.c b/drivers/irqchip/irq-mmp.c
similarity index 99%
rename from arch/arm/mach-mmp/irq.c
rename to drivers/irqchip/irq-mmp.c
index 3c71246..dab6def 100644
--- a/arch/arm/mach-mmp/irq.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -30,8 +30,6 @@
 #include <mach/pm-pxa910.h>
 #endif
 
-#include "common.h"
-
 #define MAX_ICU_NR		16
 
 struct icu_chip_data {
-- 
1.8.1.2

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

* [PATCH v6 02/11] irqchip: mmp: support irqchip
  2013-07-26 10:05 No subject Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 01/11] irqchip: move mmp irq driver Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-12 22:53   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 03/11] irqchip: mmp: support MULTI_IRQ_HANDLER Haojian Zhuang
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Support IRQCHIP on irq-mmp driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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(-)

diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index b37915d..cca529c 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -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,
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
index 4ac2567..023cb45 100644
--- a/arch/arm/mach-mmp/mmp2-dt.c
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -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,
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index dab6def..275709b 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -30,6 +30,8 @@
 #include <mach/pm-pxa910.h>
 #endif
 
+#include "irqchip.h"
+
 #define MAX_ICU_NR		16
 
 struct icu_chip_data {
@@ -324,138 +326,146 @@ void __init mmp2_init_icu(void)
 }
 
 #ifdef CONFIG_OF
-static const struct of_device_id intc_ids[] __initconst = {
-	{ .compatible = "mrvl,mmp-intc", .data = &mmp_conf },
-	{ .compatible = "mrvl,mmp2-intc", .data = &mmp2_conf },
-	{}
-};
-
-static const struct of_device_id mmp_mux_irq_match[] __initconst = {
-	{ .compatible = "mrvl,mmp2-mux-intc" },
-	{}
-};
-
-int __init mmp2_mux_init(struct device_node *parent)
+static int __init mmp_init_bases(struct device_node *node)
 {
-	struct device_node *node;
-	const struct of_device_id *of_id;
-	struct resource res;
-	int i, irq_base, ret, irq;
-	u32 nr_irqs, mfp_irq;
+	int ret, nr_irqs, irq, i = 0;
 
-	node = parent;
-	max_icu_nr = 1;
-	for (i = 1; i < MAX_ICU_NR; i++) {
-		node = of_find_matching_node(node, mmp_mux_irq_match);
-		if (!node)
-			break;
-		of_id = of_match_node(&mmp_mux_irq_match[0], node);
-		ret = of_property_read_u32(node, "mrvl,intc-nr-irqs",
-					   &nr_irqs);
-		if (ret) {
-			pr_err("Not found mrvl,intc-nr-irqs property\n");
-			ret = -EINVAL;
-			goto err;
-		}
-		ret = of_address_to_resource(node, 0, &res);
-		if (ret < 0) {
-			pr_err("Not found reg property\n");
-			ret = -EINVAL;
-			goto err;
-		}
-		icu_data[i].reg_status = mmp_icu_base + res.start;
-		ret = of_address_to_resource(node, 1, &res);
-		if (ret < 0) {
-			pr_err("Not found reg property\n");
-			ret = -EINVAL;
-			goto err;
-		}
-		icu_data[i].reg_mask = mmp_icu_base + res.start;
-		icu_data[i].cascade_irq = irq_of_parse_and_map(node, 0);
-		if (!icu_data[i].cascade_irq) {
-			ret = -EINVAL;
-			goto err;
-		}
+	ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
+	if (ret) {
+		pr_err("Not found mrvl,intc-nr-irqs property\n");
+		return ret;
+	}
 
-		irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
-		if (irq_base < 0) {
-			pr_err("Failed to allocate IRQ numbers for mux intc\n");
-			ret = irq_base;
+	mmp_icu_base = of_iomap(node, 0);
+	if (!mmp_icu_base) {
+		pr_err("Failed to get interrupt controller register\n");
+		return -ENOMEM;
+	}
+
+	icu_data[0].virq_base = 0;
+	icu_data[0].domain = irq_domain_add_linear(node, nr_irqs,
+						   &mmp_irq_domain_ops,
+						   &icu_data[0]);
+	for (irq = 0; irq < nr_irqs; irq++) {
+		ret = irq_create_mapping(icu_data[0].domain, irq);
+		if (!ret) {
+			pr_err("Failed to mapping hwirq\n");
 			goto err;
 		}
-		if (!of_property_read_u32(node, "mrvl,clr-mfp-irq",
-					  &mfp_irq)) {
-			icu_data[i].clr_mfp_irq_base = irq_base;
-			icu_data[i].clr_mfp_hwirq = mfp_irq;
-		}
-		irq_set_chained_handler(icu_data[i].cascade_irq,
-					icu_mux_irq_demux);
-		icu_data[i].nr_irqs = nr_irqs;
-		icu_data[i].virq_base = irq_base;
-		icu_data[i].domain = irq_domain_add_legacy(node, nr_irqs,
-							   irq_base, 0,
-							   &mmp_irq_domain_ops,
-							   &icu_data[i]);
-		for (irq = irq_base; irq < irq_base + nr_irqs; irq++)
-			icu_mask_irq(irq_get_irq_data(irq));
+		if (!irq)
+			icu_data[0].virq_base = ret;
 	}
-	max_icu_nr = i;
+	icu_data[0].nr_irqs = nr_irqs;
 	return 0;
 err:
-	of_node_put(node);
-	max_icu_nr = i;
-	return ret;
+	if (icu_data[0].virq_base) {
+		for (i = 0; i < irq; i++)
+			irq_dispose_mapping(icu_data[0].virq_base + i);
+	}
+	irq_domain_remove(icu_data[0].domain);
+	iounmap(mmp_icu_base);
+	return -EINVAL;
 }
 
-void __init mmp_dt_irq_init(void)
+static int __init mmp_of_init(struct device_node *node,
+			      struct device_node *parent)
 {
-	struct device_node *node;
-	const struct of_device_id *of_id;
-	struct mmp_intc_conf *conf;
-	int nr_irqs, irq_base, ret, irq;
-
-	node = of_find_matching_node(NULL, intc_ids);
-	if (!node) {
-		pr_err("Failed to find interrupt controller in arch-mmp\n");
-		return;
-	}
-	of_id = of_match_node(intc_ids, node);
-	conf = of_id->data;
+	int ret;
 
-	ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
+	ret = mmp_init_bases(node);
+	if (ret < 0)
+		return ret;
+
+	icu_data[0].conf_enable = mmp_conf.conf_enable;
+	icu_data[0].conf_disable = mmp_conf.conf_disable;
+	icu_data[0].conf_mask = mmp_conf.conf_mask;
+	irq_set_default_host(icu_data[0].domain);
+	max_icu_nr = 1;
+	return 0;
+}
+IRQCHIP_DECLARE(mmp_intc, "mrvl,mmp-intc", mmp_of_init);
+
+static int __init mmp2_of_init(struct device_node *node,
+			       struct device_node *parent)
+{
+	int ret;
+
+	ret = mmp_init_bases(node);
+	if (ret < 0)
+		return ret;
+
+	icu_data[0].conf_enable = mmp2_conf.conf_enable;
+	icu_data[0].conf_disable = mmp2_conf.conf_disable;
+	icu_data[0].conf_mask = mmp2_conf.conf_mask;
+	irq_set_default_host(icu_data[0].domain);
+	max_icu_nr = 1;
+	return 0;
+}
+IRQCHIP_DECLARE(mmp2_intc, "mrvl,mmp2-intc", mmp2_of_init);
+
+static int __init mmp2_mux_of_init(struct device_node *node,
+				   struct device_node *parent)
+{
+	struct resource res;
+	int i, ret, irq, j = 0;
+	u32 nr_irqs, mfp_irq;
+
+	if (!parent)
+		return -ENODEV;
+
+	i = max_icu_nr;
+	ret = of_property_read_u32(node, "mrvl,intc-nr-irqs",
+				   &nr_irqs);
 	if (ret) {
 		pr_err("Not found mrvl,intc-nr-irqs property\n");
-		return;
+		return -EINVAL;
 	}
-
-	mmp_icu_base = of_iomap(node, 0);
-	if (!mmp_icu_base) {
-		pr_err("Failed to get interrupt controller register\n");
-		return;
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret < 0) {
+		pr_err("Not found reg property\n");
+		return -EINVAL;
 	}
-
-	irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY, 0);
-	if (irq_base < 0) {
-		pr_err("Failed to allocate IRQ numbers\n");
-		goto err;
-	} else if (irq_base != NR_IRQS_LEGACY) {
-		pr_err("ICU's irqbase should be started from 0\n");
-		goto err;
+	icu_data[i].reg_status = mmp_icu_base + res.start;
+	ret = of_address_to_resource(node, 1, &res);
+	if (ret < 0) {
+		pr_err("Not found reg property\n");
+		return -EINVAL;
 	}
-	icu_data[0].conf_enable = conf->conf_enable;
-	icu_data[0].conf_disable = conf->conf_disable;
-	icu_data[0].conf_mask = conf->conf_mask;
-	icu_data[0].nr_irqs = nr_irqs;
-	icu_data[0].virq_base = 0;
-	icu_data[0].domain = irq_domain_add_legacy(node, nr_irqs, 0, 0,
+	icu_data[i].reg_mask = mmp_icu_base + res.start;
+	icu_data[i].cascade_irq = irq_of_parse_and_map(node, 0);
+	if (!icu_data[i].cascade_irq)
+		return -EINVAL;
+
+	icu_data[i].virq_base = 0;
+	icu_data[i].domain = irq_domain_add_linear(node, nr_irqs,
 						   &mmp_irq_domain_ops,
-						   &icu_data[0]);
-	irq_set_default_host(icu_data[0].domain);
-	for (irq = 0; irq < nr_irqs; irq++)
-		icu_mask_irq(irq_get_irq_data(irq));
-	mmp2_mux_init(node);
-	return;
+						   &icu_data[i]);
+	for (irq = 0; irq < nr_irqs; irq++) {
+		ret = irq_create_mapping(icu_data[i].domain, irq);
+		if (!ret) {
+			pr_err("Failed to mapping hwirq\n");
+			goto err;
+		}
+		if (!irq)
+			icu_data[i].virq_base = ret;
+	}
+	icu_data[i].nr_irqs = nr_irqs;
+	if (!of_property_read_u32(node, "mrvl,clr-mfp-irq",
+				  &mfp_irq)) {
+		icu_data[i].clr_mfp_irq_base = icu_data[i].virq_base;
+		icu_data[i].clr_mfp_hwirq = mfp_irq;
+	}
+	irq_set_chained_handler(icu_data[i].cascade_irq,
+				icu_mux_irq_demux);
+	max_icu_nr++;
+	return 0;
 err:
-	iounmap(mmp_icu_base);
+	if (icu_data[i].virq_base) {
+		for (j = 0; j < irq; j++)
+			irq_dispose_mapping(icu_data[i].virq_base + j);
+	}
+	irq_domain_remove(icu_data[i].domain);
+	return -EINVAL;
 }
+IRQCHIP_DECLARE(mmp2_mux_intc, "mrvl,mmp2-mux-intc", mmp2_mux_of_init);
 #endif
-- 
1.8.1.2

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

* [PATCH v6 03/11] irqchip: mmp: support MULTI_IRQ_HANDLER
  2013-07-26 10:05 No subject Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 01/11] irqchip: move mmp irq driver Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 02/11] irqchip: mmp: support irqchip Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp Haojian Zhuang
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba412e0..76793a6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -557,6 +557,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
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
deleted file mode 100644
index bd152e2..0000000
--- a/arch/arm/mach-mmp/include/mach/entry-macro.S
+++ /dev/null
@@ -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
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 275709b..84d51ff 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -21,6 +21,9 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
 #include <mach/irqs.h>
 
 #ifdef CONFIG_CPU_MMP2
@@ -34,6 +37,13 @@
 
 #define MAX_ICU_NR		16
 
+#define PJ1_INT_SEL		0x10c
+#define PJ4_INT_SEL		0x104
+
+/* bit fields in PJ1_INT_SEL and PJ4_INT_SEL */
+#define SEL_INT_PENDING		(1 << 6)
+#define SEL_INT_NUM_MASK	0x3f
+
 struct icu_chip_data {
 	int			nr_irqs;
 	unsigned int		virq_base;
@@ -54,7 +64,7 @@ struct mmp_intc_conf {
 	unsigned int	conf_mask;
 };
 
-void __iomem *mmp_icu_base;
+static void __iomem *mmp_icu_base;
 static struct icu_chip_data icu_data[MAX_ICU_NR];
 static int max_icu_nr;
 
@@ -193,6 +203,32 @@ static struct mmp_intc_conf mmp2_conf = {
 	.conf_mask	= 0x7f,
 };
 
+static asmlinkage void __exception_irq_entry
+mmp_handle_irq(struct pt_regs *regs)
+{
+	int irq, hwirq;
+
+	hwirq = readl_relaxed(mmp_icu_base + PJ1_INT_SEL);
+	if (!(hwirq & SEL_INT_PENDING))
+		return;
+	hwirq &= SEL_INT_NUM_MASK;
+	irq = irq_find_mapping(icu_data[0].domain, hwirq);
+	handle_IRQ(irq, regs);
+}
+
+static asmlinkage void __exception_irq_entry
+mmp2_handle_irq(struct pt_regs *regs)
+{
+	int irq, hwirq;
+
+	hwirq = readl_relaxed(mmp_icu_base + PJ4_INT_SEL);
+	if (!(hwirq & SEL_INT_PENDING))
+		return;
+	hwirq &= SEL_INT_NUM_MASK;
+	irq = irq_find_mapping(icu_data[0].domain, hwirq);
+	handle_IRQ(irq, regs);
+}
+
 /* MMP (ARMv5) */
 void __init icu_init_irq(void)
 {
@@ -214,6 +250,7 @@ void __init icu_init_irq(void)
 		set_irq_flags(irq, IRQF_VALID);
 	}
 	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
@@ -320,6 +357,7 @@ void __init mmp2_init_icu(void)
 		set_irq_flags(irq, IRQF_VALID);
 	}
 	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
@@ -380,6 +418,7 @@ static int __init mmp_of_init(struct device_node *node,
 	icu_data[0].conf_disable = mmp_conf.conf_disable;
 	icu_data[0].conf_mask = mmp_conf.conf_mask;
 	irq_set_default_host(icu_data[0].domain);
+	set_handle_irq(mmp_handle_irq);
 	max_icu_nr = 1;
 	return 0;
 }
@@ -398,6 +437,7 @@ static int __init mmp2_of_init(struct device_node *node,
 	icu_data[0].conf_disable = mmp2_conf.conf_disable;
 	icu_data[0].conf_mask = mmp2_conf.conf_mask;
 	irq_set_default_host(icu_data[0].domain);
+	set_handle_irq(mmp2_handle_irq);
 	max_icu_nr = 1;
 	return 0;
 }
-- 
1.8.1.2

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

* [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (2 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 03/11] irqchip: mmp: support MULTI_IRQ_HANDLER Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-14 18:56   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file Haojian Zhuang
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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

diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index c7592f1..09fbe7d 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -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)
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index a586742..96e125b 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -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)
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 84d51ff..1f81432 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -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
diff --git a/include/linux/irqchip/mmp.h b/include/linux/irqchip/mmp.h
new file mode 100644
index 0000000..c78a892
--- /dev/null
+++ b/include/linux/irqchip/mmp.h
@@ -0,0 +1,6 @@
+#ifndef	__IRQCHIP_MMP_H
+#define	__IRQCHIP_MMP_H
+
+extern struct irq_chip icu_irq_chip;
+
+#endif	/* __IRQCHIP_MMP_H */
-- 
1.8.1.2

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

* [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (3 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-07-26 16:10   ` Arnd Bergmann
  2013-07-26 10:05 ` [PATCH v6 06/11] clocksource: mmp: move mmp timer driver Haojian Zhuang
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/irqchip/irq-mmp.c | 45 +++++++++++++++++++++------------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 1f81432..2cb7cd0 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -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);
 	}
-- 
1.8.1.2

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

* [PATCH v6 06/11] clocksource: mmp: move mmp timer driver
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (4 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-14 19:22   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 07/11] ARM: mmp: move timer registers into driver Haojian Zhuang
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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%)

diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 9b702a1..5d4ccc6 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -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
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8b00c5c..7dda633 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ORION_TIMER)	+= time-orion.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
diff --git a/arch/arm/mach-mmp/time.c b/drivers/clocksource/timer-mmp.c
similarity index 99%
rename from arch/arm/mach-mmp/time.c
rename to drivers/clocksource/timer-mmp.c
index 7ac41e8..ddc1b15 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/drivers/clocksource/timer-mmp.c
@@ -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)
-- 
1.8.1.2

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

* [PATCH v6 07/11] ARM: mmp: move timer registers into driver
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (5 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 06/11] clocksource: mmp: move mmp timer driver Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-14 19:37   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level Haojian Zhuang
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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

diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index cf445ba..22e67c6 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -1,7 +1,7 @@
 #include <linux/reboot.h>
 #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(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h
index f88a44c..169c280 100644
--- a/arch/arm/mach-mmp/include/mach/addr-map.h
+++ b/arch/arm/mach-mmp/include/mach/addr-map.h
@@ -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 */
diff --git a/arch/arm/mach-mmp/include/mach/regs-timers.h b/arch/arm/mach-mmp/include/mach/regs-timers.h
deleted file mode 100644
index 45589fe..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-timers.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-timers.h
- *
- *   Timers Module
- *
- * 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.
- */
-
-#ifndef __ASM_MACH_REGS_TIMERS_H
-#define __ASM_MACH_REGS_TIMERS_H
-
-#include <mach/addr-map.h>
-
-#define TIMERS1_VIRT_BASE	(APB_VIRT_BASE + 0x14000)
-#define TIMERS2_VIRT_BASE	(APB_VIRT_BASE + 0x16000)
-
-#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)
-
-#endif /* __ASM_MACH_REGS_TIMERS_H */
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index 09fbe7d..f26ea9d 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -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 */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 144e997..b6b3d5b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -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)
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 96e125b..df379c2 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -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 */
diff --git a/drivers/clocksource/timer-mmp.c b/drivers/clocksource/timer-mmp.c
index ddc1b15..937d51e 100644
--- a/drivers/clocksource/timer-mmp.c
+++ b/drivers/clocksource/timer-mmp.c
@@ -30,19 +30,39 @@
 #include <linux/of_irq.h>
 #include <linux/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);
-- 
1.8.1.2

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

* [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (6 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 07/11] ARM: mmp: move timer registers into driver Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-10 17:29   ` Daniel Mack
  2013-07-26 10:05 ` [PATCH v6 09/11] clk: mmp: parse clock from dts Haojian Zhuang
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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(-)

diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index f26ea9d..a0abfd7 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -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);
 
 	/*
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index b6b3d5b..a332d51 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -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
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index df379c2..1a84800 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -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);
diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c
index 79ef102..6c5472b 100644
--- a/arch/arm/plat-pxa/dma.c
+++ b/arch/arm/plat-pxa/dma.c
@@ -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;
 }
-- 
1.8.1.2

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (7 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-08-09 16:04   ` Mark Rutland
  2013-08-10 14:57   ` Daniel Drake
  2013-07-26 10:05 ` [PATCH v6 10/11] ARM: dts: support common clock in arch mmp Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 11/11] ARM: mmp: avoid to use cpu_is_xxx in timer Haojian Zhuang
  10 siblings, 2 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Parse clock information from DTS file for mach-mmp.

Changelog:
v6:
1. Remove marvell string from properties in clock driver.
2. Append document for clock binding device tree.
3. Use apbc to replace apbcp. Since the main difference is register
base.

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 .../devicetree/bindings/clock/mmp-clock.txt        |  51 ++++
 arch/arm/mach-mmp/mmp-dt.c                         |   2 +
 drivers/clk/mmp/Makefile                           |   2 +-
 drivers/clk/mmp/clk-mmp.c                          | 300 +++++++++++++++++++++
 4 files changed, 354 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/mmp-clock.txt
 create mode 100644 drivers/clk/mmp/clk-mmp.c

diff --git a/Documentation/devicetree/bindings/clock/mmp-clock.txt b/Documentation/devicetree/bindings/clock/mmp-clock.txt
new file mode 100644
index 0000000..5fe52a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mmp-clock.txt
@@ -0,0 +1,51 @@
+Device Tree Clock bindings for arch-mmp
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties for fixed rate clocks:
+  - compatible : should be "marvell,mmp-fixed-clkrate".
+  - clocks : should be the input parent clock phandle for the clock. This
+	should be the reference clock.
+  - clock-output-names : should be reference name.
+  - #clock-cells : from common clock binding; should be set to 0.
+  - clock-frequency : frequency of the fixed rate clock
+
+Required properties for fixed factor clocks:
+  - compatible : should be "marvell,mmp-fixed-clkfactor".
+  - clocks : should be the input parent clock phandle for the clock. This
+	should be the reference clock.
+  - clock-output-names : should be reference name.
+  - #clock-cells : from common clock binding; should be set to 0.
+
+Required properties for mux clocks:
+  - compatible : should be "marvell,mmp-clkmux".
+  - clocks : should be the input parent clock phandle for the clock. This
+	should be the reference clock.
+  - clock-output-names : should be reference name.
+  - #clock-cells : from common clock binding; should be set to 0.
+  - mmp-clk-reg : mux register offset & mask bits.
+  - mmp-clk-sel : array of mux select bits
+
+Required properties for divider clocks:
+  - compatible : should be "marvell,mmp-apmu-clkdiv".
+  - clocks : should be the input parent clock phandle for the clock. This
+	should be the reference clock.
+  - clock-output-names : should be reference name.
+  - #clock-cells : from common clock binding; should be set to 0.
+  - mmp-clk-reg : divider register offset & mask bits.
+
+Required properties for gate clocks:
+  - compatible : should be "marvell,mmp-apbc-clk".
+  - clocks : should be the input parent clock phandle for the clock. This
+	should be the reference clock.
+  - clock-output-names : should be reference name.
+  - #clock-cells : from common clock binding; should be set to 0.
+  - mmp-clk-reg : gate register offset & mask bits.
+
+Optional properties for gate clocks:
+  - mmp-clk-delay : delay between enabling function clock and apb clock
+  - mmp-apbc-power-ctrl : enable apbc power control bit
+
+For example:
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index cca529c..f109bf6 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -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);
 }
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d780..83182e5 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -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
diff --git a/drivers/clk/mmp/clk-mmp.c b/drivers/clk/mmp/clk-mmp.c
new file mode 100644
index 0000000..50c16a0
--- /dev/null
+++ b/drivers/clk/mmp/clk-mmp.c
@@ -0,0 +1,300 @@
+/*
+ * Marvell MMP clock driver
+ *
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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, *parent_name;
+	u32 data[2];
+
+	if (of_property_read_u32_array(np, "mmp-fixed-factor",
+				&data[0], 2))
+		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_factor(NULL, clk_name, parent_name, 0,
+			data[0], data[1]);
+	if (IS_ERR(clk))
+		return;
+	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, "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, "marvell,mmp-apmu-clkdiv", mmp_apmu_div_setup);
+
+static int __init mmp_parse_mux(struct device_node *np,
+				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 < cnt; i++) {
+		if (!of_clk_get_parent_name(np, i))
+			break;
+	}
+	*num_parents = cnt;
+	clk_sel = kzalloc(sizeof(u32 *) * cnt, GFP_KERNEL);
+	if (!clk_sel)
+		return -ENOMEM;
+	ret = of_property_read_u32_array(np, "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], mask, *clk_sel = NULL, mux_flags = 0;
+	u8 shift, 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, "mmp-clk-reg", &data[0], 2))
+		return;
+	ret = mmp_parse_mux(np, &num_parents, clk_sel);
+	if (ret)
+		return;
+
+	reg = base + data[0];
+	shift = ffs(data[1]) - 1;
+	mask = data[1] >> shift;
+
+	parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+	if (!parent_names)
+		goto err;
+	for (i = 0; i < num_parents; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents,
+				     CLK_SET_RATE_PARENT, reg, shift, mask,
+				     mux_flags, clk_sel, &mmp_clk_lock);
+	if (IS_ERR(clk))
+		goto err_clk;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err_clk:
+	kfree(parent_names);
+err:
+	kfree(clk_sel);
+}
+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, "mmp-clk-reg", &data[0], 2))
+		return;
+	/* If mmp-clk-delay property isn't defined, set delay as 10us */
+	if (of_property_read_u32(np, "mmp-clk-delay", &delay))
+		delay = 10;
+	if (of_get_property(np, "mmp-apbc-power-ctrl", 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);
-- 
1.8.1.2

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

* [PATCH v6 10/11] ARM: dts: support common clock in arch mmp
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (8 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 09/11] clk: mmp: parse clock from dts Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  2013-07-26 10:05 ` [PATCH v6 11/11] ARM: mmp: avoid to use cpu_is_xxx in timer Haojian Zhuang
  10 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Support common clock in DTS file for arch mmp.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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 +-
 6 files changed, 908 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/pxa168-clk.dtsi
 create mode 100644 arch/arm/boot/dts/pxa910-clk.dtsi

diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts b/arch/arm/boot/dts/pxa168-aspenite.dts
index e762fac..2597e98 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -24,6 +24,9 @@
 
 	soc {
 		apb at d4000000 {
+			timer0: timer at d4014000 {
+				status = "okay";
+			};
 			uart1: uart at d4017000 {
 				status = "okay";
 			};
diff --git a/arch/arm/boot/dts/pxa168-clk.dtsi b/arch/arm/boot/dts/pxa168-clk.dtsi
new file mode 100644
index 0000000..c0d5bd1
--- /dev/null
+++ b/arch/arm/boot/dts/pxa168-clk.dtsi
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (C) 2013
+ *  Author: Haojian Zhuang <haojian.zhuang@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  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 */
+					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 */
+					mmp-fixed-factor = <6144 8125>;
+				};
+				refclk104m: refclk104mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&pll1_312m>;
+					clock-output-names = "refclk104mhz";
+					/* multiple & divider */
+					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 */
+					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 */
+					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 */
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x2c 0x70>;
+					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 */
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x6c 0x70>;
+					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";
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x28 0x70>;
+					marvell,mmp-apbc-power-ctl;
+					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";
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x8 0x0>;
+					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 */
+					mmp-clk-reg = <0x0 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x0 0x70>;
+					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 */
+					mmp-clk-reg = <0x4 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x4 0x70>;
+					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 */
+					mmp-clk-reg = <0x70 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x70 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0xc 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x10 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x14 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x18 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20>;
+					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";
+					mmp-clk-reg = <0x30 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x34 0x70>;
+					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";
+				mmp-clk-sel = <0 0x2>;
+				mmp-clk-reg = <0x14000 0x1c>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index 975dad2..250bf2c 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -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";
 			};
 		};
diff --git a/arch/arm/boot/dts/pxa910-clk.dtsi b/arch/arm/boot/dts/pxa910-clk.dtsi
new file mode 100644
index 0000000..2d9f9ca
--- /dev/null
+++ b/arch/arm/boot/dts/pxa910-clk.dtsi
@@ -0,0 +1,569 @@
+/*
+ *  Copyright (C) 2013
+ *  Author: Haojian Zhuang <haojian.zhuang@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  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 */
+					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 */
+					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 */
+					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 */
+					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 */
+					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 */
+					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 */
+					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 */
+					mmp-clk-sel = <0 0x20000000 0x40000000>;
+					/* register offset & mask */
+					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 */
+					mmp-clk-sel = <0 0x00800000 0x01000000>;
+					/* register offset & mask */
+					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 */
+					mmp-clk-sel = <0 0x00080000>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x8 0x00080000>;
+				};
+				refclk156m: refclk156mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&pll1_312m>;
+					clock-output-names = "refclk156mhz";
+					/* multiple & divider */
+					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 */
+					mmp-fixed-factor = <6144 8125>;
+				};
+				refclk104m: refclk104mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&pll1_312m>;
+					clock-output-names = "refclk104mhz";
+					/* multiple & divider */
+					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 */
+					mmp-fixed-factor = <1 2>;
+				};
+				refclk52m: refclk52mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk104m>;
+					clock-output-names = "refclk52mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <1 2>;
+				};
+				refclk48m: refclk48mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&pll1_624m>;
+					clock-output-names = "refclk48mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <1 13>;
+				};
+				refclk32m: refclk32mhz@ {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk48m>;
+					clock-output-names = "refclk32mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <2 3>;
+				};
+				refclk26m: refclk26mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk52m>;
+					clock-output-names = "refclk26mhz";
+					/* multiple & divider */
+					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 */
+					mmp-fixed-factor = <2 21>;
+				};
+				refclk13m: refclk13mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk26m>;
+					clock-output-names = "refclk13mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <1 2>;
+				};
+				refclk7m: refclk7mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk13m>;
+					clock-output-names = "refclk7mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <1 2>;
+				};
+				refclk3m: refclk3mhz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&refclk7m>;
+					clock-output-names = "refclk3mhz";
+					/* multiple & divider */
+					mmp-fixed-factor = <1 2>;
+				};
+				refclk16k: refclk16khz {
+					compatible = "marvell,mmp-fixed-clkfactor";
+					#clock-cells = <0>;
+					clocks = <&osc_32k>;
+					clock-output-names = "refclk16khz";
+					/* multiple & divider */
+					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 */
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x2c 0x70>;
+					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";
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x28 0x70>;
+					marvell,mmp-apbc-power-ctl;
+					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";
+					mmp-clk-sel = <0>;
+					/* register offset & mask */
+					mmp-clk-reg = <0x8 0x0>;
+					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 */
+					mmp-clk-reg = <0x0 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x0 0x70>;
+					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 */
+					mmp-clk-reg = <0x4 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x4 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0xc 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x10 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x14 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10>;
+					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";
+					mmp-clk-reg = <0x18 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x1c 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x20 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x4c 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20>;
+					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";
+					mmp-clk-reg = <0x30 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x34 0x70>;
+					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";
+					mmp-clk-sel = <0 0x10 0x20 0x30>;
+					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";
+					mmp-clk-reg = <0x44 0x70>;
+					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-apbc-clk";
+					#clock-cells = <0>;
+					clocks = <&refclk32m>;
+					clock-output-names = "apbcp_twsi2_clk";
+					/* register offset & mask */
+					mmp-clk-reg = <0x28 0x70>;
+					mmp-clk-delay = <10>;
+				};
+				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 */
+					mmp-clk-reg = <0x1c 0x70>;
+					/* register value of each item */
+					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";
+					mmp-clk-reg = <0x1c 0x70>;
+					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";
+				mmp-clk-sel = <0 0x1 0x3>;
+				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";
+				mmp-clk-sel = <0 0x1 0x3>;
+				mmp-clk-reg = <0x16000 0x1c>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..b892ebe 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -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";
 			};
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0247c62..cd888d3 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -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";
 			};
 		};
-- 
1.8.1.2

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

* [PATCH v6 11/11] ARM: mmp: avoid to use cpu_is_xxx in timer
  2013-07-26 10:05 No subject Haojian Zhuang
                   ` (9 preceding siblings ...)
  2013-07-26 10:05 ` [PATCH v6 10/11] ARM: dts: support common clock in arch mmp Haojian Zhuang
@ 2013-07-26 10:05 ` Haojian Zhuang
  10 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 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(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 76793a6..eed4919 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -553,6 +553,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
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
index 7f70a39..29c7dc6 100644
--- a/arch/arm/boot/dts/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -24,6 +24,10 @@
 
 	soc {
 		apb at d4000000 {
+			timer0: timer at d4014000 {
+				clock-frequency = <6500000>;
+				status = "okay";
+			};
 			uart3: uart at d4018000 {
 				status = "okay";
 			};
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts b/arch/arm/boot/dts/pxa168-aspenite.dts
index 2597e98..9b3d6d9 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -25,6 +25,7 @@
 	soc {
 		apb at d4000000 {
 			timer0: timer at d4014000 {
+				clock-frequency = <3250000>;
 				status = "okay";
 			};
 			uart1: uart at d4017000 {
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index b892ebe..3cd1a85 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -33,6 +33,7 @@
 				clock-output-names = "refclk1001mhz";
 			};
 			timer0: timer at d4014000 {
+				clock-frequency = <3250000>;
 				status = "okay";
 			};
 			uart1: uart at d4017000 {
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index 22e67c6..2415282 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -1,7 +1,7 @@
 #include <linux/reboot.h>
 #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(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index f109bf6..8d0253b 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -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
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
index 023cb45..2229d1d 100644
--- a/arch/arm/mach-mmp/mmp2-dt.c
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -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
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index a0abfd7..d00c0fe 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -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 */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index a332d51..28fba2b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -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)
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 1a84800..0e98bf3 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -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 */
diff --git a/drivers/clocksource/timer-mmp.c b/drivers/clocksource/timer-mmp.c
index 937d51e..7e1fc75 100644
--- a/drivers/clocksource/timer-mmp.c
+++ b/drivers/clocksource/timer-mmp.c
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/clk-provider.h>
 #include <linux/clockchips.h>
 
 #include <linux/io.h>
@@ -30,8 +31,6 @@
 #include <linux/of_irq.h>
 #include <linux/sched_clock.h>
 
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <asm/mach/time.h>
 
 #define TMR_CCR		(0x0000)
@@ -177,16 +176,19 @@ static struct clocksource cksrc = {
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static void __init timer_config(void)
+static void __init timer_init_clk(int mmp2_mode)
 {
 	uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR);
 
 	__raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
 
-	ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
+	ccr &= mmp2_mode ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
 		(TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
 	__raw_writel(ccr, mmp_timer_base + TMR_CCR);
+}
 
+static void __init timer_config(void)
+{
 	/* set timer 0 to periodic mode, and timer 1 to free-running mode */
 	__raw_writel(0x2, mmp_timer_base + TMR_CMR);
 
@@ -209,11 +211,12 @@ static struct irqaction timer_irq = {
 	.dev_id		= &ckevt,
 };
 
-void __init timer_init(void __iomem *base, int irq)
+void __init timer_init(void __iomem *base, int irq, int mmp2_mode)
 {
 	BUG_ON(!base);
 	mmp_timer_base = base;
 
+	timer_init_clk(mmp2_mode);
 	timer_config();
 
 	setup_sched_clock(mmp_read_sched_clock, 32, CLOCK_TICK_RATE);
@@ -227,36 +230,47 @@ void __init timer_init(void __iomem *base, int irq)
 					MIN_DELTA, MAX_DELTA);
 }
 
-#ifdef CONFIG_OF
-static struct of_device_id mmp_timer_dt_ids[] = {
-	{ .compatible = "mrvl,mmp-timer", },
-	{}
-};
-
-void __init mmp_dt_init_timer(void)
+static void __init mmp_dt_init_timer(struct device_node *np)
 {
-	struct device_node *np;
-	int irq, ret;
-
-	np = of_find_matching_node(NULL, mmp_timer_dt_ids);
-	if (!np) {
-		ret = -ENODEV;
-		goto out;
+	struct clk *clk;
+	int irq;
+	u32 rate = 0;
+
+	if (!of_device_is_available(np))
+		return;
+	if (of_property_read_u32(np, "clock-frequency", &rate)) {
+		pr_err("failed to find clock-frequency property\n");
+		return;
 	}
-
 	irq = irq_of_parse_and_map(np, 0);
-	if (!irq) {
-		ret = -EINVAL;
-		goto out;
+	if (!irq)
+		return;
+	clk = of_clk_get(np, 0);
+	if (IS_ERR(clk)) {
+		pr_err("failed to get timer clock\n");
+		return;
 	}
 	mmp_timer_base = of_iomap(np, 0);
-	if (!mmp_timer_base) {
-		ret = -ENOMEM;
+	if (!mmp_timer_base)
 		goto out;
-	}
-	timer_init(mmp_timer_base, irq);
+
+	__raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
+	if (rate)
+		clk_set_rate(clk, rate);
+	clk_prepare_enable(clk);
+	timer_config();
+
+	setup_sched_clock(mmp_read_sched_clock, 32, rate);
+
+	ckevt.cpumask = cpumask_of(0);
+
+	setup_irq(irq, &timer_irq);
+
+	clocksource_register_hz(&cksrc, rate);
+	clockevents_config_and_register(&ckevt, rate,
+					MIN_DELTA, MAX_DELTA);
 	return;
 out:
-	pr_err("Failed to get timer from device tree with error:%d\n", ret);
+	clk_put(clk);
 }
-#endif
+CLOCKSOURCE_OF_DECLARE(mmp_timer, "mrvl,mmp-timer", mmp_dt_init_timer);
-- 
1.8.1.2

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

* [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file
  2013-07-26 10:05 ` [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file Haojian Zhuang
@ 2013-07-26 16:10   ` Arnd Bergmann
  0 siblings, 0 replies; 32+ messages in thread
From: Arnd Bergmann @ 2013-07-26 16:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 26 July 2013, Haojian Zhuang wrote:
> Since <mach/irqs.h> in irq-mmp.c blocks the multiplatform build,
> remove it instead.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  drivers/irqchip/irq-mmp.c | 45 +++++++++++++++++++++------------------------
>  1 file changed, 21 insertions(+), 24 deletions(-)

The intention behind this patch is good, but I think the implementation is
bad, since the platform still relies on specific hardcoded values for
the base irq numbers. As long as this is the case, you should use the
constants.

> @@ -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 (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,


I'd suggest passing IRQ_MMP2_PMIC_BASE and the other constants from the caller
and changing the prototype accordingly so you can do

	mmp2_init_icu(0, IRQ_MMP2_PMIC_BASE, IRQ_MMP2_RTC_BASE, IRQ_MMP2_KEYPAD_BASE,
			 IRQ_MMP2_TWSI_BASE, IRQ_MMP2_MISC_BASE, IRQ_MMP2_MIPI_HSI1_BASE,
			 IRQ_MMP2_MIPI_HSI0_BASE);

	Arnd

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-07-26 10:05 ` [PATCH v6 09/11] clk: mmp: parse clock from dts Haojian Zhuang
@ 2013-08-09 16:04   ` Mark Rutland
  2013-08-10 11:06     ` Tomasz Figa
  2013-08-10 14:57   ` Daniel Drake
  1 sibling, 1 reply; 32+ messages in thread
From: Mark Rutland @ 2013-08-09 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 26, 2013 at 11:05:31AM +0100, Haojian Zhuang wrote:
> Parse clock information from DTS file for mach-mmp.
>
> Changelog:
> v6:
> 1. Remove marvell string from properties in clock driver.
> 2. Append document for clock binding device tree.
> 3. Use apbc to replace apbcp. Since the main difference is register
> base.
>
> v5:
> 1. Replace clk_register_mux() by clk_register_mux_table().
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  .../devicetree/bindings/clock/mmp-clock.txt        |  51 ++++
>  arch/arm/mach-mmp/mmp-dt.c                         |   2 +
>  drivers/clk/mmp/Makefile                           |   2 +-
>  drivers/clk/mmp/clk-mmp.c                          | 300 +++++++++++++++++++++
>  4 files changed, 354 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/mmp-clock.txt
>  create mode 100644 drivers/clk/mmp/clk-mmp.c
>
> diff --git a/Documentation/devicetree/bindings/clock/mmp-clock.txt b/Documentation/devicetree/bindings/clock/mmp-clock.txt
> new file mode 100644
> index 0000000..5fe52a2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mmp-clock.txt
> @@ -0,0 +1,51 @@
> +Device Tree Clock bindings for arch-mmp
> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +

Are these used somewhere already?

> +Required properties for fixed rate clocks:
> +  - compatible : should be "marvell,mmp-fixed-clkrate".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - clock-frequency : frequency of the fixed rate clock

Why is "fixed-clock" not good enough?

This doesn't seem to describe anything more, and there's nothing
additional in the driver...

> +
> +Required properties for fixed factor clocks:
> +  - compatible : should be "marvell,mmp-fixed-clkfactor".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.

The code seems to use an additional property not described here
(mmp-fixed-factor). What does that represent?

Why not "fixed-factor-clock"?

> +
> +Required properties for mux clocks:
> +  - compatible : should be "marvell,mmp-clkmux".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - mmp-clk-reg : mux register offset & mask bits.

Offset from where? There's no reg, no container's described and there's
no example.

> +  - mmp-clk-sel : array of mux select bits
> +
> +Required properties for divider clocks:
> +  - compatible : should be "marvell,mmp-apmu-clkdiv".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - mmp-clk-reg : divider register offset & mask bits.

Similar comments to those above. This is also a fixed-factor-clock, no?

> +
> +Required properties for gate clocks:
> +  - compatible : should be "marvell,mmp-apbc-clk".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - mmp-clk-reg : gate register offset & mask bits.

Offset from where?

> +
> +Optional properties for gate clocks:
> +  - mmp-clk-delay : delay between enabling function clock and apb clock

Units?

> +  - mmp-apbc-power-ctrl : enable apbc power control bit

Is this a boolean or the offset of the bit offset?

> +
> +For example:

Missing example?

[...]

> +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, },
> +};

Not documented?

Thanks,
Mark.

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-08-09 16:04   ` Mark Rutland
@ 2013-08-10 11:06     ` Tomasz Figa
  2013-08-10 12:31       ` Mark Rutland
  0 siblings, 1 reply; 32+ messages in thread
From: Tomasz Figa @ 2013-08-10 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark, Haojian,

On Friday 09 of August 2013 17:04:01 Mark Rutland wrote:
> On Fri, Jul 26, 2013 at 11:05:31AM +0100, Haojian Zhuang wrote:
> > Parse clock information from DTS file for mach-mmp.
> > 
> > Changelog:
> > v6:
> > 1. Remove marvell string from properties in clock driver.
> > 2. Append document for clock binding device tree.
> > 3. Use apbc to replace apbcp. Since the main difference is register
> > base.
> > 
> > v5:
> > 1. Replace clk_register_mux() by clk_register_mux_table().
> > 
> > Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> > ---
> > 
> >  .../devicetree/bindings/clock/mmp-clock.txt        |  51 ++++
> >  arch/arm/mach-mmp/mmp-dt.c                         |   2 +
> >  drivers/clk/mmp/Makefile                           |   2 +-
> >  drivers/clk/mmp/clk-mmp.c                          | 300
> >  +++++++++++++++++++++ 4 files changed, 354 insertions(+), 1
> >  deletion(-)
> >  create mode 100644
> >  Documentation/devicetree/bindings/clock/mmp-clock.txt create mode
> >  100644 drivers/clk/mmp/clk-mmp.c
> > 
> > diff --git a/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > b/Documentation/devicetree/bindings/clock/mmp-clock.txt new file mode
> > 100644
> > index 0000000..5fe52a2
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > @@ -0,0 +1,51 @@
> > +Device Tree Clock bindings for arch-mmp
> > +
> > +This binding uses the common clock binding[1].
> > +
> > +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> > +
> 
> Are these used somewhere already?

Hmm? Are you asking about the generic clock bindings or I didn't get your 
question right? They are supposed to be used (and they are used) whenever 
clocks are involved.

> > +Required properties for fixed rate clocks:
> > +  - compatible : should be "marvell,mmp-fixed-clkrate".
> > +  - clocks : should be the input parent clock phandle for the clock.
> > This +       should be the reference clock.
> > +  - clock-output-names : should be reference name.
> > +  - #clock-cells : from common clock binding; should be set to 0.
> > +  - clock-frequency : frequency of the fixed rate clock
> 
> Why is "fixed-clock" not good enough?
> 
> This doesn't seem to describe anything more, and there's nothing
> additional in the driver...

+1

> > +
> > +Required properties for fixed factor clocks:
> > +  - compatible : should be "marvell,mmp-fixed-clkfactor".
> > +  - clocks : should be the input parent clock phandle for the clock.
> > This +       should be the reference clock.
> > +  - clock-output-names : should be reference name.
> > +  - #clock-cells : from common clock binding; should be set to 0.
> 
> The code seems to use an additional property not described here
> (mmp-fixed-factor). What does that represent?
> 
> Why not "fixed-factor-clock"?

+1

> > +
> > +Required properties for mux clocks:
> > +  - compatible : should be "marvell,mmp-clkmux".
> > +  - clocks : should be the input parent clock phandle for the clock.
> > This +       should be the reference clock.
> > +  - clock-output-names : should be reference name.
> > +  - #clock-cells : from common clock binding; should be set to 0.
> > +  - mmp-clk-reg : mux register offset & mask bits.
> 
> Offset from where? There's no reg, no container's described and there's
> no example.

+1

> > +  - mmp-clk-sel : array of mux select bits
> > +
> > +Required properties for divider clocks:
> > +  - compatible : should be "marvell,mmp-apmu-clkdiv".
> > +  - clocks : should be the input parent clock phandle for the clock.
> > This +       should be the reference clock.
> > +  - clock-output-names : should be reference name.
> > +  - #clock-cells : from common clock binding; should be set to 0.
> > +  - mmp-clk-reg : divider register offset & mask bits.
> 
> Similar comments to those above. This is also a fixed-factor-clock, no?

This looks like a clock with configurable divisor for me, but again, why 
not use the standard divider clock here?

Best regards,
Tomasz

> > +
> > +Required properties for gate clocks:
> > +  - compatible : should be "marvell,mmp-apbc-clk".
> > +  - clocks : should be the input parent clock phandle for the clock.
> > This +       should be the reference clock.
> > +  - clock-output-names : should be reference name.
> > +  - #clock-cells : from common clock binding; should be set to 0.
> > +  - mmp-clk-reg : gate register offset & mask bits.
> 
> Offset from where?
> 
> > +
> > +Optional properties for gate clocks:
> > +  - mmp-clk-delay : delay between enabling function clock and apb
> > clock
> Units?
> 
> > +  - mmp-apbc-power-ctrl : enable apbc power control bit
> 
> Is this a boolean or the offset of the bit offset?
> 
> > +
> 
> > +For example:
> Missing example?
> 
> [...]
> 
> > +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, }, +};
> 
> Not documented?
> 
> Thanks,
> Mark.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-08-10 11:06     ` Tomasz Figa
@ 2013-08-10 12:31       ` Mark Rutland
  2013-08-10 12:34         ` Tomasz Figa
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Rutland @ 2013-08-10 12:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Aug 10, 2013 at 12:06:01PM +0100, Tomasz Figa wrote:
> Hi Mark, Haojian,
> 
> On Friday 09 of August 2013 17:04:01 Mark Rutland wrote:
> > On Fri, Jul 26, 2013 at 11:05:31AM +0100, Haojian Zhuang wrote:
> > > Parse clock information from DTS file for mach-mmp.
> > > 
> > > Changelog:
> > > v6:
> > > 1. Remove marvell string from properties in clock driver.
> > > 2. Append document for clock binding device tree.
> > > 3. Use apbc to replace apbcp. Since the main difference is register
> > > base.
> > > 
> > > v5:
> > > 1. Replace clk_register_mux() by clk_register_mux_table().
> > > 
> > > Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> > > ---
> > > 
> > >  .../devicetree/bindings/clock/mmp-clock.txt        |  51 ++++
> > >  arch/arm/mach-mmp/mmp-dt.c                         |   2 +
> > >  drivers/clk/mmp/Makefile                           |   2 +-
> > >  drivers/clk/mmp/clk-mmp.c                          | 300
> > >  +++++++++++++++++++++ 4 files changed, 354 insertions(+), 1
> > >  deletion(-)
> > >  create mode 100644
> > >  Documentation/devicetree/bindings/clock/mmp-clock.txt create mode
> > >  100644 drivers/clk/mmp/clk-mmp.c
> > > 
> > > diff --git a/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > > b/Documentation/devicetree/bindings/clock/mmp-clock.txt new file mode
> > > 100644
> > > index 0000000..5fe52a2
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > > @@ -0,0 +1,51 @@
> > > +Device Tree Clock bindings for arch-mmp
> > > +
> > > +This binding uses the common clock binding[1].
> > > +
> > > +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> > > +
> > 
> > Are these used somewhere already?
> 
> Hmm? Are you asking about the generic clock bindings or I didn't get your 
> question right? They are supposed to be used (and they are used) whenever 
> clocks are involved.

Sorry, I meant are there any dts out there using these specific
bindings? I wasn't sure how far upstream the series was, and wanted to
make sure this hadn't gone upstream before I managed to reply.

Thanks,
Mark

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-08-10 12:31       ` Mark Rutland
@ 2013-08-10 12:34         ` Tomasz Figa
  0 siblings, 0 replies; 32+ messages in thread
From: Tomasz Figa @ 2013-08-10 12:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 10 of August 2013 13:31:23 Mark Rutland wrote:
> On Sat, Aug 10, 2013 at 12:06:01PM +0100, Tomasz Figa wrote:
> > Hi Mark, Haojian,
> > 
> > On Friday 09 of August 2013 17:04:01 Mark Rutland wrote:
> > > On Fri, Jul 26, 2013 at 11:05:31AM +0100, Haojian Zhuang wrote:
> > > > Parse clock information from DTS file for mach-mmp.
> > > > 
> > > > Changelog:
> > > > v6:
> > > > 1. Remove marvell string from properties in clock driver.
> > > > 2. Append document for clock binding device tree.
> > > > 3. Use apbc to replace apbcp. Since the main difference is
> > > > register
> > > > base.
> > > > 
> > > > v5:
> > > > 1. Replace clk_register_mux() by clk_register_mux_table().
> > > > 
> > > > Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> > > > ---
> > > > 
> > > >  .../devicetree/bindings/clock/mmp-clock.txt        |  51 ++++
> > > >  arch/arm/mach-mmp/mmp-dt.c                         |   2 +
> > > >  drivers/clk/mmp/Makefile                           |   2 +-
> > > >  drivers/clk/mmp/clk-mmp.c                          | 300
> > > >  +++++++++++++++++++++ 4 files changed, 354 insertions(+), 1
> > > >  deletion(-)
> > > >  create mode 100644
> > > >  Documentation/devicetree/bindings/clock/mmp-clock.txt create mode
> > > >  100644 drivers/clk/mmp/clk-mmp.c
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > > > b/Documentation/devicetree/bindings/clock/mmp-clock.txt new file
> > > > mode
> > > > 100644
> > > > index 0000000..5fe52a2
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/clock/mmp-clock.txt
> > > > @@ -0,0 +1,51 @@
> > > > +Device Tree Clock bindings for arch-mmp
> > > > +
> > > > +This binding uses the common clock binding[1].
> > > > +
> > > > +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> > > > +
> > > 
> > > Are these used somewhere already?
> > 
> > Hmm? Are you asking about the generic clock bindings or I didn't get
> > your question right? They are supposed to be used (and they are used)
> > whenever clocks are involved.
> 
> Sorry, I meant are there any dts out there using these specific
> bindings? I wasn't sure how far upstream the series was, and wanted to
> make sure this hadn't gone upstream before I managed to reply.

OK, sorry for the noise then.

Best regards,
Tomasz

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-07-26 10:05 ` [PATCH v6 09/11] clk: mmp: parse clock from dts Haojian Zhuang
  2013-08-09 16:04   ` Mark Rutland
@ 2013-08-10 14:57   ` Daniel Drake
  2013-08-11  5:22     ` Haojian Zhuang
  1 sibling, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-10 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

I just stumbed upon this mail... I see that I have done some similar
work in my recent patches. Maybe you could CC me in future when we are
duplicating efforts.

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> Parse clock information from DTS file for mach-mmp.
>
> Changelog:
> v6:
> 1. Remove marvell string from properties in clock driver.
> 2. Append document for clock binding device tree.
> 3. Use apbc to replace apbcp. Since the main difference is register
> base.

If one replaces the other then why are both still present in the patch?
I think all these clock type acronyms deserve a quick comment
explaining what they are.

> +Required properties for divider clocks:
> +  - compatible : should be "marvell,mmp-apmu-clkdiv".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - mmp-clk-reg : divider register offset & mask bits.

I think you should use the standard 'reg' property for providing
register offets, and then other properties (with better names) for
other info that needs to be supplied e.g. mask.

I see that your implementation here moves away from using the existing
code in clk-apmu.c and instead just uses clk-divider directly. That
might make sense, but your new DTS does not reimplement many of the
static APMU clocks that were previously implemented (e.g. ccic, sdh in
clk-mmp2.c). Why is this?

> +Required properties for gate clocks:
> +  - compatible : should be "marvell,mmp-apbc-clk".
> +  - clocks : should be the input parent clock phandle for the clock. This
> +       should be the reference clock.
> +  - clock-output-names : should be reference name.
> +  - #clock-cells : from common clock binding; should be set to 0.
> +  - mmp-clk-reg : gate register offset & mask bits.

mmp-clk-reg contains two elements, I guess. But the second element is
not used in your driver for mmp-apbc-clk.

Thanks
Daniel

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

* [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level
  2013-07-26 10:05 ` [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level Haojian Zhuang
@ 2013-08-10 17:29   ` Daniel Mack
  2013-08-11  4:53     ` Haojian Zhuang
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Mack @ 2013-08-10 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

On 26.07.2013 12:05, Haojian Zhuang wrote:
> 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.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  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(-)

This will collide with my dma rework series, which removes
arch/arm/plat-pxa/dma.c eventually. Do you think it's possible to just
drop that patch here and wait for my series to settle?


Daniel

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

* [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level
  2013-08-10 17:29   ` Daniel Mack
@ 2013-08-11  4:53     ` Haojian Zhuang
  0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-08-11  4:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Aug 11, 2013 at 1:29 AM, Daniel Mack <zonque@gmail.com> wrote:
> Hi Haojian,
>
> On 26.07.2013 12:05, Haojian Zhuang wrote:
>> 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.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>> ---
>>  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(-)
>
> This will collide with my dma rework series, which removes
> arch/arm/plat-pxa/dma.c eventually. Do you think it's possible to just
> drop that patch here and wait for my series to settle?
>
>
> Daniel
>

Sure. I'll drop it from my patch list.

Best Regards
Haojian

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-08-10 14:57   ` Daniel Drake
@ 2013-08-11  5:22     ` Haojian Zhuang
  2013-08-14 21:25       ` Daniel Drake
  0 siblings, 1 reply; 32+ messages in thread
From: Haojian Zhuang @ 2013-08-11  5:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Aug 10, 2013 at 10:57 PM, Daniel Drake <dsd@laptop.org> wrote:
> Hi Haojian,
>
> I just stumbed upon this mail... I see that I have done some similar
> work in my recent patches. Maybe you could CC me in future when we are
> duplicating efforts.

Yes, I'll cc you for the next patches.

>
> On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
> <haojian.zhuang@gmail.com> wrote:
>> Parse clock information from DTS file for mach-mmp.
>>
>> Changelog:
>> v6:
>> 1. Remove marvell string from properties in clock driver.
>> 2. Append document for clock binding device tree.
>> 3. Use apbc to replace apbcp. Since the main difference is register
>> base.
>
> If one replaces the other then why are both still present in the patch?
> I think all these clock type acronyms deserve a quick comment
> explaining what they are.

Maybe I didn't explain it well. I still use the apbcp node, but I replace all
apbcp properties by apbc properties.

The apbc registers are similar to apbcp registers. But the base registers
are different. So I use different apbc & apbcp node.

>
>> +Required properties for divider clocks:
>> +  - compatible : should be "marvell,mmp-apmu-clkdiv".
>> +  - clocks : should be the input parent clock phandle for the clock. This
>> +       should be the reference clock.
>> +  - clock-output-names : should be reference name.
>> +  - #clock-cells : from common clock binding; should be set to 0.
>> +  - mmp-clk-reg : divider register offset & mask bits.
>
> I think you should use the standard 'reg' property for providing
> register offets, and then other properties (with better names) for
> other info that needs to be supplied e.g. mask.

It seems that reg property is better. I'll change it.

>
> I see that your implementation here moves away from using the existing
> code in clk-apmu.c and instead just uses clk-divider directly. That
> might make sense, but your new DTS does not reimplement many of the
> static APMU clocks that were previously implemented (e.g. ccic, sdh in
> clk-mmp2.c). Why is this?
>
I'll append them later.

>> +Required properties for gate clocks:
>> +  - compatible : should be "marvell,mmp-apbc-clk".
>> +  - clocks : should be the input parent clock phandle for the clock. This
>> +       should be the reference clock.
>> +  - clock-output-names : should be reference name.
>> +  - #clock-cells : from common clock binding; should be set to 0.
>> +  - mmp-clk-reg : gate register offset & mask bits.
>
> mmp-clk-reg contains two elements, I guess. But the second element is
> not used in your driver for mmp-apbc-clk.

Thanks. I'll fix it.

>
> Thanks
> Daniel

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

* [PATCH v6 02/11] irqchip: mmp: support irqchip
  2013-07-26 10:05 ` [PATCH v6 02/11] irqchip: mmp: support irqchip Haojian Zhuang
@ 2013-08-12 22:53   ` Daniel Drake
  2013-08-13 22:53     ` Daniel Drake
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-12 22:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> Support IRQCHIP on irq-mmp driver.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  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(-)

This patch causes boot to fail, tested on OLPC XO-1.75 (MMP2).

Calibrating delay loop... irq 13, desc: db804740, depth: 1, count: 0,
unhandled: 0
->handle_irq():  c00704f4, handle_bad_irq+0x0/0x214
->irq_data.chip(): c05aa2e8, 0xc05aa2e8
->action():   (null)
   IRQ_NOPROBE set
 IRQ_NOREQUEST set
irq 13, desc: db804740, depth: 1, count: 0, unhandled: 0
->handle_irq():  c00704f4, handle_bad_irq+0x0/0x214
->irq_data.chip(): c05aa2e8, 0xc05aa2e8
->action():   (null)
   IRQ_NOPROBE set
 IRQ_NOREQUEST set
irq 13, desc: db804740, depth: 1, count: 0, unhandled: 0
->handle_irq():  c00704f4, handle_bad_irq+0x0/0x214
->irq_data.chip(): c05aa2e8, 0xc05aa2e8
->action():   (null)
   IRQ_NOPROBE set
 IRQ_NOREQUEST set

continues as infinite loop.

I had a poke, trying to figure out what would have caused this,
without much luck. I tried to go back to irq_domain_add_legacy() and
sprinkled some icu_mask_irq() calls around, nothing changed. Any
ideas?

Thanks
Daniel

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

* [PATCH v6 02/11] irqchip: mmp: support irqchip
  2013-08-12 22:53   ` Daniel Drake
@ 2013-08-13 22:53     ` Daniel Drake
  2013-08-14 17:47       ` Daniel Drake
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-13 22:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 12, 2013 at 4:53 PM, Daniel Drake <dsd@laptop.org> wrote:

> This patch causes boot to fail, tested on OLPC XO-1.75 (MMP2).
>
> Calibrating delay loop... irq 13, desc: db804740, depth: 1, count: 0,
> unhandled: 0
> ->handle_irq():  c00704f4, handle_bad_irq+0x0/0x214
> ->irq_data.chip(): c05aa2e8, 0xc05aa2e8
> ->action():   (null)
>    IRQ_NOPROBE set
>  IRQ_NOREQUEST set
>
> continues as infinite loop.
>
> I had a poke, trying to figure out what would have caused this,
> without much luck. I tried to go back to irq_domain_add_legacy() and
> sprinkled some icu_mask_irq() calls around, nothing changed. Any
> ideas?

In my above experiments I was assuming things were crashing during the
IRQ setup path (e.g mmp_setup_bases). That was wrong - I now realise
that the setup code moved around by this patch exits OK, then the
timer driver loads and requests + unmasks interrupt 13, and these
messages start appearing upon the first interrupt which happens right
after.

It is not happy because no IRQ handler was registered. This is
normally done by mmp_irq_domain_map(), previously called immediately
from irq_domain_add_legacy().
Now that we moved to irq_domain_add_linear() in this patch, the map
function is not called.
I fixed this by calling irq_set_chip_and_handler() and set_irq_flags()
in the loop immediately after where irq_create_mapping() is used, as
is done by irq-bcm2835.c.

Now I get a new crash, still handling the first interrupt. In
icu_mask_ack_irq(), d->domain is NULL. We dereference it, causing a
crash. The domain field should have been set by irq_create_mapping().

What actually happens is that early_irq_init (kernel/irqdesc.c)
allocates 16 interrupt descriptors even before we've looked at the
device tree. Are those "legacy" interrupts? I can't figure out what
that is supposed to mean. Then the interrupts registered by irq-mmp.c
start at 16 (e.g. hwirq 0 becomes virq 16).

When the hardware interrupt 13 comes in, the call chain is:
handle_IRQ()
generic_handle_irq()
handle_level_irq()
icu_mask_ack_irq()

generic_handle_irq() above looks up the descriptor for IRQ 13, but it
does it without considering the mapping. So it picks up the descriptor
for "legacy" interrupt 13 and passes that to icu_mask_ack_irq() -
rather than passing the descriptor for the hwirq 13 that irq-mmp.c
registered and was expecting (i.e. no translation was performed).

How is this supposed to work?

Thanks
Daniel

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

* [PATCH v6 02/11] irqchip: mmp: support irqchip
  2013-08-13 22:53     ` Daniel Drake
@ 2013-08-14 17:47       ` Daniel Drake
  0 siblings, 0 replies; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 13, 2013 at 4:53 PM, Daniel Drake <dsd@laptop.org> wrote:
> generic_handle_irq() above looks up the descriptor for IRQ 13, but it
> does it without considering the mapping. So it picks up the descriptor
> for "legacy" interrupt 13 and passes that to icu_mask_ack_irq() -
> rather than passing the descriptor for the hwirq 13 that irq-mmp.c
> registered and was expecting (i.e. no translation was performed).
>
> How is this supposed to work?

All the users of irq_domain_add_linear() that I have looked at supply
a custom IRQ handler routine (via set_handle_irq) that does the
translation.

So this patch needs to be merged with patch 3 in the series (which
does just that), or the conversion from legacy to linear needs to
happen in patch 3, not this one. Personally I would just merge the 2
patches.

With patch 3 also applied, there is no more crash.

Thanks,
Daniel

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

* [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp
  2013-07-26 10:05 ` [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp Haojian Zhuang
@ 2013-08-14 18:56   ` Daniel Drake
  2013-08-24  9:45     ` Haojian Zhuang
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> 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.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

This fails to build with CONFIG_PM=n, since mmp2_set_wake() is not
defined anywhere.
This is not a regression introduced by this patch, but now seems like
a good time to fix that minor problem.

Could this line
       icu_irq_chip.irq_set_wake = mmp2_set_wake;
be moved to mmp2_pm_init() in pm-mmp2.c (or is that too late)?
If so you could even make the mmp2_set_wake function static.

Thanks
Daniel

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

* [PATCH v6 06/11] clocksource: mmp: move mmp timer driver
  2013-07-26 10:05 ` [PATCH v6 06/11] clocksource: mmp: move mmp timer driver Haojian Zhuang
@ 2013-08-14 19:22   ` Daniel Drake
  0 siblings, 0 replies; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 19:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> Move timer-mmp driver from mach-mmp to clocksource directory.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

Reviewed-by: Daniel Drake <dsd@laptop.org>

Maybe worth mentioning the underlying motivation in the commit message
- moving device drivers out of arch/arm?

Daniel

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

* [PATCH v6 07/11] ARM: mmp: move timer registers into driver
  2013-07-26 10:05 ` [PATCH v6 07/11] ARM: mmp: move timer registers into driver Haojian Zhuang
@ 2013-08-14 19:37   ` Daniel Drake
  0 siblings, 0 replies; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 19:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> Move the definition of timer registers into timer-mmp driver.
> And map timer registers in driver.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

Reviewed-by: Daniel Drake <dsd@laptop.org>

Again, the commit message could better explain the "why". I guess this
is to reduce drivers/* independence on mach/ includes, which must be
eliminated for multiplatform build support.

Daniel

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

* [PATCH v6 09/11] clk: mmp: parse clock from dts
  2013-08-11  5:22     ` Haojian Zhuang
@ 2013-08-14 21:25       ` Daniel Drake
  0 siblings, 0 replies; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 21:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Aug 10, 2013 at 11:22 PM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
>> I see that your implementation here moves away from using the existing
>> code in clk-apmu.c and instead just uses clk-divider directly. That
>> might make sense, but your new DTS does not reimplement many of the
>> static APMU clocks that were previously implemented (e.g. ccic, sdh in
>> clk-mmp2.c). Why is this?
>>
> I'll append them later.

Looking closer I see that you only implemented this for pxa910 - and
(as noted above) you only reimplemented a subset of the clocks.

The original static clock code is still in place and being called
(pxa910_init calls pxa910_clk_init). This will result in some of the
clocks being duplicated (defined once in DT and again in static code).
I think you should either add a mechanism to avoid doing both (e.g.
see the end of http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/177153.html)
or simply remove support for non-DT clocks (depending on user base,
not sure if this is possible).

I think adding support for all the clocks in DT now is quite important
as I suspect it will change your DT design. Your patch treats APMU
clocks always as simple dividers or muxes, always enabled, however I
don't think it is possible to represent the SDH/display APMU clocks in
this way, at least I have not found a way to do it. These clocks are
in reset by default and certain bits must be written to enable them.

Finally there is something confusing in mmp_apbc_setup()

+       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 (clkdev)
+               clk_register_clkdev(clk, clk_name, NULL);

Can you explain what this logic is trying to do?
I think it is wrong. If I provide the name for the clock I want to
output from my provider, I do not get registered? And in order for me
to get my clock provider registered, I have to provide a clock-names
property which is then used to name the device?? But clock-names is
usually used for the input clock name. And I don't see why providing a
name is necessary, it could just use node->name.

Thanks
Daniel

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

* [PATCH v6 01/11] irqchip: move mmp irq driver
  2013-07-26 10:05 ` [PATCH v6 01/11] irqchip: move mmp irq driver Haojian Zhuang
@ 2013-08-14 21:26   ` Daniel Drake
  2013-08-21 20:27     ` Daniel Drake
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-14 21:26 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series affects 3 different subsystems: irqchip,
clocksource, clk. It's not clear from your submission who you are
expecting to review/merge this. Unless there is some prior agreement,
maybe it would be easier and clearer to divide this up by subsystem.
There doesn't seem to be any overlap/dependencies between the 3 parts.

On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> Move irq-mmp driver from mach-mmp directory into irqchip directory.

Might be worth a 1-line commit message, explaining the motivation
here: moving hardware support from arch/arm to drivers/

> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

Reviewed-by: Daniel Drake <dsd@laptop.org>

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

* [PATCH v6 01/11] irqchip: move mmp irq driver
  2013-08-14 21:26   ` Daniel Drake
@ 2013-08-21 20:27     ` Daniel Drake
  2013-08-22  1:28       ` Haojian Zhuang
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Drake @ 2013-08-21 20:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

On Wed, Aug 14, 2013 at 3:26 PM, Daniel Drake <dsd@laptop.org> wrote:
> This patch series affects 3 different subsystems: irqchip,
> clocksource, clk. It's not clear from your submission who you are
> expecting to review/merge this. Unless there is some prior agreement,
> maybe it would be easier and clearer to divide this up by subsystem.
> There doesn't seem to be any overlap/dependencies between the 3 parts.

I haven't heard back from you on these patches. Is there anything I
can do to help?

I know these patches are blocking the 5-or-so patches I am trying to
submit for OLPC XO support. Only one of those patches is perhaps
calling for discussion (how to put the clocks in DT) and it is a bit
frustrating that after two months we have still not progressed.

To start with, maybe I could resend patches 1 to 5 in this series to
the irqchip maintainers, with the review comments incorporated, adding
the following 2 patches on at the
end?http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/176643.html
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/176643.html

Or any other suggestions for how I can help things move along?

Thanks
Daniel

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

* [PATCH v6 01/11] irqchip: move mmp irq driver
  2013-08-21 20:27     ` Daniel Drake
@ 2013-08-22  1:28       ` Haojian Zhuang
  0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-08-22  1:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 22, 2013 at 4:27 AM, Daniel Drake <dsd@laptop.org> wrote:
> Hi Haojian,
>
> On Wed, Aug 14, 2013 at 3:26 PM, Daniel Drake <dsd@laptop.org> wrote:
>> This patch series affects 3 different subsystems: irqchip,
>> clocksource, clk. It's not clear from your submission who you are
>> expecting to review/merge this. Unless there is some prior agreement,
>> maybe it would be easier and clearer to divide this up by subsystem.
>> There doesn't seem to be any overlap/dependencies between the 3 parts.
>
> I haven't heard back from you on these patches. Is there anything I
> can do to help?
>
> I know these patches are blocking the 5-or-so patches I am trying to
> submit for OLPC XO support. Only one of those patches is perhaps
> calling for discussion (how to put the clocks in DT) and it is a bit
> frustrating that after two months we have still not progressed.
>
> To start with, maybe I could resend patches 1 to 5 in this series to
> the irqchip maintainers, with the review comments incorporated, adding
> the following 2 patches on at the
> end?http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/176643.html
> http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/176643.html
>
> Or any other suggestions for how I can help things move along?
>
> Thanks
> Daniel

I'll update the clock patches in this series. Since I was very busy, I
didn't have time
to handle it. I'll submit them again in this week.

IRQ & clocksource patches will go through ARM SoC. clock patches will go through
clock tree. The clocksource patches are depended on clock patches.

Regards
Haojian

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

* [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp
  2013-08-14 18:56   ` Daniel Drake
@ 2013-08-24  9:45     ` Haojian Zhuang
  0 siblings, 0 replies; 32+ messages in thread
From: Haojian Zhuang @ 2013-08-24  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 15, 2013 at 2:56 AM, Daniel Drake <dsd@laptop.org> wrote:
> On Fri, Jul 26, 2013 at 4:05 AM, Haojian Zhuang
> <haojian.zhuang@gmail.com> wrote:
>> 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.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>
> This fails to build with CONFIG_PM=n, since mmp2_set_wake() is not
> defined anywhere.
> This is not a regression introduced by this patch, but now seems like
> a good time to fix that minor problem.
>
> Could this line
>        icu_irq_chip.irq_set_wake = mmp2_set_wake;
> be moved to mmp2_pm_init() in pm-mmp2.c (or is that too late)?
> If so you could even make the mmp2_set_wake function static.
>
> Thanks
> Daniel

Fixed.

Regards
Haojian

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

end of thread, other threads:[~2013-08-24  9:45 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-26 10:05 No subject Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 01/11] irqchip: move mmp irq driver Haojian Zhuang
2013-08-14 21:26   ` Daniel Drake
2013-08-21 20:27     ` Daniel Drake
2013-08-22  1:28       ` Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 02/11] irqchip: mmp: support irqchip Haojian Zhuang
2013-08-12 22:53   ` Daniel Drake
2013-08-13 22:53     ` Daniel Drake
2013-08-14 17:47       ` Daniel Drake
2013-07-26 10:05 ` [PATCH v6 03/11] irqchip: mmp: support MULTI_IRQ_HANDLER Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 04/11] ARM: mmp: avoid to include head file in mach-mmp Haojian Zhuang
2013-08-14 18:56   ` Daniel Drake
2013-08-24  9:45     ` Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 05/11] irqchip: mmp: avoid to include irqs head file Haojian Zhuang
2013-07-26 16:10   ` Arnd Bergmann
2013-07-26 10:05 ` [PATCH v6 06/11] clocksource: mmp: move mmp timer driver Haojian Zhuang
2013-08-14 19:22   ` Daniel Drake
2013-07-26 10:05 ` [PATCH v6 07/11] ARM: mmp: move timer registers into driver Haojian Zhuang
2013-08-14 19:37   ` Daniel Drake
2013-07-26 10:05 ` [PATCH v6 08/11] ARM: pxa: init dma debugfs in late level Haojian Zhuang
2013-08-10 17:29   ` Daniel Mack
2013-08-11  4:53     ` Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 09/11] clk: mmp: parse clock from dts Haojian Zhuang
2013-08-09 16:04   ` Mark Rutland
2013-08-10 11:06     ` Tomasz Figa
2013-08-10 12:31       ` Mark Rutland
2013-08-10 12:34         ` Tomasz Figa
2013-08-10 14:57   ` Daniel Drake
2013-08-11  5:22     ` Haojian Zhuang
2013-08-14 21:25       ` Daniel Drake
2013-07-26 10:05 ` [PATCH v6 10/11] ARM: dts: support common clock in arch mmp Haojian Zhuang
2013-07-26 10:05 ` [PATCH v6 11/11] ARM: mmp: avoid to use cpu_is_xxx in timer Haojian Zhuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).