* [PATCH v2 00/07] enable devicetree on arch-mmp @ 2011-07-28 6:41 Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 1/7] ARM: mmp: parse irq from DT Haojian Zhuang 0 siblings, 1 reply; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Changelog v2: * parse timer from DT * remove CONFIG_MMP_USE_OF * set NR_IRQS to 0 since sparse irq is enabled and allocated irq is started from NR_IRQS. * change property names according to comments * parse serial from DT and only use drivers/tty/serial/pxa.c. Avoid to touch drivers/tty/serial/of_serial.c ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-07-28 6:41 [PATCH v2 00/07] enable devicetree on arch-mmp Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Parse irq sepcifier from DT and translate it to Linux irq number. Remove the definition of NR_IRQS in irqs.h. Since sparse irq is enabled, nr_irqs will be calculated automatically. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- .../devicetree/bindings/arm/marvell/intc.txt | 114 ++++++++++ arch/arm/Kconfig | 1 + arch/arm/mach-mmp/Makefile | 2 + arch/arm/mach-mmp/common.h | 1 + arch/arm/mach-mmp/include/mach/irqs.h | 2 +- arch/arm/mach-mmp/intc.c | 224 ++++++++++++++++++++ 6 files changed, 343 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/marvell/intc.txt create mode 100644 arch/arm/mach-mmp/intc.c diff --git a/Documentation/devicetree/bindings/arm/marvell/intc.txt b/Documentation/devicetree/bindings/arm/marvell/intc.txt new file mode 100644 index 0000000..80cef58 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/intc.txt @@ -0,0 +1,114 @@ +* Interrupt Controller Binding for ARCH-MMP + +This binding specifies what properties must be available in device tree representation of an ARCH-MMP compliant interrupt controller. + +Required properties: + + - compatible: Specifies the compatibility list of the interrupt + controller. The type shall be <string> and the value shall be + "mrvl,pxa168-intc" or "mrvl,mmp2-mux-intc". + "mrvl,pxa168-intc" is the base interrupt controller. It must be + included. It's compatible for pxa910, mmp2. "mrvl,mmp2-mux-intc" + is the expanded interrupt controller, and it's optional. + + - reg: Specified the base physical address(s) and size(s) of the + interrupt controller's addressable register space. The type + should be <prop-encoded-array>. + + - interrupt-controller: The presence of this property identifies + the node as interrupt controller. No property value should be + defined. + + - #interrupt-cells: Specifies the number of cells needed to encode + an interrupt source. The type should be <u32> and the value should + be 1. + + - mrvl,intc-numbers: Specifies the number of interrupts is supported + in this interrupt controller. The type should be <u32>. + +Optional properties: + + - mrvl,intc-priority: Specifies the which path the interrupt is routed + and the priority of this interrupt. The property is used in + pxa168-intc. The value should be <u32>. + + - mrvl,status-offset: Specifies the offset of status register. The + property is used in mmp2-mux-intc. The type should be <u32>. + + - mrvl,mask-offset: Specifies the offset of mask register. The + property is used in mmp2-mux-intc. The type should be <u32>. + + - mrvl,mfp-edge: Specifies the address of mfp edge detection register. + The property is used while acking specified interrupt. The type + should be <prop-encoded-array>. The first cell indicates the address + of mfp edge detection register. The second cell indicates the + index of interrupt in current interrupt controller that should + handle mfp edge detection. + +* Examples + +Example 1: + + /* + * base INTC + */ + mmp_intc: interrupt-controller at d4282000 { + /* Compatible with pxa168-intc. */ + compatible = "mrvl,pxa168-intc"; + #address-cells = <1>; + #size-cells = <1>; + /* Offset address of 0xd4282000 and size of 0x400. */ + reg = <0xd4282000 0x400>; + + #interrupt-cells = <1>; + interrupt-controller; + + /* 64 interrupts are supported in this INTC. */ + mrvl,intc-numbers = <64>; + + /* priority bits in configuration register */ + mrvl,intc-priority = <0x20>; + }; + +Example 2: + + /* + * mux INTC that is internal wired to base INTC + */ + mux_intc4: interrupt-controller at d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd4282000 0x400>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&mmp_intc>; + + /* interrupt source '4' of parent INTC. */ + interrupts = <4>; + + /* 2 interrupts are supported in this INTC. */ + mrvl,intc-numbers = <2>; + + /* Status offset address of 0x150. */ + mrvl,status-offset = <0x150>; + + /* Mask offset address of 0x168. */ + mrvl,mask-offset = <0x168>; + + /* mfp register of 0xd401e2c4 & interrupt index of 1 */ + mrvl,mfp-edge = <0xd401e2c4 1>; + }; + +Example 3: + /* + * An interrupt generating device that is wired to an INTC. + */ + uart0: uart at d4030000 { + /* parent's '#interrupt-cells' property. */ + interrupts = <27>; + + /* The INTC that this device is wired to. */ + interrupt-parent = <&mmp_intc>; + }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 17507b8..f18eb14 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -542,6 +542,7 @@ config ARCH_MMP select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_CHIP select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 5c68382..e7862ea 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -4,6 +4,8 @@ obj-y += common.o clock.o devices.o time.o +obj-$(CONFIG_OF_IRQ) += intc.o + # SoC support obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h index ec8d65d..1c563c2 100644 --- a/arch/arm/mach-mmp/common.h +++ b/arch/arm/mach-mmp/common.h @@ -6,3 +6,4 @@ extern void timer_init(int irq); extern void __init icu_init_irq(void); extern void __init mmp_map_io(void); +extern void __init mmp_init_intc(void); diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index a09d328..65ec176 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -224,6 +224,6 @@ #define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) -#define NR_IRQS (IRQ_BOARD_START) +#define NR_IRQS 0 #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-mmp/intc.c b/arch/arm/mach-mmp/intc.c new file mode 100644 index 0000000..2e44057 --- /dev/null +++ b/arch/arm/mach-mmp/intc.c @@ -0,0 +1,224 @@ +/* + * linux/arch/arm/mach-mmp/intc.c + * + * Generic IRQ handling + * + * Author: Haojian Zhuang <haojian.zhuang@marvell.com> + * Copyright: Marvell International Ltd. 2011 + * + * 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/errno.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/slab.h> + +struct mmp_intc_info { + unsigned int en_mask; + void __iomem *virt_base; + void __iomem *status; + void __iomem *mfp_edge; + unsigned int mfp_edge_index; /* index in irq domain */ +}; + +static void mux_irq_ack(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct; + struct mmp_intc_info *info; + unsigned int data, irq_offs; + + ct = gc->chip_types; + info = (struct mmp_intc_info *)ct->regs.ack; + irq_offs = d->irq - gc->irq_base; + /* clear MFP edge-detect */ + if (info->mfp_edge && (info->mfp_edge_index == irq_offs)) { + data = __raw_readl(info->mfp_edge); + __raw_writel(data | (1 << 6), info->mfp_edge); + __raw_writel(data, info->mfp_edge); + } +} + +static void mmp_irq_demux_handler(unsigned int irq, struct irq_desc *desc) +{ + struct irq_chip_generic *gc = irq_get_handler_data(irq); + struct irq_chip_type *ct; + struct mmp_intc_info *info; + unsigned long status, n; + + ct = gc->chip_types; + info = (struct mmp_intc_info *)ct->regs.ack; + while (1) { + status = __raw_readl(info->status) & ~gc->mask_cache; + if (status == 0) + break; + n = find_first_bit(&status, BITS_PER_LONG); + while (n < BITS_PER_LONG) { + generic_handle_irq(gc->irq_base + n); + n = find_next_bit(&status, BITS_PER_LONG, n + 1); + } + } +} + +static void mux_init_intc(struct mmp_intc_info *mmp_info) +{ + struct device_node *np; + struct mmp_intc_info *mux_info; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + const __be32 *edge; + unsigned int addr = 0, offs = 0; + unsigned int status, mask, irq_base, nr, data; + int cascade; + + for_each_compatible_node(np, NULL, "mrvl,mmp2-mux-intc") { + if (of_get_property(np, "interrupt-controller", NULL) == NULL) + continue; + if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { + pr_warn("intc-numbers property is missed\n"); + continue; + } + if (of_property_read_u32(np, "mrvl,status-offset", &status) + < 0) { + pr_warn("intc-status property is missed\n"); + continue; + } + if (of_property_read_u32(np, "mrvl,mask-offset", &mask) < 0) { + pr_warn("intc-mask property is missed\n"); + continue; + } + + mux_info = kzalloc(sizeof(*mux_info), GFP_KERNEL); + if (mux_info == NULL) + goto out; + status += (unsigned int)mmp_info->virt_base; + mux_info->status = (void __iomem *)status; + + edge = of_get_property(np, "mrvl,mfp-edge", NULL); + if (edge) { + addr = be32_to_cpu(*edge) & PAGE_MASK; + offs = be32_to_cpu(*edge) - addr; + mux_info->mfp_edge = ioremap(addr, PAGE_SIZE) + offs; + mux_info->mfp_edge_index = be32_to_cpu(*++edge); + /* clear mfp edge detection for initialization */ + data = __raw_readl(mux_info->mfp_edge); + __raw_writel(data | (1 << 6), mux_info->mfp_edge); + __raw_writel(data, mux_info->mfp_edge); + } + + /* allocate new irq */ + cascade = irq_of_parse_and_map(np, 0); + irq_base = irq_alloc_descs(-1, 0, nr, 0); + irq_domain_add_simple(np, irq_base); + + gc = irq_alloc_generic_chip("mux-intc", 1, irq_base, + mmp_info->virt_base, handle_level_irq); + ct = gc->chip_types; + ct->regs.ack = (unsigned int)mux_info; + ct->regs.mask = mask; + ct->chip.irq_ack = mux_irq_ack; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + irq_setup_generic_chip(gc, IRQ_MSK(nr), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + + irq_set_handler_data(cascade, gc); + irq_set_chained_handler(cascade, mmp_irq_demux_handler); + } +out: + return; +} + +static void mmp_irq_unmask(struct irq_data *d) +{ + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); + + /* ICU_INT_CONF */ + __raw_writel(info->en_mask, info->virt_base + (d->irq << 2)); +} + +static void mmp_irq_mask(struct irq_data *d) +{ + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); + + __raw_writel(0, info->virt_base + (d->irq << 2)); +} + +static struct irq_chip mmp_irq_chip = { + .name = "mmp-intc", + .irq_unmask = mmp_irq_unmask, + .irq_mask = mmp_irq_mask, + .irq_ack = mmp_irq_mask, +}; + +void __init mmp_init_intc(void) +{ + struct mmp_intc_info *info; + struct device_node *np; + struct resource rs; + unsigned int cells, nr, enable, irq_base; + int i; + + np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-intc"); + + BUG_ON(!np); + + of_node_get(np); + if (of_get_property(np, "interrupt-controller", NULL) == NULL) + goto out; + if (of_property_read_u32(np, "#interrupt-cells", &cells) < 0) { + pr_warn("mmp-intc: interrupt-cells property is missed\n"); + goto out; + } + if (cells != 1) { + pr_warn("mmp-intc: interrupt-cells property is incorrect\n"); + goto out; + } + if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { + pr_warn("mmp-intc: mrvl,intc-numbers property is missed\n"); + goto out; + } + if (of_property_read_u32(np, "mrvl,intc-priority", &enable) < 0) { + pr_warn("mmp-intc: mrvl,intc-priority property is missed\n"); + goto out; + } + if (of_address_to_resource(np, 0, &rs) < 0) { + pr_warn("mmp-intc: invalid reg property\n"); + goto out; + } + + info = kzalloc(sizeof(struct mmp_intc_info), GFP_KERNEL); + if (info == NULL) + goto out; + info->en_mask = enable; + info->virt_base = ioremap(rs.start, PAGE_SIZE); + if (info->virt_base == NULL) { + pr_warn("mmp-intc: failed to remap reg base\n"); + goto out_mem; + } + + /* allocate new irq */ + irq_base = irq_alloc_descs(-1, 0, nr, 0); + irq_domain_add_simple(np, 0); + + for (i = irq_base; i < irq_base + nr; i++) { + irq_set_chip_data(i, info); + mmp_irq_mask(irq_get_irq_data(i)); + irq_set_chip_and_handler(i, &mmp_irq_chip, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + mux_init_intc(info); + of_node_put(np); + return; +out_mem: + kfree(info); +out: + of_node_put(np); + return; +} -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 2/7] ARM: mmp: parse timer configuration from DT 2011-07-28 6:41 ` [PATCH v2 1/7] ARM: mmp: parse irq from DT Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Haojian Zhuang 2011-07-29 16:40 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration from DT Grant Likely 2011-07-29 16:36 ` [PATCH v2 1/7] ARM: mmp: parse irq " Grant Likely 2011-08-01 8:26 ` Russell King - ARM Linux 2 siblings, 2 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Parse timer configuration from DT. Now we can merge pxa910_timer and mmp2_timer into mmp_timer. Since most configuration between these two timers are same. The difference is recorded in DT. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- .../devicetree/bindings/arm/marvell/timer.txt | 24 +++++++++ arch/arm/mach-mmp/common.h | 2 + arch/arm/mach-mmp/time.c | 50 +++++++++++++++++++- 3 files changed, 75 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/marvell/timer.txt diff --git a/Documentation/devicetree/bindings/arm/marvell/timer.txt b/Documentation/devicetree/bindings/arm/marvell/timer.txt new file mode 100644 index 0000000..24a6f97 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/timer.txt @@ -0,0 +1,24 @@ +* Timer Controller Binding for ARCH-MMP + +This binding specifies what properties must be available in device tree +representation of an ARCH-MMP compliant timer controller. + +Required properties: + + - compatible: Specifies the compatibility list of the timer controller. + The type shall be <string> and the value shall be + "mrvl,pxa168-timer". + + - mrvl,clk-conf: Specifies the address and value of timer + configuration register. + The type shall be <prop-encoded-array>. The first value indicates + the physical address of timer configuration register. The second + value indicates data should be written to timer configuration + register. + +* Example + + mmp_timer: { + compatible = "mrvl,pxa168-timer"; + mrvl,clk-conf = <0xd4000034 0x33>; + }; diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h index 1c563c2..890c664 100644 --- a/arch/arm/mach-mmp/common.h +++ b/arch/arm/mach-mmp/common.h @@ -2,6 +2,8 @@ struct sys_timer; +extern struct sys_timer mmp_timer; + extern void timer_init(int irq); extern void __init icu_init_irq(void); diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 99833b9..5a90b27 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -25,6 +25,8 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_irq.h> #include <linux/sched.h> #include <asm/sched_clock.h> @@ -150,7 +152,7 @@ static void __init timer_config(void) __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ - ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3); + ccr &= TMR_CCR_CS_0(0); __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); /* free-running mode */ @@ -187,3 +189,49 @@ void __init timer_init(int irq) clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); clockevents_register_device(&ckevt); } + +#ifdef CONFIG_OF +static void __init mmp_timer_init(void) +{ + struct device_node *np; + const __be32 *clk_offs; + void __iomem *conf; + unsigned int addr = 0, offs = 0; + int size, irq; + + np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-timer"); + + BUG_ON(!np); + + of_node_get(np); + irq = irq_of_parse_and_map(np, 0); + + clk_offs = of_get_property(np, "mrvl,clk-conf", &size); + if ((clk_offs == NULL) || (size != sizeof(int) * 2)) { + pr_warn("mmp-timer: mrvl,clk-conf property is wrong\n"); + goto out; + } + addr = be32_to_cpu(*clk_offs) & PAGE_MASK; + offs = be32_to_cpu(*clk_offs) - addr; + conf = ioremap(addr, PAGE_SIZE); + if (conf == NULL) { + pr_warn("mmp-timer: failed on mapping 0x%x\n", (uint32_t)conf); + goto out; + } + /* reset and configure */ + __raw_writel(APBC_APBCLK | APBC_RST, conf + offs); + __raw_writel(be32_to_cpu(*++clk_offs), conf + offs); + __raw_readl(conf + offs); + iounmap(conf); + + timer_init(irq); + return; +out: + of_node_put(np); + return; +} + +struct sys_timer mmp_timer = { + .init = mmp_timer_init, +}; +#endif -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Haojian Zhuang 2011-07-29 16:42 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Grant Likely 2011-07-29 16:40 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration from DT Grant Likely 1 sibling, 2 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Add new boards.c to support both TTC-DKB and MMP2-BROWNSTONE. If CONFIG_OF isn't selected, we continue to use original ttc_dkb.c and brownstone.c. While everything moving to DT in ARCH-MMP, ttc_dkb.c and brownstone.c will be abandoned. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- .../devicetree/bindings/arm/marvell/boards.txt | 7 + arch/arm/boot/dts/mmp2-brownstone.dts | 216 ++++++++++++++++++++ arch/arm/boot/dts/pxa910-dkb.dts | 81 ++++++++ arch/arm/mach-mmp/Makefile | 1 + arch/arm/mach-mmp/boards.c | 138 +++++++++++++ 5 files changed, 443 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/marvell/boards.txt create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts create mode 100644 arch/arm/mach-mmp/boards.c diff --git a/Documentation/devicetree/bindings/arm/marvell/boards.txt b/Documentation/devicetree/bindings/arm/marvell/boards.txt new file mode 100644 index 0000000..a031a26 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/boards.txt @@ -0,0 +1,7 @@ +TTC(pxa910) "DKB" evalutation board +Required root node properties: + - compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; + +mmp2(armada610) "Brownstone" evalutation board +Required root node properties: + - compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 0000000..2673282 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -0,0 +1,216 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell MMP2 Brownstone"; + compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mmp_intc>; + + memory { + reg = <0x00000000 0x20000000>; + }; + + chosen { + bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; + linux,stdout-path = &uart2; + }; + + soc at d4000000 { + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mmp_intc: interrupt-controller at d4282000 { + compatible = "mrvl,pxa168-intc"; + /* reg: <offset & size> */ + reg = <0xd4282000 0x400>; + + #interrupt-cells = <1>; + interrupt-controller; + mrvl,intc-numbers = <64>; + /* priority bits in conf register */ + mrvl,intc-priority = <0x20>; + }; + + mux_intc4: interrupt-controller at d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282150 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <4>; + mrvl,intc-numbers = <2>; + mrvl,status-offset = <0x150>; + mrvl,mask-offset = <0x168>; + /* mfp register & interrupt index */ + mrvl,mfp-edge = <0xd401e2c4 1>; + }; + + mux_intc5: interrupt-controller at d4282154 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282154 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <5>; + mrvl,intc-numbers = <2>; + mrvl,status-offset = <0x154>; + mrvl,mask-offset = <0x16c>; + }; + + mux_intc9: interrupt-controller at d4282180 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282180 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <9>; + mrvl,intc-numbers = <3>; + mrvl,status-offset = <0x180>; + mrvl,mask-offset = <0x17c>; + }; + + mux_intc17: interrupt-controller at d4282158 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282158 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <17>; + mrvl,intc-numbers = <5>; + mrvl,status-offset = <0x158>; + mrvl,mask-offset = <0x170>; + }; + + mux_intc35: interrupt-controller at d428215c { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd428215c 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <35>; + mrvl,intc-numbers = <15>; + mrvl,status-offset = <0x15c>; + mrvl,mask-offset = <0x174>; + }; + + mux_intc51: interrupt-controller at d4282160 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282160 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <51>; + mrvl,intc-numbers = <2>; + mrvl,status-offset = <0x160>; + mrvl,mask-offset = <0x178>; + }; + + mux_intc55: interrupt-controller at d4282188 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282188 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <55>; + mrvl,intc-numbers = <2>; + mrvl,status-offset = <0x188>; + mrvl,mask-offset = <0x184>; + }; + + mmp_timer: timer at 0 { + compatible = "mrvl,pxa168-timer"; + interrupts = <13>; + mrvl,clk-conf = <0xd4000024 0x13>; + }; + + i2c0: i2c at d4011000 { + compatible = "mrvl,pxa255-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd4011000 0x60>; + interrupts = <7>; + mrvl,i2c-frequency = "fast"; + }; + + i2c1: i2c at d4031000 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4031000 0x60>; + interrupts = <0>; + interrupt-parent = <&mux_intc17>; + mrvl,i2c-frequency = "fast"; + }; + + i2c2: i2c at d4032000 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4032000 0x60>; + interrupts = <1>; + interrupt-parent = <&mux_intc17>; + mrvl,i2c-frequency = "fast"; + }; + + i2c3: i2c at d4033000 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4033000 0x60>; + interrupts = <2>; + interrupt-parent = <&mux_intc17>; + mrvl,i2c-frequency = "fast"; + }; + + i2c4: i2c at d4033800 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4033800 0x60>; + interrupts = <3>; + interrupt-parent = <&mux_intc17>; + mrvl,i2c-frequency = "fast"; + }; + + i2c5: i2c at d4034000 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4034000 0x60>; + interrupts = <4>; + interrupt-parent = <&mux_intc17>; + mrvl,i2c-frequency = "fast"; + }; + + uart0: uart at d4030000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4030000 0x1000>; + reg-shift = <2>; + interrupts = <27>; + clock-frequency = <26000000>; + current-speed = <115200>; + }; + + uart1: uart at d4017000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4017000 0x1000>; + reg-shift = <2>; + interrupts = <28>; + clock-frequency = <26000000>; + current-speed = <115200>; + }; + + uart2: uart at d4018000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4018000 0x1000>; + reg-shift = <2>; + interrupts = <24>; + clock-frequency = <26000000>; + current-speed = <38400>; + }; + + uart3: uart at d4016000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4016000 0x1000>; + reg-shift = <2>; + interrupts = <46>; + clock-frequency = <26000000>; + current-speed = <115200>; + }; + }; +}; diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts new file mode 100644 index 0000000..b9f75b7 --- /dev/null +++ b/arch/arm/boot/dts/pxa910-dkb.dts @@ -0,0 +1,81 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell TTC DKB"; + compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mmp_intc>; + + memory { + reg = <0x00000000 0x20000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; + linux,stdout-path = &uart0; + }; + + soc at d4000000 { + compatible = "mrvl,pxa910", "simple-bus"; + device_type = "soc"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xd4000000 0xd4000000 0x00200000 /* APB */ + 0xd4200000 0xd4200000 0x00200000>; /* AXI */ + + mmp_intc: interrupt-controller at d4282000 { + compatible = "mrvl,pxa168-intc"; + /* reg: <offset & size> */ + reg = <0xd4282000 0x400>; + + #interrupt-cells = <1>; + interrupt-controller; + mrvl,intc-numbers = <64>; + /* priority bits in conf register */ + mrvl,intc-priority = <0x51>; + }; + + mmp_timer: timer at 0 { + compatible = "mrvl,pxa168-timer"; + interrupts = <13>; + mrvl,clk-conf = <0xd4000034 0x33>; + }; + + i2c0: i2c at d4011000 { + compatible = "mrvl,pxa255-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd4011000 0x60>; + interrupts = <7>; + mrvl,i2c-frequency = "fast"; + }; + + i2c1: i2c at d4037000 { + compatible = "mrvl,pxa255-i2c"; + reg = <0xd4037000 0x60>; + interrupts = <54>; + mrvl,i2c-frequency = "fast"; + }; + + uart0: uart at d4017000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4017000 0x1000>; + reg-shift = <2>; + interrupts = <27>; + clock-frequency = <14745600>; + current-speed = <115200>; + }; + + uart1: uart at d4018000 { + compatible = "mrvl,pxa270-serial"; + reg = <0xd4018000 0x1000>; + reg-shift = <2>; + interrupts = <28>; + clock-frequency = <14745600>; + current-speed = <115200>; + }; + }; +}; diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index e7862ea..bdf5b23 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o # board support +obj-$(CONFIG_OF) += boards.o obj-$(CONFIG_MACH_ASPENITE) += aspenite.o obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o diff --git a/arch/arm/mach-mmp/boards.c b/arch/arm/mach-mmp/boards.c new file mode 100644 index 0000000..13e61fb --- /dev/null +++ b/arch/arm/mach-mmp/boards.c @@ -0,0 +1,138 @@ +/* + * linux/arch/arm/mach-mmp/boards.c + * + * Support for the Multiple Marvell Development Platforms. + * + * Copyright (C) 2009-2011 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/i2c/pxa-i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa910.h> +#include <mach/mmp2.h> +#include <mach/mfp-mmp2.h> + +#include "common.h" + +static void __init ttc_dkb_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *ttc_dkb_dt_match[] __initdata = { + "mrvl,pxa910-dkb", + NULL, +}; + +DT_MACHINE_START(TTC_DKB, "PXA910-based TTC-DKB Development Platform") + .map_io = mmp_map_io, + .init_irq = mmp_init_intc, + .timer = &mmp_timer, + .init_machine = ttc_dkb_init, + .dt_compat = ttc_dkb_dt_match, +MACHINE_END + +static unsigned long brownstone_pin_config[] __initdata = { + /* UART1 */ + GPIO29_UART1_RXD, + GPIO30_UART1_TXD, + + /* UART3 */ + GPIO51_UART3_RXD, + GPIO52_UART3_TXD, + + /* DFI */ + GPIO168_DFI_D0, + GPIO167_DFI_D1, + GPIO166_DFI_D2, + GPIO165_DFI_D3, + GPIO107_DFI_D4, + GPIO106_DFI_D5, + GPIO105_DFI_D6, + GPIO104_DFI_D7, + GPIO111_DFI_D8, + GPIO164_DFI_D9, + GPIO163_DFI_D10, + GPIO162_DFI_D11, + GPIO161_DFI_D12, + GPIO110_DFI_D13, + GPIO109_DFI_D14, + GPIO108_DFI_D15, + GPIO143_ND_nCS0, + GPIO144_ND_nCS1, + GPIO147_ND_nWE, + GPIO148_ND_nRE, + GPIO150_ND_ALE, + GPIO149_ND_CLE, + GPIO112_ND_RDY0, + GPIO160_ND_RDY1, + + /* PMIC */ + PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, + + /* MMC0 */ + GPIO131_MMC1_DAT3 | MFP_PULL_HIGH, + GPIO132_MMC1_DAT2 | MFP_PULL_HIGH, + GPIO133_MMC1_DAT1 | MFP_PULL_HIGH, + GPIO134_MMC1_DAT0 | MFP_PULL_HIGH, + GPIO136_MMC1_CMD | MFP_PULL_HIGH, + GPIO139_MMC1_CLK, + GPIO140_MMC1_CD | MFP_PULL_LOW, + GPIO141_MMC1_WP | MFP_PULL_LOW, + + /* MMC1 */ + GPIO37_MMC2_DAT3 | MFP_PULL_HIGH, + GPIO38_MMC2_DAT2 | MFP_PULL_HIGH, + GPIO39_MMC2_DAT1 | MFP_PULL_HIGH, + GPIO40_MMC2_DAT0 | MFP_PULL_HIGH, + GPIO41_MMC2_CMD | MFP_PULL_HIGH, + GPIO42_MMC2_CLK, + + /* MMC2 */ + GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, + GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, + GPIO166_MMC3_DAT5 | MFP_PULL_HIGH, + GPIO163_MMC3_DAT4 | MFP_PULL_HIGH, + GPIO167_MMC3_DAT3 | MFP_PULL_HIGH, + GPIO164_MMC3_DAT2 | MFP_PULL_HIGH, + GPIO168_MMC3_DAT1 | MFP_PULL_HIGH, + GPIO111_MMC3_DAT0 | MFP_PULL_HIGH, + GPIO112_MMC3_CMD | MFP_PULL_HIGH, + GPIO151_MMC3_CLK, + + /* 5V regulator */ + GPIO89_GPIO, +}; + +static void __init brownstone_init(void) +{ + mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *brownstone_dt_match[] __initdata = { + "mrvl,mmp2-brownstone", + NULL, +}; + +DT_MACHINE_START(BROWNSTONE, "Brownstone Development Platform") + .map_io = mmp_map_io, + .init_irq = mmp_init_intc, + .timer = &mmp_timer, + .init_machine = brownstone_init, + .dt_compat = brownstone_dt_match, +MACHINE_END -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-07-28 6:41 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 5/7] tty: serial: check ops before registering console Haojian Zhuang 2011-07-29 16:45 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Grant Likely 2011-07-29 16:42 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Grant Likely 1 sibling, 2 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Support both normal platform driver and device tree driver in serial pxa. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- drivers/tty/serial/pxa.c | 51 ++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 4302e6e..dadd201 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -36,6 +36,7 @@ #include <linux/circ_buf.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/tty.h> #include <linux/tty_flip.h> @@ -54,6 +55,8 @@ struct uart_pxa_port { char *name; }; +#define PXA_SERIAL_NR 4 + static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) { offset <<= 2; @@ -593,7 +596,7 @@ serial_pxa_type(struct uart_port *port) return up->name; } -static struct uart_pxa_port *serial_pxa_ports[4]; +static struct uart_pxa_port *serial_pxa_ports[PXA_SERIAL_NR]; static struct uart_driver serial_pxa_reg; #ifdef CONFIG_SERIAL_PXA_CONSOLE @@ -765,7 +768,10 @@ static int serial_pxa_probe(struct platform_device *dev) { struct uart_pxa_port *sport; struct resource *mmres, *irqres; - int ret; + struct device_node *np = dev->dev.of_node; + char name[32]; + unsigned int clk = 0, spd = 0; + int ret, i; mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); @@ -776,11 +782,39 @@ static int serial_pxa_probe(struct platform_device *dev) if (!sport) return -ENOMEM; +#ifdef CONFIG_OF + for (i = 0; i < PXA_SERIAL_NR; i++) { + if (serial_pxa_ports[i] == NULL) + break; + } + if (i >= PXA_SERIAL_NR) { + pr_warn("can't find pxa serial port\n"); + return -ENODEV; + } + + if (of_property_read_u32(np, "clock-frequency", &clk)) { + pr_warn("no clock-frequency property set\n"); + return -ENODEV; + } + if (of_property_read_u32(np, "current-speed", &spd) == 0) + sport->port.custom_divisor = clk / (16 * spd); + + sprintf(name, "pxa2xx-uart.%d", i); + sport->clk = clk_get_sys(name, NULL); + if (IS_ERR(sport->clk)) { + ret = PTR_ERR(sport->clk); + goto err_free; + } + sport->port.uartclk = clk; +#else + i = dev->id; sport->clk = clk_get(&dev->dev, NULL); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); goto err_free; } + sport->port.uartclk = clk_get_rate(sport->clk); +#endif sport->port.type = PORT_PXA; sport->port.iotype = UPIO_MEM; @@ -788,12 +822,11 @@ static int serial_pxa_probe(struct platform_device *dev) sport->port.irq = irqres->start; sport->port.fifosize = 64; sport->port.ops = &serial_pxa_pops; - sport->port.line = dev->id; + sport->port.line = i; sport->port.dev = &dev->dev; sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - sport->port.uartclk = clk_get_rate(sport->clk); - switch (dev->id) { + switch (i) { case 0: sport->name = "FFUART"; break; case 1: sport->name = "BTUART"; break; case 2: sport->name = "STUART"; break; @@ -809,7 +842,7 @@ static int serial_pxa_probe(struct platform_device *dev) goto err_clk; } - serial_pxa_ports[dev->id] = sport; + serial_pxa_ports[i] = sport; uart_add_one_port(&serial_pxa_reg, &sport->port); platform_set_drvdata(dev, sport); @@ -836,6 +869,11 @@ static int serial_pxa_remove(struct platform_device *dev) return 0; } +static struct of_device_id __devinitdata of_serial_pxa_table[] = { + { .compatible = "mrvl,pxa270-serial", .data = (void *)PORT_PXA, }, + {}, +}; + static struct platform_driver serial_pxa_driver = { .probe = serial_pxa_probe, .remove = serial_pxa_remove, @@ -843,6 +881,7 @@ static struct platform_driver serial_pxa_driver = { .driver = { .name = "pxa2xx-uart", .owner = THIS_MODULE, + .of_match_table = of_serial_pxa_table, #ifdef CONFIG_PM .pm = &serial_pxa_pm_ops, #endif -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 5/7] tty: serial: check ops before registering console 2011-07-28 6:41 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Haojian Zhuang 2011-07-29 16:45 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Grant Likely 1 sibling, 1 reply; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Console should be only registered after port->ops assigned. If uart console doesn't match the current uart, port->ops keeps NULL. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- drivers/tty/serial/pxa.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index dadd201..3201a95 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -683,7 +683,7 @@ serial_pxa_console_setup(struct console *co, char *options) if (co->index == -1 || co->index >= serial_pxa_reg.nr) co->index = 0; up = serial_pxa_ports[co->index]; - if (!up) + if (!up || !up->port.ops) return -ENODEV; if (options) -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-28 6:41 ` [PATCH v2 5/7] tty: serial: check ops before registering console Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 7/7] i2c: pxa: support to parse property Haojian Zhuang 2011-07-29 16:52 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Grant Likely 0 siblings, 2 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel support i2c-pxa controller from DT. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- drivers/i2c/busses/i2c-pxa.c | 51 +++++++++++++++++++++++++++++++---------- 1 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index d603646..8c27733 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -29,6 +29,7 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/i2c-pxa.h> +#include <linux/of_device.h> #include <linux/of_i2c.h> #include <linux/platform_device.h> #include <linux/err.h> @@ -1044,15 +1045,31 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = { .functionality = i2c_pxa_functionality, }; +static const struct of_device_id pxa_i2c_of_match[] = { + { .compatible = "mrvl,pxa255-i2c", .data = (void *)REGS_PXA2XX, }, + { .compatible = "mrvl,pxa300-pwri2c", .data = (void *)REGS_PXA3XX, }, + {}, +}; + static int i2c_pxa_probe(struct platform_device *dev) { + struct device_node *np = dev->dev.of_node; + const struct of_device_id *match; struct pxa_i2c *i2c; - struct resource *res; struct i2c_pxa_platform_data *plat = dev->dev.platform_data; const struct platform_device_id *id = platform_get_device_id(dev); - enum pxa_i2c_types i2c_type = id->driver_data; - int ret; - int irq; + enum pxa_i2c_types i2c_type; + struct resource *res; + int irq, ret; + static int idx = 0; + + if (np) { + match = of_match_device(pxa_i2c_of_match, &dev->dev); + if (match == NULL) + return -ENODEV; + i2c_type = (int)match->data; + } else + i2c_type = id->driver_data; res = platform_get_resource(dev, IORESOURCE_MEM, 0); irq = platform_get_irq(dev, 0); @@ -1074,16 +1091,23 @@ static int i2c_pxa_probe(struct platform_device *dev) spin_lock_init(&i2c->lock); init_waitqueue_head(&i2c->wait); - /* - * If "dev->id" is negative we consider it as zero. - * The reason to do so is to avoid sysfs names that only make - * sense when there are multiple adapters. - */ - i2c->adap.nr = dev->id; - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", - i2c->adap.nr); - i2c->clk = clk_get(&dev->dev, NULL); + if (np) { + i2c->adap.nr = idx++; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + "pxa2xx-i2c.%u", i2c->adap.nr); + i2c->clk = clk_get_sys(i2c->adap.name, NULL); + } else { + /* + * If "dev->id" is negative we consider it as zero. + * The reason to do so is to avoid sysfs names that only make + * sense when there are multiple adapters. + */ + i2c->adap.nr = dev->id; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + "pxa_i2c-i2c.%u", i2c->adap.nr); + i2c->clk = clk_get(&dev->dev, NULL); + } if (IS_ERR(i2c->clk)) { ret = PTR_ERR(i2c->clk); goto eclk; @@ -1234,6 +1258,7 @@ static struct platform_driver i2c_pxa_driver = { .name = "pxa2xx-i2c", .owner = THIS_MODULE, .pm = I2C_PXA_DEV_PM_OPS, + .of_match_table = pxa_i2c_of_match, }, .id_table = i2c_pxa_id_table, }; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 7/7] i2c: pxa: support to parse property 2011-07-28 6:41 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Haojian Zhuang @ 2011-07-28 6:41 ` Haojian Zhuang 2011-07-29 16:52 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Grant Likely 1 sibling, 0 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-07-28 6:41 UTC (permalink / raw) To: linux-arm-kernel Support to parse some optional properties. These three properties are mrvl,use-polling, mrvl,i2c-frequency, mrvl,i2c-class. After supporting these property, i2c-pxa driver can avoid to use platform data except for slave mode. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> --- .../devicetree/bindings/i2c/pxa255-i2c.txt | 38 ++++++++++++++++++++ drivers/i2c/busses/i2c-pxa.c | 20 +++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/i2c/pxa255-i2c.txt diff --git a/Documentation/devicetree/bindings/i2c/pxa255-i2c.txt b/Documentation/devicetree/bindings/i2c/pxa255-i2c.txt new file mode 100644 index 0000000..4b5afae --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/pxa255-i2c.txt @@ -0,0 +1,38 @@ +PXA255 I2C + +The I2C-Controller is first used in PXA255. It's widely used in Intel/Marvell +silicons. + +Optional Property: + - mrvl,use-polling: Specifies whether I2C-Controller is used in polling + mode or interrupt mode. The type of property should be <empty>. + + - mrvl,i2c-frequency: Specifies the frequency that the I2C-Controller + is working. It indicates I2C-Controller running in standard(100Kb/s) + or fast(400Kb/s) speed. + The type of property should be <string>. The value should be "fast". + + - mrvl,i2c-class: Specifies the adaptor class of I2C-Controller, such as + hwmon or ddc bus. The type of property should be <u32>. + +Example: + i2c0: i2c at d4011000 { + compatible = "pxa2xx-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd4011000 0x60>; + /* I2C-Controller works in polling mode. */ + mrvl,use-polling; + /* I2C-Controller's frequency is FAST. */ + mrvl,i2c-frequency = "fast"; + /* interrupt of I2C-Controller */ + interrupts = <7>; + interrupt-parent = <&mmp_intc>; + + pm860x: pmic at 34 { + interrupt-controller; + /* interrupt of pm860x */ + interrupts = <4>; + interrupt-parent = <&mmp_intc>; + }; + }; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 8c27733..cebcd26 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1061,6 +1061,7 @@ static int i2c_pxa_probe(struct platform_device *dev) enum pxa_i2c_types i2c_type; struct resource *res; int irq, ret; + char *p = NULL; static int idx = 0; if (np) { @@ -1093,11 +1094,24 @@ static int i2c_pxa_probe(struct platform_device *dev) if (np) { + if (of_get_property(np, "mrvl,use-polling", NULL)) + i2c->use_pio = 1; + of_property_read_string(np, "mrvl,i2c-frequency", &p); + if (p && !strncmp(p, "fast", 4)) + i2c->fast_mode = 1; + of_property_read_u32(np, "mrvl,i2c-class", &i2c->adap.class); + i2c->adap.nr = idx++; snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa2xx-i2c.%u", i2c->adap.nr); i2c->clk = clk_get_sys(i2c->adap.name, NULL); } else { + if (plat) { + i2c->adap.class = plat->class; + i2c->use_pio = plat->use_pio; + i2c->fast_mode = plat->fast_mode; + } + /* * If "dev->id" is negative we consider it as zero. * The reason to do so is to avoid sysfs names that only make @@ -1142,12 +1156,6 @@ static int i2c_pxa_probe(struct platform_device *dev) clk_enable(i2c->clk); - if (plat) { - i2c->adap.class = plat->class; - i2c->use_pio = plat->use_pio; - i2c->fast_mode = plat->fast_mode; - } - if (i2c->use_pio) { i2c->adap.algo = &i2c_pxa_pio_algorithm; } else { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-28 6:41 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 7/7] i2c: pxa: support to parse property Haojian Zhuang @ 2011-07-29 16:52 ` Grant Likely 2011-07-29 16:55 ` Russell King - ARM Linux 1 sibling, 1 reply; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:52 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:32PM +0800, Haojian Zhuang wrote: > support i2c-pxa controller from DT. > > Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> > --- > drivers/i2c/busses/i2c-pxa.c | 51 +++++++++++++++++++++++++++++++---------- > 1 files changed, 38 insertions(+), 13 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c > index d603646..8c27733 100644 > --- a/drivers/i2c/busses/i2c-pxa.c > +++ b/drivers/i2c/busses/i2c-pxa.c > @@ -29,6 +29,7 @@ > #include <linux/errno.h> > #include <linux/interrupt.h> > #include <linux/i2c-pxa.h> > +#include <linux/of_device.h> > #include <linux/of_i2c.h> > #include <linux/platform_device.h> > #include <linux/err.h> > @@ -1044,15 +1045,31 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = { > .functionality = i2c_pxa_functionality, > }; > > +static const struct of_device_id pxa_i2c_of_match[] = { > + { .compatible = "mrvl,pxa255-i2c", .data = (void *)REGS_PXA2XX, }, > + { .compatible = "mrvl,pxa300-pwri2c", .data = (void *)REGS_PXA3XX, }, > + {}, > +}; > + > static int i2c_pxa_probe(struct platform_device *dev) > { > + struct device_node *np = dev->dev.of_node; > + const struct of_device_id *match; > struct pxa_i2c *i2c; > - struct resource *res; > struct i2c_pxa_platform_data *plat = dev->dev.platform_data; > const struct platform_device_id *id = platform_get_device_id(dev); > - enum pxa_i2c_types i2c_type = id->driver_data; > - int ret; > - int irq; > + enum pxa_i2c_types i2c_type; > + struct resource *res; > + int irq, ret; > + static int idx = 0; > + > + if (np) { > + match = of_match_device(pxa_i2c_of_match, &dev->dev); > + if (match == NULL) > + return -ENODEV; > + i2c_type = (int)match->data; > + } else > + i2c_type = id->driver_data; > > res = platform_get_resource(dev, IORESOURCE_MEM, 0); > irq = platform_get_irq(dev, 0); > @@ -1074,16 +1091,23 @@ static int i2c_pxa_probe(struct platform_device *dev) > spin_lock_init(&i2c->lock); > init_waitqueue_head(&i2c->wait); > > - /* > - * If "dev->id" is negative we consider it as zero. > - * The reason to do so is to avoid sysfs names that only make > - * sense when there are multiple adapters. > - */ > - i2c->adap.nr = dev->id; > - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", > - i2c->adap.nr); > > - i2c->clk = clk_get(&dev->dev, NULL); > + if (np) { > + i2c->adap.nr = idx++; Use this so that a bus number gets dynamically assigned: i2c->adap.nr = -1; > + snprintf(i2c->adap.name, sizeof(i2c->adap.name), > + "pxa2xx-i2c.%u", i2c->adap.nr); > + i2c->clk = clk_get_sys(i2c->adap.name, NULL); Missing i2c->adap.dev.of_node = dev->dev.of_node; and after the bus is registered: of_i2c_register_devices(&i2c->adap); > + } else { > + /* > + * If "dev->id" is negative we consider it as zero. > + * The reason to do so is to avoid sysfs names that only make > + * sense when there are multiple adapters. > + */ > + i2c->adap.nr = dev->id; > + snprintf(i2c->adap.name, sizeof(i2c->adap.name), > + "pxa_i2c-i2c.%u", i2c->adap.nr); > + i2c->clk = clk_get(&dev->dev, NULL); > + } > if (IS_ERR(i2c->clk)) { > ret = PTR_ERR(i2c->clk); > goto eclk; > @@ -1234,6 +1258,7 @@ static struct platform_driver i2c_pxa_driver = { > .name = "pxa2xx-i2c", > .owner = THIS_MODULE, > .pm = I2C_PXA_DEV_PM_OPS, > + .of_match_table = pxa_i2c_of_match, > }, > .id_table = i2c_pxa_id_table, > }; > -- > 1.5.6.5 > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-29 16:52 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Grant Likely @ 2011-07-29 16:55 ` Russell King - ARM Linux 2011-07-30 14:29 ` Mitch Bradley 0 siblings, 1 reply; 27+ messages in thread From: Russell King - ARM Linux @ 2011-07-29 16:55 UTC (permalink / raw) To: linux-arm-kernel On Fri, Jul 29, 2011 at 10:52:22AM -0600, Grant Likely wrote: > On Thu, Jul 28, 2011 at 02:41:32PM +0800, Haojian Zhuang wrote: > > - /* > > - * If "dev->id" is negative we consider it as zero. > > - * The reason to do so is to avoid sysfs names that only make > > - * sense when there are multiple adapters. > > - */ > > - i2c->adap.nr = dev->id; > > - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", > > - i2c->adap.nr); > > > > - i2c->clk = clk_get(&dev->dev, NULL); > > + if (np) { > > + i2c->adap.nr = idx++; > > Use this so that a bus number gets dynamically assigned: > i2c->adap.nr = -1; > > > + snprintf(i2c->adap.name, sizeof(i2c->adap.name), > > + "pxa2xx-i2c.%u", i2c->adap.nr); > > + i2c->clk = clk_get_sys(i2c->adap.name, NULL); > > Missing i2c->adap.dev.of_node = dev->dev.of_node; And here we go again. Is it really the case that this DT stuff doesn't have stable device names? ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-29 16:55 ` Russell King - ARM Linux @ 2011-07-30 14:29 ` Mitch Bradley 2011-07-30 15:37 ` Russell King - ARM Linux 0 siblings, 1 reply; 27+ messages in thread From: Mitch Bradley @ 2011-07-30 14:29 UTC (permalink / raw) To: linux-arm-kernel On 7/29/2011 6:55 AM, Russell King - ARM Linux wrote: > On Fri, Jul 29, 2011 at 10:52:22AM -0600, Grant Likely wrote: >> On Thu, Jul 28, 2011 at 02:41:32PM +0800, Haojian Zhuang wrote: >>> - /* >>> - * If "dev->id" is negative we consider it as zero. >>> - * The reason to do so is to avoid sysfs names that only make >>> - * sense when there are multiple adapters. >>> - */ >>> - i2c->adap.nr = dev->id; >>> - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", >>> - i2c->adap.nr); >>> >>> - i2c->clk = clk_get(&dev->dev, NULL); >>> + if (np) { >>> + i2c->adap.nr = idx++; >> >> Use this so that a bus number gets dynamically assigned: >> i2c->adap.nr = -1; >> >>> + snprintf(i2c->adap.name, sizeof(i2c->adap.name), >>> + "pxa2xx-i2c.%u", i2c->adap.nr); >>> + i2c->clk = clk_get_sys(i2c->adap.name, NULL); >> >> Missing i2c->adap.dev.of_node = dev->dev.of_node; > > And here we go again. Is it really the case that this DT stuff doesn't > have stable device names? Device tree names are completely stable, based on hardware addresses that don't change from boot to boot. Even for buses where access addresses are dynamically assigned, the device tree "reg property" address is based on a stable addressing form. For example, PCI devices use the (stable) configuration address as the reg property and USB devices use the (stable) hub port number. People's tendency to want to assign sequential small integers in Linux has nothing to do with the device tree. I suspect that it's a carryover from the historical Unix major/minor device numbering model, but in any case, there's nothing unstable about the device tree naming model. Quite the opposite - stable naming was a fundamental criterion when I designed Open Firmware. > _______________________________________________ > devicetree-discuss mailing list > devicetree-discuss at lists.ozlabs.org > https://lists.ozlabs.org/listinfo/devicetree-discuss > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-30 14:29 ` Mitch Bradley @ 2011-07-30 15:37 ` Russell King - ARM Linux 2011-07-31 0:38 ` Grant Likely 0 siblings, 1 reply; 27+ messages in thread From: Russell King - ARM Linux @ 2011-07-30 15:37 UTC (permalink / raw) To: linux-arm-kernel On Sat, Jul 30, 2011 at 04:29:50AM -1000, Mitch Bradley wrote: > On 7/29/2011 6:55 AM, Russell King - ARM Linux wrote: >> On Fri, Jul 29, 2011 at 10:52:22AM -0600, Grant Likely wrote: >>> On Thu, Jul 28, 2011 at 02:41:32PM +0800, Haojian Zhuang wrote: >>>> - /* >>>> - * If "dev->id" is negative we consider it as zero. >>>> - * The reason to do so is to avoid sysfs names that only make >>>> - * sense when there are multiple adapters. >>>> - */ >>>> - i2c->adap.nr = dev->id; >>>> - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", >>>> - i2c->adap.nr); >>>> >>>> - i2c->clk = clk_get(&dev->dev, NULL); >>>> + if (np) { >>>> + i2c->adap.nr = idx++; >>> >>> Use this so that a bus number gets dynamically assigned: >>> i2c->adap.nr = -1; >>> >>>> + snprintf(i2c->adap.name, sizeof(i2c->adap.name), >>>> + "pxa2xx-i2c.%u", i2c->adap.nr); >>>> + i2c->clk = clk_get_sys(i2c->adap.name, NULL); >>> >>> Missing i2c->adap.dev.of_node = dev->dev.of_node; >> >> And here we go again. Is it really the case that this DT stuff doesn't >> have stable device names? > > Device tree names are completely stable, based on hardware addresses > that don't change from boot to boot. Even for buses where access > addresses are dynamically assigned, the device tree "reg property" > address is based on a stable addressing form. For example, PCI devices > use the (stable) configuration address as the reg property and USB > devices use the (stable) hub port number. > > People's tendency to want to assign sequential small integers in Linux > has nothing to do with the device tree. I suspect that it's a carryover > from the historical Unix major/minor device numbering model, but in any > case, there's nothing unstable about the device tree naming model. Quite > the opposite - stable naming was a fundamental criterion when I designed > Open Firmware. Which means - if Grant is accepting the conversion of ARM to DT and upstreaming it, he needs to keep an eye on this madness and reject stuff which tries to do as per this patch. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 6/7] i2c: pxa: support i2c controller from DT 2011-07-30 15:37 ` Russell King - ARM Linux @ 2011-07-31 0:38 ` Grant Likely 0 siblings, 0 replies; 27+ messages in thread From: Grant Likely @ 2011-07-31 0:38 UTC (permalink / raw) To: linux-arm-kernel On Sat, Jul 30, 2011 at 04:37:28PM +0100, Russell King - ARM Linux wrote: > On Sat, Jul 30, 2011 at 04:29:50AM -1000, Mitch Bradley wrote: > > On 7/29/2011 6:55 AM, Russell King - ARM Linux wrote: > >> On Fri, Jul 29, 2011 at 10:52:22AM -0600, Grant Likely wrote: > >>> On Thu, Jul 28, 2011 at 02:41:32PM +0800, Haojian Zhuang wrote: > >>>> - /* > >>>> - * If "dev->id" is negative we consider it as zero. > >>>> - * The reason to do so is to avoid sysfs names that only make > >>>> - * sense when there are multiple adapters. > >>>> - */ > >>>> - i2c->adap.nr = dev->id; > >>>> - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", > >>>> - i2c->adap.nr); > >>>> > >>>> - i2c->clk = clk_get(&dev->dev, NULL); > >>>> + if (np) { > >>>> + i2c->adap.nr = idx++; > >>> > >>> Use this so that a bus number gets dynamically assigned: > >>> i2c->adap.nr = -1; > >>> > >>>> + snprintf(i2c->adap.name, sizeof(i2c->adap.name), > >>>> + "pxa2xx-i2c.%u", i2c->adap.nr); > >>>> + i2c->clk = clk_get_sys(i2c->adap.name, NULL); > >>> > >>> Missing i2c->adap.dev.of_node = dev->dev.of_node; > >> > >> And here we go again. Is it really the case that this DT stuff doesn't > >> have stable device names? The "full_name" is indeed stable for a device_node, so that isn't actually the problem, but the full_name is the entire path from the root of the tree to the device. The problem is that it is far too long for to be used as (struct device*)->kobj.name, and it has '/' characters in it which aren't particularly friendly. The short node name is unique among its siblings, but not globally. Currently the kernel constructs a 'short' name when creating a device with a heuristic that tries to use the physical address of the device and the node name. If that isn't available (ie. non-memory mapped devices), then it uses a globally incremented integer to assign each device a unique name so that sysfs doesn't freak out. See of_device_make_bus_id() in drivers/of/platform.c The /real/ problem is that I don't much like the heuristic; but I haven't been able to think of anything better. There is enough uncertainty (very tiny, but uncertainty never the less) on device names, and the fact that I'm hoping to improve the method of creating device names, that I don't want to rely on them for matching up resources. Instead, the dev_resdata array that is passed into of_platform_populate() has a field to override the heuristic generated name which neatly solves the problem entirely without tracking down all the references that need to be added, and has the added advantage of DT and non-DT platforms using the same names. The clk_get() changes in this patch are absolutely the wrong solution. > > Device tree names are completely stable, based on hardware addresses > > that don't change from boot to boot. Even for buses where access > > addresses are dynamically assigned, the device tree "reg property" > > address is based on a stable addressing form. For example, PCI devices > > use the (stable) configuration address as the reg property and USB > > devices use the (stable) hub port number. > > > > People's tendency to want to assign sequential small integers in Linux > > has nothing to do with the device tree. I suspect that it's a carryover > > from the historical Unix major/minor device numbering model, but in any > > case, there's nothing unstable about the device tree naming model. Quite > > the opposite - stable naming was a fundamental criterion when I designed > > Open Firmware. > > Which means - if Grant is accepting the conversion of ARM to DT and > upstreaming it, he needs to keep an eye on this madness and reject > stuff which tries to do as per this patch. Correct, I will nack/reject any patches messing about with clock attachment or similar changes. I was distracted by the other issues, so I didn't comment on it in this patch. g. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-07-28 6:41 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 5/7] tty: serial: check ops before registering console Haojian Zhuang @ 2011-07-29 16:45 ` Grant Likely 2011-07-29 16:49 ` Russell King - ARM Linux 1 sibling, 1 reply; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:45 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:30PM +0800, Haojian Zhuang wrote: > Support both normal platform driver and device tree driver in serial pxa. > > Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> > --- > drivers/tty/serial/pxa.c | 51 ++++++++++++++++++++++++++++++++++++++++----- > 1 files changed, 45 insertions(+), 6 deletions(-) > > diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c > index 4302e6e..dadd201 100644 > --- a/drivers/tty/serial/pxa.c > +++ b/drivers/tty/serial/pxa.c > @@ -36,6 +36,7 @@ > #include <linux/circ_buf.h> > #include <linux/delay.h> > #include <linux/interrupt.h> > +#include <linux/of.h> > #include <linux/platform_device.h> > #include <linux/tty.h> > #include <linux/tty_flip.h> > @@ -54,6 +55,8 @@ struct uart_pxa_port { > char *name; > }; > > +#define PXA_SERIAL_NR 4 > + > static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) > { > offset <<= 2; > @@ -593,7 +596,7 @@ serial_pxa_type(struct uart_port *port) > return up->name; > } > > -static struct uart_pxa_port *serial_pxa_ports[4]; > +static struct uart_pxa_port *serial_pxa_ports[PXA_SERIAL_NR]; > static struct uart_driver serial_pxa_reg; > > #ifdef CONFIG_SERIAL_PXA_CONSOLE > @@ -765,7 +768,10 @@ static int serial_pxa_probe(struct platform_device *dev) > { > struct uart_pxa_port *sport; > struct resource *mmres, *irqres; > - int ret; > + struct device_node *np = dev->dev.of_node; > + char name[32]; > + unsigned int clk = 0, spd = 0; > + int ret, i; > > mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); > irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); > @@ -776,11 +782,39 @@ static int serial_pxa_probe(struct platform_device *dev) > if (!sport) > return -ENOMEM; > > +#ifdef CONFIG_OF > + for (i = 0; i < PXA_SERIAL_NR; i++) { > + if (serial_pxa_ports[i] == NULL) > + break; > + } > + if (i >= PXA_SERIAL_NR) { > + pr_warn("can't find pxa serial port\n"); > + return -ENODEV; > + } > + > + if (of_property_read_u32(np, "clock-frequency", &clk)) { > + pr_warn("no clock-frequency property set\n"); > + return -ENODEV; > + } > + if (of_property_read_u32(np, "current-speed", &spd) == 0) > + sport->port.custom_divisor = clk / (16 * spd); > + > + sprintf(name, "pxa2xx-uart.%d", i); > + sport->clk = clk_get_sys(name, NULL); > + if (IS_ERR(sport->clk)) { > + ret = PTR_ERR(sport->clk); > + goto err_free; > + } > + sport->port.uartclk = clk; > +#else > + i = dev->id; > sport->clk = clk_get(&dev->dev, NULL); > if (IS_ERR(sport->clk)) { > ret = PTR_ERR(sport->clk); > goto err_free; > } > + sport->port.uartclk = clk_get_rate(sport->clk); > +#endif This means a kernel build can either support DT or non-DT, but not both. DT & non-DT booting are full supported with the same kernel image, so don't do it this way. Instead, check for the presence of an of_node. If it is there, do the DT parsing. If now, still support the old method. > > sport->port.type = PORT_PXA; > sport->port.iotype = UPIO_MEM; > @@ -788,12 +822,11 @@ static int serial_pxa_probe(struct platform_device *dev) > sport->port.irq = irqres->start; > sport->port.fifosize = 64; > sport->port.ops = &serial_pxa_pops; > - sport->port.line = dev->id; > + sport->port.line = i; > sport->port.dev = &dev->dev; > sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; > - sport->port.uartclk = clk_get_rate(sport->clk); > > - switch (dev->id) { > + switch (i) { > case 0: sport->name = "FFUART"; break; > case 1: sport->name = "BTUART"; break; > case 2: sport->name = "STUART"; break; > @@ -809,7 +842,7 @@ static int serial_pxa_probe(struct platform_device *dev) > goto err_clk; > } > > - serial_pxa_ports[dev->id] = sport; > + serial_pxa_ports[i] = sport; > > uart_add_one_port(&serial_pxa_reg, &sport->port); > platform_set_drvdata(dev, sport); > @@ -836,6 +869,11 @@ static int serial_pxa_remove(struct platform_device *dev) > return 0; > } > > +static struct of_device_id __devinitdata of_serial_pxa_table[] = { > + { .compatible = "mrvl,pxa270-serial", .data = (void *)PORT_PXA, }, > + {}, > +}; > + > static struct platform_driver serial_pxa_driver = { > .probe = serial_pxa_probe, > .remove = serial_pxa_remove, > @@ -843,6 +881,7 @@ static struct platform_driver serial_pxa_driver = { > .driver = { > .name = "pxa2xx-uart", > .owner = THIS_MODULE, > + .of_match_table = of_serial_pxa_table, > #ifdef CONFIG_PM > .pm = &serial_pxa_pm_ops, > #endif > -- > 1.5.6.5 > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-07-29 16:45 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Grant Likely @ 2011-07-29 16:49 ` Russell King - ARM Linux 2011-07-29 16:53 ` Grant Likely 2011-08-01 2:50 ` Haojian Zhuang 0 siblings, 2 replies; 27+ messages in thread From: Russell King - ARM Linux @ 2011-07-29 16:49 UTC (permalink / raw) To: linux-arm-kernel On Fri, Jul 29, 2011 at 10:45:39AM -0600, Grant Likely wrote: > On Thu, Jul 28, 2011 at 02:41:30PM +0800, Haojian Zhuang wrote: > > +#ifdef CONFIG_OF > > + for (i = 0; i < PXA_SERIAL_NR; i++) { > > + if (serial_pxa_ports[i] == NULL) > > + break; > > + } > > + if (i >= PXA_SERIAL_NR) { > > + pr_warn("can't find pxa serial port\n"); > > + return -ENODEV; > > + } > > + > > + if (of_property_read_u32(np, "clock-frequency", &clk)) { > > + pr_warn("no clock-frequency property set\n"); > > + return -ENODEV; > > + } > > + if (of_property_read_u32(np, "current-speed", &spd) == 0) > > + sport->port.custom_divisor = clk / (16 * spd); > > + > > + sprintf(name, "pxa2xx-uart.%d", i); > > + sport->clk = clk_get_sys(name, NULL); > > + if (IS_ERR(sport->clk)) { > > + ret = PTR_ERR(sport->clk); > > + goto err_free; > > + } > > + sport->port.uartclk = clk; > > +#else > > + i = dev->id; > > sport->clk = clk_get(&dev->dev, NULL); > > if (IS_ERR(sport->clk)) { > > ret = PTR_ERR(sport->clk); > > goto err_free; > > } > > + sport->port.uartclk = clk_get_rate(sport->clk); > > +#endif > > This means a kernel build can either support DT or non-DT, but not > both. DT & non-DT booting are full supported with the same kernel > image, so don't do it this way. > > Instead, check for the presence of an of_node. If it is there, do the > DT parsing. If now, still support the old method. Oh ffs, why is this DT stuff causing all the clk stuff to have to change. And specifically why is stuff converting to use clk_get_sys(). clk_get_sys() is there to allow system devices to get their clocks. It's not for general drivers to use. Please, stop this madness. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-07-29 16:49 ` Russell King - ARM Linux @ 2011-07-29 16:53 ` Grant Likely 2011-08-01 2:50 ` Haojian Zhuang 1 sibling, 0 replies; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:53 UTC (permalink / raw) To: linux-arm-kernel On Fri, Jul 29, 2011 at 05:49:22PM +0100, Russell King - ARM Linux wrote: > On Fri, Jul 29, 2011 at 10:45:39AM -0600, Grant Likely wrote: > > On Thu, Jul 28, 2011 at 02:41:30PM +0800, Haojian Zhuang wrote: > > > +#ifdef CONFIG_OF > > > + for (i = 0; i < PXA_SERIAL_NR; i++) { > > > + if (serial_pxa_ports[i] == NULL) > > > + break; > > > + } > > > + if (i >= PXA_SERIAL_NR) { > > > + pr_warn("can't find pxa serial port\n"); > > > + return -ENODEV; > > > + } > > > + > > > + if (of_property_read_u32(np, "clock-frequency", &clk)) { > > > + pr_warn("no clock-frequency property set\n"); > > > + return -ENODEV; > > > + } > > > + if (of_property_read_u32(np, "current-speed", &spd) == 0) > > > + sport->port.custom_divisor = clk / (16 * spd); > > > + > > > + sprintf(name, "pxa2xx-uart.%d", i); > > > + sport->clk = clk_get_sys(name, NULL); > > > + if (IS_ERR(sport->clk)) { > > > + ret = PTR_ERR(sport->clk); > > > + goto err_free; > > > + } > > > + sport->port.uartclk = clk; > > > +#else > > > + i = dev->id; > > > sport->clk = clk_get(&dev->dev, NULL); > > > if (IS_ERR(sport->clk)) { > > > ret = PTR_ERR(sport->clk); > > > goto err_free; > > > } > > > + sport->port.uartclk = clk_get_rate(sport->clk); > > > +#endif > > > > This means a kernel build can either support DT or non-DT, but not > > both. DT & non-DT booting are full supported with the same kernel > > image, so don't do it this way. > > > > Instead, check for the presence of an of_node. If it is there, do the > > DT parsing. If now, still support the old method. > > Oh ffs, why is this DT stuff causing all the clk stuff to have to change. > And specifically why is stuff converting to use clk_get_sys(). > > clk_get_sys() is there to allow system devices to get their clocks. > It's not for general drivers to use. > > Please, stop this madness. indeed. g. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-07-29 16:49 ` Russell King - ARM Linux 2011-07-29 16:53 ` Grant Likely @ 2011-08-01 2:50 ` Haojian Zhuang 2011-08-01 8:27 ` Russell King - ARM Linux 1 sibling, 1 reply; 27+ messages in thread From: Haojian Zhuang @ 2011-08-01 2:50 UTC (permalink / raw) To: linux-arm-kernel On Sat, Jul 30, 2011 at 12:49 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Fri, Jul 29, 2011 at 10:45:39AM -0600, Grant Likely wrote: >> On Thu, Jul 28, 2011 at 02:41:30PM +0800, Haojian Zhuang wrote: >> > +#ifdef CONFIG_OF >> > + ? for (i = 0; i < PXA_SERIAL_NR; i++) { >> > + ? ? ? ? ? if (serial_pxa_ports[i] == NULL) >> > + ? ? ? ? ? ? ? ? ? break; >> > + ? } >> > + ? if (i >= PXA_SERIAL_NR) { >> > + ? ? ? ? ? pr_warn("can't find pxa serial port\n"); >> > + ? ? ? ? ? return -ENODEV; >> > + ? } >> > + >> > + ? if (of_property_read_u32(np, "clock-frequency", &clk)) { >> > + ? ? ? ? ? pr_warn("no clock-frequency property set\n"); >> > + ? ? ? ? ? return -ENODEV; >> > + ? } >> > + ? if (of_property_read_u32(np, "current-speed", &spd) == 0) >> > + ? ? ? ? ? sport->port.custom_divisor = clk / (16 * spd); >> > + >> > + ? sprintf(name, "pxa2xx-uart.%d", i); >> > + ? sport->clk = clk_get_sys(name, NULL); >> > + ? if (IS_ERR(sport->clk)) { >> > + ? ? ? ? ? ret = PTR_ERR(sport->clk); >> > + ? ? ? ? ? goto err_free; >> > + ? } >> > + ? sport->port.uartclk = clk; >> > +#else >> > + ? i = dev->id; >> > ? ? sport->clk = clk_get(&dev->dev, NULL); >> > ? ? if (IS_ERR(sport->clk)) { >> > ? ? ? ? ? ? ret = PTR_ERR(sport->clk); >> > ? ? ? ? ? ? goto err_free; >> > ? ? } >> > + ? sport->port.uartclk = clk_get_rate(sport->clk); >> > +#endif >> >> This means a kernel build can either support DT or non-DT, but not >> both. ?DT & non-DT booting are full supported with the same kernel >> image, so don't do it this way. >> >> Instead, check for the presence of an of_node. ?If it is there, do the >> DT parsing. ?If now, still support the old method. > > Oh ffs, why is this DT stuff causing all the clk stuff to have to change. > And specifically why is stuff converting to use clk_get_sys(). > > clk_get_sys() is there to allow system devices to get their clocks. > It's not for general drivers to use. > > Please, stop this madness. > So how could I get these clocks? Thanks Haojian ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 4/7] tty: serial: support device tree in pxa 2011-08-01 2:50 ` Haojian Zhuang @ 2011-08-01 8:27 ` Russell King - ARM Linux 0 siblings, 0 replies; 27+ messages in thread From: Russell King - ARM Linux @ 2011-08-01 8:27 UTC (permalink / raw) To: linux-arm-kernel On Mon, Aug 01, 2011 at 10:50:47AM +0800, Haojian Zhuang wrote: > On Sat, Jul 30, 2011 at 12:49 AM, Russell King - ARM Linux > <linux@arm.linux.org.uk> wrote: > > Oh ffs, why is this DT stuff causing all the clk stuff to have to change. > > And specifically why is stuff converting to use clk_get_sys(). > > > > clk_get_sys() is there to allow system devices to get their clocks. > > It's not for general drivers to use. > > > > Please, stop this madness. > > > > So how could I get these clocks? Add the new _stable_ DT device name to the clkdev list. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone 2011-07-28 6:41 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Haojian Zhuang @ 2011-07-29 16:42 ` Grant Likely 2011-08-01 2:48 ` Haojian Zhuang 1 sibling, 1 reply; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:42 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:29PM +0800, Haojian Zhuang wrote: > Add new boards.c to support both TTC-DKB and MMP2-BROWNSTONE. If CONFIG_OF > isn't selected, we continue to use original ttc_dkb.c and brownstone.c. > > While everything moving to DT in ARCH-MMP, ttc_dkb.c and brownstone.c > will be abandoned. > > Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> > --- > .../devicetree/bindings/arm/marvell/boards.txt | 7 + > arch/arm/boot/dts/mmp2-brownstone.dts | 216 ++++++++++++++++++++ > arch/arm/boot/dts/pxa910-dkb.dts | 81 ++++++++ > arch/arm/mach-mmp/Makefile | 1 + > arch/arm/mach-mmp/boards.c | 138 +++++++++++++ > 5 files changed, 443 insertions(+), 0 deletions(-) > create mode 100644 Documentation/devicetree/bindings/arm/marvell/boards.txt > create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts > create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts > create mode 100644 arch/arm/mach-mmp/boards.c > > diff --git a/Documentation/devicetree/bindings/arm/marvell/boards.txt b/Documentation/devicetree/bindings/arm/marvell/boards.txt > new file mode 100644 > index 0000000..a031a26 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/marvell/boards.txt > @@ -0,0 +1,7 @@ > +TTC(pxa910) "DKB" evalutation board > +Required root node properties: > + - compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; > + > +mmp2(armada610) "Brownstone" evalutation board > +Required root node properties: > + - compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; > diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts > new file mode 100644 > index 0000000..2673282 > --- /dev/null > +++ b/arch/arm/boot/dts/mmp2-brownstone.dts > @@ -0,0 +1,216 @@ > +/dts-v1/; > + > +/include/ "skeleton.dtsi" > + > +/ { > + model = "Marvell MMP2 Brownstone"; > + compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; > + #address-cells = <1>; > + #size-cells = <1>; > + interrupt-parent = <&mmp_intc>; > + > + memory { > + reg = <0x00000000 0x20000000>; > + }; > + > + chosen { > + bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; > + linux,stdout-path = &uart2; > + }; > + > + soc at d4000000 { > + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; > + #address-cells = <1>; > + #size-cells = <1>; > + ranges; > + > + mmp_intc: interrupt-controller at d4282000 { > + compatible = "mrvl,pxa168-intc"; > + /* reg: <offset & size> */ > + reg = <0xd4282000 0x400>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + mrvl,intc-numbers = <64>; > + /* priority bits in conf register */ > + mrvl,intc-priority = <0x20>; > + }; > + > + mux_intc4: interrupt-controller at d4282150 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282150 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <4>; > + mrvl,intc-numbers = <2>; > + mrvl,status-offset = <0x150>; > + mrvl,mask-offset = <0x168>; > + /* mfp register & interrupt index */ > + mrvl,mfp-edge = <0xd401e2c4 1>; > + }; > + > + mux_intc5: interrupt-controller at d4282154 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282154 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <5>; > + mrvl,intc-numbers = <2>; > + mrvl,status-offset = <0x154>; > + mrvl,mask-offset = <0x16c>; > + }; > + > + mux_intc9: interrupt-controller at d4282180 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282180 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <9>; > + mrvl,intc-numbers = <3>; > + mrvl,status-offset = <0x180>; > + mrvl,mask-offset = <0x17c>; > + }; > + > + mux_intc17: interrupt-controller at d4282158 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282158 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <17>; > + mrvl,intc-numbers = <5>; > + mrvl,status-offset = <0x158>; > + mrvl,mask-offset = <0x170>; > + }; > + > + mux_intc35: interrupt-controller at d428215c { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd428215c 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <35>; > + mrvl,intc-numbers = <15>; > + mrvl,status-offset = <0x15c>; > + mrvl,mask-offset = <0x174>; > + }; > + > + mux_intc51: interrupt-controller at d4282160 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282160 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <51>; > + mrvl,intc-numbers = <2>; > + mrvl,status-offset = <0x160>; > + mrvl,mask-offset = <0x178>; > + }; > + > + mux_intc55: interrupt-controller at d4282188 { > + compatible = "mrvl,mmp2-mux-intc"; > + reg = <0xd4282188 0>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupts = <55>; > + mrvl,intc-numbers = <2>; > + mrvl,status-offset = <0x188>; > + mrvl,mask-offset = <0x184>; > + }; > + > + mmp_timer: timer at 0 { > + compatible = "mrvl,pxa168-timer"; > + interrupts = <13>; > + mrvl,clk-conf = <0xd4000024 0x13>; > + }; > + > + i2c0: i2c at d4011000 { > + compatible = "mrvl,pxa255-i2c"; > + #address-cells = <1>; > + #size-cells = <0>; > + reg = <0xd4011000 0x60>; > + interrupts = <7>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c1: i2c at d4031000 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4031000 0x60>; > + interrupts = <0>; > + interrupt-parent = <&mux_intc17>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c2: i2c at d4032000 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4032000 0x60>; > + interrupts = <1>; > + interrupt-parent = <&mux_intc17>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c3: i2c at d4033000 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4033000 0x60>; > + interrupts = <2>; > + interrupt-parent = <&mux_intc17>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c4: i2c at d4033800 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4033800 0x60>; > + interrupts = <3>; > + interrupt-parent = <&mux_intc17>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c5: i2c at d4034000 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4034000 0x60>; > + interrupts = <4>; > + interrupt-parent = <&mux_intc17>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + uart0: uart at d4030000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4030000 0x1000>; > + reg-shift = <2>; > + interrupts = <27>; > + clock-frequency = <26000000>; > + current-speed = <115200>; > + }; > + > + uart1: uart at d4017000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4017000 0x1000>; > + reg-shift = <2>; > + interrupts = <28>; > + clock-frequency = <26000000>; > + current-speed = <115200>; > + }; > + > + uart2: uart at d4018000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4018000 0x1000>; > + reg-shift = <2>; > + interrupts = <24>; > + clock-frequency = <26000000>; > + current-speed = <38400>; > + }; > + > + uart3: uart at d4016000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4016000 0x1000>; > + reg-shift = <2>; > + interrupts = <46>; > + clock-frequency = <26000000>; > + current-speed = <115200>; > + }; > + }; > +}; > diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts > new file mode 100644 > index 0000000..b9f75b7 > --- /dev/null > +++ b/arch/arm/boot/dts/pxa910-dkb.dts > @@ -0,0 +1,81 @@ > +/dts-v1/; > + > +/include/ "skeleton.dtsi" > + > +/ { > + model = "Marvell TTC DKB"; > + compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; > + #address-cells = <1>; > + #size-cells = <1>; > + interrupt-parent = <&mmp_intc>; > + > + memory { > + reg = <0x00000000 0x20000000>; > + }; > + > + chosen { > + bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; > + linux,stdout-path = &uart0; > + }; > + > + soc at d4000000 { > + compatible = "mrvl,pxa910", "simple-bus"; > + device_type = "soc"; > + #address-cells = <1>; > + #size-cells = <1>; > + ranges = <0xd4000000 0xd4000000 0x00200000 /* APB */ > + 0xd4200000 0xd4200000 0x00200000>; /* AXI */ > + > + mmp_intc: interrupt-controller at d4282000 { > + compatible = "mrvl,pxa168-intc"; > + /* reg: <offset & size> */ > + reg = <0xd4282000 0x400>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + mrvl,intc-numbers = <64>; > + /* priority bits in conf register */ > + mrvl,intc-priority = <0x51>; > + }; > + > + mmp_timer: timer at 0 { > + compatible = "mrvl,pxa168-timer"; > + interrupts = <13>; > + mrvl,clk-conf = <0xd4000034 0x33>; > + }; > + > + i2c0: i2c at d4011000 { > + compatible = "mrvl,pxa255-i2c"; > + #address-cells = <1>; > + #size-cells = <0>; > + reg = <0xd4011000 0x60>; > + interrupts = <7>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + i2c1: i2c at d4037000 { > + compatible = "mrvl,pxa255-i2c"; > + reg = <0xd4037000 0x60>; > + interrupts = <54>; > + mrvl,i2c-frequency = "fast"; > + }; > + > + uart0: uart at d4017000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4017000 0x1000>; > + reg-shift = <2>; > + interrupts = <27>; > + clock-frequency = <14745600>; > + current-speed = <115200>; > + }; > + > + uart1: uart at d4018000 { > + compatible = "mrvl,pxa270-serial"; > + reg = <0xd4018000 0x1000>; > + reg-shift = <2>; > + interrupts = <28>; > + clock-frequency = <14745600>; > + current-speed = <115200>; > + }; > + }; > +}; > diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile > index e7862ea..bdf5b23 100644 > --- a/arch/arm/mach-mmp/Makefile > +++ b/arch/arm/mach-mmp/Makefile > @@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o > obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o > > # board support > +obj-$(CONFIG_OF) += boards.o > obj-$(CONFIG_MACH_ASPENITE) += aspenite.o > obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o > obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o > diff --git a/arch/arm/mach-mmp/boards.c b/arch/arm/mach-mmp/boards.c > new file mode 100644 > index 0000000..13e61fb > --- /dev/null > +++ b/arch/arm/mach-mmp/boards.c > @@ -0,0 +1,138 @@ > +/* > + * linux/arch/arm/mach-mmp/boards.c > + * > + * Support for the Multiple Marvell Development Platforms. > + * > + * Copyright (C) 2009-2011 Marvell International Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * publishhed by the Free Software Foundation. > + */ > + > +#include <linux/init.h> > +#include <linux/kernel.h> > +#include <linux/of.h> > +#include <linux/of_fdt.h> > +#include <linux/of_platform.h> > +#include <linux/platform_device.h> > +#include <linux/i2c/pxa-i2c.h> > + > +#include <asm/mach-types.h> > +#include <asm/mach/arch.h> > + > +#include <mach/pxa910.h> > +#include <mach/mmp2.h> > +#include <mach/mfp-mmp2.h> > + > +#include "common.h" > + > +static void __init ttc_dkb_init(void) > +{ > + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); > +} > + > +static const char *ttc_dkb_dt_match[] __initdata = { > + "mrvl,pxa910-dkb", > + NULL, > +}; > + > +DT_MACHINE_START(TTC_DKB, "PXA910-based TTC-DKB Development Platform") > + .map_io = mmp_map_io, > + .init_irq = mmp_init_intc, > + .timer = &mmp_timer, > + .init_machine = ttc_dkb_init, > + .dt_compat = ttc_dkb_dt_match, > +MACHINE_END > + > +static unsigned long brownstone_pin_config[] __initdata = { > + /* UART1 */ > + GPIO29_UART1_RXD, > + GPIO30_UART1_TXD, > + > + /* UART3 */ > + GPIO51_UART3_RXD, > + GPIO52_UART3_TXD, > + > + /* DFI */ > + GPIO168_DFI_D0, > + GPIO167_DFI_D1, > + GPIO166_DFI_D2, > + GPIO165_DFI_D3, > + GPIO107_DFI_D4, > + GPIO106_DFI_D5, > + GPIO105_DFI_D6, > + GPIO104_DFI_D7, > + GPIO111_DFI_D8, > + GPIO164_DFI_D9, > + GPIO163_DFI_D10, > + GPIO162_DFI_D11, > + GPIO161_DFI_D12, > + GPIO110_DFI_D13, > + GPIO109_DFI_D14, > + GPIO108_DFI_D15, > + GPIO143_ND_nCS0, > + GPIO144_ND_nCS1, > + GPIO147_ND_nWE, > + GPIO148_ND_nRE, > + GPIO150_ND_ALE, > + GPIO149_ND_CLE, > + GPIO112_ND_RDY0, > + GPIO160_ND_RDY1, > + > + /* PMIC */ > + PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, > + > + /* MMC0 */ > + GPIO131_MMC1_DAT3 | MFP_PULL_HIGH, > + GPIO132_MMC1_DAT2 | MFP_PULL_HIGH, > + GPIO133_MMC1_DAT1 | MFP_PULL_HIGH, > + GPIO134_MMC1_DAT0 | MFP_PULL_HIGH, > + GPIO136_MMC1_CMD | MFP_PULL_HIGH, > + GPIO139_MMC1_CLK, > + GPIO140_MMC1_CD | MFP_PULL_LOW, > + GPIO141_MMC1_WP | MFP_PULL_LOW, > + > + /* MMC1 */ > + GPIO37_MMC2_DAT3 | MFP_PULL_HIGH, > + GPIO38_MMC2_DAT2 | MFP_PULL_HIGH, > + GPIO39_MMC2_DAT1 | MFP_PULL_HIGH, > + GPIO40_MMC2_DAT0 | MFP_PULL_HIGH, > + GPIO41_MMC2_CMD | MFP_PULL_HIGH, > + GPIO42_MMC2_CLK, > + > + /* MMC2 */ > + GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, > + GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, > + GPIO166_MMC3_DAT5 | MFP_PULL_HIGH, > + GPIO163_MMC3_DAT4 | MFP_PULL_HIGH, > + GPIO167_MMC3_DAT3 | MFP_PULL_HIGH, > + GPIO164_MMC3_DAT2 | MFP_PULL_HIGH, > + GPIO168_MMC3_DAT1 | MFP_PULL_HIGH, > + GPIO111_MMC3_DAT0 | MFP_PULL_HIGH, > + GPIO112_MMC3_CMD | MFP_PULL_HIGH, > + GPIO151_MMC3_CLK, > + > + /* 5V regulator */ > + GPIO89_GPIO, > +}; This table is /already/ in brownstone.c. Why duplicate it? > + > +static void __init brownstone_init(void) > +{ > + mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); > + > + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); > +} > + > +static const char *brownstone_dt_match[] __initdata = { > + "mrvl,mmp2-brownstone", > + NULL, > +}; > + > +DT_MACHINE_START(BROWNSTONE, "Brownstone Development Platform") > + .map_io = mmp_map_io, > + .init_irq = mmp_init_intc, > + .timer = &mmp_timer, > + .init_machine = brownstone_init, > + .dt_compat = brownstone_dt_match, > +MACHINE_END > -- > 1.5.6.5 > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone 2011-07-29 16:42 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Grant Likely @ 2011-08-01 2:48 ` Haojian Zhuang 0 siblings, 0 replies; 27+ messages in thread From: Haojian Zhuang @ 2011-08-01 2:48 UTC (permalink / raw) To: linux-arm-kernel On Sat, Jul 30, 2011 at 12:42 AM, Grant Likely <grant.likely@secretlab.ca> wrote: > On Thu, Jul 28, 2011 at 02:41:29PM +0800, Haojian Zhuang wrote: >> Add new boards.c to support both TTC-DKB and MMP2-BROWNSTONE. If CONFIG_OF >> isn't selected, we continue to use original ttc_dkb.c and brownstone.c. >> >> While everything moving to DT in ARCH-MMP, ttc_dkb.c and brownstone.c >> will be abandoned. >> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> >> --- >> ?.../devicetree/bindings/arm/marvell/boards.txt ? ? | ? ?7 + >> ?arch/arm/boot/dts/mmp2-brownstone.dts ? ? ? ? ? ? ?| ?216 ++++++++++++++++++++ >> ?arch/arm/boot/dts/pxa910-dkb.dts ? ? ? ? ? ? ? ? ? | ? 81 ++++++++ >> ?arch/arm/mach-mmp/Makefile ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 + >> ?arch/arm/mach-mmp/boards.c ? ? ? ? ? ? ? ? ? ? ? ? | ?138 +++++++++++++ >> ?5 files changed, 443 insertions(+), 0 deletions(-) >> ?create mode 100644 Documentation/devicetree/bindings/arm/marvell/boards.txt >> ?create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts >> ?create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts >> ?create mode 100644 arch/arm/mach-mmp/boards.c >> >> diff --git a/Documentation/devicetree/bindings/arm/marvell/boards.txt b/Documentation/devicetree/bindings/arm/marvell/boards.txt >> new file mode 100644 >> index 0000000..a031a26 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/arm/marvell/boards.txt >> @@ -0,0 +1,7 @@ >> +TTC(pxa910) "DKB" evalutation board >> +Required root node properties: >> + ? ? - compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; >> + >> +mmp2(armada610) "Brownstone" evalutation board >> +Required root node properties: >> + ? ? - compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; >> diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts >> new file mode 100644 >> index 0000000..2673282 >> --- /dev/null >> +++ b/arch/arm/boot/dts/mmp2-brownstone.dts >> @@ -0,0 +1,216 @@ >> +/dts-v1/; >> + >> +/include/ "skeleton.dtsi" >> + >> +/ { >> + ? ? model = "Marvell MMP2 Brownstone"; >> + ? ? compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; >> + ? ? #address-cells = <1>; >> + ? ? #size-cells = <1>; >> + ? ? interrupt-parent = <&mmp_intc>; >> + >> + ? ? memory { >> + ? ? ? ? ? ? reg = <0x00000000 0x20000000>; >> + ? ? }; >> + >> + ? ? chosen { >> + ? ? ? ? ? ? bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; >> + ? ? ? ? ? ? linux,stdout-path = &uart2; >> + ? ? }; >> + >> + ? ? soc at d4000000 { >> + ? ? ? ? ? ? compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; >> + ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? #size-cells = <1>; >> + ? ? ? ? ? ? ranges; >> + >> + ? ? ? ? ? ? mmp_intc: interrupt-controller at d4282000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa168-intc"; >> + ? ? ? ? ? ? ? ? ? ? /* reg: <offset & size> */ >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282000 0x400>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <64>; >> + ? ? ? ? ? ? ? ? ? ? /* priority bits in conf register */ >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-priority = <0x20>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc4: interrupt-controller at d4282150 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282150 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <4>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <2>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x150>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x168>; >> + ? ? ? ? ? ? ? ? ? ? /* mfp register & interrupt index */ >> + ? ? ? ? ? ? ? ? ? ? mrvl,mfp-edge = <0xd401e2c4 1>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc5: interrupt-controller at d4282154 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282154 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <5>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <2>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x154>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x16c>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc9: interrupt-controller at d4282180 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282180 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <9>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <3>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x180>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x17c>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc17: interrupt-controller at d4282158 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282158 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <5>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x158>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x170>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc35: interrupt-controller at d428215c { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd428215c 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <35>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <15>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x15c>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x174>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc51: interrupt-controller at d4282160 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282160 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <51>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <2>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x160>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x178>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mux_intc55: interrupt-controller at d4282188 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282188 0>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <55>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <2>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,status-offset = <0x188>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,mask-offset = <0x184>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mmp_timer: timer at 0 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa168-timer"; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <13>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,clk-conf = <0xd4000024 0x13>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c0: i2c at d4011000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? #size-cells = <0>; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4011000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <7>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c1: i2c at d4031000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4031000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <0>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-parent = <&mux_intc17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c2: i2c at d4032000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4032000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-parent = <&mux_intc17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c3: i2c at d4033000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4033000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-parent = <&mux_intc17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c4: i2c at d4033800 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4033800 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <3>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-parent = <&mux_intc17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c5: i2c at d4034000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4034000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <4>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-parent = <&mux_intc17>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart0: uart at d4030000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4030000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <27>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <26000000>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <115200>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart1: uart at d4017000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4017000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <28>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <26000000>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <115200>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart2: uart at d4018000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4018000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <24>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <26000000>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <38400>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart3: uart at d4016000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4016000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <46>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <26000000>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <115200>; >> + ? ? ? ? ? ? }; >> + ? ? }; >> +}; >> diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts >> new file mode 100644 >> index 0000000..b9f75b7 >> --- /dev/null >> +++ b/arch/arm/boot/dts/pxa910-dkb.dts >> @@ -0,0 +1,81 @@ >> +/dts-v1/; >> + >> +/include/ "skeleton.dtsi" >> + >> +/ { >> + ? ? model = "Marvell TTC DKB"; >> + ? ? compatible = "mrvl,pxa910-dkb", "mrvl,pxa910"; >> + ? ? #address-cells = <1>; >> + ? ? #size-cells = <1>; >> + ? ? interrupt-parent = <&mmp_intc>; >> + >> + ? ? memory { >> + ? ? ? ? ? ? reg = <0x00000000 0x20000000>; >> + ? ? }; >> + >> + ? ? chosen { >> + ? ? ? ? ? ? bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:192.168.1.101::255.255.255.0::eth0:on"; >> + ? ? ? ? ? ? linux,stdout-path = &uart0; >> + ? ? }; >> + >> + ? ? soc at d4000000 { >> + ? ? ? ? ? ? compatible = "mrvl,pxa910", "simple-bus"; >> + ? ? ? ? ? ? device_type = "soc"; >> + ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? #size-cells = <1>; >> + ? ? ? ? ? ? ranges = <0xd4000000 0xd4000000 0x00200000 ? ? ?/* APB */ >> + ? ? ? ? ? ? ? ? ? ? 0xd4200000 0xd4200000 0x00200000>; ? ? ?/* AXI */ >> + >> + ? ? ? ? ? ? mmp_intc: interrupt-controller at d4282000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa168-intc"; >> + ? ? ? ? ? ? ? ? ? ? /* reg: <offset & size> */ >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4282000 0x400>; >> + >> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-numbers = <64>; >> + ? ? ? ? ? ? ? ? ? ? /* priority bits in conf register */ >> + ? ? ? ? ? ? ? ? ? ? mrvl,intc-priority = <0x51>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? mmp_timer: timer at 0 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa168-timer"; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <13>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,clk-conf = <0xd4000034 0x33>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c0: i2c at d4011000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? ? ? ? ? #size-cells = <0>; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4011000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <7>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? i2c1: i2c at d4037000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa255-i2c"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4037000 0x60>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <54>; >> + ? ? ? ? ? ? ? ? ? ? mrvl,i2c-frequency = "fast"; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart0: uart at d4017000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4017000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <27>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <14745600>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <115200>; >> + ? ? ? ? ? ? }; >> + >> + ? ? ? ? ? ? uart1: uart at d4018000 { >> + ? ? ? ? ? ? ? ? ? ? compatible = "mrvl,pxa270-serial"; >> + ? ? ? ? ? ? ? ? ? ? reg = <0xd4018000 0x1000>; >> + ? ? ? ? ? ? ? ? ? ? reg-shift = <2>; >> + ? ? ? ? ? ? ? ? ? ? interrupts = <28>; >> + ? ? ? ? ? ? ? ? ? ? clock-frequency = <14745600>; >> + ? ? ? ? ? ? ? ? ? ? current-speed = <115200>; >> + ? ? ? ? ? ? }; >> + ? ? }; >> +}; >> diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile >> index e7862ea..bdf5b23 100644 >> --- a/arch/arm/mach-mmp/Makefile >> +++ b/arch/arm/mach-mmp/Makefile >> @@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_PXA910) ? ?+= pxa910.o irq-pxa168.o >> ?obj-$(CONFIG_CPU_MMP2) ? ? ? ? ? ? ? += mmp2.o irq-mmp2.o >> >> ?# board support >> +obj-$(CONFIG_OF) ? ? ? ? ? ? += boards.o >> ?obj-$(CONFIG_MACH_ASPENITE) ?+= aspenite.o >> ?obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o >> ?obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o >> diff --git a/arch/arm/mach-mmp/boards.c b/arch/arm/mach-mmp/boards.c >> new file mode 100644 >> index 0000000..13e61fb >> --- /dev/null >> +++ b/arch/arm/mach-mmp/boards.c >> @@ -0,0 +1,138 @@ >> +/* >> + * ?linux/arch/arm/mach-mmp/boards.c >> + * >> + * ?Support for the Multiple Marvell Development Platforms. >> + * >> + * ?Copyright (C) 2009-2011 Marvell International Ltd. >> + * >> + * ?This program is free software; you can redistribute it and/or modify >> + * ?it under the terms of the GNU General Public License version 2 as >> + * ?publishhed by the Free Software Foundation. >> + */ >> + >> +#include <linux/init.h> >> +#include <linux/kernel.h> >> +#include <linux/of.h> >> +#include <linux/of_fdt.h> >> +#include <linux/of_platform.h> >> +#include <linux/platform_device.h> >> +#include <linux/i2c/pxa-i2c.h> >> + >> +#include <asm/mach-types.h> >> +#include <asm/mach/arch.h> >> + >> +#include <mach/pxa910.h> >> +#include <mach/mmp2.h> >> +#include <mach/mfp-mmp2.h> >> + >> +#include "common.h" >> + >> +static void __init ttc_dkb_init(void) >> +{ >> + ? ? of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); >> +} >> + >> +static const char *ttc_dkb_dt_match[] __initdata = { >> + ? ? "mrvl,pxa910-dkb", >> + ? ? NULL, >> +}; >> + >> +DT_MACHINE_START(TTC_DKB, "PXA910-based TTC-DKB Development Platform") >> + ? ? .map_io ? ? ? ? = mmp_map_io, >> + ? ? .init_irq ? ? ? = mmp_init_intc, >> + ? ? .timer ? ? ? ? ?= &mmp_timer, >> + ? ? .init_machine ? = ttc_dkb_init, >> + ? ? .dt_compat ? ? ?= ttc_dkb_dt_match, >> +MACHINE_END >> + >> +static unsigned long brownstone_pin_config[] __initdata = { >> + ? ? /* UART1 */ >> + ? ? GPIO29_UART1_RXD, >> + ? ? GPIO30_UART1_TXD, >> + >> + ? ? /* UART3 */ >> + ? ? GPIO51_UART3_RXD, >> + ? ? GPIO52_UART3_TXD, >> + >> + ? ? /* DFI */ >> + ? ? GPIO168_DFI_D0, >> + ? ? GPIO167_DFI_D1, >> + ? ? GPIO166_DFI_D2, >> + ? ? GPIO165_DFI_D3, >> + ? ? GPIO107_DFI_D4, >> + ? ? GPIO106_DFI_D5, >> + ? ? GPIO105_DFI_D6, >> + ? ? GPIO104_DFI_D7, >> + ? ? GPIO111_DFI_D8, >> + ? ? GPIO164_DFI_D9, >> + ? ? GPIO163_DFI_D10, >> + ? ? GPIO162_DFI_D11, >> + ? ? GPIO161_DFI_D12, >> + ? ? GPIO110_DFI_D13, >> + ? ? GPIO109_DFI_D14, >> + ? ? GPIO108_DFI_D15, >> + ? ? GPIO143_ND_nCS0, >> + ? ? GPIO144_ND_nCS1, >> + ? ? GPIO147_ND_nWE, >> + ? ? GPIO148_ND_nRE, >> + ? ? GPIO150_ND_ALE, >> + ? ? GPIO149_ND_CLE, >> + ? ? GPIO112_ND_RDY0, >> + ? ? GPIO160_ND_RDY1, >> + >> + ? ? /* PMIC */ >> + ? ? PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, >> + >> + ? ? /* MMC0 */ >> + ? ? GPIO131_MMC1_DAT3 | MFP_PULL_HIGH, >> + ? ? GPIO132_MMC1_DAT2 | MFP_PULL_HIGH, >> + ? ? GPIO133_MMC1_DAT1 | MFP_PULL_HIGH, >> + ? ? GPIO134_MMC1_DAT0 | MFP_PULL_HIGH, >> + ? ? GPIO136_MMC1_CMD | MFP_PULL_HIGH, >> + ? ? GPIO139_MMC1_CLK, >> + ? ? GPIO140_MMC1_CD | MFP_PULL_LOW, >> + ? ? GPIO141_MMC1_WP | MFP_PULL_LOW, >> + >> + ? ? /* MMC1 */ >> + ? ? GPIO37_MMC2_DAT3 | MFP_PULL_HIGH, >> + ? ? GPIO38_MMC2_DAT2 | MFP_PULL_HIGH, >> + ? ? GPIO39_MMC2_DAT1 | MFP_PULL_HIGH, >> + ? ? GPIO40_MMC2_DAT0 | MFP_PULL_HIGH, >> + ? ? GPIO41_MMC2_CMD | MFP_PULL_HIGH, >> + ? ? GPIO42_MMC2_CLK, >> + >> + ? ? /* MMC2 */ >> + ? ? GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, >> + ? ? GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, >> + ? ? GPIO166_MMC3_DAT5 | MFP_PULL_HIGH, >> + ? ? GPIO163_MMC3_DAT4 | MFP_PULL_HIGH, >> + ? ? GPIO167_MMC3_DAT3 | MFP_PULL_HIGH, >> + ? ? GPIO164_MMC3_DAT2 | MFP_PULL_HIGH, >> + ? ? GPIO168_MMC3_DAT1 | MFP_PULL_HIGH, >> + ? ? GPIO111_MMC3_DAT0 | MFP_PULL_HIGH, >> + ? ? GPIO112_MMC3_CMD | MFP_PULL_HIGH, >> + ? ? GPIO151_MMC3_CLK, >> + >> + ? ? /* 5V regulator */ >> + ? ? GPIO89_GPIO, >> +}; > > This table is /already/ in brownstone.c. ?Why duplicate it? > As I mentioned, brownstone.c will be abandoned later. >> + >> +static void __init brownstone_init(void) >> +{ >> + ? ? mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); >> + >> + ? ? of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); >> +} >> + >> +static const char *brownstone_dt_match[] __initdata = { >> + ? ? "mrvl,mmp2-brownstone", >> + ? ? NULL, >> +}; >> + >> +DT_MACHINE_START(BROWNSTONE, "Brownstone Development Platform") >> + ? ? .map_io ? ? ? ? = mmp_map_io, >> + ? ? .init_irq ? ? ? = mmp_init_intc, >> + ? ? .timer ? ? ? ? ?= &mmp_timer, >> + ? ? .init_machine ? = brownstone_init, >> + ? ? .dt_compat ? ? ?= brownstone_dt_match, >> +MACHINE_END >> -- >> 1.5.6.5 >> > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 2/7] ARM: mmp: parse timer configuration from DT 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Haojian Zhuang @ 2011-07-29 16:40 ` Grant Likely 1 sibling, 0 replies; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:40 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:28PM +0800, Haojian Zhuang wrote: > Parse timer configuration from DT. Now we can merge pxa910_timer and > mmp2_timer into mmp_timer. Since most configuration between these two > timers are same. The difference is recorded in DT. > > Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> > --- > .../devicetree/bindings/arm/marvell/timer.txt | 24 +++++++++ > arch/arm/mach-mmp/common.h | 2 + > arch/arm/mach-mmp/time.c | 50 +++++++++++++++++++- > 3 files changed, 75 insertions(+), 1 deletions(-) > create mode 100644 Documentation/devicetree/bindings/arm/marvell/timer.txt > > diff --git a/Documentation/devicetree/bindings/arm/marvell/timer.txt b/Documentation/devicetree/bindings/arm/marvell/timer.txt > new file mode 100644 > index 0000000..24a6f97 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/marvell/timer.txt > @@ -0,0 +1,24 @@ > +* Timer Controller Binding for ARCH-MMP > + > +This binding specifies what properties must be available in device tree > +representation of an ARCH-MMP compliant timer controller. > + > +Required properties: > + > + - compatible: Specifies the compatibility list of the timer controller. > + The type shall be <string> and the value shall be > + "mrvl,pxa168-timer". > + > + - mrvl,clk-conf: Specifies the address and value of timer > + configuration register. > + The type shall be <prop-encoded-array>. The first value indicates > + the physical address of timer configuration register. The second > + value indicates data should be written to timer configuration > + register. > + > +* Example > + > + mmp_timer: { > + compatible = "mrvl,pxa168-timer"; > + mrvl,clk-conf = <0xd4000034 0x33>; > + }; > diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h > index 1c563c2..890c664 100644 > --- a/arch/arm/mach-mmp/common.h > +++ b/arch/arm/mach-mmp/common.h > @@ -2,6 +2,8 @@ > > struct sys_timer; > > +extern struct sys_timer mmp_timer; > + > extern void timer_init(int irq); > > extern void __init icu_init_irq(void); > diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c > index 99833b9..5a90b27 100644 > --- a/arch/arm/mach-mmp/time.c > +++ b/arch/arm/mach-mmp/time.c > @@ -25,6 +25,8 @@ > > #include <linux/io.h> > #include <linux/irq.h> > +#include <linux/of.h> > +#include <linux/of_irq.h> > #include <linux/sched.h> > > #include <asm/sched_clock.h> > @@ -150,7 +152,7 @@ static void __init timer_config(void) > > __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ > > - ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3); > + ccr &= TMR_CCR_CS_0(0); > __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); > > /* free-running mode */ > @@ -187,3 +189,49 @@ void __init timer_init(int irq) > clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); > clockevents_register_device(&ckevt); > } > + > +#ifdef CONFIG_OF > +static void __init mmp_timer_init(void) > +{ > + struct device_node *np; > + const __be32 *clk_offs; > + void __iomem *conf; > + unsigned int addr = 0, offs = 0; > + int size, irq; > + > + np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-timer"); > + > + BUG_ON(!np); > + > + of_node_get(np); > + irq = irq_of_parse_and_map(np, 0); > + > + clk_offs = of_get_property(np, "mrvl,clk-conf", &size); > + if ((clk_offs == NULL) || (size != sizeof(int) * 2)) { sizeof(u32) I would recommend using of_property_read_u32_array() which does the sanity checking for you. > + pr_warn("mmp-timer: mrvl,clk-conf property is wrong\n"); > + goto out; > + } > + addr = be32_to_cpu(*clk_offs) & PAGE_MASK; > + offs = be32_to_cpu(*clk_offs) - addr; > + conf = ioremap(addr, PAGE_SIZE); base addresses should be in a 'reg' property. I would put the register region into a 'reg' tuple so that of_iomap() works, and then encode just the offset/config-value pair into mrvl,clk-conf. > + if (conf == NULL) { > + pr_warn("mmp-timer: failed on mapping 0x%x\n", (uint32_t)conf); > + goto out; > + } > + /* reset and configure */ > + __raw_writel(APBC_APBCLK | APBC_RST, conf + offs); > + __raw_writel(be32_to_cpu(*++clk_offs), conf + offs); > + __raw_readl(conf + offs); > + iounmap(conf); > + > + timer_init(irq); > + return; > +out: > + of_node_put(np); > + return; > +} > + > +struct sys_timer mmp_timer = { > + .init = mmp_timer_init, > +}; > +#endif > -- > 1.5.6.5 > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-07-28 6:41 ` [PATCH v2 1/7] ARM: mmp: parse irq from DT Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang @ 2011-07-29 16:36 ` Grant Likely 2011-08-01 2:47 ` Haojian Zhuang 2011-08-01 8:26 ` Russell King - ARM Linux 2 siblings, 1 reply; 27+ messages in thread From: Grant Likely @ 2011-07-29 16:36 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:27PM +0800, Haojian Zhuang wrote: > Parse irq sepcifier from DT and translate it to Linux irq number. > Remove the definition of NR_IRQS in irqs.h. Since sparse irq is > enabled, nr_irqs will be calculated automatically. > > Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> > --- > .../devicetree/bindings/arm/marvell/intc.txt | 114 ++++++++++ > arch/arm/Kconfig | 1 + > arch/arm/mach-mmp/Makefile | 2 + > arch/arm/mach-mmp/common.h | 1 + > arch/arm/mach-mmp/include/mach/irqs.h | 2 +- > arch/arm/mach-mmp/intc.c | 224 ++++++++++++++++++++ > 6 files changed, 343 insertions(+), 1 deletions(-) > create mode 100644 Documentation/devicetree/bindings/arm/marvell/intc.txt > create mode 100644 arch/arm/mach-mmp/intc.c > > diff --git a/Documentation/devicetree/bindings/arm/marvell/intc.txt b/Documentation/devicetree/bindings/arm/marvell/intc.txt > new file mode 100644 > index 0000000..80cef58 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/marvell/intc.txt > @@ -0,0 +1,114 @@ > +* Interrupt Controller Binding for ARCH-MMP > + > +This binding specifies what properties must be available in device tree representation of an ARCH-MMP compliant interrupt controller. > + > +Required properties: > + > + - compatible: Specifies the compatibility list of the interrupt > + controller. The type shall be <string> and the value shall be > + "mrvl,pxa168-intc" or "mrvl,mmp2-mux-intc". > + "mrvl,pxa168-intc" is the base interrupt controller. It must be > + included. It's compatible for pxa910, mmp2. "mrvl,mmp2-mux-intc" > + is the expanded interrupt controller, and it's optional. > + > + - reg: Specified the base physical address(s) and size(s) of the > + interrupt controller's addressable register space. The type > + should be <prop-encoded-array>. > + > + - interrupt-controller: The presence of this property identifies > + the node as interrupt controller. No property value should be > + defined. > + > + - #interrupt-cells: Specifies the number of cells needed to encode > + an interrupt source. The type should be <u32> and the value should > + be 1. > + > + - mrvl,intc-numbers: Specifies the number of interrupts is supported > + in this interrupt controller. The type should be <u32>. > + > +Optional properties: > + > + - mrvl,intc-priority: Specifies the which path the interrupt is routed > + and the priority of this interrupt. The property is used in > + pxa168-intc. The value should be <u32>. > + > + - mrvl,status-offset: Specifies the offset of status register. The > + property is used in mmp2-mux-intc. The type should be <u32>. > + > + - mrvl,mask-offset: Specifies the offset of mask register. The > + property is used in mmp2-mux-intc. The type should be <u32>. > + > + - mrvl,mfp-edge: Specifies the address of mfp edge detection register. > + The property is used while acking specified interrupt. The type > + should be <prop-encoded-array>. The first cell indicates the address > + of mfp edge detection register. The second cell indicates the > + index of interrupt in current interrupt controller that should > + handle mfp edge detection. > + > +* Examples > + > +Example 1: > + > + /* > + * base INTC > + */ > + mmp_intc: interrupt-controller at d4282000 { > + /* Compatible with pxa168-intc. */ > + compatible = "mrvl,pxa168-intc"; > + #address-cells = <1>; > + #size-cells = <1>; > + /* Offset address of 0xd4282000 and size of 0x400. */ > + reg = <0xd4282000 0x400>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + > + /* 64 interrupts are supported in this INTC. */ > + mrvl,intc-numbers = <64>; > + > + /* priority bits in configuration register */ > + mrvl,intc-priority = <0x20>; > + }; > + > +Example 2: > + > + /* > + * mux INTC that is internal wired to base INTC > + */ > + mux_intc4: interrupt-controller at d4282150 { > + compatible = "mrvl,mmp2-mux-intc"; > + #address-cells = <1>; > + #size-cells = <1>; > + reg = <0xd4282000 0x400>; > + > + #interrupt-cells = <1>; > + interrupt-controller; > + interrupt-parent = <&mmp_intc>; > + > + /* interrupt source '4' of parent INTC. */ > + interrupts = <4>; > + > + /* 2 interrupts are supported in this INTC. */ > + mrvl,intc-numbers = <2>; > + > + /* Status offset address of 0x150. */ > + mrvl,status-offset = <0x150>; > + > + /* Mask offset address of 0x168. */ > + mrvl,mask-offset = <0x168>; > + > + /* mfp register of 0xd401e2c4 & interrupt index of 1 */ > + mrvl,mfp-edge = <0xd401e2c4 1>; > + }; > + > +Example 3: > + /* > + * An interrupt generating device that is wired to an INTC. > + */ > + uart0: uart at d4030000 { > + /* parent's '#interrupt-cells' property. */ > + interrupts = <27>; > + > + /* The INTC that this device is wired to. */ > + interrupt-parent = <&mmp_intc>; > + }; > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 17507b8..f18eb14 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -542,6 +542,7 @@ config ARCH_MMP > select ARCH_REQUIRE_GPIOLIB > select CLKDEV_LOOKUP > select GENERIC_CLOCKEVENTS > + select GENERIC_IRQ_CHIP > select HAVE_SCHED_CLOCK > select TICK_ONESHOT > select PLAT_PXA > diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile > index 5c68382..e7862ea 100644 > --- a/arch/arm/mach-mmp/Makefile > +++ b/arch/arm/mach-mmp/Makefile > @@ -4,6 +4,8 @@ > > obj-y += common.o clock.o devices.o time.o > > +obj-$(CONFIG_OF_IRQ) += intc.o > + I'm still really confused about why an entirely new interrupt controller file is being added. Drivers already exist in mach-mmp for the mux and pxa168 interrupt controllers, but this adds a whole new driver. I would expect the existing drivers should be refactored to use irq generic chip, and then extend them to add DT support. > # SoC support > obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o > obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o > diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h > index ec8d65d..1c563c2 100644 > --- a/arch/arm/mach-mmp/common.h > +++ b/arch/arm/mach-mmp/common.h > @@ -6,3 +6,4 @@ extern void timer_init(int irq); > > extern void __init icu_init_irq(void); > extern void __init mmp_map_io(void); > +extern void __init mmp_init_intc(void); > diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h > index a09d328..65ec176 100644 > --- a/arch/arm/mach-mmp/include/mach/irqs.h > +++ b/arch/arm/mach-mmp/include/mach/irqs.h > @@ -224,6 +224,6 @@ > > #define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) > > -#define NR_IRQS (IRQ_BOARD_START) > +#define NR_IRQS 0 Why is NR_IRQs getting changed? I think this will break !CONFIG_SPARSE_IRQS, and it shouldn't be necessary for this conversion. > > > -- > Regards, > Shawn > > #endif /* __ASM_MACH_IRQS_H */ > diff --git a/arch/arm/mach-mmp/intc.c b/arch/arm/mach-mmp/intc.c > new file mode 100644 > index 0000000..2e44057 > --- /dev/null > +++ b/arch/arm/mach-mmp/intc.c > @@ -0,0 +1,224 @@ > +/* > + * linux/arch/arm/mach-mmp/intc.c > + * > + * Generic IRQ handling > + * > + * Author: Haojian Zhuang <haojian.zhuang@marvell.com> > + * Copyright: Marvell International Ltd. 2011 > + * > + * 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/errno.h> > +#include <linux/io.h> > +#include <linux/kernel.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > +#include <linux/of_irq.h> > +#include <linux/slab.h> > + > +struct mmp_intc_info { > + unsigned int en_mask; > + void __iomem *virt_base; > + void __iomem *status; > + void __iomem *mfp_edge; > + unsigned int mfp_edge_index; /* index in irq domain */ > +}; > + > +static void mux_irq_ack(struct irq_data *d) > +{ > + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); > + struct irq_chip_type *ct; > + struct mmp_intc_info *info; > + unsigned int data, irq_offs; > + > + ct = gc->chip_types; > + info = (struct mmp_intc_info *)ct->regs.ack; > + irq_offs = d->irq - gc->irq_base; > + /* clear MFP edge-detect */ > + if (info->mfp_edge && (info->mfp_edge_index == irq_offs)) { > + data = __raw_readl(info->mfp_edge); > + __raw_writel(data | (1 << 6), info->mfp_edge); > + __raw_writel(data, info->mfp_edge); > + } > +} > + > +static void mmp_irq_demux_handler(unsigned int irq, struct irq_desc *desc) > +{ > + struct irq_chip_generic *gc = irq_get_handler_data(irq); > + struct irq_chip_type *ct; > + struct mmp_intc_info *info; > + unsigned long status, n; > + > + ct = gc->chip_types; > + info = (struct mmp_intc_info *)ct->regs.ack; > + while (1) { > + status = __raw_readl(info->status) & ~gc->mask_cache; > + if (status == 0) > + break; > + n = find_first_bit(&status, BITS_PER_LONG); > + while (n < BITS_PER_LONG) { > + generic_handle_irq(gc->irq_base + n); > + n = find_next_bit(&status, BITS_PER_LONG, n + 1); > + } > + } > +} > + > +static void mux_init_intc(struct mmp_intc_info *mmp_info) > +{ > + struct device_node *np; > + struct mmp_intc_info *mux_info; > + struct irq_chip_generic *gc; > + struct irq_chip_type *ct; > + const __be32 *edge; > + unsigned int addr = 0, offs = 0; > + unsigned int status, mask, irq_base, nr, data; > + int cascade; > + > + for_each_compatible_node(np, NULL, "mrvl,mmp2-mux-intc") { > + if (of_get_property(np, "interrupt-controller", NULL) == NULL) > + continue; > + if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { > + pr_warn("intc-numbers property is missed\n"); > + continue; > + } > + if (of_property_read_u32(np, "mrvl,status-offset", &status) > + < 0) { > + pr_warn("intc-status property is missed\n"); > + continue; > + } > + if (of_property_read_u32(np, "mrvl,mask-offset", &mask) < 0) { > + pr_warn("intc-mask property is missed\n"); > + continue; > + } > + > + mux_info = kzalloc(sizeof(*mux_info), GFP_KERNEL); > + if (mux_info == NULL) > + goto out; > + status += (unsigned int)mmp_info->virt_base; > + mux_info->status = (void __iomem *)status; > + > + edge = of_get_property(np, "mrvl,mfp-edge", NULL); > + if (edge) { > + addr = be32_to_cpu(*edge) & PAGE_MASK; > + offs = be32_to_cpu(*edge) - addr; > + mux_info->mfp_edge = ioremap(addr, PAGE_SIZE) + offs; > + mux_info->mfp_edge_index = be32_to_cpu(*++edge); > + /* clear mfp edge detection for initialization */ > + data = __raw_readl(mux_info->mfp_edge); > + __raw_writel(data | (1 << 6), mux_info->mfp_edge); > + __raw_writel(data, mux_info->mfp_edge); > + } > + > + /* allocate new irq */ > + cascade = irq_of_parse_and_map(np, 0); > + irq_base = irq_alloc_descs(-1, 0, nr, 0); > + irq_domain_add_simple(np, irq_base); > + > + gc = irq_alloc_generic_chip("mux-intc", 1, irq_base, > + mmp_info->virt_base, handle_level_irq); > + ct = gc->chip_types; > + ct->regs.ack = (unsigned int)mux_info; > + ct->regs.mask = mask; > + ct->chip.irq_ack = mux_irq_ack; > + ct->chip.irq_mask = irq_gc_mask_set_bit; > + ct->chip.irq_unmask = irq_gc_mask_clr_bit; > + irq_setup_generic_chip(gc, IRQ_MSK(nr), IRQ_GC_INIT_MASK_CACHE, > + IRQ_NOREQUEST | IRQ_NOPROBE, 0); > + > + irq_set_handler_data(cascade, gc); > + irq_set_chained_handler(cascade, mmp_irq_demux_handler); > + } > +out: > + return; > +} > + > +static void mmp_irq_unmask(struct irq_data *d) > +{ > + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); > + > + /* ICU_INT_CONF */ > + __raw_writel(info->en_mask, info->virt_base + (d->irq << 2)); > +} > + > +static void mmp_irq_mask(struct irq_data *d) > +{ > + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); > + > + __raw_writel(0, info->virt_base + (d->irq << 2)); > +} > + > +static struct irq_chip mmp_irq_chip = { > + .name = "mmp-intc", > + .irq_unmask = mmp_irq_unmask, > + .irq_mask = mmp_irq_mask, > + .irq_ack = mmp_irq_mask, > +}; > + > +void __init mmp_init_intc(void) > +{ > + struct mmp_intc_info *info; > + struct device_node *np; > + struct resource rs; > + unsigned int cells, nr, enable, irq_base; > + int i; > + > + np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-intc"); > + > + BUG_ON(!np); > + > + of_node_get(np); > + if (of_get_property(np, "interrupt-controller", NULL) == NULL) > + goto out; > + if (of_property_read_u32(np, "#interrupt-cells", &cells) < 0) { > + pr_warn("mmp-intc: interrupt-cells property is missed\n"); > + goto out; > + } > + if (cells != 1) { > + pr_warn("mmp-intc: interrupt-cells property is incorrect\n"); > + goto out; > + } > + if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { > + pr_warn("mmp-intc: mrvl,intc-numbers property is missed\n"); > + goto out; > + } > + if (of_property_read_u32(np, "mrvl,intc-priority", &enable) < 0) { > + pr_warn("mmp-intc: mrvl,intc-priority property is missed\n"); > + goto out; > + } > + if (of_address_to_resource(np, 0, &rs) < 0) { > + pr_warn("mmp-intc: invalid reg property\n"); > + goto out; > + } > + > + info = kzalloc(sizeof(struct mmp_intc_info), GFP_KERNEL); > + if (info == NULL) > + goto out; > + info->en_mask = enable; > + info->virt_base = ioremap(rs.start, PAGE_SIZE); > + if (info->virt_base == NULL) { > + pr_warn("mmp-intc: failed to remap reg base\n"); > + goto out_mem; > + } > + > + /* allocate new irq */ > + irq_base = irq_alloc_descs(-1, 0, nr, 0); > + irq_domain_add_simple(np, 0); > + > + for (i = irq_base; i < irq_base + nr; i++) { > + irq_set_chip_data(i, info); > + mmp_irq_mask(irq_get_irq_data(i)); > + irq_set_chip_and_handler(i, &mmp_irq_chip, handle_level_irq); > + set_irq_flags(i, IRQF_VALID); > + } > + mux_init_intc(info); > + of_node_put(np); > + return; > +out_mem: > + kfree(info); > +out: > + of_node_put(np); > + return; > +} > -- > 1.5.6.5 > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-07-29 16:36 ` [PATCH v2 1/7] ARM: mmp: parse irq " Grant Likely @ 2011-08-01 2:47 ` Haojian Zhuang 2011-08-01 14:10 ` Grant Likely 0 siblings, 1 reply; 27+ messages in thread From: Haojian Zhuang @ 2011-08-01 2:47 UTC (permalink / raw) To: linux-arm-kernel On Sat, Jul 30, 2011 at 12:36 AM, Grant Likely <grant.likely@secretlab.ca> wrote: > On Thu, Jul 28, 2011 at 02:41:27PM +0800, Haojian Zhuang wrote: >> Parse irq sepcifier from DT and translate it to Linux irq number. >> Remove the definition of NR_IRQS in irqs.h. Since sparse irq is >> enabled, nr_irqs will be calculated automatically. >> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> >> --- >> ?.../devicetree/bindings/arm/marvell/intc.txt ? ? ? | ?114 ++++++++++ >> ?arch/arm/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 + >> ?arch/arm/mach-mmp/Makefile ? ? ? ? ? ? ? ? ? ? ? ? | ? ?2 + >> ?arch/arm/mach-mmp/common.h ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 + >> ?arch/arm/mach-mmp/include/mach/irqs.h ? ? ? ? ? ? ?| ? ?2 +- >> ?arch/arm/mach-mmp/intc.c ? ? ? ? ? ? ? ? ? ? ? ? ? | ?224 ++++++++++++++++++++ >> ?6 files changed, 343 insertions(+), 1 deletions(-) >> ?create mode 100644 Documentation/devicetree/bindings/arm/marvell/intc.txt >> ?create mode 100644 arch/arm/mach-mmp/intc.c >> >> diff --git a/Documentation/devicetree/bindings/arm/marvell/intc.txt b/Documentation/devicetree/bindings/arm/marvell/intc.txt >> new file mode 100644 >> index 0000000..80cef58 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/arm/marvell/intc.txt >> @@ -0,0 +1,114 @@ >> +* Interrupt Controller Binding for ARCH-MMP >> + >> +This binding specifies what properties must be available in device tree representation of an ARCH-MMP compliant interrupt controller. >> + >> +Required properties: >> + >> + ? ? - compatible: Specifies the compatibility list of the interrupt >> + ? ? ? controller. The type shall be <string> and the value shall be >> + ? ? ? "mrvl,pxa168-intc" or "mrvl,mmp2-mux-intc". >> + ? ? ? "mrvl,pxa168-intc" is the base interrupt controller. It must be >> + ? ? ? included. It's compatible for pxa910, mmp2. "mrvl,mmp2-mux-intc" >> + ? ? ? is the expanded interrupt controller, and it's optional. >> + >> + ? ? - reg: Specified the base physical address(s) and size(s) of the >> + ? ? ? interrupt controller's addressable register space. The type >> + ? ? ? should be <prop-encoded-array>. >> + >> + ? ? - interrupt-controller: The presence of this property identifies >> + ? ? ? the node as interrupt controller. No property value should be >> + ? ? ? defined. >> + >> + ? ? - #interrupt-cells: Specifies the number of cells needed to encode >> + ? ? ? an interrupt source. The type should be <u32> and the value should >> + ? ? ? be 1. >> + >> + ? ? - mrvl,intc-numbers: Specifies the number of interrupts is supported >> + ? ? ? in this interrupt controller. The type should be <u32>. >> + >> +Optional properties: >> + >> + ? ? - mrvl,intc-priority: Specifies the which path the interrupt is routed >> + ? ? ? and the priority of this interrupt. The property is used in >> + ? ? ? pxa168-intc. The value should be <u32>. >> + >> + ? ? - mrvl,status-offset: Specifies the offset of status register. The >> + ? ? ? property is used in mmp2-mux-intc. The type should be <u32>. >> + >> + ? ? - mrvl,mask-offset: Specifies the offset of mask register. The >> + ? ? ? property is used in mmp2-mux-intc. The type should be <u32>. >> + >> + ? ? - mrvl,mfp-edge: Specifies the address of mfp edge detection register. >> + ? ? ? The property is used while acking specified interrupt. The type >> + ? ? ? should be <prop-encoded-array>. The first cell indicates the address >> + ? ? ? of mfp edge detection register. The second cell indicates the >> + ? ? ? index of interrupt in current interrupt controller that should >> + ? ? ? handle mfp edge detection. >> + >> +* Examples >> + >> +Example 1: >> + >> + ? ? /* >> + ? ? ?* base INTC >> + ? ? ?*/ >> + ? ? mmp_intc: interrupt-controller at d4282000 { >> + ? ? ? ? ? ? /* Compatible with pxa168-intc. */ >> + ? ? ? ? ? ? compatible = "mrvl,pxa168-intc"; >> + ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? #size-cells = <1>; >> + ? ? ? ? ? ? /* Offset address of 0xd4282000 and size of 0x400. */ >> + ? ? ? ? ? ? reg = <0xd4282000 0x400>; >> + >> + ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? interrupt-controller; >> + >> + ? ? ? ? ? ? /* 64 interrupts are supported in this INTC. */ >> + ? ? ? ? ? ? mrvl,intc-numbers = <64>; >> + >> + ? ? ? ? ? ? /* priority bits in configuration register */ >> + ? ? ? ? ? ? mrvl,intc-priority = <0x20>; >> + ? ? }; >> + >> +Example 2: >> + >> + ? ? /* >> + ? ? ?* mux INTC that is internal wired to base INTC >> + ? ? ?*/ >> + ? ? mux_intc4: interrupt-controller at d4282150 { >> + ? ? ? ? ? ? compatible = "mrvl,mmp2-mux-intc"; >> + ? ? ? ? ? ? #address-cells = <1>; >> + ? ? ? ? ? ? #size-cells = <1>; >> + ? ? ? ? ? ? reg = <0xd4282000 0x400>; >> + >> + ? ? ? ? ? ? #interrupt-cells = <1>; >> + ? ? ? ? ? ? interrupt-controller; >> + ? ? ? ? ? ? interrupt-parent = <&mmp_intc>; >> + >> + ? ? ? ? ? ? /* interrupt source '4' of parent INTC. */ >> + ? ? ? ? ? ? interrupts = <4>; >> + >> + ? ? ? ? ? ? /* 2 interrupts are supported in this INTC. */ >> + ? ? ? ? ? ? mrvl,intc-numbers = <2>; >> + >> + ? ? ? ? ? ? /* Status offset address of 0x150. */ >> + ? ? ? ? ? ? mrvl,status-offset = <0x150>; >> + >> + ? ? ? ? ? ? /* Mask offset address of 0x168. */ >> + ? ? ? ? ? ? mrvl,mask-offset = <0x168>; >> + >> + ? ? ? ? ? ? /* mfp register of 0xd401e2c4 & interrupt index of 1 */ >> + ? ? ? ? ? ? mrvl,mfp-edge = <0xd401e2c4 1>; >> + ? ? }; >> + >> +Example 3: >> + ? ? /* >> + ? ? ?* An interrupt generating device that is wired to an INTC. >> + ? ? ?*/ >> + ? ? uart0: uart at d4030000 { >> + ? ? ? ? ? ? /* parent's '#interrupt-cells' property. */ >> + ? ? ? ? ? ? interrupts = <27>; >> + >> + ? ? ? ? ? ? /* The INTC that this device is wired to. */ >> + ? ? ? ? ? ? interrupt-parent = <&mmp_intc>; >> + ? ? }; >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig >> index 17507b8..f18eb14 100644 >> --- a/arch/arm/Kconfig >> +++ b/arch/arm/Kconfig >> @@ -542,6 +542,7 @@ config ARCH_MMP >> ? ? ? select ARCH_REQUIRE_GPIOLIB >> ? ? ? select CLKDEV_LOOKUP >> ? ? ? select GENERIC_CLOCKEVENTS >> + ? ? select GENERIC_IRQ_CHIP >> ? ? ? select HAVE_SCHED_CLOCK >> ? ? ? select TICK_ONESHOT >> ? ? ? select PLAT_PXA >> diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile >> index 5c68382..e7862ea 100644 >> --- a/arch/arm/mach-mmp/Makefile >> +++ b/arch/arm/mach-mmp/Makefile >> @@ -4,6 +4,8 @@ >> >> ?obj-y ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?+= common.o clock.o devices.o time.o >> >> +obj-$(CONFIG_OF_IRQ) ? ? ? ? += intc.o >> + > > I'm still really confused about why an entirely new interrupt > controller file is being added. ?Drivers already exist in mach-mmp > for the mux and pxa168 interrupt controllers, but this adds a whole > new driver. ?I would expect the existing drivers should be refactored > to use irq generic chip, and then extend them to add DT support. > Before applying this patch, two irq (irq-pxa168.c & irq-mmp2.c) exists. The block issue of merging them together is different register. Now DT can resolve different register. I'm planning to remove both of irq-pxa168.c & irq-mmp2.c after these DT patches. >> ?# SoC support >> ?obj-$(CONFIG_CPU_PXA168) ? ? += pxa168.o irq-pxa168.o >> ?obj-$(CONFIG_CPU_PXA910) ? ? += pxa910.o irq-pxa168.o >> diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h >> index ec8d65d..1c563c2 100644 >> --- a/arch/arm/mach-mmp/common.h >> +++ b/arch/arm/mach-mmp/common.h >> @@ -6,3 +6,4 @@ extern void timer_init(int irq); >> >> ?extern void __init icu_init_irq(void); >> ?extern void __init mmp_map_io(void); >> +extern void __init mmp_init_intc(void); >> diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h >> index a09d328..65ec176 100644 >> --- a/arch/arm/mach-mmp/include/mach/irqs.h >> +++ b/arch/arm/mach-mmp/include/mach/irqs.h >> @@ -224,6 +224,6 @@ >> >> ?#define IRQ_BOARD_START ? ? ? ? ? ? ? ? ? ? ?(IRQ_GPIO_START + IRQ_GPIO_NUM) >> >> -#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(IRQ_BOARD_START) >> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0 > > Why is NR_IRQs getting changed? ?I think this will break > !CONFIG_SPARSE_IRQS, and it shouldn't be necessary for this > conversion. > If CONFIG_SPARSE_IRQ is enabled, arch_probe_nr_irqs() returns NR_IRQS in arm. It results registering NR_IRQS in early_irq_init(). If NR_IRQS is 200, 200 irqs are registered in early_irq_init(). It's not my requirement. What I need is registering irq from DT. So I have to define NR_IRQS to 0. And CONFIG_SPARSE_IRQS is always enabled in ARCH_MMP. So it's selected in Kconfig by default. >> >> >> -- >> Regards, >> Shawn >> >> ?#endif /* __ASM_MACH_IRQS_H */ >> diff --git a/arch/arm/mach-mmp/intc.c b/arch/arm/mach-mmp/intc.c >> new file mode 100644 >> index 0000000..2e44057 >> --- /dev/null >> +++ b/arch/arm/mach-mmp/intc.c >> @@ -0,0 +1,224 @@ >> +/* >> + * ?linux/arch/arm/mach-mmp/intc.c >> + * >> + * ?Generic IRQ handling >> + * >> + * ?Author: ?Haojian Zhuang <haojian.zhuang@marvell.com> >> + * ?Copyright: ? ? ? Marvell International Ltd. 2011 >> + * >> + * ?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/errno.h> >> +#include <linux/io.h> >> +#include <linux/kernel.h> >> +#include <linux/of.h> >> +#include <linux/of_address.h> >> +#include <linux/of_irq.h> >> +#include <linux/slab.h> >> + >> +struct mmp_intc_info { >> + ? ? unsigned int ? ? ? ? ? ?en_mask; >> + ? ? void __iomem ? ? ? ? ? ?*virt_base; >> + ? ? void __iomem ? ? ? ? ? ?*status; >> + ? ? void __iomem ? ? ? ? ? ?*mfp_edge; >> + ? ? unsigned int ? ? ? ? ? ?mfp_edge_index; /* index in irq domain */ >> +}; >> + >> +static void mux_irq_ack(struct irq_data *d) >> +{ >> + ? ? struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); >> + ? ? struct irq_chip_type *ct; >> + ? ? struct mmp_intc_info *info; >> + ? ? unsigned int data, irq_offs; >> + >> + ? ? ct = gc->chip_types; >> + ? ? info = (struct mmp_intc_info *)ct->regs.ack; >> + ? ? irq_offs = d->irq - gc->irq_base; >> + ? ? /* clear MFP edge-detect */ >> + ? ? if (info->mfp_edge && (info->mfp_edge_index == irq_offs)) { >> + ? ? ? ? ? ? data = __raw_readl(info->mfp_edge); >> + ? ? ? ? ? ? __raw_writel(data | (1 << 6), info->mfp_edge); >> + ? ? ? ? ? ? __raw_writel(data, info->mfp_edge); >> + ? ? } >> +} >> + >> +static void mmp_irq_demux_handler(unsigned int irq, struct irq_desc *desc) >> +{ >> + ? ? struct irq_chip_generic *gc = irq_get_handler_data(irq); >> + ? ? struct irq_chip_type *ct; >> + ? ? struct mmp_intc_info *info; >> + ? ? unsigned long status, n; >> + >> + ? ? ct = gc->chip_types; >> + ? ? info = (struct mmp_intc_info *)ct->regs.ack; >> + ? ? while (1) { >> + ? ? ? ? ? ? status = __raw_readl(info->status) & ~gc->mask_cache; >> + ? ? ? ? ? ? if (status == 0) >> + ? ? ? ? ? ? ? ? ? ? break; >> + ? ? ? ? ? ? n = find_first_bit(&status, BITS_PER_LONG); >> + ? ? ? ? ? ? while (n < BITS_PER_LONG) { >> + ? ? ? ? ? ? ? ? ? ? generic_handle_irq(gc->irq_base + n); >> + ? ? ? ? ? ? ? ? ? ? n = find_next_bit(&status, BITS_PER_LONG, n + 1); >> + ? ? ? ? ? ? } >> + ? ? } >> +} >> + >> +static void mux_init_intc(struct mmp_intc_info *mmp_info) >> +{ >> + ? ? struct device_node *np; >> + ? ? struct mmp_intc_info *mux_info; >> + ? ? struct irq_chip_generic *gc; >> + ? ? struct irq_chip_type *ct; >> + ? ? const __be32 *edge; >> + ? ? unsigned int addr = 0, offs = 0; >> + ? ? unsigned int status, mask, irq_base, nr, data; >> + ? ? int cascade; >> + >> + ? ? for_each_compatible_node(np, NULL, "mrvl,mmp2-mux-intc") { >> + ? ? ? ? ? ? if (of_get_property(np, "interrupt-controller", NULL) == NULL) >> + ? ? ? ? ? ? ? ? ? ? continue; >> + ? ? ? ? ? ? if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { >> + ? ? ? ? ? ? ? ? ? ? pr_warn("intc-numbers property is missed\n"); >> + ? ? ? ? ? ? ? ? ? ? continue; >> + ? ? ? ? ? ? } >> + ? ? ? ? ? ? if (of_property_read_u32(np, "mrvl,status-offset", &status) >> + ? ? ? ? ? ? ? ? ? ? < 0) { >> + ? ? ? ? ? ? ? ? ? ? pr_warn("intc-status property is missed\n"); >> + ? ? ? ? ? ? ? ? ? ? continue; >> + ? ? ? ? ? ? } >> + ? ? ? ? ? ? if (of_property_read_u32(np, "mrvl,mask-offset", &mask) < 0) { >> + ? ? ? ? ? ? ? ? ? ? pr_warn("intc-mask property is missed\n"); >> + ? ? ? ? ? ? ? ? ? ? continue; >> + ? ? ? ? ? ? } >> + >> + ? ? ? ? ? ? mux_info = kzalloc(sizeof(*mux_info), GFP_KERNEL); >> + ? ? ? ? ? ? if (mux_info == NULL) >> + ? ? ? ? ? ? ? ? ? ? goto out; >> + ? ? ? ? ? ? status += (unsigned int)mmp_info->virt_base; >> + ? ? ? ? ? ? mux_info->status = (void __iomem *)status; >> + >> + ? ? ? ? ? ? edge = of_get_property(np, "mrvl,mfp-edge", NULL); >> + ? ? ? ? ? ? if (edge) { >> + ? ? ? ? ? ? ? ? ? ? addr = be32_to_cpu(*edge) & PAGE_MASK; >> + ? ? ? ? ? ? ? ? ? ? offs = be32_to_cpu(*edge) - addr; >> + ? ? ? ? ? ? ? ? ? ? mux_info->mfp_edge = ioremap(addr, PAGE_SIZE) + offs; >> + ? ? ? ? ? ? ? ? ? ? mux_info->mfp_edge_index = be32_to_cpu(*++edge); >> + ? ? ? ? ? ? ? ? ? ? /* clear mfp edge detection for initialization */ >> + ? ? ? ? ? ? ? ? ? ? data = __raw_readl(mux_info->mfp_edge); >> + ? ? ? ? ? ? ? ? ? ? __raw_writel(data | (1 << 6), mux_info->mfp_edge); >> + ? ? ? ? ? ? ? ? ? ? __raw_writel(data, mux_info->mfp_edge); >> + ? ? ? ? ? ? } >> + >> + ? ? ? ? ? ? /* allocate new irq */ >> + ? ? ? ? ? ? cascade = irq_of_parse_and_map(np, 0); >> + ? ? ? ? ? ? irq_base = irq_alloc_descs(-1, 0, nr, 0); >> + ? ? ? ? ? ? irq_domain_add_simple(np, irq_base); >> + >> + ? ? ? ? ? ? gc = irq_alloc_generic_chip("mux-intc", 1, irq_base, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmp_info->virt_base, handle_level_irq); >> + ? ? ? ? ? ? ct = gc->chip_types; >> + ? ? ? ? ? ? ct->regs.ack = (unsigned int)mux_info; >> + ? ? ? ? ? ? ct->regs.mask = mask; >> + ? ? ? ? ? ? ct->chip.irq_ack = mux_irq_ack; >> + ? ? ? ? ? ? ct->chip.irq_mask = irq_gc_mask_set_bit; >> + ? ? ? ? ? ? ct->chip.irq_unmask = irq_gc_mask_clr_bit; >> + ? ? ? ? ? ? irq_setup_generic_chip(gc, IRQ_MSK(nr), IRQ_GC_INIT_MASK_CACHE, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQ_NOREQUEST | IRQ_NOPROBE, 0); >> + >> + ? ? ? ? ? ? irq_set_handler_data(cascade, gc); >> + ? ? ? ? ? ? irq_set_chained_handler(cascade, mmp_irq_demux_handler); >> + ? ? } >> +out: >> + ? ? return; >> +} >> + >> +static void mmp_irq_unmask(struct irq_data *d) >> +{ >> + ? ? struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); >> + >> + ? ? /* ICU_INT_CONF */ >> + ? ? __raw_writel(info->en_mask, info->virt_base + (d->irq << 2)); >> +} >> + >> +static void mmp_irq_mask(struct irq_data *d) >> +{ >> + ? ? struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); >> + >> + ? ? __raw_writel(0, info->virt_base + (d->irq << 2)); >> +} >> + >> +static struct irq_chip mmp_irq_chip = { >> + ? ? .name ? ? ? ? ? = "mmp-intc", >> + ? ? .irq_unmask ? ? = mmp_irq_unmask, >> + ? ? .irq_mask ? ? ? = mmp_irq_mask, >> + ? ? .irq_ack ? ? ? ?= mmp_irq_mask, >> +}; >> + >> +void __init mmp_init_intc(void) >> +{ >> + ? ? struct mmp_intc_info *info; >> + ? ? struct device_node *np; >> + ? ? struct resource rs; >> + ? ? unsigned int cells, nr, enable, irq_base; >> + ? ? int i; >> + >> + ? ? np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-intc"); >> + >> + ? ? BUG_ON(!np); >> + >> + ? ? of_node_get(np); >> + ? ? if (of_get_property(np, "interrupt-controller", NULL) == NULL) >> + ? ? ? ? ? ? goto out; >> + ? ? if (of_property_read_u32(np, "#interrupt-cells", &cells) < 0) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: interrupt-cells property is missed\n"); >> + ? ? ? ? ? ? goto out; >> + ? ? } >> + ? ? if (cells != 1) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: interrupt-cells property is incorrect\n"); >> + ? ? ? ? ? ? goto out; >> + ? ? } >> + ? ? if (of_property_read_u32(np, "mrvl,intc-numbers", &nr) < 0) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: mrvl,intc-numbers property is missed\n"); >> + ? ? ? ? ? ? goto out; >> + ? ? } >> + ? ? if (of_property_read_u32(np, "mrvl,intc-priority", &enable) < 0) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: mrvl,intc-priority property is missed\n"); >> + ? ? ? ? ? ? goto out; >> + ? ? } >> + ? ? if (of_address_to_resource(np, 0, &rs) < 0) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: invalid reg property\n"); >> + ? ? ? ? ? ? goto out; >> + ? ? } >> + >> + ? ? info = kzalloc(sizeof(struct mmp_intc_info), GFP_KERNEL); >> + ? ? if (info == NULL) >> + ? ? ? ? ? ? goto out; >> + ? ? info->en_mask = enable; >> + ? ? info->virt_base = ioremap(rs.start, PAGE_SIZE); >> + ? ? if (info->virt_base == NULL) { >> + ? ? ? ? ? ? pr_warn("mmp-intc: failed to remap reg base\n"); >> + ? ? ? ? ? ? goto out_mem; >> + ? ? } >> + >> + ? ? /* allocate new irq */ >> + ? ? irq_base = irq_alloc_descs(-1, 0, nr, 0); >> + ? ? irq_domain_add_simple(np, 0); >> + >> + ? ? for (i = irq_base; i < irq_base + nr; i++) { >> + ? ? ? ? ? ? irq_set_chip_data(i, info); >> + ? ? ? ? ? ? mmp_irq_mask(irq_get_irq_data(i)); >> + ? ? ? ? ? ? irq_set_chip_and_handler(i, &mmp_irq_chip, handle_level_irq); >> + ? ? ? ? ? ? set_irq_flags(i, IRQF_VALID); >> + ? ? } >> + ? ? mux_init_intc(info); >> + ? ? of_node_put(np); >> + ? ? return; >> +out_mem: >> + ? ? kfree(info); >> +out: >> + ? ? of_node_put(np); >> + ? ? return; >> +} >> -- >> 1.5.6.5 >> > ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-08-01 2:47 ` Haojian Zhuang @ 2011-08-01 14:10 ` Grant Likely 2011-08-01 14:42 ` Haojian Zhuang 0 siblings, 1 reply; 27+ messages in thread From: Grant Likely @ 2011-08-01 14:10 UTC (permalink / raw) To: linux-arm-kernel On Mon, Aug 01, 2011 at 10:47:06AM +0800, Haojian Zhuang wrote: > On Sat, Jul 30, 2011 at 12:36 AM, Grant Likely > <grant.likely@secretlab.ca> wrote: > >> diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h > >> index ec8d65d..1c563c2 100644 > >> --- a/arch/arm/mach-mmp/common.h > >> +++ b/arch/arm/mach-mmp/common.h > >> @@ -6,3 +6,4 @@ extern void timer_init(int irq); > >> > >> ?extern void __init icu_init_irq(void); > >> ?extern void __init mmp_map_io(void); > >> +extern void __init mmp_init_intc(void); > >> diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h > >> index a09d328..65ec176 100644 > >> --- a/arch/arm/mach-mmp/include/mach/irqs.h > >> +++ b/arch/arm/mach-mmp/include/mach/irqs.h > >> @@ -224,6 +224,6 @@ > >> > >> ?#define IRQ_BOARD_START ? ? ? ? ? ? ? ? ? ? ?(IRQ_GPIO_START + IRQ_GPIO_NUM) > >> > >> -#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(IRQ_BOARD_START) > >> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0 > > > > Why is NR_IRQs getting changed? ?I think this will break > > !CONFIG_SPARSE_IRQS, and it shouldn't be necessary for this > > conversion. > > > If CONFIG_SPARSE_IRQ is enabled, arch_probe_nr_irqs() returns NR_IRQS in arm. > It results registering NR_IRQS in early_irq_init(). If NR_IRQS is 200, > 200 irqs are > registered in early_irq_init(). It's not my requirement. What I need > is registering irq > from DT. > > So I have to define NR_IRQS to 0. And CONFIG_SPARSE_IRQS is always enabled > in ARCH_MMP. So it's selected in Kconfig by default. My point is, that applying this patch will break anyone depending on non-DT mach-mmp support. I'm completely fine with you doing so, but you need to be extra careful that it is done in a bisectable way. At no point in the commit series should the kernel be unable to build a working mmp image. g. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-08-01 14:10 ` Grant Likely @ 2011-08-01 14:42 ` Haojian Zhuang 2011-08-01 14:43 ` Grant Likely 0 siblings, 1 reply; 27+ messages in thread From: Haojian Zhuang @ 2011-08-01 14:42 UTC (permalink / raw) To: linux-arm-kernel On Mon, Aug 1, 2011 at 10:10 PM, Grant Likely <grant.likely@secretlab.ca> wrote: > On Mon, Aug 01, 2011 at 10:47:06AM +0800, Haojian Zhuang wrote: >> On Sat, Jul 30, 2011 at 12:36 AM, Grant Likely >> <grant.likely@secretlab.ca> wrote: >> >> diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h >> >> index ec8d65d..1c563c2 100644 >> >> --- a/arch/arm/mach-mmp/common.h >> >> +++ b/arch/arm/mach-mmp/common.h >> >> @@ -6,3 +6,4 @@ extern void timer_init(int irq); >> >> >> >> ?extern void __init icu_init_irq(void); >> >> ?extern void __init mmp_map_io(void); >> >> +extern void __init mmp_init_intc(void); >> >> diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h >> >> index a09d328..65ec176 100644 >> >> --- a/arch/arm/mach-mmp/include/mach/irqs.h >> >> +++ b/arch/arm/mach-mmp/include/mach/irqs.h >> >> @@ -224,6 +224,6 @@ >> >> >> >> ?#define IRQ_BOARD_START ? ? ? ? ? ? ? ? ? ? ?(IRQ_GPIO_START + IRQ_GPIO_NUM) >> >> >> >> -#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(IRQ_BOARD_START) >> >> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0 >> > >> > Why is NR_IRQs getting changed? ?I think this will break >> > !CONFIG_SPARSE_IRQS, and it shouldn't be necessary for this >> > conversion. >> > >> If CONFIG_SPARSE_IRQ is enabled, arch_probe_nr_irqs() returns NR_IRQS in arm. >> It results registering NR_IRQS in early_irq_init(). If NR_IRQS is 200, >> 200 irqs are >> registered in early_irq_init(). It's not my requirement. What I need >> is registering irq >> from DT. >> >> So I have to define NR_IRQS to 0. And CONFIG_SPARSE_IRQS is always enabled >> in ARCH_MMP. So it's selected in Kconfig by default. > > My point is, that applying this patch will break anyone depending on > non-DT mach-mmp support. ?I'm completely fine with you doing so, but > you need to be extra careful that it is done in a bisectable way. ?At > no point in the commit series should the kernel be unable to build a > working mmp image. > > g. > > Since .nr_irqs property is assigned in machine descriptor of brownstone.c or ttc_dkb.c, nr_irqs equals to machine_desc->nr_irqs (arch/arm/kernel/irq.c). Even NR_IRQS is defined as 0, machine_desc->nr_irqs can help us to pre-allocate irq numbers while CONFIG_OF isn't defined. So it's not an issue in ARCH_MMP. And I tested it that everything is well. Thanks Haojian ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-08-01 14:42 ` Haojian Zhuang @ 2011-08-01 14:43 ` Grant Likely 0 siblings, 0 replies; 27+ messages in thread From: Grant Likely @ 2011-08-01 14:43 UTC (permalink / raw) To: linux-arm-kernel On Mon, Aug 1, 2011 at 3:42 PM, Haojian Zhuang <haojian.zhuang@gmail.com> wrote: > On Mon, Aug 1, 2011 at 10:10 PM, Grant Likely <grant.likely@secretlab.ca> wrote: >> On Mon, Aug 01, 2011 at 10:47:06AM +0800, Haojian Zhuang wrote: >>> On Sat, Jul 30, 2011 at 12:36 AM, Grant Likely >>> <grant.likely@secretlab.ca> wrote: >>> >> diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h >>> >> index ec8d65d..1c563c2 100644 >>> >> --- a/arch/arm/mach-mmp/common.h >>> >> +++ b/arch/arm/mach-mmp/common.h >>> >> @@ -6,3 +6,4 @@ extern void timer_init(int irq); >>> >> >>> >> ?extern void __init icu_init_irq(void); >>> >> ?extern void __init mmp_map_io(void); >>> >> +extern void __init mmp_init_intc(void); >>> >> diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h >>> >> index a09d328..65ec176 100644 >>> >> --- a/arch/arm/mach-mmp/include/mach/irqs.h >>> >> +++ b/arch/arm/mach-mmp/include/mach/irqs.h >>> >> @@ -224,6 +224,6 @@ >>> >> >>> >> ?#define IRQ_BOARD_START ? ? ? ? ? ? ? ? ? ? ?(IRQ_GPIO_START + IRQ_GPIO_NUM) >>> >> >>> >> -#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(IRQ_BOARD_START) >>> >> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0 >>> > >>> > Why is NR_IRQs getting changed? ?I think this will break >>> > !CONFIG_SPARSE_IRQS, and it shouldn't be necessary for this >>> > conversion. >>> > >>> If CONFIG_SPARSE_IRQ is enabled, arch_probe_nr_irqs() returns NR_IRQS in arm. >>> It results registering NR_IRQS in early_irq_init(). If NR_IRQS is 200, >>> 200 irqs are >>> registered in early_irq_init(). It's not my requirement. What I need >>> is registering irq >>> from DT. >>> >>> So I have to define NR_IRQS to 0. And CONFIG_SPARSE_IRQS is always enabled >>> in ARCH_MMP. So it's selected in Kconfig by default. >> >> My point is, that applying this patch will break anyone depending on >> non-DT mach-mmp support. ?I'm completely fine with you doing so, but >> you need to be extra careful that it is done in a bisectable way. ?At >> no point in the commit series should the kernel be unable to build a >> working mmp image. >> >> g. >> >> > > Since .nr_irqs property is assigned in machine descriptor of brownstone.c or > ttc_dkb.c, nr_irqs equals to machine_desc->nr_irqs (arch/arm/kernel/irq.c). > > Even NR_IRQS is defined as 0, machine_desc->nr_irqs can help us to > pre-allocate irq numbers while CONFIG_OF isn't defined. > > So it's not an issue in ARCH_MMP. And I tested it that everything is well. Okay, that answers my question. Thanks. g. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2 1/7] ARM: mmp: parse irq from DT 2011-07-28 6:41 ` [PATCH v2 1/7] ARM: mmp: parse irq from DT Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang 2011-07-29 16:36 ` [PATCH v2 1/7] ARM: mmp: parse irq " Grant Likely @ 2011-08-01 8:26 ` Russell King - ARM Linux 2 siblings, 0 replies; 27+ messages in thread From: Russell King - ARM Linux @ 2011-08-01 8:26 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jul 28, 2011 at 02:41:27PM +0800, Haojian Zhuang wrote: > + unsigned int status, mask, irq_base, nr, data; > + int cascade; > + ... > + mux_info = kzalloc(sizeof(*mux_info), GFP_KERNEL); > + if (mux_info == NULL) > + goto out; > + status += (unsigned int)mmp_info->virt_base; > + mux_info->status = (void __iomem *)status; This is silly. Why not just do: mux_info->status = mmp_info->virt_base + status; and avoid those horrible casts? ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2011-08-01 14:43 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-28 6:41 [PATCH v2 00/07] enable devicetree on arch-mmp Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 1/7] ARM: mmp: parse irq from DT Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration " Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 5/7] tty: serial: check ops before registering console Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Haojian Zhuang 2011-07-28 6:41 ` [PATCH v2 7/7] i2c: pxa: support to parse property Haojian Zhuang 2011-07-29 16:52 ` [PATCH v2 6/7] i2c: pxa: support i2c controller from DT Grant Likely 2011-07-29 16:55 ` Russell King - ARM Linux 2011-07-30 14:29 ` Mitch Bradley 2011-07-30 15:37 ` Russell King - ARM Linux 2011-07-31 0:38 ` Grant Likely 2011-07-29 16:45 ` [PATCH v2 4/7] tty: serial: support device tree in pxa Grant Likely 2011-07-29 16:49 ` Russell King - ARM Linux 2011-07-29 16:53 ` Grant Likely 2011-08-01 2:50 ` Haojian Zhuang 2011-08-01 8:27 ` Russell King - ARM Linux 2011-07-29 16:42 ` [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone Grant Likely 2011-08-01 2:48 ` Haojian Zhuang 2011-07-29 16:40 ` [PATCH v2 2/7] ARM: mmp: parse timer configuration from DT Grant Likely 2011-07-29 16:36 ` [PATCH v2 1/7] ARM: mmp: parse irq " Grant Likely 2011-08-01 2:47 ` Haojian Zhuang 2011-08-01 14:10 ` Grant Likely 2011-08-01 14:42 ` Haojian Zhuang 2011-08-01 14:43 ` Grant Likely 2011-08-01 8:26 ` Russell King - ARM Linux
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).