Re: Pinmux with device tree
On Thu, May 19, 2011 at 3:33 AM, Mitch Bradley wrote: > On 5/18/2011 6:34 AM, Simon Glass wrote: >> >> Hi, >> >> I see a new pinmux system in the LKML. Has anyone looked at how to >> represent pinmux settings in the device tree? >> >> On a related topic, the examples that are used for GPIOs assume a >> flags word which describes things like pull-ups, direction, etc. This >> seems pretty cumbersome and gets worse with pinmuxes. People editing >> the device trees want to see symbolic information rather than a coded >> number, a bit like a #define. I can see this can be done with strings >> but this is inefficient in time and space, and is error-prone. Is >> there support for this in device trees that I have missed? > > Open Firmware deals with this by defining both a numerical representation > and a text representation. The numerical representation appears in memory > in device tree property values, and the corresponding text representation is > for display and human input. > Could it be supported by flattened device tree? It seems that open firmware isn't popular in ARM system. > It primarily applies to unit addresses, i.e. the "reg" property value, but > the idea generalizes. The device tree compiler could accept the symbolic > names, converting them into well-defined bitfield values which would be > stored in integer cells within property values. > > > ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
question on peripheral identification register
Hi all, I have one question on peripheral identification register. Is this register only valid for ARM's IP? Is there any spec on this register? Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] ARM: mmp: add device tree support on ttc dkb board
From: Haojian Zhuang The board support of ttc dkb is minimal to system boot. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/ttc-dkb.dts | 12 arch/arm/mach-mmp/Makefile.boot |2 ++ arch/arm/mach-mmp/ttc_dkb.c |6 ++ 3 files changed, 20 insertions(+), 0 deletions(-) create mode 100644 arch/arm/boot/dts/ttc-dkb.dts diff --git a/arch/arm/boot/dts/ttc-dkb.dts b/arch/arm/boot/dts/ttc-dkb.dts new file mode 100644 index 000..f41d666 --- /dev/null +++ b/arch/arm/boot/dts/ttc-dkb.dts @@ -0,0 +1,12 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell TTC DKB"; + compatible = "mrvl,ttc-dkb", "mrvl,pxa910-dkb"; + + memory { + reg = <0x 0x1000>; + }; +}; diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot index 574a4aa..d6fe1fc 100644 --- a/arch/arm/mach-mmp/Makefile.boot +++ b/arch/arm/mach-mmp/Makefile.boot @@ -1 +1,3 @@ zreladdr-y := 0x8000 + +dtb-$(CONFIG_MACH_TTC_DKB) += mmp-dkb.dtb diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index e411039..7f7e7fe 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -124,10 +124,16 @@ static void __init ttc_dkb_init(void) platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices)); } +static const char *ttc_dkb_dt_match[] __initdata = { + "mrvl,ttc-dkb", + NULL, +}; + MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform") .map_io = mmp_map_io, .nr_irqs= TTCDKB_NR_IRQS, .init_irq = pxa910_init_irq, .timer = &pxa910_timer, .init_machine = ttc_dkb_init, + .dt_compat = ttc_dkb_dt_match, MACHINE_END -- 1.7.4.1 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] ARM: mmp: remove SPARSE_IRQ for mmp
Avoid to use SPARSE_IRQ for mmp. There will be irq domain translation between DT irq specifier and the Linux irq number. Signed-off-by: Haojian Zhuang --- arch/arm/Kconfig |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 17507b8..48748fb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -545,7 +545,6 @@ config ARCH_MMP select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA - select SPARSE_IRQ help Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line. -- 1.5.6.5 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] mfd: convert devicetree to platform data on max8925
Make max8925 to support both platform data and device tree. So a translation between device tree and platform data is added. Signed-off-by: Haojian Zhuang --- drivers/mfd/max8925-i2c.c | 159 - 1 files changed, 157 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 0219115..fb74554 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -10,6 +10,9 @@ */ #include #include +#include +#include +#include #include #include #include @@ -135,6 +138,154 @@ static const struct i2c_device_id max8925_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, max8925_id_table); +#ifdef CONFIG_OF +static int __devinit max8925_parse_irq(struct i2c_client *i2c, + struct max8925_platform_data *pdata) +{ + struct device_node *of_node = i2c->dev.of_node; + + pdata->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0); + irq_domain_add_simple(of_node, pdata->irq_base); + return 0; +} + +static void __devinit max8925_parse_backlight(struct device_node *np, + struct max8925_platform_data *pdata) +{ + struct max8925_backlight_pdata *bk; + const __be32 *p; + + bk = kzalloc(sizeof(struct max8925_backlight_pdata), GFP_KERNEL); + if (bk == NULL) + return; + pdata->backlight = bk; + p = of_get_property(np, "lxw-scl", NULL); + if (p) + bk->lxw_scl = be32_to_cpu(*p); + p = of_get_property(np, "lxw-freq", NULL); + if (p) + bk->lxw_freq = be32_to_cpu(*p); + p = of_get_property(np, "dual-string", NULL); + if (p) + bk->dual_string = be32_to_cpu(*p); +} + +static void __devinit max8925_parse_touch(struct device_node *np, + struct max8925_platform_data *pdata) +{ + struct max8925_touch_pdata *touch; + const __be32 *p; + + touch = kzalloc(sizeof(struct max8925_touch_pdata), GFP_KERNEL); + if (touch == NULL) + return; + pdata->touch = touch; + p = of_get_property(np, "flags", NULL); + if (p) + touch->flags = be32_to_cpu(*p); + p = of_get_property(np, "interrupts", NULL); + if (p) + pdata->tsc_irq = irq_of_parse_and_map(np, 0); +} + +static void __devinit max8925_parse_power(struct device_node *np, + struct max8925_platform_data *pdata) +{ + struct max8925_power_pdata *power; + const __be32 *p; + + power = kzalloc(sizeof(struct max8925_power_pdata), GFP_KERNEL); + if (power == NULL) + return; + pdata->power = power; + p = of_get_property(np, "battery-detect", NULL); + if (p) + power->batt_detect = be32_to_cpu(*p) ? 1 : 0; + p = of_get_property(np, "topoff-threshold", NULL); + if (p) + power->topoff_threshold = be32_to_cpu(*p) & 0x3; + p = of_get_property(np, "fast-charge", NULL); + if (p) + power->fast_charge = be32_to_cpu(*p) & 0x7; +} + +static void __devinit max8925_parse_regulator(struct device_node *np, + struct max8925_platform_data *pdata) +{ + const char *name[MAX8925_MAX_REGULATOR] = { + "SD1", "SD2", "SD3", "LDO1", "LDO2", "LDO3", "LDO4", + "LDO5", "LDO6", "LDO7", "LDO8", "LDO9", "LDO10", + "LDO11", "LDO12", "LDO13", "LDO14", "LDO15", "LDO16", + "LDO17", "LDO18", "LDO19", "LDO20"}; + const char *cp; + int i; + + cp = of_get_property(np, "compatible", NULL); + if (cp == NULL) + return; + for (i = 0; i < MAX8925_MAX_REGULATOR; i++) { + if (strncmp(cp, name[i], strlen(name[i]))) + continue; + of_regulator_init_data(np, pdata->regulator[i]); + break; + } +} + +static struct max8925_platform_data __devinit +*max8925_get_alt_pdata(struct i2c_client *client) +{ + struct max8925_platform_data *pdata; + struct device_node *of_node = client->dev.of_node; + struct device_node *np, *pp = NULL; + const char *cp; + int ret, i; + + pdata = kzalloc(sizeof(struct max8925_platform_data), GFP_KERNEL); + if (pdata == NULL) + return NULL; + pdata->regulator[0] = kzalloc(sizeof(struct regulator_init_data) + * MA
[PATCH] ARM: mmp: remove builtin gpio driver support
Remove builtin gpio driver support form mmp. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/include/mach/gpio.h | 27 +++ arch/arm/mach-mmp/mmp2.c | 17 - arch/arm/mach-mmp/pxa168.c| 17 - arch/arm/mach-mmp/pxa910.c| 17 - arch/arm/plat-pxa/Makefile|2 ++ 5 files changed, 5 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h index 7bfb827..829f165 100644 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ b/arch/arm/mach-mmp/include/mach/gpio.h @@ -1,36 +1,15 @@ #ifndef __ASM_MACH_GPIO_H #define __ASM_MACH_GPIO_H -#include -#include #include -#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000) - -#define BANK_OFF(n)(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) -#define GPIO_REG(x)(*((volatile u32 *)(GPIO_REGS_VIRT + (x - -#define NR_BUILTIN_GPIOIRQ_GPIO_NUM - #define gpio_to_bank(gpio) ((gpio) >> 5) -#define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio)) -#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_START) +#define bank_to_gpio(nr) (nr << 5) +#define GPIO_bit(gpio) (1 << ((gpio) & 0x1f)) +#define gpio_to_irq(nr)__gpio_to_irq(nr) #define __gpio_is_inverted(gpio) (0) #define __gpio_is_occupied(gpio) (0) -/* NOTE: these macros are defined here to make optimization of - * gpio_{get,set}_value() to work when 'gpio' is a constant. - * Usage of these macros otherwise is no longer recommended, - * use generic GPIO API whenever possible. - */ -#define GPIO_bit(gpio) (1 << ((gpio) & 0x1f)) - -#define GPLR(x)GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x00) -#define GPDR(x)GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x0c) -#define GPSR(x)GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x18) -#define GPCR(x)GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x24) - -#include #endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 8e6c3ac..d3f9b3b 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -34,8 +34,6 @@ #define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000) -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c) - static struct mfp_addr_map mmp2_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO58, 0x54), @@ -95,24 +93,9 @@ void mmp2_clear_pmic_int(void) __raw_writel(data, mfpr_pmic); } -static void __init mmp2_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO); - - /* unmask GPIO edge detection for all 6 banks -- APMASKx */ - for (i = 0; i < 6; i++) - __raw_writel(0x, APMASK(i)); - - pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL); -} - void __init mmp2_init_irq(void) { mmp2_init_icu(); - mmp2_init_gpio(); } static void sdhc_clk_enable(struct clk *clk) diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 72b4e76..4f41ea2 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -41,26 +41,9 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c) - -static void __init pxa168_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO); - - /* unmask GPIO edge detection for all 4 banks - APMASKx */ - for (i = 0; i < 4; i++) - __raw_writel(0x, APMASK(i)); - - pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL); -} - void __init pxa168_init_irq(void) { icu_init_irq(); - pxa168_init_gpio(); } /* APB peripheral clocks */ diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 8f92ccd..e71a45a 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -78,26 +78,9 @@ static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata = MFP_ADDR_END, }; -#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c) - -static void __init pxa910_init_gpio(void) -{ - int i; - - /* enable GPIO clock */ - __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO); - - /* unmask GPIO edge detection for all 4 banks - APMASKx */ - for (i = 0; i < 4; i++) - __raw_writel(0x, APMASK(i)); - - pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL); -} - void __init pxa910_init_irq(void) { icu_init_irq(); - pxa910_init_gpio(); } /* APB peripheral clocks */ diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index 3aca5ba..8e432b1 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile @@ -4,7 +4,9 @@
[PATCH] regulator: convert devicetree to platform data on max8649
Signed-off-by: Haojian Zhuang --- drivers/regulator/max8649.c | 70 +++ 1 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 30eb9e5..4316a37 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #define MAX8649_DCDC_VMIN 75 /* uV */ @@ -275,6 +276,69 @@ static struct regulator_desc dcdc_desc = { .owner = THIS_MODULE, }; +#ifdef CONFIG_OF_REGULATOR +static struct max8649_platform_data __devinit +*max8649_get_alt_pdata(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + struct max8649_platform_data *pdata; + const __be32 *mode, *extclk, *ramp; + int ret = 0; + + if (np == NULL) + goto out; + + mode = of_get_property(np, "max8649-mode", NULL); + if (mode == NULL) { + dev_err(&client->dev, "mode property is missed\n"); + goto out; + } + extclk = of_get_property(np, "ext-clock-frequency", NULL); + if (extclk == NULL) + dev_dbg(&client->dev, "ext-clock-frequency is not set\n"); + ramp = of_get_property(np, "max8649-ramp", NULL); + if (ramp == NULL) { + dev_err(&client->dev, "ramp is missed\n"); + goto out; + } + + pdata = kzalloc(sizeof(struct max8649_platform_data), GFP_KERNEL); + if (pdata == NULL) + goto out; + pdata->mode = be32_to_cpu(*mode); + if (extclk) { + pdata->extclk = 1; + pdata->extclk_freq = be32_to_cpu(*extclk); + } + if (ramp) { + pdata->ramp_timing = be32_to_cpu(*ramp++); + pdata->ramp_down = be32_to_cpu(*ramp); + } + + pdata->regulator = kzalloc(sizeof(struct regulator_init_data), + GFP_KERNEL); + if (pdata->regulator == NULL) + goto out_pdata; + ret = of_regulator_init_data(np, pdata->regulator); + if (ret < 0) + goto out_regulator; + return pdata; + +out_regulator: + kfree(pdata->regulator); +out_pdata: + kfree(pdata); +out: + return NULL; +} +#else +static struct max8649_platform_data __devinit +*max8649_get_alt_pdata(struct i2c_client *client) +{ + return 0; +} +#endif + static int __devinit max8649_regulator_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -294,6 +358,12 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, mutex_init(&info->io_lock); i2c_set_clientdata(client, info); + if (pdata == NULL) { + pdata = max8649_get_alt_pdata(client); + if (pdata == NULL) + return -ENODEV; + } + info->mode = pdata->mode; switch (info->mode) { case 0: -- 1.5.6.5 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] ARM: mmp: add DTS file
Add DTS file to support brownstone & ttc-dkb. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/mmp2-brownstone.dts | 319 + arch/arm/boot/dts/ttc-dkb.dts | 176 ++ arch/arm/mach-mmp/brownstone.c| 66 ++- arch/arm/mach-mmp/ttc_dkb.c | 21 ++- 4 files changed, 530 insertions(+), 52 deletions(-) create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts create mode 100644 arch/arm/boot/dts/ttc-dkb.dts diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 000..5fdabc3 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -0,0 +1,319 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell MMP2 Brownstone"; + compatible = "mrvl,mmp2-brownstone", "mrvl,armada610-brownstone"; + interrupt-parent = <&mmp_intc>; + + memory { + reg = <0x 0x2000>; + }; + + 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@d400 { + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; + device_type = "soc"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mmp_intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp-intc"; + /*device_type = "intc";*/ + interrupt-controller; + #interrupt-cells = <1>; + /* +* interrupts: irq index of parent's irq domain +*/ + interrupts = <0>; + interrupt-parent = <&mmp_intc>; + sub-interrupts = <64>; + + /* enable bits in conf register */ + enable_mask = <0x20>; + + /* reg: */ + reg = <0xd4282000 0x400>; + }; + + mux_intc4: interrupt-controller@d4282150 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <4>; + interrupt-parent = <&mmp_intc>; + sub-interrupts = <2>; + reg = <0xd4282150 0>; + status-mask = <0x150 0x168>; + /* mfp register & interrupt index */ + mfp-edge-interrupt = <0xd401e2c4 1>; + }; + + mux_intc5: interrupt-controller@d4282154 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <5>; + sub-interrupts = <2>; + interrupt-parent = <&mmp_intc>; + reg = <0xd4282154 0>; + status-mask = <0x154 0x16c>; + }; + + mux_intc9: interrupt-controller@d4282180 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <9>; + interrupt-parent = <&mmp_intc>; + sub-interrupts = <3>; + reg = <0xd4282180 0>; + status-mask = <0x180 0x17c>; + }; + + mux_intc17: interrupt-controller@d4282158 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts = <17>; + interrupt-parent = <&mmp_intc>; + sub-interrupts = <5>; + reg = <0xd4282158 0>; + status-mask = <0x158 0x170>; + }; + + mux_i
[PATCH] ARM: mmp: support OF by default
Support open firmware by default. Signed-off-by: Haojian Zhuang --- arch/arm/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 48748fb..7b083a0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -545,6 +545,7 @@ config ARCH_MMP select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA + select USE_OF help Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line. -- 1.5.6.5 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] tty: serial: check ops before registering console
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 --- 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 fb80fb3..b117fab 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -685,7 +685,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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] tty: serial: support device tree in pxa
Support both normal platform driver and device tree driver in serial pxa. Signed-off-by: Haojian Zhuang --- drivers/tty/serial/Kconfig |4 +- drivers/tty/serial/of_serial.c | 12 + drivers/tty/serial/pxa.c | 91 ++-- include/linux/serial_pxa.h | 17 +++ 4 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 include/linux/serial_pxa.h diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 636144c..3f75e0d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -663,6 +663,8 @@ config SERIAL_MPSC_CONSOLE config SERIAL_PXA bool "PXA serial port support" depends on ARCH_PXA || ARCH_MMP + select SERIAL_OF_PLATFORM + select SERIAL_CORE_CONSOLE select SERIAL_CORE help If you have a machine based on an Intel XScale PXA2xx CPU you @@ -1340,7 +1342,7 @@ config SERIAL_NETX_CONSOLE config SERIAL_OF_PLATFORM tristate "Serial port on Open Firmware platform bus" depends on OF - depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL + depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL || SERIAL_PXA help If you have a PowerPC based system that has serial ports on a platform specific bus, you should enable this option. diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e65f1e8..383bff3 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,11 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) ret = nwpserial_register_port(&port); break; #endif +#ifdef CONFIG_SERIAL_PXA + case PORT_PXA: + ret = serial_pxa_register_port(&port); + break; +#endif default: /* need to add code for these */ case PORT_UNKNOWN: @@ -163,6 +169,11 @@ static int of_platform_serial_remove(struct platform_device *ofdev) nwpserial_unregister_port(info->line); break; #endif +#ifdef CONFIG_SERIAL_PXA + case PORT_PXA: + serial_pxa_unregister_port(info->line); + break; +#endif default: /* need to add code for these */ break; @@ -186,6 +197,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { { .compatible = "ibm,qpace-nwp-serial", .data = (void *)PORT_NWPSERIAL, }, #endif + { .compatible = "pxa,serial", .data = (void *)PORT_PXA, }, { .type = "serial", .data = (void *)PORT_UNKNOWN, }, { /* end of list */ }, }; diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 4302e6e..fb80fb3 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -36,10 +36,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -51,9 +53,14 @@ struct uart_pxa_port { unsigned char mcr; unsigned intlsr_break_flag; struct clk *clk; - char*name; + charname[32]; + int id; }; +#define PXA_SERIAL_NR 4 + +static DEFINE_MUTEX(serial_pxa_mutex); + static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) { offset <<= 2; @@ -346,8 +353,6 @@ static int serial_pxa_startup(struct uart_port *port) else up->mcr = 0; - up->port.uartclk = clk_get_rate(up->clk); - /* * Allocate the IRQ */ @@ -593,7 +598,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 @@ -645,7 +650,7 @@ static void serial_pxa_console_putchar(struct uart_port *port, int ch) static void serial_pxa_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_pxa_port *up = serial_pxa_ports[co->index]; + struct uart_pxa_port *up = &serial_pxa_ports[co->index]; unsigned int ier; clk_enable(up->clk); @@ -679,7 +684,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]; + up = &serial_pxa_ports[co->index]; if (!up) return -ENODEV; @@ -761,6 +766,68 @@ static const struct dev_pm_ops serial_pxa_pm_ops = { }; #endif
[PATCH] i2c: pxa: create dynamic platform device from device tree
Create two probe function to support both current platform device and created dynamic platform device from device tree. After moving to device tree, original implementation of platform device will be removed. Use property to present polling mode and frequency mode. Signed-off-by: Haojian Zhuang --- drivers/i2c/busses/i2c-pxa.c | 163 ++ 1 files changed, 163 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index d603646..7a6d774 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1044,6 +1045,162 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = { .functionality = i2c_pxa_functionality, }; +static const struct of_device_id pxa_i2c_of_match[] = { + { .compatible = "pxa2xx-i2c", .data = (void *)REGS_PXA2XX, }, + { .compatible = "pxa3xx-pwri2c", .data = (void *)REGS_PXA3XX, }, + { .compatible = "ce4100-i2c", .data = (void *)REGS_CE4100, }, + {}, +}; + +#ifdef CONFIG_OF +static int i2c_pxa_of_probe(struct platform_device *of_dev) +{ + struct device_node *np = of_dev->dev.of_node; + const struct of_device_id *match; + struct i2c_pxa_platform_data *plat = NULL; + struct pxa_i2c *i2c; + struct resource *res; + const __be32 *p; + int i2c_type, irq, data, ret; + int id = 0, poll = 0, fast = 0; + + match = of_match_device(pxa_i2c_of_match, &of_dev->dev); + if (match == NULL) + return -ENODEV; + i2c_type = (int)match->data; + + p = of_get_property(np, "cell-index", &data); + if (p) + id = be32_to_cpu(*p); + + p = of_get_property(np, "i2c-polling", &data); + if (p) + poll = be32_to_cpu(*p); + + p = of_get_property(np, "i2c-frequency", &data); + if (p && !strncmp((char *)p, "fast", data)) + fast = 1; + + res = platform_get_resource(of_dev, IORESOURCE_MEM, 0); + irq = platform_get_irq(of_dev, 0); + if (res == NULL || irq < 0) + return -ENODEV; + + if (!request_mem_region(res->start, resource_size(res), res->name)) + return -ENOMEM; + + i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL); + if (!i2c) { + ret = -ENOMEM; + goto emalloc; + } + + i2c->adap.owner = THIS_MODULE; + i2c->adap.retries = 5; + + spin_lock_init(&i2c->lock); + init_waitqueue_head(&i2c->wait); + + /* +* adap.nr comes from cell-index in dts file +*/ + i2c->adap.nr = id; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa2xx-i2c.%u", +i2c->adap.nr); + + i2c->clk = clk_get_sys(i2c->adap.name, NULL); + if (IS_ERR(i2c->clk)) { + ret = PTR_ERR(i2c->clk); + goto eclk; + } + + i2c->reg_base = ioremap(res->start, resource_size(res)); + if (!i2c->reg_base) { + ret = -EIO; + goto eremap; + } + + i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr; + i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr; + i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr; + i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr; + if (i2c_type != REGS_CE4100) + i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar; + + i2c->iobase = res->start; + i2c->iosize = resource_size(res); + + i2c->irq = irq; + i2c->use_pio = poll; + i2c->fast_mode = fast; + + i2c->slave_addr = I2C_PXA_SLAVE_ADDR; + +#ifdef CONFIG_I2C_PXA_SLAVE + if (plat) { + i2c->slave_addr = plat->slave_addr; + i2c->slave = plat->slave; + } +#endif + + clk_enable(i2c->clk); + + if (plat) + i2c->adap.class = plat->class; + + if (i2c->use_pio) { + i2c->adap.algo = &i2c_pxa_pio_algorithm; + } else { + i2c->adap.algo = &i2c_pxa_algorithm; + ret = request_irq(irq, i2c_pxa_handler, IRQF_SHARED, + i2c->adap.name, i2c); + if (ret) + goto ereqirq; + } + + i2c_pxa_reset(i2c); + + i2c->adap.algo_data = i2c; + i2c->adap.dev.parent = &of_dev->dev; + i2c->adap.dev.of_node = of_dev->dev.of_node; + + if (i2c_type == REGS_CE4100) + ret = i2c_add_adapter(&i2c->adap); + else + ret = i2c_
[PATCH] mfd: convert devicetree to platform on 88pm860x
Make 88pm860x to support both platform data and device tree. So a translation between device tree and platform data is added. Signed-off-by: Haojian Zhuang --- drivers/mfd/88pm860x-i2c.c | 191 +++- 1 files changed, 189 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index e017dc8..b017e4a 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -10,6 +10,8 @@ */ #include #include +#include +#include #include #include #include @@ -236,6 +238,187 @@ static const struct i2c_device_id pm860x_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, pm860x_id_table); +#ifdef CONFIG_OF +static int __devinit pm860x_parse_irq(struct i2c_client *i2c, + struct pm860x_platform_data *pdata) +{ + struct device_node *of_node = i2c->dev.of_node; + + pdata->irq_base = irq_alloc_descs(-1, 0, 24, 0); + irq_domain_add_simple(of_node, pdata->irq_base); + return 0; +} + +static void __devinit pm860x_parse_backlight(struct device_node *np, + struct pm860x_platform_data *pdata) +{ + const __be32 *idx, *iset, *pwm; + int i; + + idx = of_get_property(np, "cell-index", NULL); + if (idx == NULL) + return; + iset = of_get_property(np, "iset", NULL); + if (iset == NULL) + return; + pwm = of_get_property(np, "pwm", NULL); + + i = be32_to_cpu(*idx); + pdata->backlight[i].iset = be32_to_cpu(*iset); + pdata->backlight[i].flags = i; + if (pwm) + pdata->backlight[i].pwm = be32_to_cpu(*pwm); + pdata->num_backlights++; +} + +static void __devinit pm860x_parse_led(struct device_node *np, + struct pm860x_platform_data *pdata) +{ + const __be32 *idx, *iset; + int i; + + idx = of_get_property(np, "cell-index", NULL); + if (idx == NULL) + return; + iset = of_get_property(np, "iset", NULL); + if (iset == NULL) + return; + + i = be32_to_cpu(*idx); + pdata->led[i].iset = be32_to_cpu(*iset); + pdata->led[i].flags = i; + pdata->num_leds++; +} + +static void __devinit pm860x_parse_touch(struct device_node *np, + struct pm860x_platform_data *pdata) +{ + struct pm860x_touch_pdata *touch; + const __be32 *prebias, *slot, *res, *prechg; + + prebias = of_get_property(np, "prebias", NULL); + if (prebias == NULL) + return; + slot = of_get_property(np, "slot-cycle", NULL); + if (slot == NULL) + return; + res = of_get_property(np, "resistor-xplate", NULL); + if (res == NULL) + return; + prechg = of_get_property(np, "pen-prechg", NULL); + if (prechg == NULL) + return; + touch = kzalloc(sizeof(struct pm860x_touch_pdata), GFP_KERNEL); + if (touch == NULL) + return; + touch->gpadc_prebias = be32_to_cpu(*prebias++); + touch->tsi_prebias = be32_to_cpu(*prebias++); + touch->pen_prebias = be32_to_cpu(*prebias); + touch->slot_cycle = be32_to_cpu(*slot); + touch->pen_prechg = be32_to_cpu(*prechg); + pdata->touch = touch; +} + +static int data[PM8607_ID_RG_MAX]; + +static void __devinit pm860x_parse_regulator(struct device_node *np, + struct pm860x_platform_data *pdata) +{ + const char *name[PM8607_ID_RG_MAX] = { + "BUCK1", "BUCK2", "BUCK3", "LDO1", "LDO2", "LDO3", "LOD4", + "LDO5", "LDO6", "LDO7", "LDO8", "LDO9", "LDO10", "LDO11", + "LDO12", "LDO13", "LDO14", "LDO15"}; + const char *cp; + int i; + + cp = of_get_property(np, "compatible", NULL); + if (cp == NULL) + return; + for (i = 0; i < PM8607_ID_RG_MAX; i++) { + if (strncmp(cp, name[i], strlen(name[i]))) + continue; + of_regulator_init_data(np, &pdata->regulator[i]); + data[i] = i; + pdata->regulator[i].driver_data = &data[i]; + pdata->num_regulators++; + break; + } +} + +static struct pm860x_platform_data __devinit +*pm860x_get_alt_pdata(struct i2c_client *i2c) +{ + struct pm860x_platform_data *pdata; + struct device_node *of_node = i2c->dev.of_node; + struct device_node *np, *pp = NULL; + const char *cp; + const __be32 *p; + int ret; +
[PATCH] ARM: mmp: parse irq from DT
Parse irq sepcifier from DT and translate it to Linux irq number. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Makefile |2 + arch/arm/mach-mmp/common.h |1 + arch/arm/mach-mmp/intc.c | 245 3 files changed, 248 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mmp/intc.c 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/intc.c b/arch/arm/mach-mmp/intc.c new file mode 100644 index 000..48ad84b --- /dev/null +++ b/arch/arm/mach-mmp/intc.c @@ -0,0 +1,245 @@ +/* + * linux/arch/arm/mach-mmp/intc.c + * + * Generic IRQ handling + * + * Author:Haojian Zhuang + * 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 +#include +#include +#include +#include +#include +#include + +struct mmp_intc_info { + unsigned intmask; + unsigned intphy_base; + void __iomem*virt_base; + void __iomem*mux_status; + void __iomem*mux_mask; + void __iomem*mfp_edge; + unsigned intmfp_edge_index; /* index in irq domain */ + unsigned intirq_base; +}; + +static void mux_irq_unmask(struct irq_data *d) +{ + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); + unsigned int data, irq_offs; + + irq_offs = d->irq - info->irq_base; + 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); + } + data = __raw_readl(info->mux_mask) & ~(1 << (d->irq - info->irq_base)); + __raw_writel(data, info->mux_mask); +} + +static void mux_irq_mask(struct irq_data *d) +{ + struct mmp_intc_info *info = irq_data_get_irq_chip_data(d); + unsigned int data; + + data = __raw_readl(info->mux_mask) | (1 << (d->irq - info->irq_base)); + __raw_writel(data, info->mux_mask); +} + +static struct irq_chip mux_irq_chip = { + .name = "mmp mux intc", + .irq_unmask = mux_irq_unmask, + .irq_mask = mux_irq_mask, + .irq_ack= mux_irq_mask, +}; + +static void mmp_irq_demux_handler(unsigned int irq, struct irq_desc *desc) +{ + struct mmp_intc_info *info = irq_get_handler_data(irq); + unsigned long status, mask, n; + + mask = __raw_readl(info->mux_mask); + while (1) { + status = __raw_readl(info->mux_status) & ~mask; + if (status == 0) + break; + n = find_first_bit(&status, BITS_PER_LONG); + while (n < BITS_PER_LONG) { + generic_handle_irq(info->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; + const __be32 *nr, *status, *edge; + unsigned int addr = 0, offs = 0; + int cascade, irq_nr, i; + + if (mmp_info->virt_base == NULL) + goto out; + + for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) { + if (!of_device_is_compatible(np, "mrvl,mux-intc")) + continue; + if (of_get_property(np, "interrupt-controller", NULL) == NULL) + continue; + nr = of_get_property(np, "sub-interrupts", NULL); + if (nr == NULL) { + printk(KERN_WARNING "sub-interrupts property " + "is missed\n"); + continue; + } + irq_nr = be32_to_cpu(*nr); + status = of_get_property(np, "statu
[PATCH] of: add devicetree API for regulator
Signed-off-by: Haojian Zhuang --- drivers/of/Kconfig |4 + drivers/of/Makefile |1 + drivers/of/of_regulator.c| 166 ++ include/linux/of_regulator.h | 34 + 4 files changed, 205 insertions(+), 0 deletions(-) create mode 100644 drivers/of/of_regulator.c create mode 100644 include/linux/of_regulator.h diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index d06a637..edb6601 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -75,4 +75,8 @@ config OF_PCI help OpenFirmware PCI bus accessors +config OF_REGULATOR + def_tristate REGULATOR + depends on REGULATOR + endmenu # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index f7861ed..83ca06f 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o +obj-$(CONFIG_OF_REGULATOR) += of_regulator.o diff --git a/drivers/of/of_regulator.c b/drivers/of/of_regulator.c new file mode 100644 index 000..d523302 --- /dev/null +++ b/drivers/of/of_regulator.c @@ -0,0 +1,166 @@ +/* + * OF helpers for the Regulator API + * + * Copyright (c) 2011 Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include + +static int of_regulator_init_constraints(struct device_node *of_dev, + struct regulation_constraints *constraints) +{ + const __be32 *p; + const char *cp; + const char *ops[] = {"voltage", "current", "mode", "status", + "drms"}; + int i, size, len = 0, tmp = 0; + + memset(constraints, 0, sizeof(struct regulation_constraints)); + + p = of_get_property(of_dev, "voltages", &size); + if (p && size / sizeof(int) == 2) { + constraints->min_uV = be32_to_cpu(*p++); + constraints->max_uV = be32_to_cpu(*p); + } + p = of_get_property(of_dev, "currents", &size); + if (p && size / sizeof(int) == 2) { + constraints->min_uA = be32_to_cpu(*p++); + constraints->max_uA = be32_to_cpu(*p); + } + p = of_get_property(of_dev, "modes-mask", NULL); + if (p) + constraints->valid_modes_mask = be32_to_cpu(*p); + cp = of_get_property(of_dev, "ops-mask", &size); + tmp = 0; + if (cp && size > 0) { + i = 0; + do { + len = strlen(ops[i]); + if (!strncmp(cp, ops[i], len)) { + constraints->valid_ops_mask |= 1 << i; + /* need to handle '\0' */ + cp += len + 1; + size = size - len - 1; + i = 0; + } else + i++; + } while (i < ARRAY_SIZE(ops)); + if (size > 0) + printk(KERN_WARNING "Invalid string:%s\n", cp); + } + p = of_get_property(of_dev, "input-uV", NULL); + if (p) + constraints->input_uV = be32_to_cpu(*p); + p = of_get_property(of_dev, "state-pm-disk", &size); + if (p && size / sizeof(int) == 3) { + constraints->state_disk.uV = be32_to_cpu(*p++); + constraints->state_disk.mode = be32_to_cpu(*p++); + tmp = be32_to_cpu(*p); + constraints->state_disk.enabled = (tmp) ? 1 : 0; + constraints->state_disk.disabled = (tmp) ? 0 : 1; + } + p = of_get_property(of_dev, "state-pm-mem", &size); + if (p && size / sizeof(int) == 3) { + constraints->state_mem.uV = be32_to_cpu(*p++); + constraints->state_mem.mode = be32_to_cpu(*p++); + tmp = be32_to_cpu(*p); + constraints->state_mem.enabled = (tmp) ? 1 : 0; + constraints->state_mem.disabled = (tmp) ? 0 : 1; + } + p = of_get_property(of_dev, "state-pm-standby", &size); + if (p && size / sizeof(int) == 3) { + constraints->state_standby.uV = be32_to_cpu(*p++); + constraints->state_standby.mode = be32_to_cpu(*p++); + tmp = be32_to_cpu(*p); + constraints->state_standby.enabled = (tmp)
Re: [PATCH] ARM: mmp: remove builtin gpio driver support
On Sat, 2011-07-09 at 21:02 -0700, Grant Likely wrote: > On Fri, Jul 08, 2011 at 06:20:18PM +0800, Haojian Zhuang wrote: > > Remove builtin gpio driver support form mmp. > > > > Signed-off-by: Haojian Zhuang > > Hi Haojian. > > I'm not clear what this patch is intending to do. I understand that > it removes the mmp-specific gpio support, but I looks like don't see the code > that replaces it, which would mean that applying this patch breaks > gpio on mmp platforms. > > Am I missing something? > I'm sorry that I shouldn't loop this patch since my new gpio driver isn't contained in this patch series. I'm willing to add one operation to select using original gpio driver or the new one. Since the original gpio driver is shared between ARCH-PXA and ARCH-mmp. I don't want patch breaking the implementation in ARCH-PXA. Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH] ARM: mmp: add DTS file
On Sun, 2011-07-10 at 00:35 -0700, Grant Likely wrote: > On Fri, Jul 08, 2011 at 06:20:28PM +0800, Haojian Zhuang wrote: > > Add DTS file to support brownstone & ttc-dkb. > > > > Signed-off-by: Haojian Zhuang > > Hi Haojian. > > Overall, the patch series is moving in the right direction. I've made > a lot of comments, but they shouldn't be difficult to resolve. I look > forward to seeing the next version of the series. Comments below... > > > --- > > arch/arm/boot/dts/mmp2-brownstone.dts | 319 > > + > > arch/arm/boot/dts/ttc-dkb.dts | 176 ++ > > arch/arm/mach-mmp/brownstone.c| 66 ++- > > arch/arm/mach-mmp/ttc_dkb.c | 21 ++- > > 4 files changed, 530 insertions(+), 52 deletions(-) > > create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts > > create mode 100644 arch/arm/boot/dts/ttc-dkb.dts > > > > diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts > > b/arch/arm/boot/dts/mmp2-brownstone.dts > > new file mode 100644 > > index 000..5fdabc3 > > --- /dev/null > > +++ b/arch/arm/boot/dts/mmp2-brownstone.dts > > @@ -0,0 +1,319 @@ > > +/dts-v1/; > > + > > +/include/ "skeleton.dtsi" > > + > > + interrupt-controller; > > + #interrupt-cells = <1>; > > + sub-interrupts = <64>; > > What is this for? > Because I need to know how much interrupts could be supported in this domain? For example, mux4, mux5, ... and supported in mmp2 silicon. Although they have similar interface, the interrupt numbers are different in different mux. So I need a property to tell parser that how much interrupts should be allocated for this interrupt domain. > > + gpio-controller; > > + reg = < > > + 0xd4019000 0xb0 > > + 0xd4019004 0xb0 > > + 0xd4019008 0xb0 > > + 0xd4019100 0xb0 > > + 0xd4019104 0xb0 > > + 0xd4019108 0xb0>; > > This looks wrong. The address ranges overlap. Why not simply: > <0xd4019000 0x200>; > These six registers means the start address of six gpio banks. The registers are overlapped. And internal register of gpio bank are same in both ARCH-PXA and ARCH-MMP. The only difference is the start register of each gpio bank. And there're different gpio numbers in different silicons. If I can transfer the start gpio address from DTS file, I needn't to hard code them in gpio driver. If I only write it as <0xd4019000 0x200>, it can't help driver to understand how much gpio banks existed. Unless I provide a new property on gpio bank. What's your opinion on this? ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 0/7] support DT on ARCH-MMP
It's used to support DT on ARCH-MMP. Haojian Zhuang (7): ARM: mmp: parse irq from DT ARM: mmp: append MMP_USE_OF config ARM: mmp: support DT on both dkb and brownstone tty: serial: support device tree in pxa tty: serial: check ops before registering console i2c: pxa: support i2c controller from DT i2c: pxa: support to parse property .../devicetree/bindings/arm/marvell/boards.txt |7 + .../devicetree/bindings/arm/marvell/intc.txt | 120 ++ .../devicetree/bindings/i2c/pxa255-i2c.txt | 36 +++ arch/arm/Kconfig |1 + arch/arm/boot/dts/mmp2-brownstone.dts | 242 arch/arm/boot/dts/ttc-dkb.dts | 80 +++ arch/arm/mach-mmp/Kconfig |7 + arch/arm/mach-mmp/Makefile |6 + arch/arm/mach-mmp/boards.c | 159 + arch/arm/mach-mmp/common.h |1 + arch/arm/mach-mmp/include/mach/irqs.h |4 + arch/arm/mach-mmp/intc.c | 223 ++ drivers/i2c/busses/i2c-pxa.c | 78 +-- drivers/tty/serial/Kconfig |4 +- drivers/tty/serial/of_serial.c | 12 + drivers/tty/serial/pxa.c | 95 - include/linux/serial_pxa.h | 17 ++ 17 files changed, 1065 insertions(+), 27 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/marvell/boards.txt create mode 100644 Documentation/devicetree/bindings/arm/marvell/intc.txt create mode 100644 Documentation/devicetree/bindings/i2c/pxa255-i2c.txt create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts create mode 100644 arch/arm/boot/dts/ttc-dkb.dts create mode 100644 arch/arm/mach-mmp/boards.c create mode 100644 arch/arm/mach-mmp/intc.c create mode 100644 include/linux/serial_pxa.h ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 1/7] ARM: mmp: parse irq from DT
Parse irq sepcifier from DT and translate it to Linux irq number. Signed-off-by: Haojian Zhuang --- .../devicetree/bindings/arm/marvell/intc.txt | 120 +++ arch/arm/Kconfig |1 + arch/arm/mach-mmp/Makefile |2 + arch/arm/mach-mmp/common.h |1 + arch/arm/mach-mmp/intc.c | 223 5 files changed, 347 insertions(+), 0 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 000..e730a16 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/intc.txt @@ -0,0 +1,120 @@ +* 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 and the value shall be + "mrvl,mmp-intc" or "mrvl,mux-intc". + "mrvl,mmp-intc" is the base interrupt controller. It must be + included. "mrvl,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 . + + - 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 and the value should + be 1. + + - #address-cells: Specifies the number of cells needed to encode an + address. The type should be and the value should be 1. + + - #size-cells: Specifies the number of cells need to encode an + size. The type should be and the value should be 1. + + - intc-numbers: Specifies the number of interrupts is supported in + this interrupt controller. The type should be . + +Optional properties: + + - intc-enable-mask: Specifies the masking value of interrupt + configuration register. The property is used in mmp-intc. The value + should be . + + - intc-status: Specifies the offset of status register. The property + is used in mux-intc. The type should be . + + - intc-mask: Specifies the offset of mask register. The property + is used in mux-intc. The type should be . + + - intc-mfp-edge: Specifies the address of mfp edge detection register. + The property is used while acking specified interrupt. The type + should be . 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@d4282000 { + /* Compatible with mmp-intc. */ + compatible = "mrvl,mmp-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. */ + intc-numbers = <64>; + + /* enable bits in configuration register */ + intc-enable-mask = <0x20>; + }; + +Example 2: + + /* +* mux INTC that is internal wired to base INTC +*/ + mux_intc4: interrupt-controller@d4282150 { + compatible = "mrvl,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. */ + intc-numbers = <2>; + + /* Status offset address of 0x150. */ + intc-status = <0x150>; + + /* Mask offset address of 0x168. */ + intc-mask = <0x168>; + + /* mfp register of 0xd401e2c4 & interrupt index of 1 */ +
[PATCH 2/7] ARM: mmp: append MMP_USE_OF config
Since NR_IRQS is defined in irqs.h, parsing irq specifier will be started from NR_IRQS while both CONFIG_USE_OF and CONFIG_SPARSE_IRQ is enabled. It breaks the assumption that base irq is started from 0. Add CONFIG_MMP_USE_OF config to distinguish. If CONFIG_MMP_USE_OF is set, NR_IRQS is defined as 0. Otherwise, it follows the original definition. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Kconfig |7 +++ arch/arm/mach-mmp/include/mach/irqs.h |4 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 67793a6..1efe994 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -96,4 +96,11 @@ config CPU_MMP2 select CPU_PJ4 help Select code specific to MMP2. MMP2 is ARMv7 compatible. + +config MMP_USE_OF + bool "MMP Use OF" + select USE_OF + help + Select OF code to ARCH-MMP. + endif diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index a09d328..538bb69 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -224,6 +224,10 @@ #define IRQ_BOARD_START(IRQ_GPIO_START + IRQ_GPIO_NUM) +#ifdef CONFIG_MMP_USE_OF +#define NR_IRQS0 +#else #define NR_IRQS(IRQ_BOARD_START) +#endif #endif /* __ASM_MACH_IRQS_H */ -- 1.5.6.5 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 3/7] ARM: mmp: support DT on both dkb and brownstone
Add new boards.c to support both TTC-DKB and MMP2-BROWNSTONE. While CONFIG_MMP_USE_OF is selected, original ttc_dkb.c and brownstone.c won't be compiled. While everything moving to DT in ARCH-MMP, original ttc_dkb.c and brownstone.c will be abandoned. Signed-off-by: Haojian Zhuang --- .../devicetree/bindings/arm/marvell/boards.txt |7 + arch/arm/boot/dts/mmp2-brownstone.dts | 242 arch/arm/boot/dts/ttc-dkb.dts | 80 +++ arch/arm/mach-mmp/Makefile |4 + arch/arm/mach-mmp/boards.c | 159 + 5 files changed, 492 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/ttc-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 000..219e134 --- /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,ttc-dkb", "mrvl,pxa910-dkb"; + +mmp2(armada610) "Brownstone" evalutation board +Required root node properties: + - compatible = "mrvl,mmp2-brownstone", "mrvl,armada610-brownstone"; diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 000..4e14388 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -0,0 +1,242 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell MMP2 Brownstone"; + compatible = "mrvl,mmp2-brownstone", "mrvl,armada610-brownstone"; + + memory { + reg = <0x 0x2000>; + }; + + 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@d400 { + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; + device_type = "soc"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mmp_intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp-intc"; + #address-cells = <1>; + #size-cells = <1>; + /* reg: */ + reg = <0xd4282000 0x400>; + + #interrupt-cells = <1>; + interrupt-controller; + intc-numbers = <64>; + /* enable bits in conf register */ + intc-enable-mask = <0x20>; + }; + + mux_intc4: interrupt-controller@d4282150 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd4282150 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&mmp_intc>; + interrupts = <4>; + intc-numbers = <2>; + intc-status = <0x150>; + intc-mask = <0x168>; + /* mfp register & interrupt index */ + intc-mfp-edge = <0xd401e2c4 1>; + }; + + mux_intc5: interrupt-controller@d4282154 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd4282154 0>; + + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&mmp_intc>; + interrupts = <5>; + intc-numbers = <2>; + intc-status = <0x154>; + intc-mask = <0x16c>; + }; + + mux_intc9: interrupt-controller@d4282180 { + compatible = "mrvl,mux-intc"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd4282180 0>; + + #interrupt-cells = <1>; + interrupt-controller; +
[PATCH 4/7] tty: serial: support device tree in pxa
Support both normal platform driver and device tree driver in serial pxa. Signed-off-by: Haojian Zhuang --- drivers/tty/serial/Kconfig |4 +- drivers/tty/serial/of_serial.c | 12 + drivers/tty/serial/pxa.c | 93 ++- include/linux/serial_pxa.h | 17 +++ 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 include/linux/serial_pxa.h diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 636144c..3f75e0d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -663,6 +663,8 @@ config SERIAL_MPSC_CONSOLE config SERIAL_PXA bool "PXA serial port support" depends on ARCH_PXA || ARCH_MMP + select SERIAL_OF_PLATFORM + select SERIAL_CORE_CONSOLE select SERIAL_CORE help If you have a machine based on an Intel XScale PXA2xx CPU you @@ -1340,7 +1342,7 @@ config SERIAL_NETX_CONSOLE config SERIAL_OF_PLATFORM tristate "Serial port on Open Firmware platform bus" depends on OF - depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL + depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL || SERIAL_PXA help If you have a PowerPC based system that has serial ports on a platform specific bus, you should enable this option. diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e65f1e8..83e07fb 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,11 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) ret = nwpserial_register_port(&port); break; #endif +#ifdef CONFIG_SERIAL_PXA + case PORT_PXA: + ret = serial_pxa_register_port(&port); + break; +#endif default: /* need to add code for these */ case PORT_UNKNOWN: @@ -163,6 +169,11 @@ static int of_platform_serial_remove(struct platform_device *ofdev) nwpserial_unregister_port(info->line); break; #endif +#ifdef CONFIG_SERIAL_PXA + case PORT_PXA: + serial_pxa_unregister_port(info->line); + break; +#endif default: /* need to add code for these */ break; @@ -186,6 +197,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { { .compatible = "ibm,qpace-nwp-serial", .data = (void *)PORT_NWPSERIAL, }, #endif + { .compatible = "mrvl,pxa270-serial", .data = (void *)PORT_PXA, }, { .type = "serial", .data = (void *)PORT_UNKNOWN, }, { /* end of list */ }, }; diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 4302e6e..8f4d538 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -36,10 +36,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -54,6 +56,10 @@ struct uart_pxa_port { char*name; }; +#define PXA_SERIAL_NR 4 + +static DEFINE_MUTEX(serial_pxa_mutex); + static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) { offset <<= 2; @@ -346,8 +352,6 @@ static int serial_pxa_startup(struct uart_port *port) else up->mcr = 0; - up->port.uartclk = clk_get_rate(up->clk); - /* * Allocate the IRQ */ @@ -593,7 +597,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 @@ -761,6 +765,89 @@ static const struct dev_pm_ops serial_pxa_pm_ops = { }; #endif +static int serial_pxa_port_size(struct uart_pxa_port *sport) +{ + return 8 << sport->port.regshift; +} + +int serial_pxa_register_port(struct uart_port *port) +{ + struct uart_pxa_port *sport = NULL; + char name[32]; + int i, ret; + + mutex_lock(&serial_pxa_mutex); + for (i = 0; i < PXA_SERIAL_NR; i++) { + if (serial_pxa_ports[i] != NULL) + continue; + sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); + if (!sport) { + ret = -ENOMEM; + goto out; + } + switch (i) { + case 0: sport->name = "FFUART"; break; + case 1: sport->name = "BTUART"; break; + case 2: sport->name = "STUART"; break; + c
[PATCH 5/7] tty: serial: check ops before registering console
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 --- 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 8f4d538..2d8e7d0 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -684,7 +684,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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 6/7] i2c: pxa: support i2c controller from DT
support i2c-pxa controller from DT. Signed-off-by: Haojian Zhuang --- drivers/i2c/busses/i2c-pxa.c | 58 ++--- 1 files changed, 42 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index d603646..adac74a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -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; @@ -1138,11 +1162,12 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->adap.algo_data = i2c; i2c->adap.dev.parent = &dev->dev; -#ifdef CONFIG_OF i2c->adap.dev.of_node = dev->dev.of_node; -#endif - ret = i2c_add_numbered_adapter(&i2c->adap); + if (i2c_type == REGS_CE4100) + ret = i2c_add_adapter(&i2c->adap); + else + ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { printk(KERN_INFO "I2C: Failed to add bus\n"); goto eadapt; @@ -1234,6 +1259,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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 7/7] i2c: pxa: support to parse property
Support to parse some optional properties. These three properties are i2c-polling, i2c-frequency, i2c-class. After supporting these property, i2c-pxa driver can avoid to use platform data except for slave mode. Signed-off-by: Haojian Zhuang --- .../devicetree/bindings/i2c/pxa255-i2c.txt | 36 drivers/i2c/busses/i2c-pxa.c | 22 2 files changed, 51 insertions(+), 7 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 000..bf34236 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/pxa255-i2c.txt @@ -0,0 +1,36 @@ +PXA255 I2C + +The I2C-Controller is first used in PXA255. It's widely used in Intel/Marvell +silicons. + +Optional Property: + - i2c-polling: Specifies whether I2C-Controller is used in polling + mode or interrupt mode. The type of property should be . + + - i2c-frequency: Specifies the frequency that the I2C-Controller + is working. The type of property should be . + + - i2c-class: Specifies the class of I2C-Controller. The type of + property should be . + +Example: + i2c0: i2c@d4011000 { + compatible = "pxa2xx-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd4011000 0x60>; + /* I2C-Controller works in interrupt mode. */ + i2c-polling = <0>; + /* I2C-Controller's frequency is FAST. */ + i2c-frequency = "fast"; + /* interrupt of I2C-Controller */ + interrupts = <7>; + interrupt-parent = <&mmp_intc>; + + pm860x: pmic@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 adac74a..4b9fa71 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1060,7 +1060,8 @@ static int i2c_pxa_probe(struct platform_device *dev) const struct platform_device_id *id = platform_get_device_id(dev); enum pxa_i2c_types i2c_type; struct resource *res; - int irq, ret; + int irq, ret, poll; + char *p = NULL; static int idx = 0; if (np) { @@ -1093,11 +1094,24 @@ static int i2c_pxa_probe(struct platform_device *dev) if (np) { + of_property_read_u32(np, "i2c-polling", &poll); + i2c->use_pio = (poll) ? 1 : 0; + of_property_read_string(np, "i2c-frequency", &p); + if (p && !strncmp(p, "fast", 4)) + i2c->fast_mode = 1; + of_property_read_u32(np, "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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 00/07] enable devicetree on arch-mmp
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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 1/7] ARM: mmp: parse irq from DT
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 --- .../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 000..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 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 . + + - 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 and the value should + be 1. + + - mrvl,intc-numbers: Specifies the number of interrupts is supported + in this interrupt controller. The type should be . + +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 . + + - mrvl,status-offset: Specifies the offset of status register. The + property is used in mmp2-mux-intc. The type should be . + + - mrvl,mask-offset: Specifies the offset of mask register. The + property is used in mmp2-mux-intc. The type should be . + + - mrvl,mfp-edge: Specifies the address of mfp edge detection register. + The property is used while acking specified interrupt. The type + should be . 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@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@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 0xd401e2
[PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone
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 --- .../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 000..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 000..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 = <0x 0x2000>; + }; + + 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@d400 { + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mmp_intc: interrupt-controller@d4282000 { + compatible = "mrvl,pxa168-intc"; + /* reg: */ + 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@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@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@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@d4282158 { + compatible = "mrvl,mmp2-mux-intc"; + reg = <0xd4282158 0>; + + #interrupt-ce
[PATCH v2 2/7] ARM: mmp: parse timer configuration from DT
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 --- .../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 000..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 and the value shall be + "mrvl,pxa168-timer". + + - mrvl,clk-conf: Specifies the address and value of timer + configuration register. + The type shall be . 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 = <0xd434 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 #include +#include +#include #include #include @@ -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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 4/7] tty: serial: support device tree in pxa
Support both normal platform driver and device tree driver in serial pxa. Signed-off-by: Haojian Zhuang --- 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 #include #include +#include #include #include #include @@ -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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 5/7] tty: serial: check ops before registering console
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 --- 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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 6/7] i2c: pxa: support i2c controller from DT
support i2c-pxa controller from DT. Signed-off-by: Haojian Zhuang --- 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 #include #include +#include #include #include #include @@ -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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 7/7] i2c: pxa: support to parse property
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 --- .../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 000..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 . + + - 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 . 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 . + +Example: + i2c0: i2c@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@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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 1/7] ARM: mmp: parse irq from DT
On Sat, Jul 30, 2011 at 12:36 AM, Grant Likely 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 >> --- >> .../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 000..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 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 . >> + >> + - 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 and the value should >> + be 1. >> + >> + - mrvl,intc-numbers: Specifies the number of interrupts is supported >> + in this interrupt controller. The type should be . >> + >> +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 . >> + >> + - mrvl,status-offset: Specifies the offset of status register. The >> + property is used in mmp2-mux-intc. The type should be . >> + >> + - mrvl,mask-offset: Specifies the offset of mask register. The >> + property is used in mmp2-mux-intc. The type should be . >> + >> + - mrvl,mfp-edge: Specifies the address of mfp edge detection register. >> + The property is used while acking specified interrupt. The type >> + should be . 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@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
Re: [PATCH v2 3/7] ARM: mmp: support DT on both dkb and brownstone
On Sat, Jul 30, 2011 at 12:42 AM, Grant Likely 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 >> --- >> .../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 000..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 000..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 = <0x 0x2000>; >> + }; >> + >> + 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@d400 { >> + compatible = "mrvl,mmp2", "mrvl,armada610", "simple-bus"; >> + #address-cells = <1>; >> + #size-cells = <1>; >> + ranges; >> + >> + mmp_intc: interrupt-controller@d4282000 { >> + compatible = "mrvl,pxa168-intc"; >> + /* reg: */ >> + 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@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@d4282154 { >> + compatible = "mrvl,mmp2-mux-intc"; >> + reg = <0xd4282154 0>; >> + >> + #interrupt-cells = <1>; >> + interrupt-controller; >> + inte
Re: [PATCH v2 4/7] tty: serial: support device tree in pxa
On Sat, Jul 30, 2011 at 12:49 AM, 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. > So how could I get these clocks? Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 1/7] ARM: mmp: parse irq from DT
On Mon, Aug 1, 2011 at 10:10 PM, Grant Likely 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 >> 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 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 2/7] mfd: max8925: fix mfd device register failure
On Tue, Nov 6, 2012 at 3:38 PM, Qing Xu wrote: > From: Qing Xu > > we encounter rtc/power/touch driver registry failure, root cause > it is resources confilict in insert_resouce, solved by changing > mfd_add_devices 5th parameter to NULL > Since resources are not used in power/rtc driver and touch driver isn't implemented, it's OK to avoid use resources. Please remove those resources in max8925-core.c also. > Signed-off-by: Qing Xu > --- > drivers/mfd/max8925-core.c | 22 ++ > 1 files changed, 10 insertions(+), 12 deletions(-) > > diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c > index dcc218a..b1eacae 100644 > --- a/drivers/mfd/max8925-core.c > +++ b/drivers/mfd/max8925-core.c > @@ -873,7 +873,7 @@ int __devinit max8925_device_init(struct max8925_chip > *chip, > > ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], > ARRAY_SIZE(rtc_devs), > - &rtc_resources[0], chip->irq_base, NULL); > + NULL, chip->irq_base, NULL); > if (ret < 0) { > dev_err(chip->dev, "Failed to add rtc subdev\n"); > goto out; > @@ -881,7 +881,7 @@ int __devinit max8925_device_init(struct max8925_chip > *chip, > > ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], > ARRAY_SIZE(onkey_devs), > - &onkey_resources[0], 0, NULL); > + NULL, 0, NULL); > if (ret < 0) { > dev_err(chip->dev, "Failed to add onkey subdev\n"); > goto out_dev; > @@ -900,21 +900,19 @@ int __devinit max8925_device_init(struct max8925_chip > *chip, > goto out_dev; > } > > - if (pdata && pdata->power) { > - ret = mfd_add_devices(chip->dev, 0, &power_devs[0], > - ARRAY_SIZE(power_devs), > - &power_supply_resources[0], 0, NULL); > - if (ret < 0) { > - dev_err(chip->dev, "Failed to add power supply " > - "subdev\n"); > - goto out_dev; > - } > + ret = mfd_add_devices(chip->dev, 0, &power_devs[0], > + ARRAY_SIZE(power_devs), > + NULL, 0, NULL); > + if (ret < 0) { > + dev_err(chip->dev, "Failed to add power supply " > + "subdev, err = %d\n", ret); > + goto out_dev; > } > > if (pdata && pdata->touch) { > ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], > ARRAY_SIZE(touch_devs), > - &touch_resources[0], 0, NULL); > + NULL, chip->tsc_irq_base, NULL); > if (ret < 0) { > dev_err(chip->dev, "Failed to add touch subdev\n"); > goto out_dev; > -- > 1.7.0.4 > ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 7/7] mfd: max8925: add dts
On Tue, Nov 6, 2012 at 3:49 PM, Qing Xu wrote: > From: Qing Xu > > add max8925 dts support into mmp2 brownstone platform > > Signed-off-by: Qing Xu > --- > arch/arm/boot/dts/mmp2-brownstone.dts | 166 > + > arch/arm/boot/dts/mmp2.dtsi |4 +- > 2 files changed, 169 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts > b/arch/arm/boot/dts/mmp2-brownstone.dts > index c9b4f27..e22f58c 100644 > --- a/arch/arm/boot/dts/mmp2-brownstone.dts > +++ b/arch/arm/boot/dts/mmp2-brownstone.dts > @@ -29,6 +29,172 @@ > }; > twsi1: i2c@d4011000 { > status = "okay"; > + pmic: max8925@3c { > + compatible = "marvell,max8925"; > + reg = <0x3c>; > + interrupts = <1 0>; > + interrupt-parent = <&intcmux4>; > + interrupt-controller; > + #interrupt-cells = <1>; > + > + regulators { > + SDV1 { > + > regulator-min-microvolt = <637500>; > + > regulator-max-microvolt = <1425000>; > + regulator-boot-on; > + regulator-always-on; > + }; > + SDV2 { > + > regulator-min-microvolt = <65>; > + > regulator-max-microvolt = <2225000>; > + regulator-boot-on; > + regulator-always-on; > + }; > + }; > + backlight { > + dual-string = <0>; > + }; > + charger { > + batt-detect = <0>; > + topoff-threshold = <1>; > + fast-charge = <7>; > + no-temp-support = <0>; > + no-insert-detect = <0>; > + }; > + rtc { > + > + }; > + onkey { > + > + }; > + touch { > + > + }; Please remove these empty entries. Those mfd client drivers didn't parse any property from DTS file. > + }; > }; > rtc: rtc@d401 { > status = "okay"; > diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi > index 80f74e2..2165a17 100644 > --- a/arch/arm/boot/dts/mmp2.dtsi > +++ b/arch/arm/boot/dts/mmp2.dtsi > @@ -41,7 +41,7 @@ > mrvl,intc-nr-irqs = <64>; > }; > > - intcmux4@d4282150 { > + intcmux4: intcmux4@d4282150 { > compatible = "mrvl,mmp2-mux-intc"; > interrupts = <4>; > interrupt-controller; > @@ -196,6 +196,8 @@ > compatible = "mrvl,mmp-twsi"; > reg = <0xd4011000 0x1000>; > interrupts = <7>; > + #address-cells = <1>; > + #size-cells = <0>; > mrvl,i2c-fast-mode; > status = "disabled"; > }; > -- > 1.7.0.4 > ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 1/7] mfd: max8925: add irqdomain for dt
On Tue, Nov 6, 2012 at 3:37 PM, Qing Xu wrote: > From: Qing Xu > > Add irqdomains for max8925's main irq, and touch irq. > Wrap irq register operations into irqdomain's map func. > it is necessary for dt support. > Also, add dt support for max8925 driver. > > Signed-off-by: Qing Xu > --- > drivers/mfd/max8925-core.c | 87 > --- > drivers/mfd/max8925-i2c.c | 32 +++- > include/linux/mfd/max8925.h | 12 - > 3 files changed, 96 insertions(+), 35 deletions(-) > > diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c > index 1e0ab0a..dcc218a 100644 > --- a/drivers/mfd/max8925-core.c > +++ b/drivers/mfd/max8925-core.c > @@ -14,10 +14,14 @@ > #include > #include > #include > +#include > #include > #include > #include > #include > +#include > +#include > +#include > > static struct resource bk_resources[] __devinitdata = { > { 0x84, 0x84, "mode control", IORESOURCE_REG, }, > @@ -639,17 +643,34 @@ static struct irq_chip max8925_irq_chip = { > .irq_disable= max8925_irq_disable, > }; > > +static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq, > +irq_hw_number_t hw) > +{ > + irq_set_chip_data(virq, d->host_data); > + irq_set_chip_and_handler(virq, &max8925_irq_chip, handle_edge_irq); > + irq_set_nested_thread(virq, 1); > +#ifdef CONFIG_ARM > + set_irq_flags(virq, IRQF_VALID); > +#else > + irq_set_noprobe(virq); > +#endif > + return 0; > +} > + > +static struct irq_domain_ops max8925_irq_domain_ops = { > + .map= max8925_irq_domain_map, > + .xlate = irq_domain_xlate_onetwocell, > +}; > + > + > static int max8925_irq_init(struct max8925_chip *chip, int irq, > struct max8925_platform_data *pdata) > { > unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; > - int i, ret; > - int __irq; > + int ret; > + int tsc_irq; > + struct device_node *node = chip->dev->of_node; > > - if (!pdata || !pdata->irq_base) { > - dev_warn(chip->dev, "No interrupt support on IRQ base\n"); > - return -EINVAL; > - } > /* clear all interrupts */ > max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1); > max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2); > @@ -667,45 +688,51 @@ static int max8925_irq_init(struct max8925_chip *chip, > int irq, > max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); > > mutex_init(&chip->irq_lock); > - chip->core_irq = irq; > - chip->irq_base = pdata->irq_base; > > - /* register with genirq */ > - for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { > - __irq = i + chip->irq_base; > - irq_set_chip_data(__irq, chip); > - irq_set_chip_and_handler(__irq, &max8925_irq_chip, > -handle_edge_irq); > - irq_set_nested_thread(__irq, 1); > -#ifdef CONFIG_ARM > - set_irq_flags(__irq, IRQF_VALID); > -#else > - irq_set_noprobe(__irq); > -#endif > - } > - if (!irq) { > - dev_warn(chip->dev, "No interrupt support on core IRQ\n"); > - goto tsc_irq; > + /* domain1: init charger/rtc/onkey irq domain*/ > + chip->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0); > + if (chip->irq_base < 0) { > + dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n", > + chip->irq_base); > + return -EBUSY; > } > > + irq_domain_add_legacy(node, MAX8925_NR_IRQS, chip->irq_base, 0, > + &max8925_irq_domain_ops, chip); > + chip->core_irq = irq; > + if (!chip->core_irq) > + return -EBUSY; > + > ret = request_threaded_irq(irq, NULL, max8925_irq, flags, >"max8925", chip); > if (ret) { > dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); > chip->core_irq = 0; > + return -EBUSY; > } > > -tsc_irq: > + /* domain2: init touch irq domain*/ > /* mask TSC interrupt */ > max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); > > - if (!pdata->tsc_irq) { > + chip->tsc_irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_TSC_IRQS, 0); > + if (chip->tsc_irq < 0) { > + dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n", > + chip->tsc_irq_base); > + return -EBUSY; > + } > + > + irq_domain_add_legacy(node, MAX8925_NR_TSC_IRQS, chip->tsc_irq_base, > 0, > + &max8925_irq_domain_ops, chip); > + > + tsc_irq = irq_of_parse_and_map(node, 1); > + I'm confused on this. Let's look at your definition in DTS. +
Re: [PATCH 6/7] mfd: max8925: support dt for backlight
On Tue, Nov 6, 2012 at 3:47 PM, Qing Xu wrote: > From: Qing Xu > > Signed-off-by: Qing Xu > --- > drivers/video/backlight/max8925_bl.c | 31 ++- > 1 files changed, 30 insertions(+), 1 deletions(-) > > diff --git a/drivers/video/backlight/max8925_bl.c > b/drivers/video/backlight/max8925_bl.c > index f72ba54..7de02ed 100644 > --- a/drivers/video/backlight/max8925_bl.c > +++ b/drivers/video/backlight/max8925_bl.c > @@ -101,6 +101,29 @@ static const struct backlight_ops max8925_backlight_ops > = { > .get_brightness = max8925_backlight_get_brightness, > }; > > +#ifdef CONFIG_OF > +static int max8925_backlight_dt_init(struct platform_device *pdev, > + struct max8925_backlight_pdata *pdata) > +{ > + struct device_node *nproot = pdev->dev.parent->of_node, *np; > + int dual_string; > + > + if (!nproot) > + return -ENODEV; > + np = of_find_node_by_name(nproot, "backlight"); > + if (!np) { > + dev_err(&pdev->dev, "failed to find backlight node\n"); > + return -ENODEV; > + } > + > + of_property_read_u32(np, "dual-string", &dual_string); Please use the property like "maxium,max8925-dual-string" at here. It's used to avoid naming conflict. > + pdata->dual_string = dual_string; > + return 0; > +} > +#else > +#define max8925_backlight_dt_init(x, y)(-1) > +#endif > + > static int __devinit max8925_backlight_probe(struct platform_device *pdev) > { > struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); > @@ -150,6 +173,13 @@ static int __devinit max8925_backlight_probe(struct > platform_device *pdev) > platform_set_drvdata(pdev, bl); > > value = 0; > + if (pdev->dev.parent->of_node && !pdata) { > + pdata = devm_kzalloc(&pdev->dev, > +sizeof(struct max8925_backlight_pdata), > +GFP_KERNEL); > + max8925_backlight_dt_init(pdev, pdata); > + } > + > if (pdata) { > if (pdata->lxw_scl) > value |= (1 << 7); > @@ -161,7 +191,6 @@ static int __devinit max8925_backlight_probe(struct > platform_device *pdev) > ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value); > if (ret < 0) > goto out_brt; > - > backlight_update_status(bl); > return 0; > out_brt: > -- > 1.7.0.4 > ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 0/7] mfd: update on max8925 for DT support
On Tue, Nov 6, 2012 at 3:35 PM, Qing Xu wrote: > From: Qing Xu > > 1. add irqdomain for max8925, it is necessary for dt support > 2. bug fix in max8925 mfd devices'irq base and device registry failure > 3. support DT for max8925 mfd devices > > Qing Xu (7): > mfd: max8925: add irqdomain for dt > mfd: max8925: fix mfd device register failure > mfd: max8925: fix onkey driver irq base > mfd: max8925: support dt for power supply > mfd: max8925: support dt for regulator > mfd: max8925: support dt for backlight > mfd: max8925: add dts > > arch/arm/boot/dts/mmp2-brownstone.dts | 166 > + > arch/arm/boot/dts/mmp2.dtsi |4 +- > drivers/input/misc/max8925_onkey.c|3 - > drivers/mfd/max8925-core.c| 107 + > drivers/mfd/max8925-i2c.c | 32 ++- > drivers/power/max8925_power.c | 57 ++- > drivers/regulator/max8925-regulator.c | 35 +++- > drivers/video/backlight/max8925_bl.c | 31 ++- > include/linux/mfd/max8925.h | 12 ++- > 9 files changed, 389 insertions(+), 58 deletions(-) > No document on devicetree binding? ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v3 1/7] mfd: max8925: add irqdomain for dt
} > chip->tsc_irq = pdata->tsc_irq; > - > ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, >flags, "max8925-tsc", chip); > if (ret) { > @@ -876,7 +891,7 @@ int __devinit max8925_device_init(struct max8925_chip > *chip, > if (pdata && pdata->power) { > ret = mfd_add_devices(chip->dev, 0, &power_devs[0], > ARRAY_SIZE(power_devs), > - &power_supply_resources[0], 0, NULL); > + &power_supply_resources[0], 0, NULL); > if (ret < 0) { > dev_err(chip->dev, "Failed to add power supply " > "subdev\n"); > diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c > index d9e4b36..46df784 100644 > --- a/drivers/mfd/max8925-i2c.c > +++ b/drivers/mfd/max8925-i2c.c > @@ -135,13 +135,38 @@ static const struct i2c_device_id max8925_id_table[] = { > }; > MODULE_DEVICE_TABLE(i2c, max8925_id_table); > > +static int __devinit max8925_dt_init(struct device_node *np, > + struct device *dev, > + struct max8925_platform_data *pdata) > +{ > + int ret; > + > + ret = of_property_read_u32(np, "tsc-irq", &pdata->tsc_irq); > + if (ret) { > + dev_err(dev, "Not found \"tsc-irq\" property\n"); > + return -EINVAL; > + } > + return 0; > +} > + > static int __devinit max8925_probe(struct i2c_client *client, >const struct i2c_device_id *id) > { > struct max8925_platform_data *pdata = client->dev.platform_data; > static struct max8925_chip *chip; > - > - if (!pdata) { > + struct device_node *node = client->dev.of_node; > + > + if (node && !pdata) { > + /* parse DT to get platform data */ > + pdata = devm_kzalloc(&client->dev, > +sizeof(struct max8925_platform_data), > +GFP_KERNEL); > + if (!pdata) > + return -ENOMEM; > + > + if (max8925_dt_init(node, &client->dev, pdata)) > + return -EINVAL; > + } else if (!pdata) { > pr_info("%s: platform data is missing\n", __func__); > return -EINVAL; > } > @@ -203,11 +228,18 @@ static int max8925_resume(struct device *dev) > > static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); > > +static const struct of_device_id max8925_dt_ids[] = { > + { .compatible = "maxim,max8925", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, max8925_dt_ids); > + > static struct i2c_driver max8925_driver = { > .driver = { > .name = "max8925", > .owner = THIS_MODULE, > .pm = &max8925_pm_ops, > + .of_match_table = of_match_ptr(max8925_dt_ids), > }, > .probe = max8925_probe, > .remove = __devexit_p(max8925_remove), > @@ -217,7 +249,6 @@ static struct i2c_driver max8925_driver = { > static int __init max8925_i2c_init(void) > { > int ret; > - > ret = i2c_add_driver(&max8925_driver); > if (ret != 0) > pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); > diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h > index 74d8e29..ce8502e 100644 > --- a/include/linux/mfd/max8925.h > +++ b/include/linux/mfd/max8925.h > @@ -190,6 +190,8 @@ enum { > MAX8925_NR_IRQS, > }; > > + > + > struct max8925_chip { > struct device *dev; > struct i2c_client *i2c; > @@ -201,7 +203,6 @@ struct max8925_chip { > int irq_base; > int core_irq; > int tsc_irq; > - > unsigned intwakeup_flag; > }; > > -- > 1.7.0.4 > Acked-by: Haojian Zhuang ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v4 7/7] mfd: max8925: add dts
> regulator-max-microvolt = <390>; > + regulator-boot-on; > + regulator-always-on; > + }; > + LDO16 { > + > regulator-min-microvolt = <75>; > + > regulator-max-microvolt = <390>; > + regulator-boot-on; > + regulator-always-on; > + }; > + LDO17 { > + > regulator-min-microvolt = <65>; > + > regulator-max-microvolt = <225>; > + regulator-boot-on; > + regulator-always-on; > + }; > + LDO18 { > + > regulator-min-microvolt = <65>; > + > regulator-max-microvolt = <225>; > + regulator-boot-on; > + regulator-always-on; > + }; > + LDO19 { > + > regulator-min-microvolt = <75>; > + > regulator-max-microvolt = <390>; > + regulator-boot-on; > + regulator-always-on; > + }; > + LDO20 { > + > regulator-min-microvolt = <75>; > + > regulator-max-microvolt = <390>; > + regulator-boot-on; > + regulator-always-on; > + }; > + }; > + backlight { > + max8925-dual-string = <0>; > + }; > + charger { > + batt-detect = <0>; > + topoff-threshold = <1>; > + fast-charge = <7>; > + no-temp-support = <0>; > + no-insert-detect = <0>; > + }; > + }; > }; > rtc: rtc@d401 { > status = "okay"; > diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi > index 80f74e2..76f9cc7 100644 > --- a/arch/arm/boot/dts/mmp2.dtsi > +++ b/arch/arm/boot/dts/mmp2.dtsi > @@ -41,7 +41,7 @@ > mrvl,intc-nr-irqs = <64>; > }; > > - intcmux4@d4282150 { > + intcmux4: interrupt-controller@d4282150 { > compatible = "mrvl,mmp2-mux-intc"; > interrupts = <4>; > interrupt-controller; > @@ -196,6 +196,8 @@ > compatible = "mrvl,mmp-twsi"; > reg = <0xd4011000 0x1000>; > interrupts = <7>; > + #address-cells = <1>; > + #size-cells = <0>; > mrvl,i2c-fast-mode; > status = "disabled"; > }; > -- > 1.7.0.4 > Acked-by: Haojian Zhuang ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH] Documentation: add docs for max8925 dt
On Thu, Nov 29, 2012 at 1:52 PM, Qing Xu wrote: > From: Qing Xu > > add docs for dt of max8925-mfd, max8925-backlight, and > max8925-battery > > Signed-off-by: Qing Xu > --- > Documentation/devicetree/bindings/mfd/max8925.txt | 64 > > .../bindings/power_supply/max8925_batter.txt | 18 ++ > .../bindings/video/backlight/max8925-backlight.txt | 10 +++ > 3 files changed, 92 insertions(+), 0 deletions(-) > create mode 100644 Documentation/devicetree/bindings/mfd/max8925.txt > create mode 100644 > Documentation/devicetree/bindings/power_supply/max8925_batter.txt > create mode 100644 > Documentation/devicetree/bindings/video/backlight/max8925-backlight.txt > Acked-by: Haojian Zhuang ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 0/7] mfd: update on max8925 for DT support
On Thu, Nov 29, 2012 at 1:54 PM, Qing Xu wrote: > On 11/23/2012 05:09 PM, Haojian Zhuang wrote: >> >> On Tue, Nov 6, 2012 at 3:35 PM, Qing Xu wrote: >>> >>> From: Qing Xu >>> >>> 1. add irqdomain for max8925, it is necessary for dt support >>> 2. bug fix in max8925 mfd devices'irq base and device registry failure >>> 3. support DT for max8925 mfd devices >>> >>> Qing Xu (7): >>>mfd: max8925: add irqdomain for dt >>>mfd: max8925: fix mfd device register failure >>>mfd: max8925: fix onkey driver irq base >>>mfd: max8925: support dt for power supply >>>mfd: max8925: support dt for regulator >>>mfd: max8925: support dt for backlight >>>mfd: max8925: add dts >>> >>> arch/arm/boot/dts/mmp2-brownstone.dts | 166 >>> + >>> arch/arm/boot/dts/mmp2.dtsi |4 +- >>> drivers/input/misc/max8925_onkey.c|3 - >>> drivers/mfd/max8925-core.c| 107 + >>> drivers/mfd/max8925-i2c.c | 32 ++- >>> drivers/power/max8925_power.c | 57 ++- >>> drivers/regulator/max8925-regulator.c | 35 +++- >>> drivers/video/backlight/max8925_bl.c | 31 ++- >>> include/linux/mfd/max8925.h | 12 ++- >>> 9 files changed, 389 insertions(+), 58 deletions(-) >>> >> No document on devicetree binding? > > I added a new patch of "Documentation: add docs for max8925 dt", > please help to review, thanks a lot! Acked. Samuel, How do you think about this patch series? From my view, it's ok. Best Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 5/7] ARM: mmp: append OF support on pxa168
On Mon, Apr 9, 2012 at 9:36 AM, Chris Ball wrote: > Hi, > > On Mon, Mar 05 2012, Haojian Zhuang wrote: >> Enable PXA168 and aspenite support. >> >> Signed-off-by: Haojian Zhuang >> --- >> arch/arm/mach-mmp/Kconfig | 10 ++ >> arch/arm/mach-mmp/Makefile | 1 + >> arch/arm/mach-mmp/mmp-dt.c | 75 >> >> 3 files changed, 86 insertions(+), 0 deletions(-) >> create mode 100644 arch/arm/mach-mmp/mmp-dt.c >> >> diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig >> index 323d4c9..5a90b9a 100644 >> --- a/arch/arm/mach-mmp/Kconfig >> +++ b/arch/arm/mach-mmp/Kconfig >> @@ -2,6 +2,16 @@ if ARCH_MMP >> >> menu "Marvell PXA168/910/MMP2 Implmentations" >> >> +config MACH_MMP_DT >> + bool "Support MMP2 platforms from device tree" >> + select CPU_PXA168 >> + select CPU_PXA910 >> + select USE_OF >> + help >> + Include support for Marvell MMP2 based platforms using >> + the device tree. Needn't select any other machine while >> + MACH_MMP_DT is enabled. >> + > > This patch breaks the build with MACH_MMP_DT=y in 3.4-rc2 for me: > > MACH_MMP_DT selects CPU_PXA168 which selects CPU_32v5, which results in: > > armv7-unknown-linux-gnueabi-gcc -Wp,-MD,arch/arm/mm/.dma-mapping.o.d > -nostdinc -isystem > /opt/crosstool/gcc-4.6.0/lib/gcc/armv7-unknown-linux-gnueabi/4.6.0/include > -I/home/cjb/git/olpc-kernel/arch/arm/include -Iarch/arm/include/generated > -Iinclude -I/home/cjb/git/olpc-kernel/include -include > /home/cjb/git/olpc-kernel/include/linux/kconfig.h > -I/home/cjb/git/olpc-kernel/arch/arm/mm -Iarch/arm/mm -D__KERNEL__ > -mlittle-endian -I/home/cjb/git/olpc-kernel/arch/arm/mach-mmp/include > -I/home/cjb/git/olpc-kernel/arch/arm/plat-pxa/include -Wall -Wundef > -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common > -Werror-implicit-function-declaration -Wno-format-security > -fno-delete-null-pointer-checks -Os -marm -fno-dwarf2-cfi-asm > -mabi=aapcs-linux -mno-thumb-interwork -funwind-tables -D__LINUX_ARM_ARCH__=5 > -march=armv5te -msoft-float -Uarm -Wframe-larger-than=1024 > -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g > -Wdeclaration-after-statement -Wno-pointer > -sign -fno-strict-overflow -fconserve-stack -D"KBUILD_STR(s)=#s" > -D"KBUILD_BASENAME=KBUILD_STR(dma_mapping)" > -D"KBUILD_MODNAME=KBUILD_STR(dma_mapping)" -c -o arch/arm/mm/dma-mapping.o > /home/cjb/git/olpc-kernel/arch/arm/mm/dma-mapping.c > /home/cjb/git/olpc-kernel/arch/arm/kernel/entry-armv.S: Assembler messages: > /home/cjb/git/olpc-kernel/arch/arm/kernel/entry-armv.S:207: Error: selected > processor does not support ARM mode `clrex' > > CPU_32v5=y adds: > > arch/arm/Makefile:arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call > cc-option,-march=armv5te,-march=armv4t) > There's a typo error in comments. MMP_DT is only for PXA168 & PXA910. We need to append MMP2_DT for ARMv7 in arch-mmp directory. Since we are not intended to build ARMv5 and ARMv7 together. Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 5/7] ARM: mmp: append OF support on pxa168
On Mon, Apr 9, 2012 at 9:43 AM, Chris Ball wrote: > Hi, > > On Mon, Mar 05 2012, Haojian Zhuang wrote: >> +static int __init mmp_intc_add_irq_domain(struct device_node *np, >> + struct device_node *parent) >> +{ >> + irq_domain_add_simple(np, 0); >> + return 0; >> +} >> + >> +static int __init mmp_gpio_add_irq_domain(struct device_node *np, >> + struct device_node *parent) >> +{ >> + irq_domain_add_simple(np, IRQ_GPIO_START); >> + return 0; >> +} > > This patch was merged for 3.4-rc1, but it fails to compile because Grant > removed irq_domain_add_simple() in 3.4-rc1. > Noticed. I'll fix it. Best Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 5/7] ARM: mmp: append OF support on pxa168
On Mon, Apr 9, 2012 at 9:51 AM, Chris Ball wrote: > Hi, > > On Sun, Apr 08 2012, Haojian Zhuang wrote: >> There's a typo error in comments. MMP_DT is only for PXA168 & PXA910. >> We need to append MMP2_DT for ARMv7 in arch-mmp directory. Since we >> are not intended to build ARMv5 and ARMv7 together. > > Okay. In that case, you should make sure that MMP_DT cannot be selected > when CPU_MMP2 is selected, by encoding that dependency in the Kconfig. > Sure. I'll protect it in Kconfig. Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 0/9] add more devicetree support in arch-mmp
1. Fix the build issue in mmp-dt.c since irq interface changed. 2. Parse intc in new irq that could support both pxa168 and mmp2. After arch-mmp is totally moved to device tree, irq-pxa168 and irq-mmp2 will be removed. 3. Parse interrupt in gpio controller. 4. Append timer with device tree. 5. Update documents. ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 1/9] ARM: mmp: fix build issue on mmp with device tree
Since irq_domain_add_simple() is removed, remove it in mmp-dt.c also. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/mmp-dt.c | 22 -- 1 files changed, 0 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c index 6707539..ca22e3c0 100644 --- a/arch/arm/mach-mmp/mmp-dt.c +++ b/arch/arm/mach-mmp/mmp-dt.c @@ -32,31 +32,9 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { {} }; -static int __init mmp_intc_add_irq_domain(struct device_node *np, - struct device_node *parent) -{ - irq_domain_add_simple(np, 0); - return 0; -} - -static int __init mmp_gpio_add_irq_domain(struct device_node *np, - struct device_node *parent) -{ - irq_domain_add_simple(np, IRQ_GPIO_START); - return 0; -} - -static const struct of_device_id mmp_irq_match[] __initconst = { - { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, }, - { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, }, - {} -}; - static void __init mmp_dt_init(void) { - of_irq_init(mmp_irq_match); - of_platform_populate(NULL, of_default_bus_match_table, mmp_auxdata_lookup, NULL); } -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 2/9] ARM: mmp: distinguish mmp and mmp2 in Kconfig
Append four CONFIG_* MACRO to distinguish boards in arch-mmp. CONFIG_MMP_LEGACY and CONFIG_MMP2_LEGACY are used to support boards without device tree. CONFIG_MMP_DT and CONFIG_MMP2_DT are used to support boards with device tree. At the same time, only one of these four macro could be selected. It's used to miss compiling all boards file together. Signed-off-by: Haojian Zhuang --- arch/arm/configs/mmp2_defconfig |1 + arch/arm/configs/pxa168_defconfig |1 + arch/arm/configs/pxa910_defconfig |1 + arch/arm/mach-mmp/Kconfig | 37 ++--- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index 5a58452..8c309d1 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -8,6 +8,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_MMP=y +CONFIG_MMP2_LEGACY=y CONFIG_MACH_BROWNSTONE=y CONFIG_MACH_FLINT=y CONFIG_MACH_MARVELL_JASPER=y diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig index 74d7e01..2abaa9f 100644 --- a/arch/arm/configs/pxa168_defconfig +++ b/arch/arm/configs/pxa168_defconfig @@ -8,6 +8,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_MMP=y +CONFIG_MMP_LEGACY=y CONFIG_MACH_ASPENITE=y CONFIG_MACH_ZYLONITE2=y CONFIG_MACH_AVENGERS_LITE=y diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig index 1cd381e..1e95263 100644 --- a/arch/arm/configs/pxa910_defconfig +++ b/arch/arm/configs/pxa910_defconfig @@ -9,6 +9,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_MMP=y +CONFIG_MMP_LEGACY=y CONFIG_MACH_TAVOREVB=y CONFIG_MACH_TTC_DKB=y CONFIG_NO_HZ=y diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 5a90b9a..5d49913 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -2,6 +2,9 @@ if ARCH_MMP menu "Marvell PXA168/910/MMP2 Implmentations" +choice + prompt "Support Machines for MMP series" + config MACH_MMP_DT bool "Support MMP2 platforms from device tree" select CPU_PXA168 @@ -12,8 +15,30 @@ config MACH_MMP_DT the device tree. Needn't select any other machine while MACH_MMP_DT is enabled. +config MACH_MMP2_DT + bool "Support MMP2 platforms from device tree" + select CPU_MMP2 + select USE_OF + help + Include support for Marvell MMP2 based platforms using + the device tree. + +config MMP_LEGACY + bool "Support MMP platform without device tree" + help + Include support for Marvell MMP based platforms in legacy + mode without device tree. + +config MMP2_LEGACY + bool "Support MMP2 platform without device tree" + help + Include support for Marvell MMP2 based platforms in legacy + mode without device tree. +endchoice + config MACH_ASPENITE bool "Marvell's PXA168 Aspenite Development Board" + depends on MMP_LEGACY select CPU_PXA168 help Say 'Y' here if you want to support the Marvell PXA168-based @@ -21,6 +46,7 @@ config MACH_ASPENITE config MACH_ZYLONITE2 bool "Marvell's PXA168 Zylonite2 Development Board" + depends on MMP_LEGACY select CPU_PXA168 help Say 'Y' here if you want to support the Marvell PXA168-based @@ -28,6 +54,7 @@ config MACH_ZYLONITE2 config MACH_AVENGERS_LITE bool "Marvell's PXA168 Avengers Lite Development Board" + depends on MMP_LEGACY select CPU_PXA168 help Say 'Y' here if you want to support the Marvell PXA168-based @@ -35,6 +62,7 @@ config MACH_AVENGERS_LITE config MACH_TAVOREVB bool "Marvell's PXA910 TavorEVB Development Board" + depends on MMP_LEGACY select CPU_PXA910 help Say 'Y' here if you want to support the Marvell PXA910-based @@ -42,6 +70,7 @@ config MACH_TAVOREVB config MACH_TTC_DKB bool "Marvell's PXA910 TavorEVB Development Board" + depends on MMP_LEGACY select CPU_PXA910 help Say 'Y' here if you want to support the Marvell PXA910-based @@ -49,7 +78,7 @@ config MACH_TTC_DKB config MACH_BROWNSTONE bool "Marvell's Brownstone Development Platform" - depends on !CPU_MOHAWK + depends on MMP2_LEGACY && !CPU_MOHAWK select CPU_MMP2 help Say 'Y' here if you want to support the Marvell MMP2-based @@ -60,7 +89,7 @@ config MACH_BROWNSTONE config MACH_FLINT bool "Marvell's Flint Development Platform" -
[PATCH 3/9] ARM: mmp: support DT in irq
Append new interrupt driver that could support both pxa168 and mmp2 silicon. And this driver supports device tree. Since CONFIG_SPARSE_IRQ is enabled in arch-mmp, irq driver should handle reserved NR_IRQS_LEGACY in irq domain. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Makefile |2 +- arch/arm/mach-mmp/include/mach/entry-macro.S |9 + arch/arm/mach-mmp/irq.c | 287 ++ 3 files changed, 297 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-mmp/irq.c diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 4fc0ff5..4e73a15 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -18,6 +18,6 @@ obj-$(CONFIG_MACH_TTC_DKB)+= ttc_dkb.o obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o -obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o +obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o irq.o obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o obj-$(CONFIG_MACH_GPLUGD) += gplugd.o diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S index 9cff9e7..6b9d925 100644 --- a/arch/arm/mach-mmp/include/mach/entry-macro.S +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S @@ -6,13 +6,19 @@ * published by the Free Software Foundation. */ +#include #include .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c0, c0, 0 @ CPUID and \tmp, \tmp, #0xff00 cmp \tmp, #0x5800 +#ifdef CONFIG_OF + ldr \base, =mmp_icu_base + ldr \base, [\base, #0] +#else ldr \base, =ICU_VIRT_BASE +#endif addne \base, \base, #0x10c@ PJ1 AP INT SEL register addeq \base, \base, #0x104@ PJ4 IRQ SEL register .endm @@ -20,5 +26,8 @@ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \tmp, [\base, #0] and \irqnr, \tmp, #0x3f +#ifdef CONFIG_OF + add \irqnr, \irqnr, #NR_IRQS_LEGACY +#endif tst \tmp, #(1 << 6) .endm diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c new file mode 100644 index 000..8d0890f --- /dev/null +++ b/arch/arm/mach-mmp/irq.c @@ -0,0 +1,287 @@ +/* + * linux/arch/arm/mach-mmp/irq.c + * + * Generic IRQ handling, GPIO IRQ demultiplexing, etc. + * Copyright (C) 2008 - 2012 Marvell Technology Group Ltd. + * + * Author:Bin Yang + * Haojian Zhuang + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#define MAX_ICU_NR 16 + +struct icu_chip_data { + int nr_irqs; + unsigned intvirq_base; + unsigned intcascade_irq; + void __iomem*reg_status; + void __iomem*reg_mask; + unsigned intconf_enable; + unsigned intconf_disable; + unsigned intconf_mask; + struct irq_domain *domain; +}; + +struct mmp_intc_conf { + unsigned intconf_enable; + unsigned intconf_disable; + unsigned intconf_mask; +}; + +void __iomem *mmp_icu_base; +static struct icu_chip_data icu_data[MAX_ICU_NR]; +static int max_icu_nr; + +static void icu_mask_irq(struct irq_data *d) +{ + struct irq_domain *domain = d->domain; + struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data; + int hwirq; + u32 r; + + hwirq = d->irq - data->virq_base; + if (data == &icu_data[0]) { + r = readl_relaxed(mmp_icu_base + (hwirq << 2)); + r &= ~data->conf_mask; + r |= data->conf_disable; + writel_relaxed(r, mmp_icu_base + (hwirq << 2)); + } else { + r = readl_relaxed(data->reg_mask) | (1 << hwirq); + writel_relaxed(r, data->reg_mask); + } +} + +static void icu_unmask_irq(struct irq_data *d) +{ + struct irq_domain *domain = d->domain; + struct icu_chip_data *data = (struct icu_chip_data *)domain->host_data; + int hwirq; + u32 r; + + hwirq = d->irq - data->virq_base; + if (data == &icu_data[0]) { + r = readl_relaxed(mmp_icu_base + (hwirq << 2)); + r &= ~data->conf_mask; + r |= data->conf_enable; + writel_relaxed(r, mmp_icu_base + (hwirq << 2)); + } else { + r = readl_relaxed(data->reg_mask) & ~(1 << hwirq); + writel_relaxed(r, data->
[PATCH 4/9] ARM: mmp: support DT in timer
Parse timer from DTS file. Avoid to use hardcoding marco for register. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/time.c | 81 ++ 1 files changed, 60 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 71fc4ee..936447c 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #include @@ -41,6 +44,8 @@ #define MAX_DELTA (0xfffe) #define MIN_DELTA (16) +static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; + /* * FIXME: the timer needs some delay to stablize the counter capture */ @@ -48,12 +53,12 @@ static inline uint32_t timer_read(void) { int delay = 100; - __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1)); + __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); while (delay--) cpu_relax(); - return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); + return __raw_readl(mmp_timer_base + TMR_CVWR(1)); } static u32 notrace mmp_read_sched_clock(void) @@ -68,12 +73,12 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) /* * Clear pending interrupt status. */ - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); + __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); /* * Disable timer 0. */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x02, mmp_timer_base + TMR_CER); c->event_handler(c); @@ -90,23 +95,23 @@ static int timer_set_next_event(unsigned long delta, /* * Disable timer 0. */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x02, mmp_timer_base + TMR_CER); /* * Clear and enable timer match 0 interrupt. */ - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); + __raw_writel(0x01, mmp_timer_base + TMR_IER(0)); /* * Setup new clockevent timer value. */ - __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); + __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0)); /* * Enable timer 0. */ - __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x03, mmp_timer_base + TMR_CER); local_irq_restore(flags); @@ -124,7 +129,7 @@ static void timer_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* disable the matching interrupt */ - __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x00, mmp_timer_base + TMR_IER(0)); break; case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_PERIODIC: @@ -157,27 +162,27 @@ static struct clocksource cksrc = { static void __init timer_config(void) { - uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); + uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */ + __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */ ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); - __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); + __raw_writel(ccr, mmp_timer_base + TMR_CCR); /* set timer 0 to periodic mode, and timer 1 to free-running mode */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR); + __raw_writel(0x2, mmp_timer_base + TMR_CMR); - __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */ - __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */ + __raw_writel(0x7, mmp_timer_base + TMR_ICR(0)); /* clear status */ + __raw_writel(0x0, mmp_timer_base + TMR_IER(0)); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */ - __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); + __raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */ + __raw_writel(0x7, mmp_timer_base + TMR_ICR(1)); /* clear status */ + __raw_writel(0x0, mmp_timer_base + TMR_IER(1)); /* enable timer 1 counter */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x2, mmp_timer_base + TMR_CER); } static struct irqaction timer_irq = { @@ -203,3 +208,37 @@ void __init timer_init(int irq) clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); clockevents_register_device(&ckevt); } + +#
[PATCH 5/9] gpio: pxa: parse gpio from DTS file
Parse GPIO numbers from DTS file. Allocate interrupt according to GPIO numbers. Signed-off-by: Haojian Zhuang --- drivers/gpio/gpio-pxa.c | 116 +++--- 1 files changed, 98 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce6..1f5f1ac 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -11,13 +11,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -56,6 +60,10 @@ int pxa_last_gpio; +#ifdef CONFIG_OF +static struct irq_domain *domain; +#endif + struct pxa_gpio_chip { struct gpio_chip chip; void __iomem*regbase; @@ -80,7 +88,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, - MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); @@ -460,21 +467,91 @@ static int pxa_gpio_nums(void) gpio_type = MMP_GPIO; } else if (cpu_is_mmp2()) { count = 191; - gpio_type = MMP2_GPIO; + gpio_type = MMP_GPIO; } #endif /* CONFIG_ARCH_MMP */ return count; } +static struct of_device_id pxa_gpio_dt_ids[] = { + { .compatible = "mrvl,pxa-gpio" }, + { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, + {} +}; + +static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, +handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + return 0; +} + +const struct irq_domain_ops pxa_irq_domain_ops = { + .map= pxa_irq_domain_map, +}; + +#ifdef CONFIG_OF +static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) +{ + int ret, nr_banks, nr_gpios, irq_base; + struct device_node *prev, *next, *np = pdev->dev.of_node; + const struct of_device_id *of_id = + of_match_device(pxa_gpio_dt_ids, &pdev->dev); + + if (!of_id) { + dev_err(&pdev->dev, "Failed to find gpio controller\n"); + return -EFAULT; + } + gpio_type = (int)of_id->data; + + next = of_get_next_child(np, NULL); + prev = next; + if (!next) { + dev_err(&pdev->dev, "Failed to find child gpio node\n"); + ret = -EINVAL; + goto err; + } + for (nr_banks = 1; ; nr_banks++) { + next = of_get_next_child(np, prev); + if (!next) + break; + prev = next; + } + of_node_put(prev); + nr_gpios = nr_banks << 5; + pxa_last_gpio = nr_gpios - 1; + + irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); + if (irq_base < 0) { + dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); + goto err; + } + domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, + &pxa_irq_domain_ops, NULL); + return 0; +err: + iounmap(gpio_reg_base); + return ret; +} +#else +#define pxa_gpio_probe_dt(pdev)(-1) +#endif + static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; - int gpio, irq, ret; + int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; - pxa_last_gpio = pxa_gpio_nums(); + ret = pxa_gpio_probe_dt(pdev); + if (ret < 0) + pxa_last_gpio = pxa_gpio_nums(); + else + use_of = 1; if (!pxa_last_gpio) return -EINVAL; @@ -528,25 +605,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); } + if (!use_of) { #ifdef CONFIG_ARCH_PXA - irq = gpio_to_irq(0); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, -handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - - irq = gpio_to_irq(1); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, -handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); -#endif + irq = gpio_to_irq(0); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, +
[PATCH 6/9] ARM: mmp: support mmp2 with device tree
Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Makefile |1 + arch/arm/mach-mmp/mmp2-dt.c | 60 +++ 2 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mmp/mmp2-dt.c diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 4e73a15..45c66f3 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -19,5 +19,6 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o irq.o +obj-$(CONFIG_MACH_MMP2_DT) += mmp2-dt.o irq.o obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o obj-$(CONFIG_MACH_GPLUGD) += gplugd.o diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c new file mode 100644 index 000..535a5ed --- /dev/null +++ b/arch/arm/mach-mmp/mmp2-dt.c @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/mach-mmp/mmp2-dt.c + * + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +extern void __init mmp_dt_irq_init(void); +extern void __init mmp_dt_init_timer(void); + +static struct sys_timer mmp_dt_timer = { + .init = mmp_dt_init_timer, +}; + +static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd403, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd401, "sa1100-rtc", NULL), + {} +}; + +static void __init mmp2_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, +mmp2_auxdata_lookup, NULL); +} + +static const char *mmp2_dt_board_compat[] __initdata = { + "mrvl,mmp2-brownstone", + NULL, +}; + +DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)") + .map_io = mmp_map_io, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = mmp2_dt_init, + .dt_compat = mmp2_dt_board_compat, +MACHINE_END -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 7/9] ARM: mmp: support pxa910 with device tree
Suppot gpio/irq/timer in mmp-dt driver. Support PXA910 also in mmp-dt driver. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/mmp-dt.c | 50 +++ 1 files changed, 40 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c index ca22e3c0..033cc31 100644 --- a/arch/arm/mach-mmp/mmp-dt.c +++ b/arch/arm/mach-mmp/mmp-dt.c @@ -14,14 +14,19 @@ #include #include #include +#include #include #include "common.h" -extern struct sys_timer pxa168_timer; -extern void __init icu_init_irq(void); +extern void __init mmp_dt_irq_init(void); +extern void __init mmp_dt_init_timer(void); -static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { +static struct sys_timer mmp_dt_timer = { + .init = mmp_dt_init_timer, +}; + +static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), @@ -32,22 +37,47 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { {} }; -static void __init mmp_dt_init(void) +static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd401, "sa1100-rtc", NULL), + {} +}; + +static void __init pxa168_dt_init(void) { + of_platform_populate(NULL, of_default_bus_match_table, +pxa168_auxdata_lookup, NULL); +} +static void __init pxa910_dt_init(void) +{ of_platform_populate(NULL, of_default_bus_match_table, -mmp_auxdata_lookup, NULL); +pxa910_auxdata_lookup, NULL); } -static const char *pxa168_dt_board_compat[] __initdata = { +static const char *mmp_dt_board_compat[] __initdata = { "mrvl,pxa168-aspenite", + "mrvl,pxa910-dkb", NULL, }; DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") .map_io = mmp_map_io, - .init_irq = icu_init_irq, - .timer = &pxa168_timer, - .init_machine = mmp_dt_init, - .dt_compat = pxa168_dt_board_compat, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = pxa168_dt_init, + .dt_compat = mmp_dt_board_compat, +MACHINE_END + +DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)") + .map_io = mmp_map_io, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = pxa910_dt_init, + .dt_compat = mmp_dt_board_compat, MACHINE_END -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 8/9] ARM: dts: refresh dts file for arch mmp
Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq, timer, gpio components. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/mmp2-brownstone.dts | 38 ++ arch/arm/boot/dts/mmp2.dtsi | 219 + arch/arm/boot/dts/pxa168.dtsi | 67 --- arch/arm/boot/dts/pxa910-dkb.dts | 38 ++ arch/arm/boot/dts/pxa910.dtsi | 140 + 5 files changed, 486 insertions(+), 16 deletions(-) create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts create mode 100644 arch/arm/boot/dts/mmp2.dtsi create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts create mode 100644 arch/arm/boot/dts/pxa910.dtsi diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 000..153a4b2 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; +/include/ "mmp2.dtsi" + +/ { + model = "Marvell MMP2 Aspenite Development Board"; + compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; + + chosen { + bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on"; + }; + + memory { + reg = <0x 0x0400>; + }; + + soc { + apb@d400 { + uart3: uart@d4018000 { + status = "okay"; + }; + twsi1: i2c@d4011000 { + status = "okay"; + }; + rtc: rtc@d401 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi new file mode 100644 index 000..8c95538 --- /dev/null +++ b/arch/arm/boot/dts/mmp2.dtsi @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/include/ "skeleton.dtsi" + +/ { + aliases { + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + i2c0 = &twsi1; + i2c1 = &twsi2; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&intc>; + ranges; + + axi@d420 { /* AXI */ + compatible = "mrvl,axi-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd420 0x0020>; + ranges; + + intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp2-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd4282000 0x1000>; + mrvl,intc-nr-irqs = <64>; + }; + + intcmux4@d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <4>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x150 0x4>, <0x168 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr-irqs = <2>; + }; + + intcmux5: interrupt-controller@d4282154 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <5>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x154 0x4>, <0x16c 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr
[PATCH 9/9] Documentation: update docs for mmp dt
Append interrupt controller and timer document for mmp. Updates documents for gpio and i2c. Signed-off-by: Haojian Zhuang --- Documentation/devicetree/bindings/arm/mrvl.txt |6 --- .../devicetree/bindings/arm/mrvl/intc.txt | 38 .../devicetree/bindings/arm/mrvl/mrvl.txt | 14 +++ .../devicetree/bindings/arm/mrvl/timer.txt | 13 +++ .../devicetree/bindings/gpio/mrvl-gpio.txt | 18 ++--- Documentation/devicetree/bindings/i2c/mrvl-i2c.txt | 15 +++- 6 files changed, 83 insertions(+), 21 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/mrvl.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/intc.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/mrvl.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/timer.txt diff --git a/Documentation/devicetree/bindings/arm/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl.txt deleted file mode 100644 index d8de933..000 --- a/Documentation/devicetree/bindings/arm/mrvl.txt +++ /dev/null @@ -1,6 +0,0 @@ -Marvell Platforms Device Tree Bindings - - -PXA168 Aspenite Board -Required root node properties: - - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168"; diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt new file mode 100644 index 000..b81e396 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt @@ -0,0 +1,38 @@ +* Marvell MMP Interrupt controller + +Required properties: +- compatible : Should be "mrvl,mmp-intc", "mrvl,mmp2-intc" or + "mrvl,mmp2-mux-intc" +- reg : Address and length of the register set of the interrupt controller. + If the interrupt controller is intc, address and length means the range + of the whold interrupt controller. If the interrupt controller is mux-intc, + address and length means one register. Since address of mux-intc is in the + range of intc. mux-intc is secondary interrupt controller. +- reg-names : Name of the register set of the interrupt controller. It's + only required in mux-intc interrupt controller. +- interrupts : Should be the port interrupt shared by mux interrupts. It's + only required in mux-intc interrupt controller. +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. +- mrvl,intc-nr-irqs : Specifies the number of interrupts in the interrupt + controller. + +Example: + intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp2-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd4282000 0x1000>; + mrvl,intc-nr-irqs = <64>; + }; + + intcmux4@d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <4>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x150 0x4>, <0x168 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr-irqs = <2>; + }; diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt new file mode 100644 index 000..117d741 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt @@ -0,0 +1,14 @@ +Marvell Platforms Device Tree Bindings + + +PXA168 Aspenite Board +Required root node properties: + - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168"; + +PXA910 DKB Board +Required root node properties: + - compatible = "mrvl,pxa910-dkb"; + +MMP2 Brownstone Board +Required root node properties: + - compatible = "mrvl,mmp2-brownstone"; diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt b/Documentation/devicetree/bindings/arm/mrvl/timer.txt new file mode 100644 index 000..9a6e251 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt @@ -0,0 +1,13 @@ +* Marvell MMP Timer controller + +Required properties: +- compatible : Should be "mrvl,mmp-timer". +- reg : Address and length of the register set of timer controller. +- interrupts : Should be the interrupt number. + +Example: + timer0: timer@d4014000 { + compatible = "mrvl,mmp-timer"; + reg = <0xd4014000 0x100>; + interrupts = <13>; + }; diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index 1e34cfe..05428f3 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt ++
Re: [PATCH 1/9] ARM: mmp: fix build issue on mmp with device tree
On Sat, Apr 28, 2012 at 4:15 AM, Arnd Bergmann wrote: > On Friday 27 April 2012, Haojian Zhuang wrote: >> Since irq_domain_add_simple() is removed, remove it in mmp-dt.c also. >> >> Signed-off-by: Haojian Zhuang > > This should also be fixed for v3.4, right? > Since I have more code updated in irq, I update them together to avoid dependency issue. > >> diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c >> index 6707539..ca22e3c0 100644 >> --- a/arch/arm/mach-mmp/mmp-dt.c >> +++ b/arch/arm/mach-mmp/mmp-dt.c >> @@ -32,31 +32,9 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] >> __initconst = { >> {} >> }; >> >> -static int __init mmp_intc_add_irq_domain(struct device_node *np, >> - struct device_node *parent) >> -{ >> - irq_domain_add_simple(np, 0); >> - return 0; >> -} >> - >> -static int __init mmp_gpio_add_irq_domain(struct device_node *np, >> - struct device_node *parent) >> -{ >> - irq_domain_add_simple(np, IRQ_GPIO_START); >> - return 0; >> -} >> - >> -static const struct of_device_id mmp_irq_match[] __initconst = { >> - { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, }, >> - { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, }, >> - {} >> -}; >> - >> static void __init mmp_dt_init(void) >> { >> >> - of_irq_init(mmp_irq_match); >> - >> of_platform_populate(NULL, of_default_bus_match_table, >> mmp_auxdata_lookup, NULL); >> } > > Shouldn't you be calling irq_domain_add_legacy now? > irq_domain_add_legacy() is used in irq.c. It's in another patch in this series. ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/9] ARM: mmp: support DT in irq
On Sat, Apr 28, 2012 at 3:06 AM, Grant Likely wrote: > On Fri, 27 Apr 2012 16:39:11 +0800, Haojian Zhuang > wrote: >> Append new interrupt driver that could support both pxa168 and mmp2 >> silicon. And this driver supports device tree. >> >> Since CONFIG_SPARSE_IRQ is enabled in arch-mmp, irq driver should >> handle reserved NR_IRQS_LEGACY in irq domain. >> >> Signed-off-by: Haojian Zhuang >> --- >> arch/arm/mach-mmp/Makefile | 2 +- >> arch/arm/mach-mmp/include/mach/entry-macro.S | 9 + >> arch/arm/mach-mmp/irq.c | 287 >> ++ > > It shouldn't be necessary to create an entirely new irq controller > driver that duplicates the functionality of irq-mmp2.c and > irq-pxa168.c. Instead, the existing drivers should be refactored to > work with both DT and non-DT user. > New irq controller driver handles both pxa168 and mmp2. The register definition is different. And some mux interrupt controllers are in mmp2. There are different interrupt numbers in each mux interrupt controller. Directly merging these two drivers are a bit difficult. But I can make use of DTS file to record register address and interrupt numbers. >> diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S >> b/arch/arm/mach-mmp/include/mach/entry-macro.S >> index 9cff9e7..6b9d925 100644 >> --- a/arch/arm/mach-mmp/include/mach/entry-macro.S >> +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S >> @@ -6,13 +6,19 @@ >> * published by the Free Software Foundation. >> */ >> >> +#include >> #include >> >> .macro get_irqnr_preamble, base, tmp >> mrc p15, 0, \tmp, c0, c0, 0 @ CPUID >> and \tmp, \tmp, #0xff00 >> cmp \tmp, #0x5800 >> +#ifdef CONFIG_OF >> + ldr \base, =mmp_icu_base >> + ldr \base, [\base, #0] >> +#else >> ldr \base, =ICU_VIRT_BASE >> +#endif >> addne \base, \base, #0x10c @ PJ1 AP INT SEL register >> addeq \base, \base, #0x104 @ PJ4 IRQ SEL register >> .endm >> @@ -20,5 +26,8 @@ >> .macro get_irqnr_and_base, irqnr, irqstat, base, tmp >> ldr \tmp, [\base, #0] >> and \irqnr, \tmp, #0x3f >> +#ifdef CONFIG_OF >> + add \irqnr, \irqnr, #NR_IRQS_LEGACY >> +#endif > > What do these do? Does turning on CONFIG_OF break booting with atags? > If so then this will need to be reworked. CONFIG_OF must not disable > non-devicetree usage. > > g. I use two CONFIG_OF in this file. The first one is used to record register base address of interrupt controller. In legacy code, the register address is hardcoding. Do you mean that I should remove this CONFIG_OF? The second CONFIG_OF is used to do a rebase of interrupt number. Since SPARSE IRQ is enabled, NR_IRQS_LEGACY (16) is defined already. I have two choices. Either I extended to define ".nr_irqs" in machine script for internal interrupts, or I reserve NR_IRQS_LEGACY and allocate new irqs for internal interrupts. I choose the second solution. Do you mean that I have to use the first solution? ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 2/9] ARM: mmp: distinguish mmp and mmp2 in Kconfig
On Sat, Apr 28, 2012 at 4:14 AM, Arnd Bergmann wrote: > On Friday 27 April 2012, Haojian Zhuang wrote: >> Append four CONFIG_* MACRO to distinguish boards in arch-mmp. >> >> CONFIG_MMP_LEGACY and CONFIG_MMP2_LEGACY are used to support boards >> without device tree. >> >> CONFIG_MMP_DT and CONFIG_MMP2_DT are used to support boards with >> device tree. >> >> At the same time, only one of these four macro could be selected. >> It's used to miss compiling all boards file together. > > Can you explain why this is done? It seems counterintuitive to > have the DT and non-DT support be mutually exclusive. > If I selected DT support, I needn't select those machine support one by one. I want to use mmp-dt to support all PXA168/PXA910 boards, and use mmp2-dt to support all mmp2 boards. So I use exclusive statements in Kconfig for convenience. Thanks Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/9] ARM: mmp: support DT in irq
On Wed, May 2, 2012 at 8:51 PM, Arnd Bergmann wrote: > On Wednesday 02 May 2012, Haojian Zhuang wrote: >> I use two CONFIG_OF in this file. The first one is used to record >> register base address >> of interrupt controller. In legacy code, the register address is >> hardcoding. Do you mean >> that I should remove this CONFIG_OF? > > Unless it's a noticeable performance impact, I would recommend just > always using the mmp_icu_base variable, even for when CONFIG_OF is > disabled. > > Arnd But I appended new irq handler for DT support. I still need to reserve this CONFIG_OF since I need to keep compatible with legacy code. While everything in arch-mmp is moved into DT, I can remove this CONFIG_OF. For the second CONFIG_OF, I can try to remove it. Best Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 0/9] support dt for mmp2
v2: 1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY 2. use irq.c to replace irq-pxa168.c & irq-mmp2.c 3. Avoid to use CONFIG_OF in entry-macro.S ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 1/9] ARM: mmp: fix build issue on mmp with device tree
Since irq_domain_add_simple() is removed, remove it in mmp-dt.c also. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/mmp-dt.c | 22 -- 1 files changed, 0 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c index 6707539..ca22e3c0 100644 --- a/arch/arm/mach-mmp/mmp-dt.c +++ b/arch/arm/mach-mmp/mmp-dt.c @@ -32,31 +32,9 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { {} }; -static int __init mmp_intc_add_irq_domain(struct device_node *np, - struct device_node *parent) -{ - irq_domain_add_simple(np, 0); - return 0; -} - -static int __init mmp_gpio_add_irq_domain(struct device_node *np, - struct device_node *parent) -{ - irq_domain_add_simple(np, IRQ_GPIO_START); - return 0; -} - -static const struct of_device_id mmp_irq_match[] __initconst = { - { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, }, - { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, }, - {} -}; - static void __init mmp_dt_init(void) { - of_irq_init(mmp_irq_match); - of_platform_populate(NULL, of_default_bus_match_table, mmp_auxdata_lookup, NULL); } -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 2/9] ARM: mmp: append CONFIG_MACH_MMP2_DT
Append CONFIG_MACH_MMP2_DT. CONFIG_MACH_MMP_DT is used to ARMv5 DT support. CONFIG_MACH_MMP2_DT is used to ARMv7 DT support. These two machine support can't be selected at the same time. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Kconfig | 29 +++-- 1 files changed, 19 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 5a90b9a..ede7216 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -2,16 +2,6 @@ if ARCH_MMP menu "Marvell PXA168/910/MMP2 Implmentations" -config MACH_MMP_DT - bool "Support MMP2 platforms from device tree" - select CPU_PXA168 - select CPU_PXA910 - select USE_OF - help - Include support for Marvell MMP2 based platforms using - the device tree. Needn't select any other machine while - MACH_MMP_DT is enabled. - config MACH_ASPENITE bool "Marvell's PXA168 Aspenite Development Board" select CPU_PXA168 @@ -94,6 +84,25 @@ config MACH_GPLUGD Say 'Y' here if you want to support the Marvell PXA168-based GuruPlug Display (gplugD) Board +config MACH_MMP_DT + bool "Support MMP (ARMv5) platforms from device tree" + select CPU_PXA168 + select CPU_PXA910 + select USE_OF + help + Include support for Marvell MMP2 based platforms using + the device tree. Needn't select any other machine while + MACH_MMP_DT is enabled. + +config MACH_MMP2_DT + bool "Support MMP2 (ARMv7) platforms from device tree" + depends on !CPU_MOHAWK + select CPU_MMP2 + select USE_OF + help + Include support for Marvell MMP2 based platforms using + the device tree. + endmenu config CPU_PXA168 -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 3/9] ARM: mmp: support DT in irq
Merge irq-pxa168 and irq-mmp2. And support device tree also. Since CONFIG_SPARSE_IRQ is enabled in arch-mmp, base irq starts from NR_IRQS_LEGACY. Signed-off-by: Haojian Zhuang --- arch/arm/Kconfig |1 + arch/arm/mach-mmp/Makefile |8 +- arch/arm/mach-mmp/include/mach/entry-macro.S |4 +- arch/arm/mach-mmp/include/mach/irqs.h| 27 ++- arch/arm/mach-mmp/irq-mmp2.c | 158 - arch/arm/mach-mmp/irq-pxa168.c | 54 --- arch/arm/mach-mmp/irq.c | 445 ++ 7 files changed, 472 insertions(+), 225 deletions(-) delete mode 100644 arch/arm/mach-mmp/irq-mmp2.c delete mode 100644 arch/arm/mach-mmp/irq-pxa168.c create mode 100644 arch/arm/mach-mmp/irq.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cf006d4..4cf9d42 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -632,6 +632,7 @@ config ARCH_MMP select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select GPIO_PXA + select IRQ_DOMAIN select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 4fc0ff5..77f63c1 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -2,12 +2,12 @@ # Makefile for Marvell's PXA168 processors line # -obj-y += common.o clock.o devices.o time.o +obj-y += common.o clock.o devices.o time.o irq.o # SoC support -obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o -obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o -obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o +obj-$(CONFIG_CPU_PXA168) += pxa168.o +obj-$(CONFIG_CPU_PXA910) += pxa910.o +obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o # board support obj-$(CONFIG_MACH_ASPENITE)+= aspenite.o diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S index 9cff9e7..bd152e2 100644 --- a/arch/arm/mach-mmp/include/mach/entry-macro.S +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S @@ -6,13 +6,15 @@ * published by the Free Software Foundation. */ +#include #include .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c0, c0, 0 @ CPUID and \tmp, \tmp, #0xff00 cmp \tmp, #0x5800 - ldr \base, =ICU_VIRT_BASE + ldr \base, =mmp_icu_base + ldr \base, [\base, #0] addne \base, \base, #0x10c@ PJ1 AP INT SEL register addeq \base, \base, #0x104@ PJ4 IRQ SEL register .endm diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index d0e7466..fb492a5 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -125,7 +125,7 @@ #define IRQ_MMP2_RTC_MUX 5 #define IRQ_MMP2_TWSI1 7 #define IRQ_MMP2_GPU 8 -#define IRQ_MMP2_KEYPAD9 +#define IRQ_MMP2_KEYPAD_MUX9 #define IRQ_MMP2_ROTARY10 #define IRQ_MMP2_TRACKBALL 11 #define IRQ_MMP2_ONEWIRE 12 @@ -163,11 +163,11 @@ #define IRQ_MMP2_DMA_FIQ 47 #define IRQ_MMP2_DMA_RIQ 48 #define IRQ_MMP2_GPIO 49 -#define IRQ_MMP2_SSP_MUX 51 +#define IRQ_MMP2_MIPI_HSI1_MUX 51 #define IRQ_MMP2_MMC2 52 #define IRQ_MMP2_MMC3 53 #define IRQ_MMP2_MMC4 54 -#define IRQ_MMP2_MIPI_HSI 55 +#define IRQ_MMP2_MIPI_HSI0_MUX 55 #define IRQ_MMP2_MSP 58 #define IRQ_MMP2_MIPI_SLIM_DMA 59 #define IRQ_MMP2_PJ4_FREQ_CHG 60 @@ -186,8 +186,14 @@ #define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0) #define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1) +/* secondary interrupt of INT #9 */ +#define IRQ_MMP2_KEYPAD_BASE (IRQ_MMP2_RTC_BASE + 2) +#define IRQ_MMP2_KPC (IRQ_MMP2_KEYPAD_BASE + 0) +#define IRQ_MMP2_ROTORY(IRQ_MMP2_KEYPAD_BASE + 1) +#define IRQ_MMP2_TBALL (IRQ_MMP2_KEYPAD_BASE + 2) + /* secondary interrupt of INT #17 */ -#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2) +#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_KEYPAD_BASE + 3) #define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0) #define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1) #define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2) @@ -212,11 +218,16 @@ #define IRQ_MMP2_COMMRX(IRQ_MMP2_MISC_BASE + 14) /* secondary interrupt of INT #51 */ -#define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15) -#define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0) -#define IRQ_MMP2_SSP3
[PATCH v2 4/9] ARM: mmp: support DT in timer
Parse timer from DTS file. Avoid to use hardcoding marco for register. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/time.c | 81 ++ 1 files changed, 60 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 71fc4ee..936447c 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #include @@ -41,6 +44,8 @@ #define MAX_DELTA (0xfffe) #define MIN_DELTA (16) +static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; + /* * FIXME: the timer needs some delay to stablize the counter capture */ @@ -48,12 +53,12 @@ static inline uint32_t timer_read(void) { int delay = 100; - __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1)); + __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); while (delay--) cpu_relax(); - return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); + return __raw_readl(mmp_timer_base + TMR_CVWR(1)); } static u32 notrace mmp_read_sched_clock(void) @@ -68,12 +73,12 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) /* * Clear pending interrupt status. */ - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); + __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); /* * Disable timer 0. */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x02, mmp_timer_base + TMR_CER); c->event_handler(c); @@ -90,23 +95,23 @@ static int timer_set_next_event(unsigned long delta, /* * Disable timer 0. */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x02, mmp_timer_base + TMR_CER); /* * Clear and enable timer match 0 interrupt. */ - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x01, mmp_timer_base + TMR_ICR(0)); + __raw_writel(0x01, mmp_timer_base + TMR_IER(0)); /* * Setup new clockevent timer value. */ - __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); + __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0)); /* * Enable timer 0. */ - __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x03, mmp_timer_base + TMR_CER); local_irq_restore(flags); @@ -124,7 +129,7 @@ static void timer_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* disable the matching interrupt */ - __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x00, mmp_timer_base + TMR_IER(0)); break; case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_PERIODIC: @@ -157,27 +162,27 @@ static struct clocksource cksrc = { static void __init timer_config(void) { - uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); + uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */ + __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */ ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); - __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); + __raw_writel(ccr, mmp_timer_base + TMR_CCR); /* set timer 0 to periodic mode, and timer 1 to free-running mode */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR); + __raw_writel(0x2, mmp_timer_base + TMR_CMR); - __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */ - __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */ + __raw_writel(0x7, mmp_timer_base + TMR_ICR(0)); /* clear status */ + __raw_writel(0x0, mmp_timer_base + TMR_IER(0)); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */ - __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); + __raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */ + __raw_writel(0x7, mmp_timer_base + TMR_ICR(1)); /* clear status */ + __raw_writel(0x0, mmp_timer_base + TMR_IER(1)); /* enable timer 1 counter */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x2, mmp_timer_base + TMR_CER); } static struct irqaction timer_irq = { @@ -203,3 +208,37 @@ void __init timer_init(int irq) clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); clockevents_register_device(&ckevt); } + +#
[PATCH v2 5/9] gpio: pxa: parse gpio from DTS file
Parse GPIO numbers from DTS file. Allocate interrupt according to GPIO numbers. Signed-off-by: Haojian Zhuang --- drivers/gpio/gpio-pxa.c | 116 +++--- 1 files changed, 98 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index fc3ace3..58a6a63 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -11,13 +11,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -56,6 +60,10 @@ int pxa_last_gpio; +#ifdef CONFIG_OF +static struct irq_domain *domain; +#endif + struct pxa_gpio_chip { struct gpio_chip chip; void __iomem*regbase; @@ -81,7 +89,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, - MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); @@ -475,22 +482,92 @@ static int pxa_gpio_nums(void) gpio_type = MMP_GPIO; } else if (cpu_is_mmp2()) { count = 191; - gpio_type = MMP2_GPIO; + gpio_type = MMP_GPIO; } #endif /* CONFIG_ARCH_MMP */ return count; } +static struct of_device_id pxa_gpio_dt_ids[] = { + { .compatible = "mrvl,pxa-gpio" }, + { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, + {} +}; + +static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, +handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + return 0; +} + +const struct irq_domain_ops pxa_irq_domain_ops = { + .map= pxa_irq_domain_map, +}; + +#ifdef CONFIG_OF +static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) +{ + int ret, nr_banks, nr_gpios, irq_base; + struct device_node *prev, *next, *np = pdev->dev.of_node; + const struct of_device_id *of_id = + of_match_device(pxa_gpio_dt_ids, &pdev->dev); + + if (!of_id) { + dev_err(&pdev->dev, "Failed to find gpio controller\n"); + return -EFAULT; + } + gpio_type = (int)of_id->data; + + next = of_get_next_child(np, NULL); + prev = next; + if (!next) { + dev_err(&pdev->dev, "Failed to find child gpio node\n"); + ret = -EINVAL; + goto err; + } + for (nr_banks = 1; ; nr_banks++) { + next = of_get_next_child(np, prev); + if (!next) + break; + prev = next; + } + of_node_put(prev); + nr_gpios = nr_banks << 5; + pxa_last_gpio = nr_gpios - 1; + + irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); + if (irq_base < 0) { + dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); + goto err; + } + domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, + &pxa_irq_domain_ops, NULL); + return 0; +err: + iounmap(gpio_reg_base); + return ret; +} +#else +#define pxa_gpio_probe_dt(pdev)(-1) +#endif + static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; struct pxa_gpio_platform_data *info; - int gpio, irq, ret; + int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; - pxa_last_gpio = pxa_gpio_nums(); + ret = pxa_gpio_probe_dt(pdev); + if (ret < 0) + pxa_last_gpio = pxa_gpio_nums(); + else + use_of = 1; if (!pxa_last_gpio) return -EINVAL; @@ -545,25 +622,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); } + if (!use_of) { #ifdef CONFIG_ARCH_PXA - irq = gpio_to_irq(0); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, -handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - - irq = gpio_to_irq(1); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, -handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); -#endif + irq = gpio_to_irq(0); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip
[PATCH v2 6/9] ARM: mmp: support mmp2 with device tree
Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Makefile |1 + arch/arm/mach-mmp/mmp2-dt.c | 60 +++ 2 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mmp/mmp2-dt.c diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 77f63c1..b920b9b 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -19,5 +19,6 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o +obj-$(CONFIG_MACH_MMP2_DT) += mmp2-dt.o obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o obj-$(CONFIG_MACH_GPLUGD) += gplugd.o diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c new file mode 100644 index 000..535a5ed --- /dev/null +++ b/arch/arm/mach-mmp/mmp2-dt.c @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/mach-mmp/mmp2-dt.c + * + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +extern void __init mmp_dt_irq_init(void); +extern void __init mmp_dt_init_timer(void); + +static struct sys_timer mmp_dt_timer = { + .init = mmp_dt_init_timer, +}; + +static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd403, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd401, "sa1100-rtc", NULL), + {} +}; + +static void __init mmp2_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, +mmp2_auxdata_lookup, NULL); +} + +static const char *mmp2_dt_board_compat[] __initdata = { + "mrvl,mmp2-brownstone", + NULL, +}; + +DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)") + .map_io = mmp_map_io, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = mmp2_dt_init, + .dt_compat = mmp2_dt_board_compat, +MACHINE_END -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 7/9] ARM: mmp: support pxa910 with device tree
Suppot gpio/irq/timer in mmp-dt driver. Support PXA910 also in mmp-dt driver. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/mmp-dt.c | 50 +++ 1 files changed, 40 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c index ca22e3c0..033cc31 100644 --- a/arch/arm/mach-mmp/mmp-dt.c +++ b/arch/arm/mach-mmp/mmp-dt.c @@ -14,14 +14,19 @@ #include #include #include +#include #include #include "common.h" -extern struct sys_timer pxa168_timer; -extern void __init icu_init_irq(void); +extern void __init mmp_dt_irq_init(void); +extern void __init mmp_dt_init_timer(void); -static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { +static struct sys_timer mmp_dt_timer = { + .init = mmp_dt_init_timer, +}; + +static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), @@ -32,22 +37,47 @@ static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { {} }; -static void __init mmp_dt_init(void) +static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd401, "sa1100-rtc", NULL), + {} +}; + +static void __init pxa168_dt_init(void) { + of_platform_populate(NULL, of_default_bus_match_table, +pxa168_auxdata_lookup, NULL); +} +static void __init pxa910_dt_init(void) +{ of_platform_populate(NULL, of_default_bus_match_table, -mmp_auxdata_lookup, NULL); +pxa910_auxdata_lookup, NULL); } -static const char *pxa168_dt_board_compat[] __initdata = { +static const char *mmp_dt_board_compat[] __initdata = { "mrvl,pxa168-aspenite", + "mrvl,pxa910-dkb", NULL, }; DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") .map_io = mmp_map_io, - .init_irq = icu_init_irq, - .timer = &pxa168_timer, - .init_machine = mmp_dt_init, - .dt_compat = pxa168_dt_board_compat, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = pxa168_dt_init, + .dt_compat = mmp_dt_board_compat, +MACHINE_END + +DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)") + .map_io = mmp_map_io, + .init_irq = mmp_dt_irq_init, + .timer = &mmp_dt_timer, + .init_machine = pxa910_dt_init, + .dt_compat = mmp_dt_board_compat, MACHINE_END -- 1.7.5.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq, timer, gpio components. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/mmp2-brownstone.dts | 38 ++ arch/arm/boot/dts/mmp2.dtsi | 220 + arch/arm/boot/dts/pxa168.dtsi | 67 --- arch/arm/boot/dts/pxa910-dkb.dts | 38 ++ arch/arm/boot/dts/pxa910.dtsi | 140 + 5 files changed, 487 insertions(+), 16 deletions(-) create mode 100644 arch/arm/boot/dts/mmp2-brownstone.dts create mode 100644 arch/arm/boot/dts/mmp2.dtsi create mode 100644 arch/arm/boot/dts/pxa910-dkb.dts create mode 100644 arch/arm/boot/dts/pxa910.dtsi diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts new file mode 100644 index 000..153a4b2 --- /dev/null +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; +/include/ "mmp2.dtsi" + +/ { + model = "Marvell MMP2 Aspenite Development Board"; + compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; + + chosen { + bootargs = "console=ttyS2,38400 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on"; + }; + + memory { + reg = <0x 0x0400>; + }; + + soc { + apb@d400 { + uart3: uart@d4018000 { + status = "okay"; + }; + twsi1: i2c@d4011000 { + status = "okay"; + }; + rtc: rtc@d401 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi new file mode 100644 index 000..80f74e2 --- /dev/null +++ b/arch/arm/boot/dts/mmp2.dtsi @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/include/ "skeleton.dtsi" + +/ { + aliases { + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + i2c0 = &twsi1; + i2c1 = &twsi2; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&intc>; + ranges; + + axi@d420 { /* AXI */ + compatible = "mrvl,axi-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd420 0x0020>; + ranges; + + intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp2-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd4282000 0x1000>; + mrvl,intc-nr-irqs = <64>; + }; + + intcmux4@d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <4>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x150 0x4>, <0x168 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr-irqs = <2>; + }; + + intcmux5: interrupt-controller@d4282154 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <5>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x154 0x4>, <0x16c 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr-
[PATCH v2 9/9] Documentation: update docs for mmp dt
Append interrupt controller and timer document for mmp. Updates documents for gpio and i2c. Signed-off-by: Haojian Zhuang --- Documentation/devicetree/bindings/arm/mrvl.txt |6 --- .../devicetree/bindings/arm/mrvl/intc.txt | 40 .../devicetree/bindings/arm/mrvl/mrvl.txt | 14 +++ .../devicetree/bindings/arm/mrvl/timer.txt | 13 ++ .../devicetree/bindings/gpio/mrvl-gpio.txt | 18 ++--- Documentation/devicetree/bindings/i2c/mrvl-i2c.txt | 15 +++ 6 files changed, 85 insertions(+), 21 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/mrvl.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/intc.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/mrvl.txt create mode 100644 Documentation/devicetree/bindings/arm/mrvl/timer.txt diff --git a/Documentation/devicetree/bindings/arm/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl.txt deleted file mode 100644 index d8de933..000 --- a/Documentation/devicetree/bindings/arm/mrvl.txt +++ /dev/null @@ -1,6 +0,0 @@ -Marvell Platforms Device Tree Bindings - - -PXA168 Aspenite Board -Required root node properties: - - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168"; diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt new file mode 100644 index 000..80b9a94 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt @@ -0,0 +1,40 @@ +* Marvell MMP Interrupt controller + +Required properties: +- compatible : Should be "mrvl,mmp-intc", "mrvl,mmp2-intc" or + "mrvl,mmp2-mux-intc" +- reg : Address and length of the register set of the interrupt controller. + If the interrupt controller is intc, address and length means the range + of the whold interrupt controller. If the interrupt controller is mux-intc, + address and length means one register. Since address of mux-intc is in the + range of intc. mux-intc is secondary interrupt controller. +- reg-names : Name of the register set of the interrupt controller. It's + only required in mux-intc interrupt controller. +- interrupts : Should be the port interrupt shared by mux interrupts. It's + only required in mux-intc interrupt controller. +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. +- mrvl,intc-nr-irqs : Specifies the number of interrupts in the interrupt + controller. +- mrvl,clr-mfp-irq : Specifies the interrupt that needs to clear MFP edge + detection first. + +Example: + intc: interrupt-controller@d4282000 { + compatible = "mrvl,mmp2-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd4282000 0x1000>; + mrvl,intc-nr-irqs = <64>; + }; + + intcmux4@d4282150 { + compatible = "mrvl,mmp2-mux-intc"; + interrupts = <4>; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x150 0x4>, <0x168 0x4>; + reg-names = "mux status", "mux mask"; + mrvl,intc-nr-irqs = <2>; + }; diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt new file mode 100644 index 000..117d741 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt @@ -0,0 +1,14 @@ +Marvell Platforms Device Tree Bindings + + +PXA168 Aspenite Board +Required root node properties: + - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168"; + +PXA910 DKB Board +Required root node properties: + - compatible = "mrvl,pxa910-dkb"; + +MMP2 Brownstone Board +Required root node properties: + - compatible = "mrvl,mmp2-brownstone"; diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt b/Documentation/devicetree/bindings/arm/mrvl/timer.txt new file mode 100644 index 000..9a6e251 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt @@ -0,0 +1,13 @@ +* Marvell MMP Timer controller + +Required properties: +- compatible : Should be "mrvl,mmp-timer". +- reg : Address and length of the register set of timer controller. +- interrupts : Should be the interrupt number. + +Example: + timer0: timer@d4014000 { + compatible = "mrvl,mmp-timer"; + reg = <0xd4014000 0x100>; + interrupts = <13>; + }; diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt ind
Re: [PATCH v2 0/9] support dt for mmp2
On Fri, May 18, 2012 at 7:57 AM, Rob Herring wrote: > On 05/04/2012 07:30 AM, Haojian Zhuang wrote: >> v2: >> 1. remove MACH_MMP_LEGACY & MACH_MMP2_LEGACY >> 2. use irq.c to replace irq-pxa168.c & irq-mmp2.c >> 3. Avoid to use CONFIG_OF in entry-macro.S >> > > I think you should combine all the DT board files in this series into 1 > DT board file. The only diff I can see between the files is auxdata and > board strings. You don't have any platform_data for the auxdata, so I'm > guessing you are using it for clkdev lookup. You can instead simply add > addition clkdev lookup names for the DT device names. Any other reason > for needing the old device name is pretty much wrong. > > Rob > I only tested limited devices. So platform data is not used really. While more devices are added, platform data has to be used. So I reserve it first. I need to add clkdev also into DT board files. It's in my TODO list. Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/9] ARM: mmp: support DT in irq
On Thu, May 31, 2012 at 3:38 AM, Chris Ball wrote: > Hi Haojian, > > > Did you test non-DT boot with these changes? > I tested non-DT boot on my brownstone board on TTC dkb board. It seems that you meet issue in icu_mux_irq_demux(). Could you give me the detail which interrupt is running while you meet the error? By the way, do you have the boot log? Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
On Tue, Jun 5, 2012 at 8:08 AM, Chris Ball wrote: > Hi Haojian, > > On Fri, May 04 2012, Haojian Zhuang wrote: >> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq, >> timer, gpio components. > > The patch I'm replying to introduced a device tree for MMP2/Brownstone > in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC > XO-1.75 board, and Mitch Bradley has some corrections to the device tree > format that we'd like to make, appended below. > > You can see all of the files Mitch mentions at: > http://dev.laptop.org/~wmb/mmp2-devicetree/ > > Here's my proposal for what to do next: > * First, you choose one of the two forms that Mitch links to. > (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference > for mmp2-flat.dtsi.) > * Then we'll post patches that modify the arch code to handle the new > DT format, and ask for your testing and ACK. > * We can try to merge the modified .dts files and .c code to 3.5/3.6. > * We'll work on merging XO-1.75 support into mainline and adding DT > support for new devices, too. > > What do you think? > I think that mmp2-flat.dtsi is better. We can use this. Thanks for your effort. Regards Haojian > Thanks, > > - Chris. > ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
On Wed, Jun 6, 2012 at 9:47 AM, Mitch Bradley wrote: > On 6/5/2012 3:28 PM, Arnd Bergmann wrote: >> >> On Tuesday 05 June 2012, Chris Ball wrote: >>> >>> Hi Haojian, >>> >>> On Fri, May 04 2012, Haojian Zhuang wrote: >>>> >>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq, >>>> timer, gpio components. >>> >>> >>> The patch I'm replying to introduced a device tree for MMP2/Brownstone >>> in 3.5-rc1. We're looking at adopting the MMP2 device tree for the OLPC >>> XO-1.75 board, and Mitch Bradley has some corrections to the device tree >>> format that we'd like to make, appended below. >>> >>> You can see all of the files Mitch mentions at: >>> http://dev.laptop.org/~wmb/mmp2-devicetree/ >>> >>> Here's my proposal for what to do next: >>> * First, you choose one of the two forms that Mitch links to. >>> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference >>> for mmp2-flat.dtsi.) >> >> >> My preference would be towards mmp2.dtsi. I've recommended doing it >> that way to other people, too. > > In most cases, I have found that exposing the full hierarchy is preferable. > For this specific SoC, which I have been working with for quite awhile now, > I haven't found any instance where exposing the AXI/APB levels buys you > anything. The hierarchy just adds clutter. > > That said, I don't feel strongly about it. > mmp2-brownstone.dts is too complex since both apb & axi are imported. Could we only use flat structure in mmp2-brownstone.dts? > >> >> >>> d) Moved the "intcmux" nodes down a level so they are children of the >>> top-level interrupt-controller node. The problem with having them as >>> peers of the top-level interrupt-controller is that their "reg" >>> properties conflict. For example: >>> intcmux4@d4282150 { ... reg =<0x150 0x4>,<0x168 0x4> ... } >>> >>> This is incorrect in several ways: >>> >>> 1) "@d4282150" is inconsistent with "reg =<0x150" . The "unit >>> address" after @ is supposed to be the same as the first component >>> of the reg property. d4282150 is not identical to 150. >> >> >> I thought the rule was that the @... part should be a translated address >> in the presence of "ranges" translation so we get a unique value in case >> we have multiple devices of the same name on the same address but on >> different buses. >> >> If we change this here, I suppose it also needs to be changed in a number >> of other places, and we have to rethink the method for unique device >> names. > > > My thinking was that "ranges" is inappropriate in this case (within the > top-level interrupt controller node), and I got rid of it. That being the > case, this is not "in the presence of ranges". > > >> >> >>> The solution is to put the intcmux nodes underneath the >>> interrupt-controller node. The interrupt-controller node now has >>> #address-cells and #size-cells properties so it can have children, but >>> it does not have a ranges property, so the address space is not passed >>> through. The child (intcmux) reg addresses can then be interpreted >>> independently, without conflict. >> >> >> Right. The implication for this however is that the driver cannot >> treat the reg property as a physical address it can do ioremap on, >> but needs to interface with the driver that provides the address >> space. > > > Indeed. For this driver, the intcmux subnodes are handled by the same > driver as the top-level interrupt controller, and those subordinate > registers are accessed via that driver's one mapping of the register block. > Mitch, Did you test cascade intcmux in DTS? I tried it before and got failure. But I didn't dig it yet, so I use parallel intc node instead. ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 8/9] ARM: dts: refresh dts file for arch mmp
On Wed, Jun 6, 2012 at 1:22 PM, Mitch Bradley wrote: > On 6/5/2012 4:35 PM, Haojian Zhuang wrote: >> >> On Wed, Jun 6, 2012 at 9:47 AM, Mitch Bradley wrote: >>> >>> On 6/5/2012 3:28 PM, Arnd Bergmann wrote: >>>> >>>> >>>> On Tuesday 05 June 2012, Chris Ball wrote: >>>>> >>>>> >>>>> Hi Haojian, >>>>> >>>>> On Fri, May 04 2012, Haojian Zhuang wrote: >>>>>> >>>>>> >>>>>> Append mmp2 and pxa910 dts files. Update PXA168 dts files for irq, >>>>>> timer, gpio components. >>>>> >>>>> >>>>> >>>>> The patch I'm replying to introduced a device tree for MMP2/Brownstone >>>>> in 3.5-rc1. We're looking at adopting the MMP2 device tree for the >>>>> OLPC >>>>> XO-1.75 board, and Mitch Bradley has some corrections to the device >>>>> tree >>>>> format that we'd like to make, appended below. >>>>> >>>>> You can see all of the files Mitch mentions at: >>>>> http://dev.laptop.org/~wmb/mmp2-devicetree/ >>>>> >>>>> Here's my proposal for what to do next: >>>>> * First, you choose one of the two forms that Mitch links to. >>>>> (Either "mmp2.dtsi" or "mmp2-flat.dtsi"; we have a weak preference >>>>> for mmp2-flat.dtsi.) >>>> >>>> >>>> >>>> My preference would be towards mmp2.dtsi. I've recommended doing it >>>> that way to other people, too. >>> >>> >>> In most cases, I have found that exposing the full hierarchy is >>> preferable. >>> For this specific SoC, which I have been working with for quite awhile >>> now, >>> I haven't found any instance where exposing the AXI/APB levels buys you >>> anything. The hierarchy just adds clutter. >>> >>> That said, I don't feel strongly about it. >>> >> mmp2-brownstone.dts is too complex since both apb& axi are imported. >> >> Could we only use flat structure in mmp2-brownstone.dts? > > > See http://dev.laptop.org/~wmb/mmp2-devicetree/mmp2-brownstone-flat.dts > <http://dev.laptop.org/%7Ewmb/mmp2-devicetree/mmp2-brownstone-flat.dts> > My meaning is mmp2-brownstone-flat.dts + mmp2.dtsi. Is it acceptable? ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: Re: [PATCH] mmc: sdhci-pxa: Add device tree support
On , Chris Ball wrote: Hi Zhangfei, On Tue, Jun 12 2012, zhangfei gao wrote: > On Wed, Jun 13, 2012 at 3:05 AM, Chris Ball c...@laptop.org> wrote: How do you feel about having the compatible node say "sdhci-pxav3" instead of "mrvl,pxav3-mmc"? I used the mrvl prefix because it fits in with the rest of your existing DT, but it seems like it would be better to name the driver directly. The DTs here live inside the source tree, so we're not depending on anyone else's terminology. If you're okay with sdhci-pxav{2,3} in compatible, I'll include that in v2 of the patch with the rest of your fixes. Compatible node could be "mrvl,pxav3-mmc" or "mrvl,sdhci-pxav3". It's depend on your choice. I prefer to use vendor name in compatible property. And we could avoid naming conflict. + if (of_find_property(np, "non-removable", NULL)) + pdata->flags |= PXA_FLAG_CARD_PERMANENT; + + of_property_read_u32(np, "bus-width", &bus_width); + if (bus_width == 8) + pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT; + + of_property_read_u32(np, "clk-delay-cycles", &clk_delay_cycles); + if (clk_delay_cycles > 0) + pdata->clk_delay_cycles = clk_delay_cycles; + These properties should be "mrvl,non-removable", "mrvl,bus-width", "mrvl,clk-delay-cycles". Since it's mentioned in Documentations/devicetree/booting-without-of.txt. "It is recommended that if you add any "custom" property whose name may clash with standard defined ones, you prefix them with your vendor name and a comma." ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH] mmc: sdhci-pxa: Add device tree support
On Wed, Jun 20, 2012 at 1:49 PM, Chris Ball wrote: > Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y) > > Signed-off-by: Chris Ball > --- > Changes since v1: > > * Add CONFIG_OF guard around of_match_table, per Zhangfei. > * Fix function prototypes under !CONFIG_OF, per Zhangfei. > * Change "clk-delay-cycles" to "mrvl,clk-delay-cycles", per Haojian. > > .../devicetree/bindings/mmc/sdhci-pxa.txt | 21 > drivers/mmc/host/sdhci-pxav2.c | 54 > > drivers/mmc/host/sdhci-pxav3.c | 52 +++++++ > 3 files changed, 127 insertions(+) Acked-by: Haojian Zhuang ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH] gpio: pxa: using for_each_set_bit to simplify the code
On Mon, Sep 17, 2012 at 6:56 PM, Linus Walleij wrote: > On Fri, Sep 14, 2012 at 4:36 AM, Wei Yongjun wrote: > >> From: Wei Yongjun >> >> Using for_each_set_bit() to simplify the code. >> >> spatch with a semantic match is used to found this. >> (http://coccinelle.lip6.fr/) >> >> Signed-off-by: Wei Yongjun > > PXA maintainers: does this look OK? > > Yours, > Linus Walleij It seems good. Acked-by: Haojian Zhuang ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH] gpio: pxa: using for_each_set_bit to simplify the code
On Tue, Sep 18, 2012 at 1:43 PM, Eric Miao wrote: > On Mon, Sep 17, 2012 at 6:56 PM, Linus Walleij > wrote: >> On Fri, Sep 14, 2012 at 4:36 AM, Wei Yongjun wrote: >> >>> From: Wei Yongjun >>> >>> Using for_each_set_bit() to simplify the code. >>> >>> spatch with a semantic match is used to found this. >>> (http://coccinelle.lip6.fr/) >>> >>> Signed-off-by: Wei Yongjun >> >> PXA maintainers: does this look OK? > > I seem to have Acked this already in another mail, if that got lost, here > it is: > > Acked-by: Eric Miao > The another mail thread is for irq, not gpio. I'll apply it today. :) ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 01/10] pinctrl: use postcore_initcall
Since pins are configured in device driver, pinctrl driver should be loaded by those device driver. module_platform_driver() only declares pinctrl driver is in module_initcall privilege. Use postcore_initcall privilege instead. Signed-off-by: Haojian Zhuang --- drivers/pinctrl/pinctrl-single.c | 12 +++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 76a4260..64d109a 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -980,7 +980,17 @@ static struct platform_driver pcs_driver = { }, }; -module_platform_driver(pcs_driver); +static int __init pcs_driver_init(void) +{ + return platform_driver_register(&pcs_driver); +} +postcore_initcall(pcs_driver_init); + +static void __exit pcs_driver_exit(void) +{ + platform_driver_unregister(&pcs_driver); +} +module_exit(pcs_driver_exit); MODULE_AUTHOR("Tony Lindgren "); MODULE_DESCRIPTION("One-register-per-pin type device tree based pinctrl driver"); -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 02/10] ARM: mmp: select pinctrl driver
Pinctrl driver is necessary for MMP DT & MMP2 DT platforms. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Kconfig |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 7fddd01..c70c787 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -89,6 +89,7 @@ config MACH_MMP_DT select CPU_PXA168 select CPU_PXA910 select USE_OF + select PINCTRL help Include support for Marvell MMP2 based platforms using the device tree. Needn't select any other machine while @@ -99,6 +100,7 @@ config MACH_MMP2_DT depends on !CPU_MOHAWK select CPU_MMP2 select USE_OF + select PINCTRL help Include support for Marvell MMP2 based platforms using the device tree. -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 03/10] tty: pxa: configure pin
Configure pins by pinctrl driver. Signed-off-by: Haojian Zhuang --- drivers/tty/serial/pxa.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 5847a4b..ee6118a 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -795,6 +796,7 @@ static int serial_pxa_probe_dt(struct platform_device *pdev, struct uart_pxa_port *sport) { struct device_node *np = pdev->dev.of_node; + struct pinctrl *pinctrl; int ret; if (!np) @@ -805,6 +807,12 @@ static int serial_pxa_probe_dt(struct platform_device *pdev, dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); return ret; } + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); + return ret; + } + sport->port.line = ret; return 0; } -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 04/10] i2c: pxa: configure pins
Configure pins by pinctrl driver. Signed-off-by: Haojian Zhuang --- drivers/i2c/busses/i2c-pxa.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 1034d93..cd66ec2 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1051,6 +1052,7 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, enum pxa_i2c_types *i2c_types) { struct device_node *np = pdev->dev.of_node; + struct pinctrl *pinctrl; const struct of_device_id *of_id = of_match_device(i2c_pxa_dt_ids, &pdev->dev); int ret; @@ -1063,6 +1065,9 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, return ret; } pdev->id = ret; + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) + return 1; if (of_get_property(np, "mrvl,i2c-polling", NULL)) i2c->use_pio = 1; if (of_get_property(np, "mrvl,i2c-fast-mode", NULL)) -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 05/10] i2c: pxa: use devm_kzalloc
Use devm_kzalloc & add checking in probe() function. Signed-off-by: Haojian Zhuang --- drivers/i2c/busses/i2c-pxa.c | 26 ++ 1 files changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index cd66ec2..5f96310 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1083,6 +1083,8 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev, struct i2c_pxa_platform_data *plat = pdev->dev.platform_data; const struct platform_device_id *id = platform_get_device_id(pdev); + if (!id) + return -EINVAL; *i2c_types = id->driver_data; if (plat) { i2c->use_pio = plat->use_pio; @@ -1099,29 +1101,23 @@ static int i2c_pxa_probe(struct platform_device *dev) struct resource *res = NULL; int ret, irq; - i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL); - if (!i2c) { - ret = -ENOMEM; - goto emalloc; - } + i2c = devm_kzalloc(&dev->dev, sizeof(struct pxa_i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type); if (ret > 0) ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type); if (ret < 0) - goto eclk; + return ret; res = platform_get_resource(dev, IORESOURCE_MEM, 0); irq = platform_get_irq(dev, 0); - if (res == NULL || irq < 0) { - ret = -ENODEV; - goto eclk; - } + if (res == NULL || irq < 0) + return -ENODEV; - if (!request_mem_region(res->start, resource_size(res), res->name)) { - ret = -ENOMEM; - goto eclk; - } + if (!request_mem_region(res->start, resource_size(res), res->name)) + return -ENOMEM; i2c->adap.owner = THIS_MODULE; i2c->adap.retries = 5; @@ -1214,8 +1210,6 @@ ereqirq: eremap: clk_put(i2c->clk); eclk: - kfree(i2c); -emalloc: release_mem_region(res->start, resource_size(res)); return ret; } -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 06/10] pinctrl: single: support gpio request and free
Marvell's PXA/MMP silicon also match the behavior of pinctrl-single. Each pin binds to one register. A lot of pins could be configured as gpio. Now add three properties in below. pinctrl-single,gpio-mask: mask of enable/disable value of gpio pinctrl-single,gpio-ranges: gpio range array pinctrl-single,gpio: pinctrl-single,gpio-enable: pinctrl-single,gpio-disable: Signed-off-by: Haojian Zhuang --- drivers/pinctrl/pinctrl-single.c | 140 +- 1 files changed, 138 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 64d109a..02cd412 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -29,6 +29,7 @@ #define PCS_MUX_NAME "pinctrl-single,pins" #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_OFF_DISABLED ~0U +#define PCS_MAX_GPIO_VALUES3 /** * struct pcs_pingroup - pingroups for a function @@ -75,6 +76,26 @@ struct pcs_function { }; /** + * struct pcs_gpio_range - pinctrl gpio range + * @range: subrange of the GPIO number space + * @reg_en:register of enabling gpio function + * @reg_dis: register of disabling gpio function + * @val_en:enable value on gpio function + * @val_dis: disable value on gpio function + * @need_en: need to handle enable value on gpio function + * @need_dis: need to handle disable value on gpio function + */ +struct pcs_gpio_range { + struct pinctrl_gpio_range range; + u32 reg_en; + u32 reg_dis; + int val_en; + int val_dis; + unsigned need_en:1; + unsigned need_dis:1; +}; + +/** * struct pcs_data - wrapper for data needed by pinctrl framework * @pa:pindesc array * @cur: index to current element @@ -115,14 +136,17 @@ struct pcs_name { * @fshift:function register shift * @foff: value to turn mux off * @fmax: max number of functions in fmask + * @gmask: gpio control mask * @names: array of register names for pins * @pins: physical pins on the SoC * @pgtree:pingroup index radix tree * @ftree: function index radix tree * @pingroups: list of pingroups * @functions: list of functions + * @ranges:list of gpio ranges * @ngroups: number of pingroups * @nfuncs:number of functions + * @nranges: number of gpio ranges * @desc: pin controller descriptor * @read: register read function to use * @write: register write function to use @@ -139,14 +163,17 @@ struct pcs_device { unsigned fshift; unsigned foff; unsigned fmax; + unsigned gmask; struct pcs_name *names; struct pcs_data pins; struct radix_tree_root pgtree; struct radix_tree_root ftree; struct list_head pingroups; struct list_head functions; + struct list_head ranges; unsigned ngroups; unsigned nfuncs; + unsigned nranges; struct pinctrl_desc desc; unsigned (*read)(void __iomem *reg); void (*write)(unsigned val, void __iomem *reg); @@ -387,9 +414,48 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) + struct pinctrl_gpio_range *range, unsigned offset) { - return -ENOTSUPP; + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_gpio_range *gpio = NULL; + int end; + unsigned data; + + gpio = container_of(range, struct pcs_gpio_range, range); + if (!gpio->need_en) + return 0; + end = range->pin_base + range->npins - 1; + if (offset < range->pin_base || offset > end) { + dev_err(pctldev->dev, "offset %d isn't in the range of " + "%d to %d\n", offset, range->pin_base, end); + return -EINVAL; + } + data = pcs_readl((void __iomem *)gpio->reg_en) & ~pcs->gmask; + data |= gpio->val_en; + pcs_writel(data, (void __iomem *)gpio->reg_en); + return 0; +} + +static void pcs_disable_gpio(struct pinctrl_dev *pctldev, +struct pinctrl_gpio_range *range, unsigned offset) +{ + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_gpio_range *gpio = NULL; + int end; + unsigned data; + + gpio = container_of(range, struct pcs_gpio_range, range); + if (!gpio->need_dis) + return; + end = range->pin_base + range->npins - 1; + if (offset < range->pin_base || offset > end) { + dev_err(pctldev->dev, "offset %d isn't in the range of " + &
[PATCH 07/10] pinctrl: remove mutex lock in groups show
Mutex is locked duplicatly by pinconf_groups_show() and pin_config_group_get(). It results dead lock. So avoid to lock mutex in pinconf_groups_show(). Signed-off-by: Haojian Zhuang --- drivers/pinctrl/pinconf.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 43f474c..baee2cc 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -537,8 +537,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what) seq_puts(s, "Pin config settings per pin group\n"); seq_puts(s, "Format: group (name): configs\n"); - mutex_lock(&pinctrl_mutex); - while (selector < ngroups) { const char *gname = pctlops->get_group_name(pctldev, selector); @@ -549,8 +547,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what) selector++; } - mutex_unlock(&pinctrl_mutex); - return 0; } -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 08/10] pinctrl: single: support pinconf generic
Add pinconf generic support with POWER SOURCE, BIAS PULL. Signed-off-by: Haojian Zhuang --- drivers/pinctrl/Kconfig |2 +- drivers/pinctrl/pinctrl-single.c | 286 -- 2 files changed, 274 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 54e3588..cc2ef20 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -106,7 +106,7 @@ config PINCTRL_SINGLE tristate "One-register-per-pin type device tree based pinctrl driver" depends on OF select PINMUX - select PINCONF + select GENERIC_PINCONF help This selects the device tree based generic pinctrl driver. diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 02cd412..a396944 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -27,6 +28,9 @@ #define DRIVER_NAME"pinctrl-single" #define PCS_MUX_NAME "pinctrl-single,pins" +#define PCS_BIAS_NAME "pinctrl-single,bias" +#define PCS_POWER_SOURCE_NAME "pinctrl-single,power-source" +#define PCS_SCHMITT_NAME "pinctrl-single,input-schmitt" #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_OFF_DISABLED ~0U #define PCS_MAX_GPIO_VALUES3 @@ -137,6 +141,15 @@ struct pcs_name { * @foff: value to turn mux off * @fmax: max number of functions in fmask * @gmask: gpio control mask + * @bmask: mask of bias in pinconf + * @bshift:offset of bias in pinconf + * @bdis: bias disable value in pinconf + * @bpullup: bias pull up value in pinconf + * @bpulldown: bias pull down value in pinconf + * @ismask:mask of input schmitt in pinconf + * @isshift: offset of input schmitt in pinconf + * @psmask:mask of power source in pinconf + * @psshift: offset of power source in pinconf * @names: array of register names for pins * @pins: physical pins on the SoC * @pgtree:pingroup index radix tree @@ -164,6 +177,15 @@ struct pcs_device { unsigned foff; unsigned fmax; unsigned gmask; + unsigned bmask; + unsigned bshift; + unsigned bdis; + unsigned bpullup; + unsigned bpulldown; + unsigned ismask; + unsigned isshift; + unsigned psmask; + unsigned psshift; struct pcs_name *names; struct pcs_data pins; struct radix_tree_root pgtree; @@ -268,9 +290,14 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev, static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) + unsigned pin) { - seq_printf(s, " " DRIVER_NAME); + struct pcs_device *pcs; + unsigned offset; + + pcs = pinctrl_dev_get_drvdata(pctldev); + offset = pin * (pcs->width / BITS_PER_BYTE); + seq_printf(s, " register value:0x%x", pcs_readl(pcs->base + offset)); } static void pcs_dt_free_map(struct pinctrl_dev *pctldev, @@ -468,28 +495,163 @@ static struct pinmux_ops pcs_pinmux_ops = { .gpio_disable_free = pcs_disable_gpio, }; +static void pcs_free_pingroups(struct pcs_device *pcs); + static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned data; + u32 offset; + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs_readl(pcs->base + offset); + + switch (param) { + case PIN_CONFIG_POWER_SOURCE: + if (pcs->psmask == PCS_OFF_DISABLED + || pcs->psshift == PCS_OFF_DISABLED) + return -ENOTSUPP; + data &= pcs->psmask; + data = data >> pcs->psshift; + *config = data; + return 0; + break; + case PIN_CONFIG_BIAS_DISABLE: + if (pcs->bmask == PCS_OFF_DISABLED + || pcs->bshift == PCS_OFF_DISABLED + || pcs->bdis == PCS_OFF_DISABLED) + return -ENOTSUPP; + data &= pcs->bmask; + *config = 0; + if (data == pcs->bdis) + return 0; + else + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (pcs->bmask == PCS_OFF_DISABLED +
[PATCH 09/10] ARM: dts: support pinctrl single in pxa910
Add pinctrl-single support with device tree in pxa910 dkb platform. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/pxa910-dkb.dts | 187 +- arch/arm/boot/dts/pxa910.dtsi| 81 2 files changed, 267 insertions(+), 1 deletions(-) diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts index e92be5a..2ad0a98 100644 --- a/arch/arm/boot/dts/pxa910-dkb.dts +++ b/arch/arm/boot/dts/pxa910-dkb.dts @@ -24,10 +24,195 @@ soc { apb@d400 { - uart1: uart@d4017000 { + pmx: pinmux@d401e000 { + pinctrl-names = "default"; + pinctrl-0 = <&board_pins>; + + board_pins: pinmux_board_pins { + /* pins not owned by device driver */ + }; + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + 0x198 0x6 /* GPIO47_UART1_RXD */ + 0x19c 0x6 /* GPIO48_UART1_TXD */ + >; + pinctrl-single,power-source = <0x2>; + pinctrl-single,bias = <0x6>; + }; + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x150 0x4 /* GPIO29_UART2_CTS */ + 0x154 0x4 /* GPIO30_UART2_RTS */ + 0x158 0x4 /* GPIO31_UART2_TXD */ + 0x15c 0x4 /* GPIO32_UART2_RXD */ + >; + pinctrl-single,power-source = <0x2>; + pinctrl-single,bias = <0>; + }; + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x188 0x7 /* GPIO43_UART3_RXD */ + 0x18c 0x7 /* GPIO44_UART3_TXD */ + >; + pinctrl-single,power-source = <0x2>; + pinctrl-single,bias = <0>; + }; + twsi1_pins: pinmux_twsi1_pins { + pinctrl-single,pins = < + 0x1b0 0x2 /* GPIO53_TWSI_SCL */ + 0x1b4 0x2 /* GPIO54_TWSI_SDA */ + >; + pinctrl-single,power-source = <0x2>; + pinctrl-single,bias = <0>; + }; + nand_pins: pinmux_nand_pins { + pinctrl-single,pins = < + 0x040 0x0 /* ND_IO0 */ + 0x03c 0x0 /* ND_IO1 */ + 0x038 0x0 /* ND_IO2 */ + 0x034 0x0 /* ND_IO3 */ + 0x030 0x0 /* ND_IO4 */ + 0x02c 0x0 /* ND_IO5 */ + 0x028 0x0 /* ND_IO6 */ + 0x024 0x0 /* ND_IO7 */ + 0x020 0x0 /* ND_IO8 */ + 0x01c 0x0 /* ND_IO9 */ + 0x018 0x0 /* ND_IO10 */ + 0x014 0x0 /* ND_IO11 */ + 0x010 0x0 /* ND_IO12 */ + 0x00c 0x0 /* ND_IO13 */ + 0x008 0x0 /* ND_IO14 */ + 0x004 0x0 /* ND_IO15 */ + 0x044 0x0 /* ND_nCS0 */ + 0x060 0x1 /* ND_ALE */ + 0x05c 0x0 /* ND_CLE */ + 0x054 0
[PATCH 10/10] document: devicetree: bind pinconf in pinctrl single
Add comments with pinconf & gpio range in the document of pinctrl-single. Signed-off-by: Haojian Zhuang --- .../devicetree/bindings/pinctrl/pinctrl-single.txt | 43 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt index 5187f0d..b0e5059 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt @@ -15,6 +15,49 @@ Optional properties: available and same for all registers; if not specified, disabling of pin functions is ignored +- pinctrl-single,gpio-mask : mask of enabling gpio function register + +- pinctrl-single,gpio-ranges : gpio range list + +- pinctrl-single,gpio : array with gpio range start, size & register + offset + +- pinctrl-single,gpio-enable : value of enabling gpio function + +- pinctrl-single,gpio-disable : value of disabling gpio function + +- pinctrl-single,power-source-mask : mask of setting power source in + the pinmux register + +- pinctrl-single,power-source-shift : shift of power source field in + the pinmux register + +- pinctrl-single,power-source : value of setting power source field + in the pinmux register + +- pinctrl-single,bias-mask : mask of setting bias value in the pinmux + register + +- pinctrl-single,bias-shift : shift of setting bias value in the + pinmux register + +- pinctrl-single,bias-disable : value of disabling bias in the pinmux + register + +- pinctrl-single,bias-pull-down : value of setting bias pull down in + the pinmux register + +- pinctrl-single,bias-pull-up : value of setting bias pull up in the + pinmux register + +- pinctrl-single,bias : value of setting bias in the pinmux register + +- pinctrl-single,input-schmitt-mask : mask of setting input schmitt + in the pinmux register + +- pinctrl-single,input-schmitt-shift : shift of setting input schmitt + in the pinmux register + This driver assumes that there is only one register for each pin, and uses the common pinctrl bindings as specified in the pinctrl-bindings.txt document in this directory. -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 05/10] i2c: pxa: use devm_kzalloc
On Fri, Oct 19, 2012 at 6:27 AM, Stephen Warren wrote: > On 10/18/2012 03:06 AM, Haojian Zhuang wrote: >> Use devm_kzalloc & add checking in probe() function. > > This patch seems unrelated to this series. In fact, the series touches a > bunch of different subsystems; would you expect all these patches to be > merged through a single tree? If so, which? Yes, I expect all these patches could be merged by pinctrl subtree. Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 01/10] pinctrl: use postcore_initcall
On Fri, Oct 19, 2012 at 6:28 AM, Tony Lindgren wrote: > * Stephen Warren [121018 15:20]: >> On 10/18/2012 03:06 AM, Haojian Zhuang wrote: >> > Since pins are configured in device driver, pinctrl driver should be >> > loaded by those device driver. module_platform_driver() only declares >> > pinctrl driver is in module_initcall privilege. Use postcore_initcall >> > privilege instead. >> >> I'm not convinced this is needed; doesn't deferred probe sort out the >> dependencies correctly? > > I'm a bit concerned about this need too as the trend is towards > initializing things later than earlier. The drivers/Makefile order > and deferred probe should be already enough? > > Specifically could you decribe the cases where this issue happens? > Also check if one of your client drivers has some early initcall > that's no longer needed. > > Regards, > > Tony Yes, the special case is PMIC. Most of PMIC are based on I2C/SPI bus. It means that I2C/SPI bus driver should be initialized firstly. For example, we could find that PMIC mfd driver are initialized in subsys init call level. It means that pinctrl should be initialized earlier than I2C/SPI bus driver. Otherwise, pins of I2C bus may not be configured as I2C function since pinctrl driver is module init call level. Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 08/10] pinctrl: single: support pinconf generic
On Fri, Oct 19, 2012 at 6:29 AM, Tony Lindgren wrote: > * Linus Walleij [121018 11:32]: >> On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang >> wrote: >> >> > Add pinconf generic support with POWER SOURCE, BIAS PULL. >> > >> > Signed-off-by: Haojian Zhuang >> >> I really like the looks of this, good job Haojian! >> >> Now we just need to hear what Tony says about it... > > Hey that's cool, maybe I'll find some use for those too :) > I'll take a closer look tonigh or on Friday. > > Regards, > > Tony I wonder whether gpio function in OMAP is also configured in the pinmux register. For example, the function is 3bit field in pinmux register of Marvell's PXA/MMP silicon. GPIO function is the one of function. If the usage case is same in OMAP silicon, I can merge "pinctrl-single,gpio-mask" with "pinctrl-single,function-mask". Do we need "pinctrl-single,gpio-disable" at here? I want to remove it, but I don't know whether it's necessary in OMAP case. Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 01/10] pinctrl: use postcore_initcall
On Fri, Oct 19, 2012 at 10:38 AM, Tony Lindgren wrote: > * Haojian Zhuang [121018 19:17]: >> On Fri, Oct 19, 2012 at 6:28 AM, Tony Lindgren wrote: >> > >> > Specifically could you decribe the cases where this issue happens? >> > Also check if one of your client drivers has some early initcall >> > that's no longer needed. >> >> Yes, the special case is PMIC. Most of PMIC are based on I2C/SPI bus. >> It means that I2C/SPI bus driver should be initialized firstly. For example, >> we could find that PMIC mfd driver are initialized in subsys init call level. >> It means that pinctrl should be initialized earlier than I2C/SPI bus driver. >> Otherwise, pins of I2C bus may not be configured as I2C function since >> pinctrl driver is module init call level. > > Hmm, the order in drivers/Makefile is already: > > pinctrl/ > i2c/ > > Maybe check that your i2c drivers don't have non-standard initcalls? > > Also the i2c drivers may need to return -EPROBE_DEFER? > > Regards, > > Tony OK. I'll support -EPROBE_DEFER if failed to get pin from pinctrl system. This solution could also resolve the issue. Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 08/10] pinctrl: single: support pinconf generic
On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren wrote: > * Haojian Zhuang [121018 02:08]: >> Add pinconf generic support with POWER SOURCE, BIAS PULL. > ... > >> + case PIN_CONFIG_POWER_SOURCE: >> + if (pcs->psmask == PCS_OFF_DISABLED >> + || pcs->psshift == PCS_OFF_DISABLED) >> + return -ENOTSUPP; >> + data &= pcs->psmask; >> + data = data >> pcs->psshift; >> + *config = data; >> + return 0; >> + break; > > Hmm, only slightly related to this patch, mostly a generic > question to others: Do others have any mux registers with > status bits for things like PIN_CONFIG_POWER_SOURCE? > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS > for omap MMC. But there's also a status bit that needs to be > checked for that. I think there was some other similar mux > register for USB PHY that has a status register. > > So I'm wondering should the checking for status bit be handled > in the pinctrl consume driver? Or should we have some bindings > for that? > Do you mean that the status register only exists in USB PHY controller or MMC controller? If so, could we use regulator framework in USB PHY or MMC driver? Regards Haojian ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 0/9] support pinctrl single in arch pxa/mmp
Changelog: v2: 1. Remove "pinctrl-single,gpio-mask". Since GPIO function is one of the mux function in the pinmux register of both OMAP and PXA/MMP silicons. Use "pinctrl-single,function-mask" instead. 2. Remove "pinctrl-single,gpio-enable" & "pinctrl-single,gpio-disable". Use "pinctrl-single,gpio-func" instead. Because GPIO mode is only one of the mux functions in the pinmux register. Defining "gpio-enable" & "gpio-disable" are redundant. 3. Define register with __iomem, not u32 type. 4. Remove "pinctrl-single,input-schmit-shift", "pinctrl-single,power-source-shift", "pinctrl-single,bias-shift". All these properties could be calculated by mask fields. 5. Return -EPROBE_DEFER if pinmux could be got in device driver. And the device driver would be probed again deferred. ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 1/9] ARM: mmp: select pinctrl driver
Pinctrl driver is necessary for MMP DT & MMP2 DT platforms. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/Kconfig |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 178d4da..ebdda83 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -89,6 +89,8 @@ config MACH_MMP_DT select CPU_PXA168 select CPU_PXA910 select USE_OF + select PINCTRL + select PINCTRL_SINGLE help Include support for Marvell MMP2 based platforms using the device tree. Needn't select any other machine while @@ -99,6 +101,8 @@ config MACH_MMP2_DT depends on !CPU_MOHAWK select CPU_MMP2 select USE_OF + select PINCTRL + select PINCTRL_SINGLE help Include support for Marvell MMP2 based platforms using the device tree. -- 1.7.0.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH v2 2/9] pinctrl: single: support gpio request and free
Marvell's PXA/MMP silicon also match the behavior of pinctrl-single. Each pin binds to one register. A lot of pins could be configured as gpio. Now add three properties in below. pinctrl-single,gpio-ranges: gpio range array pinctrl-single,gpio: pinctrl-single,gpio-func: Signed-off-by: Haojian Zhuang --- drivers/pinctrl/pinctrl-single.c | 94 +- 1 files changed, 92 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 726a729..6a0b24b 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -28,8 +28,10 @@ #define DRIVER_NAME"pinctrl-single" #define PCS_MUX_PINS_NAME "pinctrl-single,pins" #define PCS_MUX_BITS_NAME "pinctrl-single,bits" +#define PCS_GPIO_FUNC_NAME "pinctrl-single,gpio-func" #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_OFF_DISABLED ~0U +#define PCS_MAX_GPIO_VALUES3 /** * struct pcs_pingroup - pingroups for a function @@ -77,6 +79,18 @@ struct pcs_function { }; /** + * struct pcs_gpio_range - pinctrl gpio range + * @range: subrange of the GPIO number space + * @gpio_func: gpio function value in the pinmux register + * @func_en: need to handle gpio function in the pinmux register + */ +struct pcs_gpio_range { + struct pinctrl_gpio_range range; + int gpio_func; + unsigned func_en:1; +}; + +/** * struct pcs_data - wrapper for data needed by pinctrl framework * @pa:pindesc array * @cur: index to current element @@ -123,8 +137,10 @@ struct pcs_name { * @ftree: function index radix tree * @pingroups: list of pingroups * @functions: list of functions + * @ranges:list of gpio ranges * @ngroups: number of pingroups * @nfuncs:number of functions + * @nranges: number of gpio ranges * @desc: pin controller descriptor * @read: register read function to use * @write: register write function to use @@ -148,8 +164,10 @@ struct pcs_device { struct radix_tree_root ftree; struct list_head pingroups; struct list_head functions; + struct list_head ranges; unsigned ngroups; unsigned nfuncs; + unsigned nranges; struct pinctrl_desc desc; unsigned (*read)(void __iomem *reg); void (*write)(unsigned val, void __iomem *reg); @@ -403,9 +421,27 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) + struct pinctrl_gpio_range *range, unsigned pin) { - return -ENOTSUPP; + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_gpio_range *gpio = NULL; + int end, mux_bytes; + unsigned data; + + gpio = container_of(range, struct pcs_gpio_range, range); + if (!gpio->func_en) + return 0; + end = range->pin_base + range->npins - 1; + if (pin < range->pin_base || pin > end) { + dev_err(pctldev->dev, "pin %d isn't in the range of " + "%d to %d\n", pin, range->pin_base, end); + return -EINVAL; + } + mux_bytes = pcs->width / BITS_PER_BYTE; + data = pcs_readl(pcs->base + pin * mux_bytes) & ~pcs->fmask; + data |= gpio->gpio_func; + pcs_writel(data, pcs->base + pin * mux_bytes); + return 0; } static struct pinmux_ops pcs_pinmux_ops = { @@ -879,6 +915,55 @@ static void pcs_free_resources(struct pcs_device *pcs) static struct of_device_id pcs_of_match[]; +static int __devinit pcs_add_gpio_range(struct device_node *node, + struct pcs_device *pcs) +{ + struct pcs_gpio_range *gpio; + struct device_node *np; + const __be32 *list; + const char list_name[] = "pinctrl-single,gpio-ranges"; + const char name[] = "pinctrl-single"; + u32 gpiores[PCS_MAX_GPIO_VALUES]; + int ret, size, i, mux_bytes = 0; + + list = of_get_property(node, list_name, &size); + if (!list) + return -ENOENT; + size = size / sizeof(*list); + for (i = 0; i < size; i++) { + np = of_parse_phandle(node, list_name, i); + memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES); + ret = of_property_read_u32_array(np, "pinctrl-single,gpio", +gpiores, PCS_MAX_GPIO_VALUES); + if (ret < 0) + return -ENOENT; + gpio = devm_kzalloc(pcs->dev, sizeof(*gpio),