* [PATCH v2 0/9] support dt for mmp2
@ 2012-05-04 12:30 Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree Haojian Zhuang
` (10 more replies)
0 siblings, 11 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
v2:
1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY
2. use irq.c to replace irq-pxa168.c & irq-mmp2.c
3. Avoid to use CONFIG_OF in entry-macro.S
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 2/9] ARM: mmp: append CONFIG_MACH_MMP2_DT Haojian Zhuang
` (9 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Since irq_domain_add_simple() is removed, remove it in mmp-dt.c also.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/mach-mmp/mmp-dt.c | 22 ----------------------
1 files changed, 0 insertions(+), 22 deletions(-)
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index 6707539..ca22e3c0 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -32,31 +32,9 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = {
{}
};
-static int __init mmp_intc_add_irq_domain(struct device_node *np,
- struct device_node *parent)
-{
- irq_domain_add_simple(np, 0);
- return 0;
-}
-
-static int __init mmp_gpio_add_irq_domain(struct device_node *np,
- struct device_node *parent)
-{
- irq_domain_add_simple(np, IRQ_GPIO_START);
- return 0;
-}
-
-static const struct of_device_id mmp_irq_match[] __initconst = {
- { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, },
- { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, },
- {}
-};
-
static void __init mmp_dt_init(void)
{
- of_irq_init(mmp_irq_match);
-
of_platform_populate(NULL, of_default_bus_match_table,
mmp_auxdata_lookup, NULL);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/9] ARM: mmp: append CONFIG_MACH_MMP2_DT
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 3/9] ARM: mmp: support DT in irq Haojian Zhuang
` (8 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Append CONFIG_MACH_MMP2_DT.
CONFIG_MACH_MMP_DT is used to ARMv5 DT support. CONFIG_MACH_MMP2_DT
is used to ARMv7 DT support. These two machine support can't be
selected at the same time.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/mach-mmp/Kconfig | 29 +++++++++++++++++++----------
1 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 5a90b9a..ede7216 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -2,16 +2,6 @@ if ARCH_MMP
menu "Marvell PXA168/910/MMP2 Implmentations"
-config MACH_MMP_DT
- bool "Support MMP2 platforms from device tree"
- select CPU_PXA168
- select CPU_PXA910
- select USE_OF
- help
- Include support for Marvell MMP2 based platforms using
- the device tree. Needn't select any other machine while
- MACH_MMP_DT is enabled.
-
config MACH_ASPENITE
bool "Marvell's PXA168 Aspenite Development Board"
select CPU_PXA168
@@ -94,6 +84,25 @@ config MACH_GPLUGD
Say 'Y' here if you want to support the Marvell PXA168-based
GuruPlug Display (gplugD) Board
+config MACH_MMP_DT
+ bool "Support MMP (ARMv5) platforms from device tree"
+ select CPU_PXA168
+ select CPU_PXA910
+ select USE_OF
+ help
+ Include support for Marvell MMP2 based platforms using
+ the device tree. Needn't select any other machine while
+ MACH_MMP_DT is enabled.
+
+config MACH_MMP2_DT
+ bool "Support MMP2 (ARMv7) platforms from device tree"
+ depends on !CPU_MOHAWK
+ select CPU_MMP2
+ select USE_OF
+ help
+ Include support for Marvell MMP2 based platforms using
+ the device tree.
+
endmenu
config CPU_PXA168
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/9] ARM: mmp: support DT in irq
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 2/9] ARM: mmp: append CONFIG_MACH_MMP2_DT Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-08 17:56 ` Grant Likely
2012-05-04 12:30 ` [PATCH v2 4/9] ARM: mmp: support DT in timer Haojian Zhuang
` (7 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Merge irq-pxa168 and irq-mmp2. And support device tree also.
Since CONFIG_SPARSE_IRQ is enabled in arch-mmp, base irq starts from
NR_IRQS_LEGACY.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-mmp/Makefile | 8 +-
arch/arm/mach-mmp/include/mach/entry-macro.S | 4 +-
arch/arm/mach-mmp/include/mach/irqs.h | 27 ++-
arch/arm/mach-mmp/irq-mmp2.c | 158 ---------
arch/arm/mach-mmp/irq-pxa168.c | 54 ---
arch/arm/mach-mmp/irq.c | 445 ++++++++++++++++++++++++++
7 files changed, 472 insertions(+), 225 deletions(-)
delete mode 100644 arch/arm/mach-mmp/irq-mmp2.c
delete mode 100644 arch/arm/mach-mmp/irq-pxa168.c
create mode 100644 arch/arm/mach-mmp/irq.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cf006d4..4cf9d42 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -632,6 +632,7 @@ config ARCH_MMP
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select GPIO_PXA
+ select IRQ_DOMAIN
select TICK_ONESHOT
select PLAT_PXA
select SPARSE_IRQ
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 4fc0ff5..77f63c1 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -2,12 +2,12 @@
# Makefile for Marvell's PXA168 processors line
#
-obj-y += common.o clock.o devices.o time.o
+obj-y += common.o clock.o devices.o time.o irq.o
# SoC support
-obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o
-obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o
-obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o
+obj-$(CONFIG_CPU_PXA168) += pxa168.o
+obj-$(CONFIG_CPU_PXA910) += pxa910.o
+obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o
# board support
obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
index 9cff9e7..bd152e2 100644
--- a/arch/arm/mach-mmp/include/mach/entry-macro.S
+++ b/arch/arm/mach-mmp/include/mach/entry-macro.S
@@ -6,13 +6,15 @@
* 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, =ICU_VIRT_BASE
+ 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
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index d0e7466..fb492a5 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -125,7 +125,7 @@
#define IRQ_MMP2_RTC_MUX 5
#define IRQ_MMP2_TWSI1 7
#define IRQ_MMP2_GPU 8
-#define IRQ_MMP2_KEYPAD 9
+#define IRQ_MMP2_KEYPAD_MUX 9
#define IRQ_MMP2_ROTARY 10
#define IRQ_MMP2_TRACKBALL 11
#define IRQ_MMP2_ONEWIRE 12
@@ -163,11 +163,11 @@
#define IRQ_MMP2_DMA_FIQ 47
#define IRQ_MMP2_DMA_RIQ 48
#define IRQ_MMP2_GPIO 49
-#define IRQ_MMP2_SSP_MUX 51
+#define IRQ_MMP2_MIPI_HSI1_MUX 51
#define IRQ_MMP2_MMC2 52
#define IRQ_MMP2_MMC3 53
#define IRQ_MMP2_MMC4 54
-#define IRQ_MMP2_MIPI_HSI 55
+#define IRQ_MMP2_MIPI_HSI0_MUX 55
#define IRQ_MMP2_MSP 58
#define IRQ_MMP2_MIPI_SLIM_DMA 59
#define IRQ_MMP2_PJ4_FREQ_CHG 60
@@ -186,8 +186,14 @@
#define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0)
#define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1)
+/* secondary interrupt of INT #9 */
+#define IRQ_MMP2_KEYPAD_BASE (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_KPC (IRQ_MMP2_KEYPAD_BASE + 0)
+#define IRQ_MMP2_ROTORY (IRQ_MMP2_KEYPAD_BASE + 1)
+#define IRQ_MMP2_TBALL (IRQ_MMP2_KEYPAD_BASE + 2)
+
/* secondary interrupt of INT #17 */
-#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_KEYPAD_BASE + 3)
#define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0)
#define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1)
#define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2)
@@ -212,11 +218,16 @@
#define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14)
/* secondary interrupt of INT #51 */
-#define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15)
-#define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0)
-#define IRQ_MMP2_SSP3_SRDY (IRQ_MMP2_SSP_BASE + 1)
+#define IRQ_MMP2_MIPI_HSI1_BASE (IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_HSI1_CAWAKE (IRQ_MMP2_MIPI_HSI1_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT1 (IRQ_MMP2_MIPI_HSI1_BASE + 1)
+
+/* secondary interrupt of INT #55 */
+#define IRQ_MMP2_MIPI_HSI0_BASE (IRQ_MMP2_MIPI_HSI1_BASE + 2)
+#define IRQ_MMP2_HSI0_CAWAKE (IRQ_MMP2_MIPI_HSI0_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT0 (IRQ_MMP2_MIPI_HSI0_BASE + 1)
-#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2)
+#define IRQ_MMP2_MUX_END (IRQ_MMP2_MIPI_HSI0_BASE + 2)
#define IRQ_GPIO_START 128
#define MMP_NR_BUILTIN_GPIO 192
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
deleted file mode 100644
index 7895d27..0000000
--- a/arch/arm/mach-mmp/irq-mmp2.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/irq-mmp2.c
- *
- * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
- *
- * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
- * Copyright: Marvell International Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/irqs.h>
-#include <mach/regs-icu.h>
-#include <mach/mmp2.h>
-
-#include "common.h"
-
-static void icu_mask_irq(struct irq_data *d)
-{
- uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
-
- r &= ~ICU_INT_ROUTE_PJ4_IRQ;
- __raw_writel(r, ICU_INT_CONF(d->irq));
-}
-
-static void icu_unmask_irq(struct irq_data *d)
-{
- uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
-
- r |= ICU_INT_ROUTE_PJ4_IRQ;
- __raw_writel(r, ICU_INT_CONF(d->irq));
-}
-
-static struct irq_chip icu_irq_chip = {
- .name = "icu_irq",
- .irq_mask = icu_mask_irq,
- .irq_mask_ack = icu_mask_irq,
- .irq_unmask = icu_unmask_irq,
-};
-
-static void pmic_irq_ack(struct irq_data *d)
-{
- if (d->irq == IRQ_MMP2_PMIC)
- mmp2_clear_pmic_int();
-}
-
-#define SECOND_IRQ_MASK(_name_, irq_base, prefix) \
-static void _name_##_mask_irq(struct irq_data *d) \
-{ \
- uint32_t r; \
- r = __raw_readl(prefix##_MASK) | (1 << (d->irq - irq_base)); \
- __raw_writel(r, prefix##_MASK); \
-}
-
-#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
-static void _name_##_unmask_irq(struct irq_data *d) \
-{ \
- uint32_t r; \
- r = __raw_readl(prefix##_MASK) & ~(1 << (d->irq - irq_base)); \
- __raw_writel(r, prefix##_MASK); \
-}
-
-#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
-static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc) \
-{ \
- unsigned long status, mask, n; \
- mask = __raw_readl(prefix##_MASK); \
- while (1) { \
- status = __raw_readl(prefix##_STATUS) & ~mask; \
- if (status == 0) \
- break; \
- n = find_first_bit(&status, BITS_PER_LONG); \
- while (n < BITS_PER_LONG) { \
- generic_handle_irq(irq_base + n); \
- n = find_next_bit(&status, BITS_PER_LONG, n+1); \
- } \
- } \
-}
-
-#define SECOND_IRQ_CHIP(_name_, irq_base, prefix) \
-SECOND_IRQ_MASK(_name_, irq_base, prefix) \
-SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
-SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
-static struct irq_chip _name_##_irq_chip = { \
- .name = #_name_, \
- .irq_mask = _name_##_mask_irq, \
- .irq_unmask = _name_##_unmask_irq, \
-}
-
-SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
-SECOND_IRQ_CHIP(rtc, IRQ_MMP2_RTC_BASE, MMP2_ICU_INT5);
-SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
-SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
-SECOND_IRQ_CHIP(ssp, IRQ_MMP2_SSP_BASE, MMP2_ICU_INT51);
-
-static void init_mux_irq(struct irq_chip *chip, int start, int num)
-{
- int irq;
-
- for (irq = start; num > 0; irq++, num--) {
- struct irq_data *d = irq_get_irq_data(irq);
-
- /* mask and clear the IRQ */
- chip->irq_mask(d);
- if (chip->irq_ack)
- chip->irq_ack(d);
-
- irq_set_chip(irq, chip);
- set_irq_flags(irq, IRQF_VALID);
- irq_set_handler(irq, handle_level_irq);
- }
-}
-
-void __init mmp2_init_icu(void)
-{
- int irq;
-
- for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
- icu_mask_irq(irq_get_irq_data(irq));
- irq_set_chip(irq, &icu_irq_chip);
- set_irq_flags(irq, IRQF_VALID);
-
- switch (irq) {
- case IRQ_MMP2_PMIC_MUX:
- case IRQ_MMP2_RTC_MUX:
- case IRQ_MMP2_TWSI_MUX:
- case IRQ_MMP2_MISC_MUX:
- case IRQ_MMP2_SSP_MUX:
- break;
- default:
- irq_set_handler(irq, handle_level_irq);
- break;
- }
- }
-
- /* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
- * to be written to clear the interrupt
- */
- pmic_irq_chip.irq_ack = pmic_irq_ack;
-
- init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
- init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
- init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
- init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
- init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
-
- irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
- irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
- irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
- irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
- irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
-}
diff --git a/arch/arm/mach-mmp/irq-pxa168.c b/arch/arm/mach-mmp/irq-pxa168.c
deleted file mode 100644
index 89706a0..0000000
--- a/arch/arm/mach-mmp/irq-pxa168.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/irq.c
- *
- * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
- *
- * Author: Bin Yang <bin.yang@marvell.com>
- * Created: Sep 30, 2008
- * Copyright: Marvell International Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/regs-icu.h>
-
-#include "common.h"
-
-#define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ)
-
-#define PRIORITY_DEFAULT 0x1
-#define PRIORITY_NONE 0x0 /* means IRQ disabled */
-
-static void icu_mask_irq(struct irq_data *d)
-{
- __raw_writel(PRIORITY_NONE, ICU_INT_CONF(d->irq));
-}
-
-static void icu_unmask_irq(struct irq_data *d)
-{
- __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(d->irq));
-}
-
-static struct irq_chip icu_irq_chip = {
- .name = "icu_irq",
- .irq_ack = icu_mask_irq,
- .irq_mask = icu_mask_irq,
- .irq_unmask = icu_unmask_irq,
-};
-
-void __init icu_init_irq(void)
-{
- int irq;
-
- for (irq = 0; irq < 64; irq++) {
- icu_mask_irq(irq_get_irq_data(irq));
- irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-}
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
new file mode 100644
index 0000000..3705470
--- /dev/null
+++ b/arch/arm/mach-mmp/irq.c
@@ -0,0 +1,445 @@
+/*
+ * linux/arch/arm/mach-mmp/irq.c
+ *
+ * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ * Copyright (C) 2008 - 2012 Marvell Technology Group Ltd.
+ *
+ * Author: Bin Yang <bin.yang@marvell.com>
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <mach/irqs.h>
+
+#include "common.h"
+
+#define MAX_ICU_NR 16
+
+struct icu_chip_data {
+ int nr_irqs;
+ unsigned int virq_base;
+ unsigned int cascade_irq;
+ void __iomem *reg_status;
+ void __iomem *reg_mask;
+ unsigned int conf_enable;
+ unsigned int conf_disable;
+ unsigned int conf_mask;
+ unsigned int clr_mfp_irq_base;
+ unsigned int clr_mfp_hwirq;
+ struct irq_domain *domain;
+};
+
+struct mmp_intc_conf {
+ unsigned int conf_enable;
+ unsigned int conf_disable;
+ unsigned int conf_mask;
+};
+
+void __iomem *mmp_icu_base;
+static struct icu_chip_data icu_data[MAX_ICU_NR];
+static int max_icu_nr;
+
+extern void mmp2_clear_pmic_int(void);
+
+static void icu_mask_ack_irq(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
+ int hwirq;
+ u32 r;
+
+ hwirq = d->irq - data->virq_base;
+ if (data == &icu_data[0]) {
+ r = readl_relaxed(mmp_icu_base + (hwirq << 2));
+ r &= ~data->conf_mask;
+ r |= data->conf_disable;
+ writel_relaxed(r, mmp_icu_base + (hwirq << 2));
+ } else {
+#ifdef CONFIG_CPU_MMP2
+ if ((data->virq_base == data->clr_mfp_irq_base)
+ && (hwirq == data->clr_mfp_hwirq))
+ mmp2_clear_pmic_int();
+#endif
+ r = readl_relaxed(data->reg_mask) | (1 << hwirq);
+ writel_relaxed(r, data->reg_mask);
+ }
+}
+
+static void icu_mask_irq(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
+ int hwirq;
+ u32 r;
+
+ hwirq = d->irq - data->virq_base;
+ if (data == &icu_data[0]) {
+ r = readl_relaxed(mmp_icu_base + (hwirq << 2));
+ r &= ~data->conf_mask;
+ r |= data->conf_disable;
+ writel_relaxed(r, mmp_icu_base + (hwirq << 2));
+ } else {
+ r = readl_relaxed(data->reg_mask) | (1 << hwirq);
+ writel_relaxed(r, data->reg_mask);
+ }
+}
+
+static void icu_unmask_irq(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
+ int hwirq;
+ u32 r;
+
+ hwirq = d->irq - data->virq_base;
+ if (data == &icu_data[0]) {
+ r = readl_relaxed(mmp_icu_base + (hwirq << 2));
+ r &= ~data->conf_mask;
+ r |= data->conf_enable;
+ writel_relaxed(r, mmp_icu_base + (hwirq << 2));
+ } else {
+ r = readl_relaxed(data->reg_mask) & ~(1 << hwirq);
+ writel_relaxed(r, data->reg_mask);
+ }
+}
+
+static struct irq_chip icu_irq_chip = {
+ .name = "icu_irq",
+ .irq_mask = icu_mask_irq,
+ .irq_mask_ack = icu_mask_ack_irq,
+ .irq_unmask = icu_unmask_irq,
+};
+
+static void icu_mux_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ struct irq_domain *domain;
+ struct icu_chip_data *data;
+ int i;
+ unsigned long mask, status, n;
+
+ for (i = 1; i < max_icu_nr; i++) {
+ if (irq == icu_data[i].cascade_irq) {
+ domain = icu_data[i].domain;
+ data = (struct icu_chip_data *)domain->host_data;
+ break;
+ }
+ }
+ if (i >= max_icu_nr) {
+ pr_err("Spurious irq %d in MMP INTC\n", irq);
+ return;
+ }
+
+ mask = readl_relaxed(data->reg_mask);
+ while (1) {
+ status = readl_relaxed(data->reg_status) & ~mask;
+ if (status == 0)
+ break;
+ n = find_first_bit(&status, BITS_PER_LONG);
+ while (n < BITS_PER_LONG) {
+ generic_handle_irq(icu_data[i].virq_base + n);
+ n = find_next_bit(&status, BITS_PER_LONG, n + 1);
+ }
+ }
+}
+
+static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ return 0;
+}
+
+static int mmp_irq_domain_xlate(struct irq_domain *d, struct device_node *node,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ *out_hwirq = intspec[0];
+ return 0;
+}
+
+const struct irq_domain_ops mmp_irq_domain_ops = {
+ .map = mmp_irq_domain_map,
+ .xlate = mmp_irq_domain_xlate,
+};
+
+static struct mmp_intc_conf mmp_conf = {
+ .conf_enable = 0x51,
+ .conf_disable = 0x0,
+ .conf_mask = 0x7f,
+};
+
+static struct mmp_intc_conf mmp2_conf = {
+ .conf_enable = 0x20,
+ .conf_disable = 0x0,
+ .conf_mask = 0x7f,
+};
+
+/* MMP (ARMv5) */
+void __init icu_init_irq(void)
+{
+ int irq;
+
+ max_icu_nr = 1;
+ mmp_icu_base = ioremap(0xd4282000, 0x1000);
+ 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;
+ icu_data[0].nr_irqs = 64;
+ icu_data[0].virq_base = 0;
+ icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0,
+ &irq_domain_simple_ops,
+ &icu_data[0]);
+ for (irq = 0; irq < 64; irq++) {
+ icu_mask_irq(irq_get_irq_data(irq));
+ irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ irq_set_default_host(icu_data[0].domain);
+}
+
+/* MMP2 (ARMv7) */
+void __init mmp2_init_icu(void)
+{
+ int irq;
+
+ max_icu_nr = 8;
+ mmp_icu_base = ioremap(0xd4282000, 0x1000);
+ 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;
+ icu_data[0].nr_irqs = 64;
+ icu_data[0].virq_base = 0;
+ icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0,
+ &irq_domain_simple_ops,
+ &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].nr_irqs = 2;
+ icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE;
+ icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs,
+ icu_data[1].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[1]);
+ icu_data[2].reg_status = mmp_icu_base + 0x154;
+ icu_data[2].reg_mask = mmp_icu_base + 0x16c;
+ icu_data[2].nr_irqs = 2;
+ icu_data[2].virq_base = IRQ_MMP2_RTC_BASE;
+ icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs,
+ icu_data[2].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[2]);
+ icu_data[3].reg_status = mmp_icu_base + 0x180;
+ icu_data[3].reg_mask = mmp_icu_base + 0x17c;
+ icu_data[3].nr_irqs = 3;
+ icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE;
+ icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs,
+ icu_data[3].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[3]);
+ icu_data[4].reg_status = mmp_icu_base + 0x158;
+ icu_data[4].reg_mask = mmp_icu_base + 0x170;
+ icu_data[4].nr_irqs = 5;
+ icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE;
+ icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs,
+ icu_data[4].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[4]);
+ icu_data[5].reg_status = mmp_icu_base + 0x15c;
+ icu_data[5].reg_mask = mmp_icu_base + 0x174;
+ icu_data[5].nr_irqs = 15;
+ icu_data[5].virq_base = IRQ_MMP2_MISC_BASE;
+ icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs,
+ icu_data[5].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[5]);
+ icu_data[6].reg_status = mmp_icu_base + 0x160;
+ icu_data[6].reg_mask = mmp_icu_base + 0x178;
+ icu_data[6].nr_irqs = 2;
+ icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE;
+ icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs,
+ icu_data[6].virq_base, 0,
+ &irq_domain_simple_ops,
+ &icu_data[6]);
+ icu_data[7].reg_status = mmp_icu_base + 0x188;
+ icu_data[7].reg_mask = mmp_icu_base + 0x184;
+ icu_data[7].nr_irqs = 2;
+ icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE;
+ 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++) {
+ 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:
+ irq_set_chip(irq, &icu_irq_chip);
+ irq_set_chained_handler(irq, icu_mux_irq_demux);
+ break;
+ default:
+ irq_set_chip_and_handler(irq, &icu_irq_chip,
+ handle_level_irq);
+ break;
+ }
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ irq_set_default_host(icu_data[0].domain);
+}
+
+#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)
+{
+ 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;
+
+ 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;
+ }
+
+ 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;
+ 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));
+ }
+ max_icu_nr = i;
+ return 0;
+err:
+ of_node_put(node);
+ max_icu_nr = i;
+ return ret;
+}
+
+void __init mmp_dt_irq_init(void)
+{
+ 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;
+
+ 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;
+ }
+
+ mmp_icu_base = of_iomap(node, 0);
+ if (!mmp_icu_base) {
+ pr_err("Failed to get interrupt controller register\n");
+ return;
+ }
+
+ 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[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,
+ &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;
+err:
+ iounmap(mmp_icu_base);
+}
+#endif
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 4/9] ARM: mmp: support DT in timer
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (2 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 3/9] ARM: mmp: support DT in irq Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file Haojian Zhuang
` (6 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Parse timer from DTS file. Avoid to use hardcoding marco for register.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/mach-mmp/time.c | 81 ++++++++++++++++++++++++++++++++++------------
1 files changed, 60 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 71fc4ee..936447c 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -25,6 +25,9 @@
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <asm/sched_clock.h>
#include <mach/addr-map.h>
@@ -41,6 +44,8 @@
#define MAX_DELTA (0xfffffffe)
#define MIN_DELTA (16)
+static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+
/*
* FIXME: the timer needs some delay to stablize the counter capture
*/
@@ -48,12 +53,12 @@ static inline uint32_t timer_read(void)
{
int delay = 100;
- __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1));
+ __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
while (delay--)
cpu_relax();
- return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1));
+ return __raw_readl(mmp_timer_base + TMR_CVWR(1));
}
static u32 notrace mmp_read_sched_clock(void)
@@ -68,12 +73,12 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
/*
* Clear pending interrupt status.
*/
- __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
+ __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
/*
* Disable timer 0.
*/
- __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER);
+ __raw_writel(0x02, mmp_timer_base + TMR_CER);
c->event_handler(c);
@@ -90,23 +95,23 @@ static int timer_set_next_event(unsigned long delta,
/*
* Disable timer 0.
*/
- __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER);
+ __raw_writel(0x02, mmp_timer_base + TMR_CER);
/*
* Clear and enable timer match 0 interrupt.
*/
- __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
- __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0));
+ __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
+ __raw_writel(0x01, mmp_timer_base + TMR_IER(0));
/*
* Setup new clockevent timer value.
*/
- __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0));
+ __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0));
/*
* Enable timer 0.
*/
- __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER);
+ __raw_writel(0x03, mmp_timer_base + TMR_CER);
local_irq_restore(flags);
@@ -124,7 +129,7 @@ static void timer_set_mode(enum clock_event_mode mode,
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
/* disable the matching interrupt */
- __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0));
+ __raw_writel(0x00, mmp_timer_base + TMR_IER(0));
break;
case CLOCK_EVT_MODE_RESUME:
case CLOCK_EVT_MODE_PERIODIC:
@@ -157,27 +162,27 @@ static struct clocksource cksrc = {
static void __init timer_config(void)
{
- uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR);
+ uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR);
- __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */
+ __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
(TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
- __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
+ __raw_writel(ccr, mmp_timer_base + TMR_CCR);
/* set timer 0 to periodic mode, and timer 1 to free-running mode */
- __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR);
+ __raw_writel(0x2, mmp_timer_base + TMR_CMR);
- __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */
- __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */
- __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+ __raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */
+ __raw_writel(0x7, mmp_timer_base + TMR_ICR(0)); /* clear status */
+ __raw_writel(0x0, mmp_timer_base + TMR_IER(0));
- __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */
- __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */
- __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1));
+ __raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */
+ __raw_writel(0x7, mmp_timer_base + TMR_ICR(1)); /* clear status */
+ __raw_writel(0x0, mmp_timer_base + TMR_IER(1));
/* enable timer 1 counter */
- __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER);
+ __raw_writel(0x2, mmp_timer_base + TMR_CER);
}
static struct irqaction timer_irq = {
@@ -203,3 +208,37 @@ void __init timer_init(int irq)
clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
clockevents_register_device(&ckevt);
}
+
+#ifdef CONFIG_OF
+static struct of_device_id mmp_timer_dt_ids[] = {
+ { .compatible = "mrvl,mmp-timer", },
+ {}
+};
+
+void __init mmp_dt_init_timer(void)
+{
+ struct device_node *np;
+ int irq, ret;
+
+ np = of_find_matching_node(NULL, mmp_timer_dt_ids);
+ if (!np) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ ret = -EINVAL;
+ goto out;
+ }
+ mmp_timer_base = of_iomap(np, 0);
+ if (!mmp_timer_base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ timer_init(irq);
+ return;
+out:
+ pr_err("Failed to get timer from device tree with error:%d\n", ret);
+}
+#endif
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (3 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 4/9] ARM: mmp: support DT in timer Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-08 19:40 ` Grant Likely
2012-05-04 12:30 ` [PATCH v2 6/9] ARM: mmp: support mmp2 with device tree Haojian Zhuang
` (5 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Parse GPIO numbers from DTS file. Allocate interrupt according to
GPIO numbers.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
drivers/gpio/gpio-pxa.c | 116 +++++++++++++++++++++++++++++++++++++++-------
1 files changed, 98 insertions(+), 18 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index fc3ace3..58a6a63 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -11,13 +11,17 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/slab.h>
@@ -56,6 +60,10 @@
int pxa_last_gpio;
+#ifdef CONFIG_OF
+static struct irq_domain *domain;
+#endif
+
struct pxa_gpio_chip {
struct gpio_chip chip;
void __iomem *regbase;
@@ -81,7 +89,6 @@ enum {
PXA3XX_GPIO,
PXA93X_GPIO,
MMP_GPIO = 0x10,
- MMP2_GPIO,
};
static DEFINE_SPINLOCK(gpio_lock);
@@ -475,22 +482,92 @@ static int pxa_gpio_nums(void)
gpio_type = MMP_GPIO;
} else if (cpu_is_mmp2()) {
count = 191;
- gpio_type = MMP2_GPIO;
+ gpio_type = MMP_GPIO;
}
#endif /* CONFIG_ARCH_MMP */
return count;
}
+static struct of_device_id pxa_gpio_dt_ids[] = {
+ { .compatible = "mrvl,pxa-gpio" },
+ { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+ {}
+};
+
+static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+const struct irq_domain_ops pxa_irq_domain_ops = {
+ .map = pxa_irq_domain_map,
+};
+
+#ifdef CONFIG_OF
+static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
+{
+ int ret, nr_banks, nr_gpios, irq_base;
+ struct device_node *prev, *next, *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(pxa_gpio_dt_ids, &pdev->dev);
+
+ if (!of_id) {
+ dev_err(&pdev->dev, "Failed to find gpio controller\n");
+ return -EFAULT;
+ }
+ gpio_type = (int)of_id->data;
+
+ next = of_get_next_child(np, NULL);
+ prev = next;
+ if (!next) {
+ dev_err(&pdev->dev, "Failed to find child gpio node\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ for (nr_banks = 1; ; nr_banks++) {
+ next = of_get_next_child(np, prev);
+ if (!next)
+ break;
+ prev = next;
+ }
+ of_node_put(prev);
+ nr_gpios = nr_banks << 5;
+ pxa_last_gpio = nr_gpios - 1;
+
+ irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
+ if (irq_base < 0) {
+ dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
+ goto err;
+ }
+ domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
+ &pxa_irq_domain_ops, NULL);
+ return 0;
+err:
+ iounmap(gpio_reg_base);
+ return ret;
+}
+#else
+#define pxa_gpio_probe_dt(pdev) (-1)
+#endif
+
static int __devinit pxa_gpio_probe(struct platform_device *pdev)
{
struct pxa_gpio_chip *c;
struct resource *res;
struct clk *clk;
struct pxa_gpio_platform_data *info;
- int gpio, irq, ret;
+ int gpio, irq, ret, use_of = 0;
int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
- pxa_last_gpio = pxa_gpio_nums();
+ ret = pxa_gpio_probe_dt(pdev);
+ if (ret < 0)
+ pxa_last_gpio = pxa_gpio_nums();
+ else
+ use_of = 1;
if (!pxa_last_gpio)
return -EINVAL;
@@ -545,25 +622,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
}
+ if (!use_of) {
#ifdef CONFIG_ARCH_PXA
- irq = gpio_to_irq(0);
- irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
-
- irq = gpio_to_irq(1);
- irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
-#endif
+ irq = gpio_to_irq(0);
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
- for (irq = gpio_to_irq(gpio_offset);
- irq <= gpio_to_irq(pxa_last_gpio); irq++) {
+ irq = gpio_to_irq(1);
irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
+#endif
+
+ for (irq = gpio_to_irq(gpio_offset);
+ irq <= gpio_to_irq(pxa_last_gpio); irq++) {
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
}
irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
@@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = {
.probe = pxa_gpio_probe,
.driver = {
.name = "pxa-gpio",
+ .of_match_table = pxa_gpio_dt_ids,
},
};
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 6/9] ARM: mmp: support mmp2 with device tree
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (4 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 7/9] ARM: mmp: support pxa910 " Haojian Zhuang
` (4 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/mach-mmp/Makefile | 1 +
arch/arm/mach-mmp/mmp2-dt.c | 60 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mmp/mmp2-dt.c
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 77f63c1..b920b9b 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -19,5 +19,6 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o
obj-$(CONFIG_MACH_FLINT) += flint.o
obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o
+obj-$(CONFIG_MACH_MMP2_DT) += mmp2-dt.o
obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
obj-$(CONFIG_MACH_GPLUGD) += gplugd.o
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
new file mode 100644
index 0000000..535a5ed
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -0,0 +1,60 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp2-dt.c
+ *
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.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 struct sys_timer mmp_dt_timer = {
+ .init = mmp_dt_init_timer,
+};
+
+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),
+ OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
+ {}
+};
+
+static void __init mmp2_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ mmp2_auxdata_lookup, NULL);
+}
+
+static const char *mmp2_dt_board_compat[] __initdata = {
+ "mrvl,mmp2-brownstone",
+ NULL,
+};
+
+DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
+ .map_io = mmp_map_io,
+ .init_irq = mmp_dt_irq_init,
+ .timer = &mmp_dt_timer,
+ .init_machine = mmp2_dt_init,
+ .dt_compat = mmp2_dt_board_compat,
+MACHINE_END
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 7/9] ARM: mmp: support pxa910 with device tree
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (5 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 6/9] ARM: mmp: support mmp2 with device tree Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp Haojian Zhuang
` (3 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Suppot gpio/irq/timer in mmp-dt driver. Support PXA910 also in mmp-dt
driver.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/mach-mmp/mmp-dt.c | 50 +++++++++++++++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index ca22e3c0..033cc31 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -14,14 +14,19 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
#include <mach/irqs.h>
#include "common.h"
-extern struct sys_timer pxa168_timer;
-extern void __init icu_init_irq(void);
+extern void __init mmp_dt_irq_init(void);
+extern void __init mmp_dt_init_timer(void);
-static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = {
+static struct sys_timer mmp_dt_timer = {
+ .init = mmp_dt_init_timer,
+};
+
+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),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL),
@@ -32,22 +37,47 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = {
{}
};
-static void __init mmp_dt_init(void)
+static const struct of_dev_auxdata pxa910_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),
+ OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+ OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
+ {}
+};
+
+static void __init pxa168_dt_init(void)
{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ pxa168_auxdata_lookup, NULL);
+}
+static void __init pxa910_dt_init(void)
+{
of_platform_populate(NULL, of_default_bus_match_table,
- mmp_auxdata_lookup, NULL);
+ pxa910_auxdata_lookup, NULL);
}
-static const char *pxa168_dt_board_compat[] __initdata = {
+static const char *mmp_dt_board_compat[] __initdata = {
"mrvl,pxa168-aspenite",
+ "mrvl,pxa910-dkb",
NULL,
};
DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
.map_io = mmp_map_io,
- .init_irq = icu_init_irq,
- .timer = &pxa168_timer,
- .init_machine = mmp_dt_init,
- .dt_compat = pxa168_dt_board_compat,
+ .init_irq = mmp_dt_irq_init,
+ .timer = &mmp_dt_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_irq = mmp_dt_irq_init,
+ .timer = &mmp_dt_timer,
+ .init_machine = pxa910_dt_init,
+ .dt_compat = mmp_dt_board_compat,
MACHINE_END
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (6 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 7/9] ARM: mmp: support pxa910 " Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-06-05 0:08 ` Chris Ball
2012-05-04 12:30 ` [PATCH v2 9/9] Documentation: update docs for mmp dt Haojian Zhuang
` (2 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
timer, gpio components.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/boot/dts/mmp2-brownstone.dts | 38 ++++++
arch/arm/boot/dts/mmp2.dtsi | 220 +++++++++++++++++++++++++++++++++
arch/arm/boot/dts/pxa168.dtsi | 67 ++++++++---
arch/arm/boot/dts/pxa910-dkb.dts | 38 ++++++
arch/arm/boot/dts/pxa910.dtsi | 140 +++++++++++++++++++++
5 files changed, 487 insertions(+), 16 deletions(-)
create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts
create mode 100644 arch/arm/boot/dts/mmp2.dtsi
create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts
create mode 100644 arch/arm/boot/dts/pxa910.dtsi
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
new file mode 100644
index 0000000..153a4b2
--- /dev/null
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "mmp2.dtsi"
+
+/ {
+ model = "Marvell MMP2 Aspenite Development Board";
+ compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2";
+
+ chosen {
+ bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+ };
+
+ memory {
+ reg = <0x00000000 0x04000000>;
+ };
+
+ soc {
+ apb at d4000000 {
+ uart3: uart at d4018000 {
+ status = "okay";
+ };
+ twsi1: i2c at d4011000 {
+ status = "okay";
+ };
+ rtc: rtc at d4010000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
new file mode 100644
index 0000000..80f74e2
--- /dev/null
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ i2c0 = &twsi1;
+ i2c1 = &twsi2;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ axi at d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller at d4282000 {
+ compatible = "mrvl,mmp2-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ intcmux4 at d4282150 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <4>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x150 0x4>, <0x168 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+
+ intcmux5: interrupt-controller at d4282154 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <5>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x154 0x4>, <0x16c 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ mrvl,clr-mfp-irq = <1>;
+ };
+
+ intcmux9: interrupt-controller at d4282180 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <9>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x180 0x4>, <0x17c 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <3>;
+ };
+
+ intcmux17: interrupt-controller at d4282158 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <17>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x158 0x4>, <0x170 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <5>;
+ };
+
+ intcmux35: interrupt-controller at d428215c {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <35>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x15c 0x4>, <0x174 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <15>;
+ };
+
+ intcmux51: interrupt-controller at d4282160 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <51>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x160 0x4>, <0x178 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+
+ intcmux55: interrupt-controller at d4282188 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <55>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x188 0x4>, <0x184 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
+ };
+
+ apb at d4000000 { /* APB */
+ compatible = "mrvl,apb-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4000000 0x00200000>;
+ ranges;
+
+ timer0: timer at d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
+ uart1: uart at d4030000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4030000 0x1000>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ uart2: uart at d4017000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4017000 0x1000>;
+ interrupts = <28>;
+ status = "disabled";
+ };
+
+ uart3: uart at d4018000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4018000 0x1000>;
+ interrupts = <24>;
+ status = "disabled";
+ };
+
+ uart4: uart at d4016000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4016000 0x1000>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ gpio at d4019000 {
+ compatible = "mrvl,mmp-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <49>;
+ interrupt-names = "gpio_mux";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio at d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio at d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio at d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio at d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
+
+ gcb4: gpio at d4019104 {
+ reg = <0xd4019104 0x4>;
+ };
+
+ gcb5: gpio at d4019108 {
+ reg = <0xd4019108 0x4>;
+ };
+ };
+
+ twsi1: i2c at d4011000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4011000 0x1000>;
+ interrupts = <7>;
+ mrvl,i2c-fast-mode;
+ status = "disabled";
+ };
+
+ twsi2: i2c at d4025000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4025000 0x1000>;
+ interrupts = <58>;
+ status = "disabled";
+ };
+
+ rtc: rtc at d4010000 {
+ compatible = "mrvl,mmp-rtc";
+ reg = <0xd4010000 0x1000>;
+ interrupts = <1 0>;
+ interrupt-names = "rtc 1Hz", "rtc alarm";
+ interrupt-parent = <&intcmux5>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index d32d512..31a7186 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -18,13 +18,6 @@
i2c1 = &twsi2;
};
- intc: intc-interrupt-controller at d4282000 {
- compatible = "mrvl,mmp-intc", "mrvl,intc";
- interrupt-controller;
- #interrupt-cells = <1>;
- reg = <0xd4282000 0x1000>;
- };
-
soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -32,6 +25,23 @@
interrupt-parent = <&intc>;
ranges;
+ axi at d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller at d4282000 {
+ compatible = "mrvl,mmp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ };
+
apb at d4000000 { /* APB */
compatible = "mrvl,apb-bus", "simple-bus";
#address-cells = <1>;
@@ -39,40 +49,65 @@
reg = <0xd4000000 0x00200000>;
ranges;
+ timer0: timer at d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
uart1: uart at d4017000 {
- compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+ compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>;
interrupts = <27>;
status = "disabled";
};
uart2: uart at d4018000 {
- compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+ compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>;
interrupts = <28>;
status = "disabled";
};
uart3: uart at d4026000 {
- compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+ compatible = "mrvl,mmp-uart";
reg = <0xd4026000 0x1000>;
interrupts = <29>;
status = "disabled";
};
- gpio: gpio at d4019000 {
- compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio";
+ gpio at d4019000 {
+ compatible = "mrvl,mmp-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
interrupts = <49>;
interrupt-names = "gpio_mux";
- gpio-controller;
- #gpio-cells = <1>;
interrupt-controller;
#interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio at d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio at d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio at d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio at d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
};
twsi1: i2c at d4011000 {
- compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+ compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>;
interrupts = <7>;
mrvl,i2c-fast-mode;
@@ -80,7 +115,7 @@
};
twsi2: i2c at d4025000 {
- compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+ compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>;
interrupts = <58>;
status = "disabled";
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
new file mode 100644
index 0000000..e92be5a
--- /dev/null
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "pxa910.dtsi"
+
+/ {
+ model = "Marvell PXA910 DKB Development Board";
+ compatible = "mrvl,pxa910-dkb", "mrvl,pxa910";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+ };
+
+ memory {
+ reg = <0x00000000 0x10000000>;
+ };
+
+ soc {
+ apb at d4000000 {
+ uart1: uart at d4017000 {
+ status = "okay";
+ };
+ twsi1: i2c at d4011000 {
+ status = "okay";
+ };
+ rtc: rtc at d4010000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
new file mode 100644
index 0000000..aebf32d
--- /dev/null
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 Marvell Technology Group Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ i2c0 = &twsi1;
+ i2c1 = &twsi2;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ axi at d4200000 { /* AXI */
+ compatible = "mrvl,axi-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4200000 0x00200000>;
+ ranges;
+
+ intc: interrupt-controller at d4282000 {
+ compatible = "mrvl,mmp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ };
+
+ apb at d4000000 { /* APB */
+ compatible = "mrvl,apb-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4000000 0x00200000>;
+ ranges;
+
+ timer0: timer at d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
+
+ timer1: timer at d4016000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4016000 0x100>;
+ interrupts = <29>;
+ status = "disabled";
+ };
+
+ uart1: uart at d4017000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4017000 0x1000>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ uart2: uart at d4018000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4018000 0x1000>;
+ interrupts = <28>;
+ status = "disabled";
+ };
+
+ uart3: uart at d4036000 {
+ compatible = "mrvl,mmp-uart";
+ reg = <0xd4036000 0x1000>;
+ interrupts = <59>;
+ status = "disabled";
+ };
+
+ gpio at d4019000 {
+ compatible = "mrvl,mmp-gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd4019000 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <49>;
+ interrupt-names = "gpio_mux";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ranges;
+
+ gcb0: gpio at d4019000 {
+ reg = <0xd4019000 0x4>;
+ };
+
+ gcb1: gpio at d4019004 {
+ reg = <0xd4019004 0x4>;
+ };
+
+ gcb2: gpio at d4019008 {
+ reg = <0xd4019008 0x4>;
+ };
+
+ gcb3: gpio at d4019100 {
+ reg = <0xd4019100 0x4>;
+ };
+ };
+
+ twsi1: i2c at d4011000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4011000 0x1000>;
+ interrupts = <7>;
+ mrvl,i2c-fast-mode;
+ status = "disabled";
+ };
+
+ twsi2: i2c at d4037000 {
+ compatible = "mrvl,mmp-twsi";
+ reg = <0xd4037000 0x1000>;
+ interrupts = <54>;
+ status = "disabled";
+ };
+
+ rtc: rtc at d4010000 {
+ compatible = "mrvl,mmp-rtc";
+ reg = <0xd4010000 0x1000>;
+ interrupts = <5 6>;
+ interrupt-names = "rtc 1Hz", "rtc alarm";
+ status = "disabled";
+ };
+ };
+ };
+};
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 9/9] Documentation: update docs for mmp dt
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (7 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp Haojian Zhuang
@ 2012-05-04 12:30 ` Haojian Zhuang
2012-05-04 14:27 ` [PATCH v2 0/9] support dt for mmp2 Arnd Bergmann
2012-05-17 23:57 ` Rob Herring
10 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-04 12:30 UTC (permalink / raw)
To: linux-arm-kernel
Append interrupt controller and timer document for mmp. Updates
documents for gpio and i2c.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
Documentation/devicetree/bindings/arm/mrvl.txt | 6 ---
.../devicetree/bindings/arm/mrvl/intc.txt | 40 ++++++++++++++++++++
.../devicetree/bindings/arm/mrvl/mrvl.txt | 14 +++++++
.../devicetree/bindings/arm/mrvl/timer.txt | 13 ++++++
.../devicetree/bindings/gpio/mrvl-gpio.txt | 18 ++++++---
Documentation/devicetree/bindings/i2c/mrvl-i2c.txt | 15 +++----
6 files changed, 85 insertions(+), 21 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/arm/mrvl.txt
create mode 100644 Documentation/devicetree/bindings/arm/mrvl/intc.txt
create mode 100644 Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
create mode 100644 Documentation/devicetree/bindings/arm/mrvl/timer.txt
diff --git a/Documentation/devicetree/bindings/arm/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl.txt
deleted file mode 100644
index d8de933..0000000
--- a/Documentation/devicetree/bindings/arm/mrvl.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Marvell Platforms Device Tree Bindings
-----------------------------------------------------
-
-PXA168 Aspenite Board
-Required root node properties:
- - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
new file mode 100644
index 0000000..80b9a94
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
@@ -0,0 +1,40 @@
+* Marvell MMP Interrupt controller
+
+Required properties:
+- compatible : Should be "mrvl,mmp-intc", "mrvl,mmp2-intc" or
+ "mrvl,mmp2-mux-intc"
+- reg : Address and length of the register set of the interrupt controller.
+ If the interrupt controller is intc, address and length means the range
+ of the whold interrupt controller. If the interrupt controller is mux-intc,
+ address and length means one register. Since address of mux-intc is in the
+ range of intc. mux-intc is secondary interrupt controller.
+- reg-names : Name of the register set of the interrupt controller. It's
+ only required in mux-intc interrupt controller.
+- interrupts : Should be the port interrupt shared by mux interrupts. It's
+ only required in mux-intc interrupt controller.
+- interrupt-controller : Identifies the node as an interrupt controller.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source.
+- mrvl,intc-nr-irqs : Specifies the number of interrupts in the interrupt
+ controller.
+- mrvl,clr-mfp-irq : Specifies the interrupt that needs to clear MFP edge
+ detection first.
+
+Example:
+ intc: interrupt-controller at d4282000 {
+ compatible = "mrvl,mmp2-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-nr-irqs = <64>;
+ };
+
+ intcmux4 at d4282150 {
+ compatible = "mrvl,mmp2-mux-intc";
+ interrupts = <4>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x150 0x4>, <0x168 0x4>;
+ reg-names = "mux status", "mux mask";
+ mrvl,intc-nr-irqs = <2>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
new file mode 100644
index 0000000..117d741
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
@@ -0,0 +1,14 @@
+Marvell Platforms Device Tree Bindings
+----------------------------------------------------
+
+PXA168 Aspenite Board
+Required root node properties:
+ - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
+
+PXA910 DKB Board
+Required root node properties:
+ - compatible = "mrvl,pxa910-dkb";
+
+MMP2 Brownstone Board
+Required root node properties:
+ - compatible = "mrvl,mmp2-brownstone";
diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
new file mode 100644
index 0000000..9a6e251
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
@@ -0,0 +1,13 @@
+* Marvell MMP Timer controller
+
+Required properties:
+- compatible : Should be "mrvl,mmp-timer".
+- reg : Address and length of the register set of timer controller.
+- interrupts : Should be the interrupt number.
+
+Example:
+ timer0: timer at d4014000 {
+ compatible = "mrvl,mmp-timer";
+ reg = <0xd4014000 0x100>;
+ interrupts = <13>;
+ };
diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
index 1e34cfe..05428f3 100644
--- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
@@ -3,19 +3,25 @@
Required properties:
- compatible : Should be "mrvl,pxa-gpio" or "mrvl,mmp-gpio"
- reg : Address and length of the register set for the device
-- interrupts : Should be the port interrupt shared by all gpio pins, if
-- interrupt-name : Should be the name of irq resource.
- one number.
+- interrupts : Should be the port interrupt shared by all gpio pins.
+ There're three gpio interrupts in arch-pxa, and they're gpio0,
+ gpio1 and gpio_mux. There're only one gpio interrupt in arch-mmp,
+ gpio_mux.
+- interrupt-name : Should be the name of irq resource. Each interrupt
+ binds its interrupt-name.
+- interrupt-controller : Identifies the node as an interrupt controller.
+- #interrupt-cells: Specifies the number of cells needed to encode an
+ interrupt source.
- gpio-controller : Marks the device node as a gpio controller.
- #gpio-cells : Should be one. It is the pin number.
Example:
gpio: gpio at d4019000 {
- compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio";
+ compatible = "mrvl,mmp-gpio";
reg = <0xd4019000 0x1000>;
- interrupts = <49>, <17>, <18>;
- interrupt-name = "gpio_mux", "gpio0", "gpio1";
+ interrupts = <49>;
+ interrupt-name = "gpio_mux";
gpio-controller;
#gpio-cells = <1>;
interrupt-controller;
diff --git a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt b/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt
index 071eb3c..b891ee2 100644
--- a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt
@@ -3,34 +3,31 @@
Required properties :
- reg : Offset and length of the register set for the device
- - compatible : should be "mrvl,mmp-twsi" where CHIP is the name of a
+ - compatible : should be "mrvl,mmp-twsi" where mmp is the name of a
compatible processor, e.g. pxa168, pxa910, mmp2, mmp3.
For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required
as shown in the example below.
Recommended properties :
- - interrupts : <a b> where a is the interrupt number and b is a
- field that represents an encoding of the sense and level
- information for the interrupt. This should be encoded based on
- the information in section 2) depending on the type of interrupt
- controller you have.
+ - interrupts : the interrupt number
- interrupt-parent : the phandle for the interrupt controller that
- services interrupts for this device.
+ services interrupts for this device. If the parent is the default
+ interrupt controller in device tree, it could be ignored.
- mrvl,i2c-polling : Disable interrupt of i2c controller. Polling
status register of i2c controller instead.
- mrvl,i2c-fast-mode : Enable fast mode of i2c controller.
Examples:
twsi1: i2c at d4011000 {
- compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+ compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>;
interrupts = <7>;
mrvl,i2c-fast-mode;
};
twsi2: i2c at d4025000 {
- compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+ compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>;
interrupts = <58>;
};
--
1.7.5.4
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 0/9] support dt for mmp2
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (8 preceding siblings ...)
2012-05-04 12:30 ` [PATCH v2 9/9] Documentation: update docs for mmp dt Haojian Zhuang
@ 2012-05-04 14:27 ` Arnd Bergmann
2012-05-17 23:57 ` Rob Herring
10 siblings, 0 replies; 24+ messages in thread
From: Arnd Bergmann @ 2012-05-04 14:27 UTC (permalink / raw)
To: linux-arm-kernel
On Friday 04 May 2012, Haojian Zhuang wrote:
> v2:
> 1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY
> 2. use irq.c to replace irq-pxa168.c & irq-mmp2.c
> 3. Avoid to use CONFIG_OF in entry-macro.S
>
Looks all good to me now,
Acked-by: Arnd Bergmann <arnd@arndb.de>
Arnd
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 3/9] ARM: mmp: support DT in irq
2012-05-04 12:30 ` [PATCH v2 3/9] ARM: mmp: support DT in irq Haojian Zhuang
@ 2012-05-08 17:56 ` Grant Likely
0 siblings, 0 replies; 24+ messages in thread
From: Grant Likely @ 2012-05-08 17:56 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 4 May 2012 20:30:20 +0800, Haojian Zhuang <haojian.zhuang@gmail.com> wrote:
> Merge irq-pxa168 and irq-mmp2. And support device tree also.
>
> Since CONFIG_SPARSE_IRQ is enabled in arch-mmp, base irq starts from
> NR_IRQS_LEGACY.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
This is a really big change and difficult to review for regressions.
Is there any way you can break it down into incremental steps? ie.
something like:
- first rename one of the drivers,
- factor out commit bits,
- pull in features from the other irq driver
- add DT support
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/mach-mmp/Makefile | 8 +-
> arch/arm/mach-mmp/include/mach/entry-macro.S | 4 +-
> arch/arm/mach-mmp/include/mach/irqs.h | 27 ++-
> arch/arm/mach-mmp/irq-mmp2.c | 158 ---------
> arch/arm/mach-mmp/irq-pxa168.c | 54 ---
> arch/arm/mach-mmp/irq.c | 445 ++++++++++++++++++++++++++
> 7 files changed, 472 insertions(+), 225 deletions(-)
> delete mode 100644 arch/arm/mach-mmp/irq-mmp2.c
> delete mode 100644 arch/arm/mach-mmp/irq-pxa168.c
> create mode 100644 arch/arm/mach-mmp/irq.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index cf006d4..4cf9d42 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -632,6 +632,7 @@ config ARCH_MMP
> select CLKDEV_LOOKUP
> select GENERIC_CLOCKEVENTS
> select GPIO_PXA
> + select IRQ_DOMAIN
> select TICK_ONESHOT
> select PLAT_PXA
> select SPARSE_IRQ
> diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
> index 4fc0ff5..77f63c1 100644
> --- a/arch/arm/mach-mmp/Makefile
> +++ b/arch/arm/mach-mmp/Makefile
> @@ -2,12 +2,12 @@
> # Makefile for Marvell's PXA168 processors line
> #
>
> -obj-y += common.o clock.o devices.o time.o
> +obj-y += common.o clock.o devices.o time.o irq.o
>
> # SoC support
> -obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o
> -obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o
> -obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o
> +obj-$(CONFIG_CPU_PXA168) += pxa168.o
> +obj-$(CONFIG_CPU_PXA910) += pxa910.o
> +obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o
>
> # board support
> obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
> diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
> index 9cff9e7..bd152e2 100644
> --- a/arch/arm/mach-mmp/include/mach/entry-macro.S
> +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S
> @@ -6,13 +6,15 @@
> * 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, =ICU_VIRT_BASE
> + 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
> diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
> index d0e7466..fb492a5 100644
> --- a/arch/arm/mach-mmp/include/mach/irqs.h
> +++ b/arch/arm/mach-mmp/include/mach/irqs.h
> @@ -125,7 +125,7 @@
> #define IRQ_MMP2_RTC_MUX 5
> #define IRQ_MMP2_TWSI1 7
> #define IRQ_MMP2_GPU 8
> -#define IRQ_MMP2_KEYPAD 9
> +#define IRQ_MMP2_KEYPAD_MUX 9
> #define IRQ_MMP2_ROTARY 10
> #define IRQ_MMP2_TRACKBALL 11
> #define IRQ_MMP2_ONEWIRE 12
> @@ -163,11 +163,11 @@
> #define IRQ_MMP2_DMA_FIQ 47
> #define IRQ_MMP2_DMA_RIQ 48
> #define IRQ_MMP2_GPIO 49
> -#define IRQ_MMP2_SSP_MUX 51
> +#define IRQ_MMP2_MIPI_HSI1_MUX 51
> #define IRQ_MMP2_MMC2 52
> #define IRQ_MMP2_MMC3 53
> #define IRQ_MMP2_MMC4 54
> -#define IRQ_MMP2_MIPI_HSI 55
> +#define IRQ_MMP2_MIPI_HSI0_MUX 55
> #define IRQ_MMP2_MSP 58
> #define IRQ_MMP2_MIPI_SLIM_DMA 59
> #define IRQ_MMP2_PJ4_FREQ_CHG 60
> @@ -186,8 +186,14 @@
> #define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0)
> #define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1)
>
> +/* secondary interrupt of INT #9 */
> +#define IRQ_MMP2_KEYPAD_BASE (IRQ_MMP2_RTC_BASE + 2)
> +#define IRQ_MMP2_KPC (IRQ_MMP2_KEYPAD_BASE + 0)
> +#define IRQ_MMP2_ROTORY (IRQ_MMP2_KEYPAD_BASE + 1)
> +#define IRQ_MMP2_TBALL (IRQ_MMP2_KEYPAD_BASE + 2)
> +
> /* secondary interrupt of INT #17 */
> -#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2)
> +#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_KEYPAD_BASE + 3)
> #define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0)
> #define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1)
> #define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2)
> @@ -212,11 +218,16 @@
> #define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14)
>
> /* secondary interrupt of INT #51 */
> -#define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15)
> -#define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0)
> -#define IRQ_MMP2_SSP3_SRDY (IRQ_MMP2_SSP_BASE + 1)
> +#define IRQ_MMP2_MIPI_HSI1_BASE (IRQ_MMP2_MISC_BASE + 15)
> +#define IRQ_MMP2_HSI1_CAWAKE (IRQ_MMP2_MIPI_HSI1_BASE + 0)
> +#define IRQ_MMP2_MIPI_HSI_INT1 (IRQ_MMP2_MIPI_HSI1_BASE + 1)
> +
> +/* secondary interrupt of INT #55 */
> +#define IRQ_MMP2_MIPI_HSI0_BASE (IRQ_MMP2_MIPI_HSI1_BASE + 2)
> +#define IRQ_MMP2_HSI0_CAWAKE (IRQ_MMP2_MIPI_HSI0_BASE + 0)
> +#define IRQ_MMP2_MIPI_HSI_INT0 (IRQ_MMP2_MIPI_HSI0_BASE + 1)
>
> -#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2)
> +#define IRQ_MMP2_MUX_END (IRQ_MMP2_MIPI_HSI0_BASE + 2)
>
> #define IRQ_GPIO_START 128
> #define MMP_NR_BUILTIN_GPIO 192
> diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
> deleted file mode 100644
> index 7895d27..0000000
> --- a/arch/arm/mach-mmp/irq-mmp2.c
> +++ /dev/null
> @@ -1,158 +0,0 @@
> -/*
> - * linux/arch/arm/mach-mmp/irq-mmp2.c
> - *
> - * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
> - *
> - * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
> - * Copyright: Marvell International Ltd.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/init.h>
> -#include <linux/irq.h>
> -#include <linux/io.h>
> -
> -#include <mach/irqs.h>
> -#include <mach/regs-icu.h>
> -#include <mach/mmp2.h>
> -
> -#include "common.h"
> -
> -static void icu_mask_irq(struct irq_data *d)
> -{
> - uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
> -
> - r &= ~ICU_INT_ROUTE_PJ4_IRQ;
> - __raw_writel(r, ICU_INT_CONF(d->irq));
> -}
> -
> -static void icu_unmask_irq(struct irq_data *d)
> -{
> - uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
> -
> - r |= ICU_INT_ROUTE_PJ4_IRQ;
> - __raw_writel(r, ICU_INT_CONF(d->irq));
> -}
> -
> -static struct irq_chip icu_irq_chip = {
> - .name = "icu_irq",
> - .irq_mask = icu_mask_irq,
> - .irq_mask_ack = icu_mask_irq,
> - .irq_unmask = icu_unmask_irq,
> -};
> -
> -static void pmic_irq_ack(struct irq_data *d)
> -{
> - if (d->irq == IRQ_MMP2_PMIC)
> - mmp2_clear_pmic_int();
> -}
> -
> -#define SECOND_IRQ_MASK(_name_, irq_base, prefix) \
> -static void _name_##_mask_irq(struct irq_data *d) \
> -{ \
> - uint32_t r; \
> - r = __raw_readl(prefix##_MASK) | (1 << (d->irq - irq_base)); \
> - __raw_writel(r, prefix##_MASK); \
> -}
> -
> -#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
> -static void _name_##_unmask_irq(struct irq_data *d) \
> -{ \
> - uint32_t r; \
> - r = __raw_readl(prefix##_MASK) & ~(1 << (d->irq - irq_base)); \
> - __raw_writel(r, prefix##_MASK); \
> -}
> -
> -#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
> -static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc) \
> -{ \
> - unsigned long status, mask, n; \
> - mask = __raw_readl(prefix##_MASK); \
> - while (1) { \
> - status = __raw_readl(prefix##_STATUS) & ~mask; \
> - if (status == 0) \
> - break; \
> - n = find_first_bit(&status, BITS_PER_LONG); \
> - while (n < BITS_PER_LONG) { \
> - generic_handle_irq(irq_base + n); \
> - n = find_next_bit(&status, BITS_PER_LONG, n+1); \
> - } \
> - } \
> -}
> -
> -#define SECOND_IRQ_CHIP(_name_, irq_base, prefix) \
> -SECOND_IRQ_MASK(_name_, irq_base, prefix) \
> -SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
> -SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
> -static struct irq_chip _name_##_irq_chip = { \
> - .name = #_name_, \
> - .irq_mask = _name_##_mask_irq, \
> - .irq_unmask = _name_##_unmask_irq, \
> -}
> -
> -SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
> -SECOND_IRQ_CHIP(rtc, IRQ_MMP2_RTC_BASE, MMP2_ICU_INT5);
> -SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
> -SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
> -SECOND_IRQ_CHIP(ssp, IRQ_MMP2_SSP_BASE, MMP2_ICU_INT51);
> -
> -static void init_mux_irq(struct irq_chip *chip, int start, int num)
> -{
> - int irq;
> -
> - for (irq = start; num > 0; irq++, num--) {
> - struct irq_data *d = irq_get_irq_data(irq);
> -
> - /* mask and clear the IRQ */
> - chip->irq_mask(d);
> - if (chip->irq_ack)
> - chip->irq_ack(d);
> -
> - irq_set_chip(irq, chip);
> - set_irq_flags(irq, IRQF_VALID);
> - irq_set_handler(irq, handle_level_irq);
> - }
> -}
> -
> -void __init mmp2_init_icu(void)
> -{
> - int irq;
> -
> - for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
> - icu_mask_irq(irq_get_irq_data(irq));
> - irq_set_chip(irq, &icu_irq_chip);
> - set_irq_flags(irq, IRQF_VALID);
> -
> - switch (irq) {
> - case IRQ_MMP2_PMIC_MUX:
> - case IRQ_MMP2_RTC_MUX:
> - case IRQ_MMP2_TWSI_MUX:
> - case IRQ_MMP2_MISC_MUX:
> - case IRQ_MMP2_SSP_MUX:
> - break;
> - default:
> - irq_set_handler(irq, handle_level_irq);
> - break;
> - }
> - }
> -
> - /* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
> - * to be written to clear the interrupt
> - */
> - pmic_irq_chip.irq_ack = pmic_irq_ack;
> -
> - init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
> - init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
> - init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
> - init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
> - init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
> -
> - irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
> - irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
> - irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
> - irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
> - irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
> -}
> diff --git a/arch/arm/mach-mmp/irq-pxa168.c b/arch/arm/mach-mmp/irq-pxa168.c
> deleted file mode 100644
> index 89706a0..0000000
> --- a/arch/arm/mach-mmp/irq-pxa168.c
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -/*
> - * linux/arch/arm/mach-mmp/irq.c
> - *
> - * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
> - *
> - * Author: Bin Yang <bin.yang@marvell.com>
> - * Created: Sep 30, 2008
> - * Copyright: Marvell International Ltd.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/init.h>
> -#include <linux/irq.h>
> -#include <linux/io.h>
> -
> -#include <mach/regs-icu.h>
> -
> -#include "common.h"
> -
> -#define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ)
> -
> -#define PRIORITY_DEFAULT 0x1
> -#define PRIORITY_NONE 0x0 /* means IRQ disabled */
> -
> -static void icu_mask_irq(struct irq_data *d)
> -{
> - __raw_writel(PRIORITY_NONE, ICU_INT_CONF(d->irq));
> -}
> -
> -static void icu_unmask_irq(struct irq_data *d)
> -{
> - __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(d->irq));
> -}
> -
> -static struct irq_chip icu_irq_chip = {
> - .name = "icu_irq",
> - .irq_ack = icu_mask_irq,
> - .irq_mask = icu_mask_irq,
> - .irq_unmask = icu_unmask_irq,
> -};
> -
> -void __init icu_init_irq(void)
> -{
> - int irq;
> -
> - for (irq = 0; irq < 64; irq++) {
> - icu_mask_irq(irq_get_irq_data(irq));
> - irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
> - set_irq_flags(irq, IRQF_VALID);
> - }
> -}
> diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
> new file mode 100644
> index 0000000..3705470
> --- /dev/null
> +++ b/arch/arm/mach-mmp/irq.c
> @@ -0,0 +1,445 @@
> +/*
> + * linux/arch/arm/mach-mmp/irq.c
> + *
> + * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
> + * Copyright (C) 2008 - 2012 Marvell Technology Group Ltd.
> + *
> + * Author: Bin Yang <bin.yang@marvell.com>
> + * 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
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +
> +#include <mach/irqs.h>
> +
> +#include "common.h"
> +
> +#define MAX_ICU_NR 16
> +
> +struct icu_chip_data {
> + int nr_irqs;
> + unsigned int virq_base;
> + unsigned int cascade_irq;
> + void __iomem *reg_status;
> + void __iomem *reg_mask;
> + unsigned int conf_enable;
> + unsigned int conf_disable;
> + unsigned int conf_mask;
> + unsigned int clr_mfp_irq_base;
> + unsigned int clr_mfp_hwirq;
> + struct irq_domain *domain;
> +};
> +
> +struct mmp_intc_conf {
> + unsigned int conf_enable;
> + unsigned int conf_disable;
> + unsigned int conf_mask;
> +};
> +
> +void __iomem *mmp_icu_base;
> +static struct icu_chip_data icu_data[MAX_ICU_NR];
> +static int max_icu_nr;
> +
> +extern void mmp2_clear_pmic_int(void);
> +
> +static void icu_mask_ack_irq(struct irq_data *d)
> +{
> + struct irq_domain *domain = d->domain;
> + struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
> + int hwirq;
> + u32 r;
> +
> + hwirq = d->irq - data->virq_base;
> + if (data == &icu_data[0]) {
> + r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> + r &= ~data->conf_mask;
> + r |= data->conf_disable;
> + writel_relaxed(r, mmp_icu_base + (hwirq << 2));
> + } else {
> +#ifdef CONFIG_CPU_MMP2
> + if ((data->virq_base == data->clr_mfp_irq_base)
> + && (hwirq == data->clr_mfp_hwirq))
> + mmp2_clear_pmic_int();
> +#endif
> + r = readl_relaxed(data->reg_mask) | (1 << hwirq);
> + writel_relaxed(r, data->reg_mask);
> + }
> +}
> +
> +static void icu_mask_irq(struct irq_data *d)
> +{
> + struct irq_domain *domain = d->domain;
> + struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
> + int hwirq;
> + u32 r;
> +
> + hwirq = d->irq - data->virq_base;
> + if (data == &icu_data[0]) {
> + r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> + r &= ~data->conf_mask;
> + r |= data->conf_disable;
> + writel_relaxed(r, mmp_icu_base + (hwirq << 2));
> + } else {
> + r = readl_relaxed(data->reg_mask) | (1 << hwirq);
> + writel_relaxed(r, data->reg_mask);
> + }
> +}
> +
> +static void icu_unmask_irq(struct irq_data *d)
> +{
> + struct irq_domain *domain = d->domain;
> + struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data;
> + int hwirq;
> + u32 r;
> +
> + hwirq = d->irq - data->virq_base;
> + if (data == &icu_data[0]) {
> + r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> + r &= ~data->conf_mask;
> + r |= data->conf_enable;
> + writel_relaxed(r, mmp_icu_base + (hwirq << 2));
> + } else {
> + r = readl_relaxed(data->reg_mask) & ~(1 << hwirq);
> + writel_relaxed(r, data->reg_mask);
> + }
> +}
> +
> +static struct irq_chip icu_irq_chip = {
> + .name = "icu_irq",
> + .irq_mask = icu_mask_irq,
> + .irq_mask_ack = icu_mask_ack_irq,
> + .irq_unmask = icu_unmask_irq,
> +};
> +
> +static void icu_mux_irq_demux(unsigned int irq, struct irq_desc *desc)
> +{
> + struct irq_domain *domain;
> + struct icu_chip_data *data;
> + int i;
> + unsigned long mask, status, n;
> +
> + for (i = 1; i < max_icu_nr; i++) {
> + if (irq == icu_data[i].cascade_irq) {
> + domain = icu_data[i].domain;
> + data = (struct icu_chip_data *)domain->host_data;
> + break;
> + }
> + }
> + if (i >= max_icu_nr) {
> + pr_err("Spurious irq %d in MMP INTC\n", irq);
> + return;
> + }
> +
> + mask = readl_relaxed(data->reg_mask);
> + while (1) {
> + status = readl_relaxed(data->reg_status) & ~mask;
> + if (status == 0)
> + break;
> + n = find_first_bit(&status, BITS_PER_LONG);
> + while (n < BITS_PER_LONG) {
> + generic_handle_irq(icu_data[i].virq_base + n);
> + n = find_next_bit(&status, BITS_PER_LONG, n + 1);
> + }
> + }
> +}
> +
> +static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
> + set_irq_flags(irq, IRQF_VALID);
> + return 0;
> +}
> +
> +static int mmp_irq_domain_xlate(struct irq_domain *d, struct device_node *node,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq,
> + unsigned int *out_type)
> +{
> + *out_hwirq = intspec[0];
> + return 0;
> +}
> +
> +const struct irq_domain_ops mmp_irq_domain_ops = {
> + .map = mmp_irq_domain_map,
> + .xlate = mmp_irq_domain_xlate,
> +};
> +
> +static struct mmp_intc_conf mmp_conf = {
> + .conf_enable = 0x51,
> + .conf_disable = 0x0,
> + .conf_mask = 0x7f,
> +};
> +
> +static struct mmp_intc_conf mmp2_conf = {
> + .conf_enable = 0x20,
> + .conf_disable = 0x0,
> + .conf_mask = 0x7f,
> +};
> +
> +/* MMP (ARMv5) */
> +void __init icu_init_irq(void)
> +{
> + int irq;
> +
> + max_icu_nr = 1;
> + mmp_icu_base = ioremap(0xd4282000, 0x1000);
> + 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;
> + icu_data[0].nr_irqs = 64;
> + icu_data[0].virq_base = 0;
> + icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0,
> + &irq_domain_simple_ops,
> + &icu_data[0]);
> + for (irq = 0; irq < 64; irq++) {
> + icu_mask_irq(irq_get_irq_data(irq));
> + irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
> + set_irq_flags(irq, IRQF_VALID);
> + }
> + irq_set_default_host(icu_data[0].domain);
> +}
> +
> +/* MMP2 (ARMv7) */
> +void __init mmp2_init_icu(void)
> +{
> + int irq;
> +
> + max_icu_nr = 8;
> + mmp_icu_base = ioremap(0xd4282000, 0x1000);
> + 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;
> + icu_data[0].nr_irqs = 64;
> + icu_data[0].virq_base = 0;
> + icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0,
> + &irq_domain_simple_ops,
> + &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].nr_irqs = 2;
> + icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE;
> + icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs,
> + icu_data[1].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[1]);
> + icu_data[2].reg_status = mmp_icu_base + 0x154;
> + icu_data[2].reg_mask = mmp_icu_base + 0x16c;
> + icu_data[2].nr_irqs = 2;
> + icu_data[2].virq_base = IRQ_MMP2_RTC_BASE;
> + icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs,
> + icu_data[2].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[2]);
> + icu_data[3].reg_status = mmp_icu_base + 0x180;
> + icu_data[3].reg_mask = mmp_icu_base + 0x17c;
> + icu_data[3].nr_irqs = 3;
> + icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE;
> + icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs,
> + icu_data[3].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[3]);
> + icu_data[4].reg_status = mmp_icu_base + 0x158;
> + icu_data[4].reg_mask = mmp_icu_base + 0x170;
> + icu_data[4].nr_irqs = 5;
> + icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE;
> + icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs,
> + icu_data[4].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[4]);
> + icu_data[5].reg_status = mmp_icu_base + 0x15c;
> + icu_data[5].reg_mask = mmp_icu_base + 0x174;
> + icu_data[5].nr_irqs = 15;
> + icu_data[5].virq_base = IRQ_MMP2_MISC_BASE;
> + icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs,
> + icu_data[5].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[5]);
> + icu_data[6].reg_status = mmp_icu_base + 0x160;
> + icu_data[6].reg_mask = mmp_icu_base + 0x178;
> + icu_data[6].nr_irqs = 2;
> + icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE;
> + icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs,
> + icu_data[6].virq_base, 0,
> + &irq_domain_simple_ops,
> + &icu_data[6]);
> + icu_data[7].reg_status = mmp_icu_base + 0x188;
> + icu_data[7].reg_mask = mmp_icu_base + 0x184;
> + icu_data[7].nr_irqs = 2;
> + icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE;
> + 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++) {
> + 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:
> + irq_set_chip(irq, &icu_irq_chip);
> + irq_set_chained_handler(irq, icu_mux_irq_demux);
> + break;
> + default:
> + irq_set_chip_and_handler(irq, &icu_irq_chip,
> + handle_level_irq);
> + break;
> + }
> + set_irq_flags(irq, IRQF_VALID);
> + }
> + irq_set_default_host(icu_data[0].domain);
> +}
> +
> +#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)
> +{
> + 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;
> +
> + 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;
> + }
> +
> + 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;
> + 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));
> + }
> + max_icu_nr = i;
> + return 0;
> +err:
> + of_node_put(node);
> + max_icu_nr = i;
> + return ret;
> +}
> +
> +void __init mmp_dt_irq_init(void)
> +{
> + 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;
> +
> + 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;
> + }
> +
> + mmp_icu_base = of_iomap(node, 0);
> + if (!mmp_icu_base) {
> + pr_err("Failed to get interrupt controller register\n");
> + return;
> + }
> +
> + 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[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,
> + &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;
> +err:
> + iounmap(mmp_icu_base);
> +}
> +#endif
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies, Ltd.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file
2012-05-04 12:30 ` [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file Haojian Zhuang
@ 2012-05-08 19:40 ` Grant Likely
0 siblings, 0 replies; 24+ messages in thread
From: Grant Likely @ 2012-05-08 19:40 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 4 May 2012 20:30:22 +0800, Haojian Zhuang <haojian.zhuang@gmail.com> wrote:
> Parse GPIO numbers from DTS file. Allocate interrupt according to
> GPIO numbers.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
> drivers/gpio/gpio-pxa.c | 116 +++++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 98 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
> index fc3ace3..58a6a63 100644
> --- a/drivers/gpio/gpio-pxa.c
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -11,13 +11,17 @@
> * it under the terms of the GNU General Public License version 2 as
> * published by the Free Software Foundation.
> */
> +#include <linux/module.h>
> #include <linux/clk.h>
> #include <linux/err.h>
> #include <linux/gpio.h>
> #include <linux/gpio-pxa.h>
> #include <linux/init.h>
> #include <linux/irq.h>
> +#include <linux/irqdomain.h>
> #include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> #include <linux/platform_device.h>
> #include <linux/syscore_ops.h>
> #include <linux/slab.h>
> @@ -56,6 +60,10 @@
>
> int pxa_last_gpio;
>
> +#ifdef CONFIG_OF
> +static struct irq_domain *domain;
> +#endif
> +
> struct pxa_gpio_chip {
> struct gpio_chip chip;
> void __iomem *regbase;
> @@ -81,7 +89,6 @@ enum {
> PXA3XX_GPIO,
> PXA93X_GPIO,
> MMP_GPIO = 0x10,
> - MMP2_GPIO,
> };
>
> static DEFINE_SPINLOCK(gpio_lock);
> @@ -475,22 +482,92 @@ static int pxa_gpio_nums(void)
> gpio_type = MMP_GPIO;
> } else if (cpu_is_mmp2()) {
> count = 191;
> - gpio_type = MMP2_GPIO;
> + gpio_type = MMP_GPIO;
> }
> #endif /* CONFIG_ARCH_MMP */
> return count;
> }
>
> +static struct of_device_id pxa_gpio_dt_ids[] = {
> + { .compatible = "mrvl,pxa-gpio" },
> + { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
> + {}
> +};
> +
> +static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> + handle_edge_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + return 0;
> +}
> +
> +const struct irq_domain_ops pxa_irq_domain_ops = {
> + .map = pxa_irq_domain_map,
> +};
> +
> +#ifdef CONFIG_OF
> +static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
> +{
> + int ret, nr_banks, nr_gpios, irq_base;
> + struct device_node *prev, *next, *np = pdev->dev.of_node;
> + const struct of_device_id *of_id =
> + of_match_device(pxa_gpio_dt_ids, &pdev->dev);
> +
> + if (!of_id) {
> + dev_err(&pdev->dev, "Failed to find gpio controller\n");
> + return -EFAULT;
> + }
> + gpio_type = (int)of_id->data;
> +
> + next = of_get_next_child(np, NULL);
> + prev = next;
> + if (!next) {
> + dev_err(&pdev->dev, "Failed to find child gpio node\n");
> + ret = -EINVAL;
> + goto err;
> + }
> + for (nr_banks = 1; ; nr_banks++) {
> + next = of_get_next_child(np, prev);
> + if (!next)
> + break;
> + prev = next;
> + }
> + of_node_put(prev);
> + nr_gpios = nr_banks << 5;
> + pxa_last_gpio = nr_gpios - 1;
> +
> + irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
> + if (irq_base < 0) {
> + dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
> + goto err;
> + }
> + domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
> + &pxa_irq_domain_ops, NULL);
> + return 0;
Instead of putting the irq_domain_add_legacy() call into the DT-only
path, the entire driver should be converted over to use an irq_domain.
That will keep the driver simpler overall.
Also, as part of the conversion to irq_domain the irq handling
functions and the *_gpio_to_irq functions need to be refactored to use
irq_find_mapping() instead of a hard coded offset. Also, the hwirq
number (which should always equal the gpio number) is now available in
irq_data via irq->hwirq.
So, for example, pxa_gpio_irq_type does:
int gpio = pxa_irq_to_gpio(d->irq);
but now it can simply be:
int gpio = d->irq;
> +err:
> + iounmap(gpio_reg_base);
> + return ret;
> +}
> +#else
> +#define pxa_gpio_probe_dt(pdev) (-1)
> +#endif
> +
> static int __devinit pxa_gpio_probe(struct platform_device *pdev)
> {
> struct pxa_gpio_chip *c;
> struct resource *res;
> struct clk *clk;
> struct pxa_gpio_platform_data *info;
> - int gpio, irq, ret;
> + int gpio, irq, ret, use_of = 0;
> int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
>
> - pxa_last_gpio = pxa_gpio_nums();
> + ret = pxa_gpio_probe_dt(pdev);
> + if (ret < 0)
> + pxa_last_gpio = pxa_gpio_nums();
> + else
> + use_of = 1;
> if (!pxa_last_gpio)
> return -EINVAL;
>
> @@ -545,25 +622,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
> writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
> }
>
> + if (!use_of) {
> #ifdef CONFIG_ARCH_PXA
> - irq = gpio_to_irq(0);
> - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> - handle_edge_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> - irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
> -
> - irq = gpio_to_irq(1);
> - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> - handle_edge_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> - irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
> -#endif
> + irq = gpio_to_irq(0);
> + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> + handle_edge_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
>
> - for (irq = gpio_to_irq(gpio_offset);
> - irq <= gpio_to_irq(pxa_last_gpio); irq++) {
> + irq = gpio_to_irq(1);
> irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> handle_edge_irq);
> set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
> +#endif
See? With this patch the mapping mechanism is duplicated for DT and
non-DT. If the legacy mapping was registered here, then there the
duplicate code path goes away.
> +
> + for (irq = gpio_to_irq(gpio_offset);
> + irq <= gpio_to_irq(pxa_last_gpio); irq++) {
> + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
> + handle_edge_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + }
> }
>
> irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
> @@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = {
> .probe = pxa_gpio_probe,
> .driver = {
> .name = "pxa-gpio",
> + .of_match_table = pxa_gpio_dt_ids,
> },
> };
>
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies, Ltd.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 0/9] support dt for mmp2
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
` (9 preceding siblings ...)
2012-05-04 14:27 ` [PATCH v2 0/9] support dt for mmp2 Arnd Bergmann
@ 2012-05-17 23:57 ` Rob Herring
2012-05-18 2:15 ` Haojian Zhuang
10 siblings, 1 reply; 24+ messages in thread
From: Rob Herring @ 2012-05-17 23:57 UTC (permalink / raw)
To: linux-arm-kernel
On 05/04/2012 07:30 AM, Haojian Zhuang wrote:
> v2:
> 1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY
> 2. use irq.c to replace irq-pxa168.c & irq-mmp2.c
> 3. Avoid to use CONFIG_OF in entry-macro.S
>
I think you should combine all the DT board files in this series into 1
DT board file. The only diff I can see between the files is auxdata and
board strings. You don't have any platform_data for the auxdata, so I'm
guessing you are using it for clkdev lookup. You can instead simply add
addition clkdev lookup names for the DT device names. Any other reason
for needing the old device name is pretty much wrong.
Rob
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 0/9] support dt for mmp2
2012-05-17 23:57 ` Rob Herring
@ 2012-05-18 2:15 ` Haojian Zhuang
0 siblings, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-05-18 2:15 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, May 18, 2012 at 7:57 AM, Rob Herring <robherring2@gmail.com> wrote:
> On 05/04/2012 07:30 AM, Haojian Zhuang wrote:
>> v2:
>> 1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY
>> 2. use irq.c to replace irq-pxa168.c & irq-mmp2.c
>> 3. Avoid to use CONFIG_OF in entry-macro.S
>>
>
> I think you should combine all the DT board files in this series into 1
> DT board file. The only diff I can see between the files is auxdata and
> board strings. You don't have any platform_data for the auxdata, so I'm
> guessing you are using it for clkdev lookup. You can instead simply add
> addition clkdev lookup names for the DT device names. Any other reason
> for needing the old device name is pretty much wrong.
>
> Rob
>
I only tested limited devices. So platform data is not used really. While more
devices are added, platform data has to be used. So I reserve it first.
I need to add clkdev also into DT board files. It's in my TODO list.
Regards
Haojian
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-05-04 12:30 ` [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp Haojian Zhuang
@ 2012-06-05 0:08 ` Chris Ball
2012-06-05 2:03 ` Haojian Zhuang
2012-06-06 1:28 ` Arnd Bergmann
0 siblings, 2 replies; 24+ messages in thread
From: Chris Ball @ 2012-06-05 0:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi Haojian,
On Fri, May 04 2012, Haojian Zhuang wrote:
> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
> timer, gpio components.
The patch I'm replying to introduced a device tree for MMP2/Brownstone
in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC
XO-1.75 board, and Mitch Bradley has some corrections to the device tree
format that we'd like to make, appended below.
You can see all of the files Mitch mentions at:
http://dev.laptop.org/~wmb/mmp2-devicetree/
Here's my proposal for what to do next:
* First, you choose one of the two forms that Mitch links to.
(Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
for mmp2-flat.dtsi.)
* Then we'll post patches that modify the arch code to handle the new
DT format, and ask for your testing and ACK.
* We can try to merge the modified .dts files and .c code to 3.5/3.6.
* We'll work on merging XO-1.75 support into mainline and adding DT
support for new devices, too.
What do you think?
Thanks,
- Chris.
==
Mitch's DT review:
This directory (http://dev.laptop.org/~wmb/mmp2-devicetree) contains
modified versions of the MMP2 device tree files. They are based on the
versions from:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=ff290fc3ed7c4f451ea029190624cff692f028a5
I present them as complete files, rather than as patches, because
indentation depth changes cause nearly every line to be different.
The basic reason for the change is because the existing structure is an
ad-hoc and inaccurate representation of the system. With a SoC system
where the buses are internal and largely software-transparent, there are
two basic self-consistent approaches that one can take.
One approach is to model the software view of addressing, hiding all
"transparent" details of the bus structure.
The other approach is to model the hardware structure accurately,
exposing the actual bus hierarchy.
The existing MMP2 device tree is somewhere in the middle. It exposes
the AXI and APB buses, but the device tree hierarchy does not match the
actual bus hierarchy. In particular, the APB bus is subordinate to the
AXI bus in the hardware, but in the device tree they are peers.
I present two different modified MMP2 device trees:
mmp2.dtsi / mmp2-brownstone.dts :
This is the hardware-centric view. It models the AXI / APB
bus hierarchy, translating address ranges accurately via the
"ranges" proper. APB is subordinate to AXI. Device
addresses are relative to their parent bus.
mmp2-flat.dtsi / mmp2-brownstone-flat.dts :
This is the software-centric view. There are no bus nodes
for AXI or APB. The devices are just children of the root
node "bus", with absolute addresses.
In addition to the structural changes, the following other things were
fixed:
a) Removed the "twsi2" device node. The address that was given for that
node does not match any of the TWSI devices listed in the MMP2
documentation. I think that it was an editing mistake, as it matches
the PXA168 TWSI2 device.
b) Removed the "soc" node and moved its "interrupt-parent" property to
the root node (for the flat version) or the axi node (for the
hierarchical version). There is no need for a "soc" node; it has no
function.
c) Removed the "reg" property from the axi and apb nodes. It is
incorrect to list a memory-mapped bus's pass-through address range in a
"reg" property. The only case where a memory-mapped bus would have a
"reg" property is when the bus controller has additional control
registers (in its parent's address space) separate from the address
range that is passed through to the children. The correct way to
specify the pass-through address range is with the "ranges" property.
d) Moved the "intcmux" nodes down a level so they are children of the
top-level interrupt-controller node. The problem with having them as
peers of the top-level interrupt-controller is that their "reg"
properties conflict. For example:
intcmux4 at d4282150 { ... reg = <0x150 0x4>, <0x168 0x4> ... }
This is incorrect in several ways:
1) "@d4282150" is inconsistent with "reg = <0x150" . The "unit
address" after @ is supposed to be the same as the first component
of the reg property. d4282150 is not identical to 150.
2) The reg property is interpreted in the parent address space. In
the existing MMP2 device tree addressing structure, the parent
address space for the intcmux nodes is absolute, so address 0x150
is part of the DRAM. The reg property address would need to be
0xd4282150.
3) If the reg property were 0xd4282150, it would conflict with the
reg property of the top-level interrupt-controller, which "claims"
0x1000 bytes of address space starting at 0xd42082000.
The solution is to put the intcmux nodes underneath the
interrupt-controller node. The interrupt-controller node now has
#address-cells and #size-cells properties so it can have children, but
it does not have a ranges property, so the address space is not passed
through. The child (intcmux) reg addresses can then be interpreted
independently, without conflict.
e) The AXI bus address space is actually larger than the existing MMP2
device tree implies. According to the MMP2 datasheet, the range from
0xD400_0000 to 0xD401_0000 is AXI (PDMA controller). AXI space also
extends up to address 0xF800_0000, and there are some devices up above
0xF000_0000 - USB SPH, ULPI, ISP, EPD, and VMeta config. So (in the
hierarchical version), the AXI ranges property encompasses the full
range from 0xD400_0000 up to 0xF800_0000.
f) The APB bus address space does not start at 0xD400_0000, but
rather at 0xD401_0000.
g) For the reasons mentioned in point (c), the top-level gpio node
cannot have both a ranges property (to pass through the address space)
and also a reg property claiming that address space. The solution is to
remove its ranges property, adjusting its children's (gcb nodes)
addresses to be offsets within a private (not pass-through) address
space.
h) The "model" property in mmp2-brownstone.dts said "Aspenite".
I changed it to "Brownstone".
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-05 0:08 ` Chris Ball
@ 2012-06-05 2:03 ` Haojian Zhuang
2012-06-06 1:28 ` Arnd Bergmann
1 sibling, 0 replies; 24+ messages in thread
From: Haojian Zhuang @ 2012-06-05 2:03 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jun 5, 2012 at 8:08 AM, Chris Ball <cjb@laptop.org> wrote:
> Hi Haojian,
>
> On Fri, May 04 2012, Haojian Zhuang wrote:
>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
>> timer, gpio components.
>
> The patch I'm replying to introduced a device tree for MMP2/Brownstone
> in 3.5-rc1. ?We're looking at adopting the MMP2 device tree for the OLPC
> XO-1.75 board, and Mitch Bradley has some corrections to the device tree
> format that we'd like to make, appended below.
>
> You can see all of the files Mitch mentions at:
> http://dev.laptop.org/~wmb/mmp2-devicetree/
>
> Here's my proposal for what to do next:
> ?* First, you choose one of the two forms that Mitch links to.
> ? (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
> ? for mmp2-flat.dtsi.)
> ?* Then we'll post patches that modify the arch code to handle the new
> ? DT format, and ask for your testing and ACK.
> ?* We can try to merge the modified .dts files and .c code to 3.5/3.6.
> ?* We'll work on merging XO-1.75 support into mainline and adding DT
> ? support for new devices, too.
>
> What do you think?
>
I think that mmp2-flat.dtsi is better. We can use this. Thanks for your effort.
Regards
Haojian
> Thanks,
>
> - Chris.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-05 0:08 ` Chris Ball
2012-06-05 2:03 ` Haojian Zhuang
@ 2012-06-06 1:28 ` Arnd Bergmann
2012-06-06 1:47 ` Mitch Bradley
1 sibling, 1 reply; 24+ messages in thread
From: Arnd Bergmann @ 2012-06-06 1:28 UTC (permalink / raw)
To: linux-arm-kernel
On Tuesday 05 June 2012, Chris Ball wrote:
> Hi Haojian,
>
> On Fri, May 04 2012, Haojian Zhuang wrote:
> > Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
> > timer, gpio components.
>
> The patch I'm replying to introduced a device tree for MMP2/Brownstone
> in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC
> XO-1.75 board, and Mitch Bradley has some corrections to the device tree
> format that we'd like to make, appended below.
>
> You can see all of the files Mitch mentions at:
> http://dev.laptop.org/~wmb/mmp2-devicetree/
>
> Here's my proposal for what to do next:
> * First, you choose one of the two forms that Mitch links to.
> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
> for mmp2-flat.dtsi.)
My preference would be towards mmp2.dtsi. I've recommended doing it
that way to other people, too.
> d) Moved the "intcmux" nodes down a level so they are children of the
> top-level interrupt-controller node. The problem with having them as
> peers of the top-level interrupt-controller is that their "reg"
> properties conflict. For example:
> intcmux4 at d4282150 { ... reg = <0x150 0x4>, <0x168 0x4> ... }
>
> This is incorrect in several ways:
>
> 1) "@d4282150" is inconsistent with "reg = <0x150" . The "unit
> address" after @ is supposed to be the same as the first component
> of the reg property. d4282150 is not identical to 150.
I thought the rule was that the @... part should be a translated address
in the presence of "ranges" translation so we get a unique value in case
we have multiple devices of the same name on the same address but on
different buses.
If we change this here, I suppose it also needs to be changed in a number
of other places, and we have to rethink the method for unique device
names.
> The solution is to put the intcmux nodes underneath the
> interrupt-controller node. The interrupt-controller node now has
> #address-cells and #size-cells properties so it can have children, but
> it does not have a ranges property, so the address space is not passed
> through. The child (intcmux) reg addresses can then be interpreted
> independently, without conflict.
Right. The implication for this however is that the driver cannot
treat the reg property as a physical address it can do ioremap on,
but needs to interface with the driver that provides the address
space.
Arnd
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 1:28 ` Arnd Bergmann
@ 2012-06-06 1:47 ` Mitch Bradley
2012-06-06 2:35 ` Haojian Zhuang
2012-06-06 3:05 ` Arnd Bergmann
0 siblings, 2 replies; 24+ messages in thread
From: Mitch Bradley @ 2012-06-06 1:47 UTC (permalink / raw)
To: linux-arm-kernel
On 6/5/2012 3:28 PM, Arnd Bergmann wrote:
> On Tuesday 05 June 2012, Chris Ball wrote:
>> Hi Haojian,
>>
>> On Fri, May 04 2012, Haojian Zhuang wrote:
>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
>>> timer, gpio components.
>>
>> The patch I'm replying to introduced a device tree for MMP2/Brownstone
>> in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC
>> XO-1.75 board, and Mitch Bradley has some corrections to the device tree
>> format that we'd like to make, appended below.
>>
>> You can see all of the files Mitch mentions at:
>> http://dev.laptop.org/~wmb/mmp2-devicetree/
>>
>> Here's my proposal for what to do next:
>> * First, you choose one of the two forms that Mitch links to.
>> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
>> for mmp2-flat.dtsi.)
>
> My preference would be towards mmp2.dtsi. I've recommended doing it
> that way to other people, too.
In most cases, I have found that exposing the full hierarchy is
preferable. For this specific SoC, which I have been working with for
quite awhile now, I haven't found any instance where exposing the
AXI/APB levels buys you anything. The hierarchy just adds clutter.
That said, I don't feel strongly about it.
>
>
>> d) Moved the "intcmux" nodes down a level so they are children of the
>> top-level interrupt-controller node. The problem with having them as
>> peers of the top-level interrupt-controller is that their "reg"
>> properties conflict. For example:
>> intcmux4 at d4282150 { ... reg =<0x150 0x4>,<0x168 0x4> ... }
>>
>> This is incorrect in several ways:
>>
>> 1) "@d4282150" is inconsistent with "reg =<0x150" . The "unit
>> address" after @ is supposed to be the same as the first component
>> of the reg property. d4282150 is not identical to 150.
>
> I thought the rule was that the @... part should be a translated address
> in the presence of "ranges" translation so we get a unique value in case
> we have multiple devices of the same name on the same address but on
> different buses.
>
> If we change this here, I suppose it also needs to be changed in a number
> of other places, and we have to rethink the method for unique device
> names.
My thinking was that "ranges" is inappropriate in this case (within the
top-level interrupt controller node), and I got rid of it. That being
the case, this is not "in the presence of ranges".
>
>
>> The solution is to put the intcmux nodes underneath the
>> interrupt-controller node. The interrupt-controller node now has
>> #address-cells and #size-cells properties so it can have children, but
>> it does not have a ranges property, so the address space is not passed
>> through. The child (intcmux) reg addresses can then be interpreted
>> independently, without conflict.
>
> Right. The implication for this however is that the driver cannot
> treat the reg property as a physical address it can do ioremap on,
> but needs to interface with the driver that provides the address
> space.
Indeed. For this driver, the intcmux subnodes are handled by the same
driver as the top-level interrupt controller, and those subordinate
registers are accessed via that driver's one mapping of the register block.
>
>
> Arnd
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 1:47 ` Mitch Bradley
@ 2012-06-06 2:35 ` Haojian Zhuang
2012-06-06 5:22 ` Mitch Bradley
2012-06-06 3:05 ` Arnd Bergmann
1 sibling, 1 reply; 24+ messages in thread
From: Haojian Zhuang @ 2012-06-06 2:35 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jun 6, 2012 at 9:47 AM, Mitch Bradley <wmb@firmworks.com> wrote:
> On 6/5/2012 3:28 PM, Arnd Bergmann wrote:
>>
>> On Tuesday 05 June 2012, Chris Ball wrote:
>>>
>>> Hi Haojian,
>>>
>>> On Fri, May 04 2012, Haojian Zhuang wrote:
>>>>
>>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
>>>> timer, gpio components.
>>>
>>>
>>> The patch I'm replying to introduced a device tree for MMP2/Brownstone
>>> in 3.5-rc1. ?We're looking at adopting the MMP2 device tree for the OLPC
>>> XO-1.75 board, and Mitch Bradley has some corrections to the device tree
>>> format that we'd like to make, appended below.
>>>
>>> You can see all of the files Mitch mentions at:
>>> http://dev.laptop.org/~wmb/mmp2-devicetree/
>>>
>>> Here's my proposal for what to do next:
>>> ?* First, you choose one of the two forms that Mitch links to.
>>> ? ?(Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
>>> ? ?for mmp2-flat.dtsi.)
>>
>>
>> My preference would be towards mmp2.dtsi. I've recommended doing it
>> that way to other people, too.
>
> In most cases, I have found that exposing the full hierarchy is preferable.
> ?For this specific SoC, which I have been working with for quite awhile now,
> I haven't found any instance where exposing the AXI/APB levels buys you
> anything. ?The hierarchy just adds clutter.
>
> That said, I don't feel strongly about it.
>
mmp2-brownstone.dts is too complex since both apb & axi are imported.
Could we only use flat structure in mmp2-brownstone.dts?
>
>>
>>
>>> d) Moved the "intcmux" nodes down a level so they are children of the
>>> top-level interrupt-controller node. ?The problem with having them as
>>> peers of the top-level interrupt-controller is that their "reg"
>>> properties conflict. ?For example:
>>> intcmux4 at d4282150 { ... reg =<0x150 0x4>,<0x168 0x4> ?... }
>>>
>>> This is incorrect in several ways:
>>>
>>> ? ?1) "@d4282150" is inconsistent with "reg =<0x150" . ?The "unit
>>> ? ? ? address" after @ is supposed to be the same as the first component
>>> ? ? ? of the reg property. ?d4282150 is not identical to 150.
>>
>>
>> I thought the rule was that the @... part should be a translated address
>> in the presence of "ranges" translation so we get a unique value in case
>> we have multiple devices of the same name on the same address but on
>> different buses.
>>
>> If we change this here, I suppose it also needs to be changed in a number
>> of other places, and we have to rethink the method for unique device
>> names.
>
>
> My thinking was that "ranges" is inappropriate in this case (within the
> top-level interrupt controller node), and I got rid of it. ?That being the
> case, this is not "in the presence of ranges".
>
>
>>
>>
>>> The solution is to put the intcmux nodes underneath the
>>> interrupt-controller node. ?The interrupt-controller node now has
>>> #address-cells and #size-cells properties so it can have children, but
>>> it does not have a ranges property, so the address space is not passed
>>> through. ?The child (intcmux) reg addresses can then be interpreted
>>> independently, without conflict.
>>
>>
>> Right. The implication for this however is that the driver cannot
>> treat the reg property as a physical address it can do ioremap on,
>> but needs to interface with the driver that provides the address
>> space.
>
>
> Indeed. ?For this driver, the intcmux subnodes are handled by the same
> driver as the top-level interrupt controller, and those subordinate
> registers are accessed via that driver's one mapping of the register block.
>
Mitch,
Did you test cascade intcmux in DTS? I tried it before and got failure. But I
didn't dig it yet, so I use parallel intc node instead.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 1:47 ` Mitch Bradley
2012-06-06 2:35 ` Haojian Zhuang
@ 2012-06-06 3:05 ` Arnd Bergmann
1 sibling, 0 replies; 24+ messages in thread
From: Arnd Bergmann @ 2012-06-06 3:05 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 06 June 2012, Mitch Bradley wrote:
> On 6/5/2012 3:28 PM, Arnd Bergmann wrote:
> > On Tuesday 05 June 2012, Chris Ball wrote:
> >> Here's my proposal for what to do next:
> >> * First, you choose one of the two forms that Mitch links to.
> >> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
> >> for mmp2-flat.dtsi.)
> >
> > My preference would be towards mmp2.dtsi. I've recommended doing it
> > that way to other people, too.
>
> In most cases, I have found that exposing the full hierarchy is
> preferable. For this specific SoC, which I have been working with for
> quite awhile now, I haven't found any instance where exposing the
> AXI/APB levels buys you anything. The hierarchy just adds clutter.
>
> That said, I don't feel strongly about it.
Neither do I. Haojian might have a better idea of what the other
SoCs in this family are like, so I think it's best if he makes the
decision which one to use.
> >> d) Moved the "intcmux" nodes down a level so they are children of the
> >> top-level interrupt-controller node. The problem with having them as
> >> peers of the top-level interrupt-controller is that their "reg"
> >> properties conflict. For example:
> >> intcmux4 at d4282150 { ... reg =<0x150 0x4>,<0x168 0x4> ... }
> >>
> >> This is incorrect in several ways:
> >>
> >> 1) "@d4282150" is inconsistent with "reg =<0x150" . The "unit
> >> address" after @ is supposed to be the same as the first component
> >> of the reg property. d4282150 is not identical to 150.
> >
> > I thought the rule was that the @... part should be a translated address
> > in the presence of "ranges" translation so we get a unique value in case
> > we have multiple devices of the same name on the same address but on
> > different buses.
> >
> > If we change this here, I suppose it also needs to be changed in a number
> > of other places, and we have to rethink the method for unique device
> > names.
>
> My thinking was that "ranges" is inappropriate in this case (within the
> top-level interrupt controller node), and I got rid of it. That being
> the case, this is not "in the presence of ranges".
Ok, makes sense.
Arnd
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 2:35 ` Haojian Zhuang
@ 2012-06-06 5:22 ` Mitch Bradley
2012-06-06 5:25 ` Haojian Zhuang
0 siblings, 1 reply; 24+ messages in thread
From: Mitch Bradley @ 2012-06-06 5:22 UTC (permalink / raw)
To: linux-arm-kernel
On 6/5/2012 4:35 PM, Haojian Zhuang wrote:
> On Wed, Jun 6, 2012 at 9:47 AM, Mitch Bradley<wmb@firmworks.com> wrote:
>> On 6/5/2012 3:28 PM, Arnd Bergmann wrote:
>>>
>>> On Tuesday 05 June 2012, Chris Ball wrote:
>>>>
>>>> Hi Haojian,
>>>>
>>>> On Fri, May 04 2012, Haojian Zhuang wrote:
>>>>>
>>>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
>>>>> timer, gpio components.
>>>>
>>>>
>>>> The patch I'm replying to introduced a device tree for MMP2/Brownstone
>>>> in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC
>>>> XO-1.75 board, and Mitch Bradley has some corrections to the device tree
>>>> format that we'd like to make, appended below.
>>>>
>>>> You can see all of the files Mitch mentions at:
>>>> http://dev.laptop.org/~wmb/mmp2-devicetree/
>>>>
>>>> Here's my proposal for what to do next:
>>>> * First, you choose one of the two forms that Mitch links to.
>>>> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
>>>> for mmp2-flat.dtsi.)
>>>
>>>
>>> My preference would be towards mmp2.dtsi. I've recommended doing it
>>> that way to other people, too.
>>
>> In most cases, I have found that exposing the full hierarchy is preferable.
>> For this specific SoC, which I have been working with for quite awhile now,
>> I haven't found any instance where exposing the AXI/APB levels buys you
>> anything. The hierarchy just adds clutter.
>>
>> That said, I don't feel strongly about it.
>>
> mmp2-brownstone.dts is too complex since both apb& axi are imported.
> Could we only use flat structure in mmp2-brownstone.dts?
See http://dev.laptop.org/~wmb/mmp2-devicetree/mmp2-brownstone-flat.dts
<http://dev.laptop.org/%7Ewmb/mmp2-devicetree/mmp2-brownstone-flat.dts>
>
>
>>
>>>
>>>
>>>> d) Moved the "intcmux" nodes down a level so they are children of the
>>>> top-level interrupt-controller node. The problem with having them as
>>>> peers of the top-level interrupt-controller is that their "reg"
>>>> properties conflict. For example:
>>>> intcmux4 at d4282150 { ... reg =<0x150 0x4>,<0x168 0x4> ... }
>>>>
>>>> This is incorrect in several ways:
>>>>
>>>> 1) "@d4282150" is inconsistent with "reg =<0x150" . The "unit
>>>> address" after @ is supposed to be the same as the first component
>>>> of the reg property. d4282150 is not identical to 150.
>>>
>>>
>>> I thought the rule was that the @... part should be a translated address
>>> in the presence of "ranges" translation so we get a unique value in case
>>> we have multiple devices of the same name on the same address but on
>>> different buses.
>>>
>>> If we change this here, I suppose it also needs to be changed in a number
>>> of other places, and we have to rethink the method for unique device
>>> names.
>>
>>
>> My thinking was that "ranges" is inappropriate in this case (within the
>> top-level interrupt controller node), and I got rid of it. That being the
>> case, this is not "in the presence of ranges".
>>
>>
>>>
>>>
>>>> The solution is to put the intcmux nodes underneath the
>>>> interrupt-controller node. The interrupt-controller node now has
>>>> #address-cells and #size-cells properties so it can have children, but
>>>> it does not have a ranges property, so the address space is not passed
>>>> through. The child (intcmux) reg addresses can then be interpreted
>>>> independently, without conflict.
>>>
>>>
>>> Right. The implication for this however is that the driver cannot
>>> treat the reg property as a physical address it can do ioremap on,
>>> but needs to interface with the driver that provides the address
>>> space.
>>
>>
>> Indeed. For this driver, the intcmux subnodes are handled by the same
>> driver as the top-level interrupt controller, and those subordinate
>> registers are accessed via that driver's one mapping of the register block.
>>
> Mitch,
>
> Did you test cascade intcmux in DTS? I tried it before and got failure. But I
> didn't dig it yet, so I use parallel intc node instead.
Chris and I are testing it now. It's not working yet, but we have only
been looking at it for less than one hour. Perhaps we will make
progress tomorrow.
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 5:22 ` Mitch Bradley
@ 2012-06-06 5:25 ` Haojian Zhuang
2012-06-06 16:22 ` Mitch Bradley
0 siblings, 1 reply; 24+ messages in thread
From: Haojian Zhuang @ 2012-06-06 5:25 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jun 6, 2012 at 1:22 PM, Mitch Bradley <wmb@firmworks.com> wrote:
> On 6/5/2012 4:35 PM, Haojian Zhuang wrote:
>>
>> On Wed, Jun 6, 2012 at 9:47 AM, Mitch Bradley<wmb@firmworks.com> ?wrote:
>>>
>>> On 6/5/2012 3:28 PM, Arnd Bergmann wrote:
>>>>
>>>>
>>>> On Tuesday 05 June 2012, Chris Ball wrote:
>>>>>
>>>>>
>>>>> Hi Haojian,
>>>>>
>>>>> On Fri, May 04 2012, Haojian Zhuang wrote:
>>>>>>
>>>>>>
>>>>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq,
>>>>>> timer, gpio components.
>>>>>
>>>>>
>>>>>
>>>>> The patch I'm replying to introduced a device tree for MMP2/Brownstone
>>>>> in 3.5-rc1. ?We're looking at adopting the MMP2 device tree for the
>>>>> OLPC
>>>>> XO-1.75 board, and Mitch Bradley has some corrections to the device
>>>>> tree
>>>>> format that we'd like to make, appended below.
>>>>>
>>>>> You can see all of the files Mitch mentions at:
>>>>> http://dev.laptop.org/~wmb/mmp2-devicetree/
>>>>>
>>>>> Here's my proposal for what to do next:
>>>>> ?* First, you choose one of the two forms that Mitch links to.
>>>>> ? ?(Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference
>>>>> ? ?for mmp2-flat.dtsi.)
>>>>
>>>>
>>>>
>>>> My preference would be towards mmp2.dtsi. I've recommended doing it
>>>> that way to other people, too.
>>>
>>>
>>> In most cases, I have found that exposing the full hierarchy is
>>> preferable.
>>> ?For this specific SoC, which I have been working with for quite awhile
>>> now,
>>> I haven't found any instance where exposing the AXI/APB levels buys you
>>> anything. ?The hierarchy just adds clutter.
>>>
>>> That said, I don't feel strongly about it.
>>>
>> mmp2-brownstone.dts is too complex since both apb& ?axi are imported.
>>
>> Could we only use flat structure in mmp2-brownstone.dts?
>
>
> See http://dev.laptop.org/~wmb/mmp2-devicetree/mmp2-brownstone-flat.dts
> <http://dev.laptop.org/%7Ewmb/mmp2-devicetree/mmp2-brownstone-flat.dts>
>
My meaning is mmp2-brownstone-flat.dts + mmp2.dtsi. Is it acceptable?
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
2012-06-06 5:25 ` Haojian Zhuang
@ 2012-06-06 16:22 ` Mitch Bradley
0 siblings, 0 replies; 24+ messages in thread
From: Mitch Bradley @ 2012-06-06 16:22 UTC (permalink / raw)
To: linux-arm-kernel
On 6/5/2012 7:25 PM, Haojian Zhuang wrote:
> ...
>
>>> mmp2-brownstone.dts is too complex since both apb& axi are imported.
>>>
>>> Could we only use flat structure in mmp2-brownstone.dts?
>>
>>
>> See http://dev.laptop.org/~wmb/mmp2-devicetree/mmp2-brownstone-flat.dts
>> <http://dev.laptop.org/%7Ewmb/mmp2-devicetree/mmp2-brownstone-flat.dts>
>>
>
> My meaning is mmp2-brownstone-flat.dts + mmp2.dtsi. Is it acceptable?
>
No, you must use mmp2-brownstone.dts with mmp2.dtsi . The position of
the uart , twsi, and rtc nodes must agree in both cases.
Do you have a use case where exposing the AXI and APB bus levels is helpful?
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2012-06-06 16:22 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-04 12:30 [PATCH v2 0/9] support dt for mmp2 Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 2/9] ARM: mmp: append CONFIG_MACH_MMP2_DT Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 3/9] ARM: mmp: support DT in irq Haojian Zhuang
2012-05-08 17:56 ` Grant Likely
2012-05-04 12:30 ` [PATCH v2 4/9] ARM: mmp: support DT in timer Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 5/9] gpio: pxa: parse gpio from DTS file Haojian Zhuang
2012-05-08 19:40 ` Grant Likely
2012-05-04 12:30 ` [PATCH v2 6/9] ARM: mmp: support mmp2 with device tree Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 7/9] ARM: mmp: support pxa910 " Haojian Zhuang
2012-05-04 12:30 ` [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp Haojian Zhuang
2012-06-05 0:08 ` Chris Ball
2012-06-05 2:03 ` Haojian Zhuang
2012-06-06 1:28 ` Arnd Bergmann
2012-06-06 1:47 ` Mitch Bradley
2012-06-06 2:35 ` Haojian Zhuang
2012-06-06 5:22 ` Mitch Bradley
2012-06-06 5:25 ` Haojian Zhuang
2012-06-06 16:22 ` Mitch Bradley
2012-06-06 3:05 ` Arnd Bergmann
2012-05-04 12:30 ` [PATCH v2 9/9] Documentation: update docs for mmp dt Haojian Zhuang
2012-05-04 14:27 ` [PATCH v2 0/9] support dt for mmp2 Arnd Bergmann
2012-05-17 23:57 ` Rob Herring
2012-05-18 2:15 ` 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).