2013-04-11 03:42:12

by Neil Zhang

[permalink] [raw]
Subject: [PATCH 0/4] bring up pxa988 with DT

This patch sets do the following things:
1. add wakeup function for ICU.
2. move some common funciton declaration to common.h
3. bring up pxa988 with DT support

Chao Xie (1):
ARM: mmp: add wakeup function for ICU

Neil Zhang (3):
ARM: mmp: move function declaration to head file
ARM: mmp: bring up pxa988 with device tree support
ARM: mmp: add SMP support for pxa988

.../devicetree/bindings/arm/mrvl/intc.txt | 9 +
arch/arm/boot/dts/pxa988-dkb.dts | 36 ++++
arch/arm/boot/dts/pxa988.dtsi | 196 ++++++++++++++++++++
arch/arm/mach-mmp/Kconfig | 25 +++
arch/arm/mach-mmp/Makefile | 5 +
arch/arm/mach-mmp/common.c | 11 +-
arch/arm/mach-mmp/common.h | 5 +
arch/arm/mach-mmp/headsmp.S | 104 +++++++++++
arch/arm/mach-mmp/include/mach/addr-map.h | 6 +
arch/arm/mach-mmp/irq.c | 51 ++++-
arch/arm/mach-mmp/mmp-dt.c | 3 -
arch/arm/mach-mmp/mmp2-dt.c | 3 -
arch/arm/mach-mmp/mmpx-dt.c | 80 ++++++++
arch/arm/mach-mmp/platsmp.c | 170 +++++++++++++++++
arch/arm/mach-mmp/reset.c | 66 +++++++
arch/arm/mach-mmp/reset.h | 29 +++
drivers/clk/mmp/Makefile | 1 +
17 files changed, 783 insertions(+), 17 deletions(-)
create mode 100644 arch/arm/boot/dts/pxa988-dkb.dts
create mode 100644 arch/arm/boot/dts/pxa988.dtsi
create mode 100644 arch/arm/mach-mmp/headsmp.S
create mode 100644 arch/arm/mach-mmp/mmpx-dt.c
create mode 100644 arch/arm/mach-mmp/platsmp.c
create mode 100644 arch/arm/mach-mmp/reset.c
create mode 100644 arch/arm/mach-mmp/reset.h

--
1.7.4.1


2013-04-11 03:38:39

by Neil Zhang

[permalink] [raw]
Subject: [PATCH 1/4] ARM: mmp: add wakeup function for ICU

From: Chao Xie <[email protected]>

PXA988 will use GIC as its interrupt controller, and ICU is used as wakeup
logic. When AP subsystem is powered off, GIC will lose its context, the
PMU will need ICU to wakeup the AP subsystem.
When ICU works as wakeup logic, there is no need to know intc-nr-irqs,
change the corresponding code.

Signed-off-by: Chao Xie <[email protected]>
Signed-off-by: Neil Zhang <[email protected]>
---
.../devicetree/bindings/arm/mrvl/intc.txt | 9 ++++
arch/arm/mach-mmp/irq.c | 51 ++++++++++++++++----
2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
index 8b53273..58c0e74 100644
--- a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
+++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
@@ -15,6 +15,8 @@ Required properties:
- interrupt-controller : Identifies the node as an interrupt controller.
- #interrupt-cells : Specifies the number of cells needed to encode an
interrupt source.
+- mrvl,intc-wakeup : Specifies the address and value for global mask in the
+ interrupt controller.
- 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
@@ -39,6 +41,13 @@ Example:
mrvl,intc-nr-irqs = <2>;
};

+ intc: [email protected] {
+ compatible = "mrvl,mmp-intc";
+ reg = <0xd4282000 0x1000>;
+ mrvl,intc-wakeup = <0x114 0x3
+ 0x144 0x3>;
+ };
+
* Marvell Orion Interrupt controller

Required properties
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
index 3c71246..b8df948 100644
--- a/arch/arm/mach-mmp/irq.c
+++ b/arch/arm/mach-mmp/irq.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
+#include <linux/irqchip/arm-gic.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/of_address.h>
@@ -57,6 +58,7 @@ struct mmp_intc_conf {
void __iomem *mmp_icu_base;
static struct icu_chip_data icu_data[MAX_ICU_NR];
static int max_icu_nr;
+static bool mmp_icu_wakeup;

extern void mmp2_clear_pmic_int(void);

@@ -91,8 +93,11 @@ static void icu_mask_irq(struct irq_data *d)
int hwirq;
u32 r;

- hwirq = d->irq - data->virq_base;
- if (data == &icu_data[0]) {
+ if (mmp_icu_wakeup)
+ hwirq = d->hwirq;
+ else
+ hwirq = d->irq - data->virq_base;
+ if (data == &icu_data[0] || mmp_icu_wakeup) {
r = readl_relaxed(mmp_icu_base + (hwirq << 2));
r &= ~data->conf_mask;
r |= data->conf_disable;
@@ -110,8 +115,11 @@ static void icu_unmask_irq(struct irq_data *d)
int hwirq;
u32 r;

- hwirq = d->irq - data->virq_base;
- if (data == &icu_data[0]) {
+ if (mmp_icu_wakeup)
+ hwirq = d->hwirq;
+ else
+ hwirq = d->irq - data->virq_base;
+ if (data == &icu_data[0] || mmp_icu_wakeup) {
r = readl_relaxed(mmp_icu_base + (hwirq << 2));
r &= ~data->conf_mask;
r |= data->conf_enable;
@@ -415,6 +423,8 @@ void __init mmp_dt_irq_init(void)
const struct of_device_id *of_id;
struct mmp_intc_conf *conf;
int nr_irqs, irq_base, ret, irq;
+ const __be32 *wakeup_reg;
+ int size, i;

node = of_find_matching_node(NULL, intc_ids);
if (!node) {
@@ -424,18 +434,39 @@ void __init mmp_dt_irq_init(void)
of_id = of_match_node(intc_ids, node);
conf = of_id->data;

- ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
- if (ret) {
- pr_err("Not found mrvl,intc-nr-irqs property\n");
- return;
- }
-
mmp_icu_base = of_iomap(node, 0);
if (!mmp_icu_base) {
pr_err("Failed to get interrupt controller register\n");
return;
}

+ /* ICU is only used as wake up logic. */
+ wakeup_reg = of_get_property(node, "mrvl,intc-wakeup", &size);
+ if (wakeup_reg) {
+ mmp_icu_wakeup = 1;
+ size /= sizeof(*wakeup_reg);
+ i = 0;
+ /* disable the global irq/fiq in icu for all cores. */
+ while (i < size) {
+ unsigned offset, val;
+
+ offset = be32_to_cpup(wakeup_reg + i++);
+ val = be32_to_cpup(wakeup_reg + i++);
+ writel_relaxed(val, mmp_icu_base + offset);
+ }
+
+ gic_arch_extn.irq_mask = icu_mask_irq;
+ gic_arch_extn.irq_unmask = icu_unmask_irq;
+
+ return;
+ }
+
+ ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
+ if (ret) {
+ pr_err("Not found mrvl,intc-nr-irqs property\n");
+ return;
+ }
+
irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY, 0);
if (irq_base < 0) {
pr_err("Failed to allocate IRQ numbers\n");
--
1.7.4.1

2013-04-11 03:42:26

by Neil Zhang

[permalink] [raw]
Subject: [PATCH 2/4] ARM: mmp: move function declaration to head file

Move some of the function declaration to head file.

Signed-off-by: Neil Zhang <[email protected]>
Signed-off-by: Chao Xie <[email protected]>
---
arch/arm/mach-mmp/common.h | 3 +++
arch/arm/mach-mmp/mmp-dt.c | 3 ---
arch/arm/mach-mmp/mmp2-dt.c | 3 ---
3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index 0bdc50b..8c9b510 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -8,3 +8,6 @@ extern void mmp_restart(char, const char *);
extern void __init pxa168_clk_init(void);
extern void __init pxa910_clk_init(void);
extern void __init mmp2_clk_init(void);
+
+extern void __init mmp_dt_irq_init(void);
+extern void __init mmp_dt_init_timer(void);
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
index d063efa..af0bb5b 100644
--- a/arch/arm/mach-mmp/mmp-dt.c
+++ b/arch/arm/mach-mmp/mmp-dt.c
@@ -19,9 +19,6 @@

#include "common.h"

-extern void __init mmp_dt_irq_init(void);
-extern void __init mmp_dt_init_timer(void);
-
static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
index fad431a..4ba1fbe 100644
--- a/arch/arm/mach-mmp/mmp2-dt.c
+++ b/arch/arm/mach-mmp/mmp2-dt.c
@@ -21,9 +21,6 @@

#include "common.h"

-extern void __init mmp_dt_irq_init(void);
-extern void __init mmp_dt_init_timer(void);
-
static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL),
--
1.7.4.1

2013-04-13 12:50:21

by Haojian Zhuang

[permalink] [raw]
Subject: Re: [PATCH 1/4] ARM: mmp: add wakeup function for ICU

On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]> wrote:
> From: Chao Xie <[email protected]>
>
> PXA988 will use GIC as its interrupt controller, and ICU is used as wakeup
> logic. When AP subsystem is powered off, GIC will lose its context, the
> PMU will need ICU to wakeup the AP subsystem.
> When ICU works as wakeup logic, there is no need to know intc-nr-irqs,
> change the corresponding code.
>
> Signed-off-by: Chao Xie <[email protected]>
> Signed-off-by: Neil Zhang <[email protected]>
> ---
> .../devicetree/bindings/arm/mrvl/intc.txt | 9 ++++
> arch/arm/mach-mmp/irq.c | 51 ++++++++++++++++----
> 2 files changed, 50 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> index 8b53273..58c0e74 100644
> --- a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> @@ -15,6 +15,8 @@ Required properties:
> - interrupt-controller : Identifies the node as an interrupt controller.
> - #interrupt-cells : Specifies the number of cells needed to encode an
> interrupt source.
> +- mrvl,intc-wakeup : Specifies the address and value for global mask in the
> + interrupt controller.
> - 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
> @@ -39,6 +41,13 @@ Example:
> mrvl,intc-nr-irqs = <2>;
> };
>
> + intc: [email protected] {
> + compatible = "mrvl,mmp-intc";
> + reg = <0xd4282000 0x1000>;
> + mrvl,intc-wakeup = <0x114 0x3
> + 0x144 0x3>;
> + };
> +
> * Marvell Orion Interrupt controller
>
> Required properties
> diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
> index 3c71246..b8df948 100644
> --- a/arch/arm/mach-mmp/irq.c
> +++ b/arch/arm/mach-mmp/irq.c
> @@ -16,6 +16,7 @@
> #include <linux/init.h>
> #include <linux/irq.h>
> #include <linux/irqdomain.h>
> +#include <linux/irqchip/arm-gic.h>
> #include <linux/io.h>
> #include <linux/ioport.h>
> #include <linux/of_address.h>
> @@ -57,6 +58,7 @@ struct mmp_intc_conf {
> void __iomem *mmp_icu_base;
> static struct icu_chip_data icu_data[MAX_ICU_NR];
> static int max_icu_nr;
> +static bool mmp_icu_wakeup;
>
> extern void mmp2_clear_pmic_int(void);
>
> @@ -91,8 +93,11 @@ static void icu_mask_irq(struct irq_data *d)
> int hwirq;
> u32 r;
>
> - hwirq = d->irq - data->virq_base;
> - if (data == &icu_data[0]) {
> + if (mmp_icu_wakeup)
> + hwirq = d->hwirq;
> + else
> + hwirq = d->irq - data->virq_base;
> + if (data == &icu_data[0] || mmp_icu_wakeup) {
> r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> r &= ~data->conf_mask;
> r |= data->conf_disable;
> @@ -110,8 +115,11 @@ static void icu_unmask_irq(struct irq_data *d)
> int hwirq;
> u32 r;
>
> - hwirq = d->irq - data->virq_base;
> - if (data == &icu_data[0]) {
> + if (mmp_icu_wakeup)
> + hwirq = d->hwirq;
> + else
> + hwirq = d->irq - data->virq_base;
> + if (data == &icu_data[0] || mmp_icu_wakeup) {
> r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> r &= ~data->conf_mask;
> r |= data->conf_enable;
> @@ -415,6 +423,8 @@ void __init mmp_dt_irq_init(void)
> const struct of_device_id *of_id;
> struct mmp_intc_conf *conf;
> int nr_irqs, irq_base, ret, irq;
> + const __be32 *wakeup_reg;
> + int size, i;
>
> node = of_find_matching_node(NULL, intc_ids);
> if (!node) {
> @@ -424,18 +434,39 @@ void __init mmp_dt_irq_init(void)
> of_id = of_match_node(intc_ids, node);
> conf = of_id->data;
>
> - ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
> - if (ret) {
> - pr_err("Not found mrvl,intc-nr-irqs property\n");
> - return;
> - }
> -
> mmp_icu_base = of_iomap(node, 0);
> if (!mmp_icu_base) {
> pr_err("Failed to get interrupt controller register\n");
> return;
> }
>
> + /* ICU is only used as wake up logic. */
> + wakeup_reg = of_get_property(node, "mrvl,intc-wakeup", &size);
> + if (wakeup_reg) {
> + mmp_icu_wakeup = 1;
> + size /= sizeof(*wakeup_reg);
> + i = 0;
> + /* disable the global irq/fiq in icu for all cores. */
> + while (i < size) {
> + unsigned offset, val;
> +
> + offset = be32_to_cpup(wakeup_reg + i++);
> + val = be32_to_cpup(wakeup_reg + i++);
> + writel_relaxed(val, mmp_icu_base + offset);
> + }
> +
> + gic_arch_extn.irq_mask = icu_mask_irq;
> + gic_arch_extn.irq_unmask = icu_unmask_irq;
> +
> + return;
> + }

Since it's totally different from original ICU irq initialization, I suggest to
create a new entry to handle this kind of wakeup event. And we could
create a new mask/unmask function.

> +
> + ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
> + if (ret) {
> + pr_err("Not found mrvl,intc-nr-irqs property\n");
> + return;
> + }
> +
> irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY, 0);
> if (irq_base < 0) {
> pr_err("Failed to allocate IRQ numbers\n");
> --
> 1.7.4.1
>

2013-04-13 12:59:16

by Haojian Zhuang

[permalink] [raw]
Subject: Re: [PATCH 2/4] ARM: mmp: move function declaration to head file

On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]> wrote:
> Move some of the function declaration to head file.
>
> Signed-off-by: Neil Zhang <[email protected]>
> Signed-off-by: Chao Xie <[email protected]>
> ---
> arch/arm/mach-mmp/common.h | 3 +++
> arch/arm/mach-mmp/mmp-dt.c | 3 ---
> arch/arm/mach-mmp/mmp2-dt.c | 3 ---
> 3 files changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
> index 0bdc50b..8c9b510 100644
> --- a/arch/arm/mach-mmp/common.h
> +++ b/arch/arm/mach-mmp/common.h
> @@ -8,3 +8,6 @@ extern void mmp_restart(char, const char *);
> extern void __init pxa168_clk_init(void);
> extern void __init pxa910_clk_init(void);
> extern void __init mmp2_clk_init(void);
> +
> +extern void __init mmp_dt_irq_init(void);
> +extern void __init mmp_dt_init_timer(void);

It's better to make use of of_irq_init() & CLOCKSOURCE_OF_DECLARE()
for timer. So I'll move mmp timer into clocksource & mmp irq into
irqchip directory in the next week. You can rebase your code. Is it OK?

> diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
> index d063efa..af0bb5b 100644
> --- a/arch/arm/mach-mmp/mmp-dt.c
> +++ b/arch/arm/mach-mmp/mmp-dt.c
> @@ -19,9 +19,6 @@
>
> #include "common.h"
>
> -extern void __init mmp_dt_irq_init(void);
> -extern void __init mmp_dt_init_timer(void);
> -
> static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = {
> OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
> OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
> diff --git a/arch/arm/mach-mmp/mmp2-dt.c b/arch/arm/mach-mmp/mmp2-dt.c
> index fad431a..4ba1fbe 100644
> --- a/arch/arm/mach-mmp/mmp2-dt.c
> +++ b/arch/arm/mach-mmp/mmp2-dt.c
> @@ -21,9 +21,6 @@
>
> #include "common.h"
>
> -extern void __init mmp_dt_irq_init(void);
> -extern void __init mmp_dt_init_timer(void);
> -
> static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = {
> OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL),
> OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL),
> --
> 1.7.4.1
>

2013-04-15 11:11:23

by Neil Zhang

[permalink] [raw]
Subject: RE: [PATCH 1/4] ARM: mmp: add wakeup function for ICU





> -----Original Message-----
> From: Haojian Zhuang [mailto:[email protected]]
> Sent: 2013??4??13?? 20:50
> To: Neil Zhang
> Cc: Grant Likely; [email protected];
> [email protected]; Chao Xie
> Subject: Re: [PATCH 1/4] ARM: mmp: add wakeup function for ICU
>
> On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]>
> wrote:
> > From: Chao Xie <[email protected]>
> >
> > PXA988 will use GIC as its interrupt controller, and ICU is used as
> > wakeup logic. When AP subsystem is powered off, GIC will lose its
> > context, the PMU will need ICU to wakeup the AP subsystem.
> > When ICU works as wakeup logic, there is no need to know intc-nr-irqs,
> > change the corresponding code.
> >
> > Signed-off-by: Chao Xie <[email protected]>
> > Signed-off-by: Neil Zhang <[email protected]>
> > ---
> > .../devicetree/bindings/arm/mrvl/intc.txt | 9 ++++
> > arch/arm/mach-mmp/irq.c | 51
> ++++++++++++++++----
> > 2 files changed, 50 insertions(+), 10 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > index 8b53273..58c0e74 100644
> > --- a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > @@ -15,6 +15,8 @@ Required properties:
> > - interrupt-controller : Identifies the node as an interrupt controller.
> > - #interrupt-cells : Specifies the number of cells needed to encode an
> > interrupt source.
> > +- mrvl,intc-wakeup : Specifies the address and value for global mask
> > +in the
> > + interrupt controller.
> > - 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 @@ -39,6 +41,13 @@ Example:
> > mrvl,intc-nr-irqs = <2>;
> > };
> >
> > + intc: [email protected] {
> > + compatible = "mrvl,mmp-intc";
> > + reg = <0xd4282000 0x1000>;
> > + mrvl,intc-wakeup = <0x114 0x3
> > + 0x144 0x3>;
> > + };
> > +
> > * Marvell Orion Interrupt controller
> >
> > Required properties
> > diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c index
> > 3c71246..b8df948 100644
> > --- a/arch/arm/mach-mmp/irq.c
> > +++ b/arch/arm/mach-mmp/irq.c
> > @@ -16,6 +16,7 @@
> > #include <linux/init.h>
> > #include <linux/irq.h>
> > #include <linux/irqdomain.h>
> > +#include <linux/irqchip/arm-gic.h>
> > #include <linux/io.h>
> > #include <linux/ioport.h>
> > #include <linux/of_address.h>
> > @@ -57,6 +58,7 @@ struct mmp_intc_conf { void __iomem
> *mmp_icu_base;
> > static struct icu_chip_data icu_data[MAX_ICU_NR]; static int
> > max_icu_nr;
> > +static bool mmp_icu_wakeup;
> >
> > extern void mmp2_clear_pmic_int(void);
> >
> > @@ -91,8 +93,11 @@ static void icu_mask_irq(struct irq_data *d)
> > int hwirq;
> > u32 r;
> >
> > - hwirq = d->irq - data->virq_base;
> > - if (data == &icu_data[0]) {
> > + if (mmp_icu_wakeup)
> > + hwirq = d->hwirq;
> > + else
> > + hwirq = d->irq - data->virq_base;
> > + if (data == &icu_data[0] || mmp_icu_wakeup) {
> > r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> > r &= ~data->conf_mask;
> > r |= data->conf_disable; @@ -110,8 +115,11 @@
> static
> > void icu_unmask_irq(struct irq_data *d)
> > int hwirq;
> > u32 r;
> >
> > - hwirq = d->irq - data->virq_base;
> > - if (data == &icu_data[0]) {
> > + if (mmp_icu_wakeup)
> > + hwirq = d->hwirq;
> > + else
> > + hwirq = d->irq - data->virq_base;
> > + if (data == &icu_data[0] || mmp_icu_wakeup) {
> > r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> > r &= ~data->conf_mask;
> > r |= data->conf_enable; @@ -415,6 +423,8 @@ void
> > __init mmp_dt_irq_init(void)
> > const struct of_device_id *of_id;
> > struct mmp_intc_conf *conf;
> > int nr_irqs, irq_base, ret, irq;
> > + const __be32 *wakeup_reg;
> > + int size, i;
> >
> > node = of_find_matching_node(NULL, intc_ids);
> > if (!node) {
> > @@ -424,18 +434,39 @@ void __init mmp_dt_irq_init(void)
> > of_id = of_match_node(intc_ids, node);
> > conf = of_id->data;
> >
> > - ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
> > - if (ret) {
> > - pr_err("Not found mrvl,intc-nr-irqs property\n");
> > - return;
> > - }
> > -
> > mmp_icu_base = of_iomap(node, 0);
> > if (!mmp_icu_base) {
> > pr_err("Failed to get interrupt controller register\n");
> > return;
> > }
> >
> > + /* ICU is only used as wake up logic. */
> > + wakeup_reg = of_get_property(node, "mrvl,intc-wakeup", &size);
> > + if (wakeup_reg) {
> > + mmp_icu_wakeup = 1;
> > + size /= sizeof(*wakeup_reg);
> > + i = 0;
> > + /* disable the global irq/fiq in icu for all cores. */
> > + while (i < size) {
> > + unsigned offset, val;
> > +
> > + offset = be32_to_cpup(wakeup_reg + i++);
> > + val = be32_to_cpup(wakeup_reg + i++);
> > + writel_relaxed(val, mmp_icu_base + offset);
> > + }
> > +
> > + gic_arch_extn.irq_mask = icu_mask_irq;
> > + gic_arch_extn.irq_unmask = icu_unmask_irq;
> > +
> > + return;
> > + }
>
> Since it's totally different from original ICU irq initialization, I suggest to
> create a new entry to handle this kind of wakeup event. And we could create
> a new mask/unmask function.

Ok, I'll update it.

>
> > +
> > + ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs);
> > + if (ret) {
> > + pr_err("Not found mrvl,intc-nr-irqs property\n");
> > + return;
> > + }
> > +
> > irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY, 0);
> > if (irq_base < 0) {
> > pr_err("Failed to allocate IRQ numbers\n");
> > --
> > 1.7.4.1
> >

Best Regards,
Neil Zhang
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-04-15 11:11:56

by Neil Zhang

[permalink] [raw]
Subject: RE: [PATCH 2/4] ARM: mmp: move function declaration to head file





> -----Original Message-----
> From: Haojian Zhuang [mailto:[email protected]]
> Sent: 2013??4??13?? 20:59
> To: Neil Zhang
> Cc: Grant Likely; [email protected];
> [email protected]; Chao Xie
> Subject: Re: [PATCH 2/4] ARM: mmp: move function declaration to head file
>
> On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]>
> wrote:
> > Move some of the function declaration to head file.
> >
> > Signed-off-by: Neil Zhang <[email protected]>
> > Signed-off-by: Chao Xie <[email protected]>
> > ---
> > arch/arm/mach-mmp/common.h | 3 +++
> > arch/arm/mach-mmp/mmp-dt.c | 3 ---
> > arch/arm/mach-mmp/mmp2-dt.c | 3 ---
> > 3 files changed, 3 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/arm/mach-mmp/common.h
> b/arch/arm/mach-mmp/common.h
> > index 0bdc50b..8c9b510 100644
> > --- a/arch/arm/mach-mmp/common.h
> > +++ b/arch/arm/mach-mmp/common.h
> > @@ -8,3 +8,6 @@ extern void mmp_restart(char, const char *); extern
> > void __init pxa168_clk_init(void); extern void __init
> > pxa910_clk_init(void); extern void __init mmp2_clk_init(void);
> > +
> > +extern void __init mmp_dt_irq_init(void); extern void __init
> > +mmp_dt_init_timer(void);
>
> It's better to make use of of_irq_init() & CLOCKSOURCE_OF_DECLARE() for
> timer. So I'll move mmp timer into clocksource & mmp irq into irqchip
> directory in the next week. You can rebase your code. Is it OK?
>

Ok, I'll rebase after your update.


> > diff --git a/arch/arm/mach-mmp/mmp-dt.c
> b/arch/arm/mach-mmp/mmp-dt.c
> > index d063efa..af0bb5b 100644
> > --- a/arch/arm/mach-mmp/mmp-dt.c
> > +++ b/arch/arm/mach-mmp/mmp-dt.c
> > @@ -19,9 +19,6 @@
> >
> > #include "common.h"
> >
> > -extern void __init mmp_dt_irq_init(void); -extern void __init
> > mmp_dt_init_timer(void);
> > -
> > static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst
> = {
> > OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000,
> "pxa2xx-uart.0", NULL),
> > OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000,
> "pxa2xx-uart.1",
> > NULL), diff --git a/arch/arm/mach-mmp/mmp2-dt.c
> > b/arch/arm/mach-mmp/mmp2-dt.c index fad431a..4ba1fbe 100644
> > --- a/arch/arm/mach-mmp/mmp2-dt.c
> > +++ b/arch/arm/mach-mmp/mmp2-dt.c
> > @@ -21,9 +21,6 @@
> >
> > #include "common.h"
> >
> > -extern void __init mmp_dt_irq_init(void); -extern void __init
> > mmp_dt_init_timer(void);
> > -
> > static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst
> = {
> > OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000,
> "pxa2xx-uart.0", NULL),
> > OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000,
> "pxa2xx-uart.1",
> > NULL),
> > --
> > 1.7.4.1
> >

Best Regards,
Neil Zhang
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-04-16 01:58:37

by Neil Zhang

[permalink] [raw]
Subject: RE: [PATCH 1/4] ARM: mmp: add wakeup function for ICU

Haojian,

> -----Original Message-----
> From: Neil Zhang
> Sent: 2013??4??15?? 19:10
> To: 'Haojian Zhuang'
> Cc: Grant Likely; [email protected];
> [email protected]; Chao Xie
> Subject: RE: [PATCH 1/4] ARM: mmp: add wakeup function for ICU
>
>
>
>
>
> > -----Original Message-----
> > From: Haojian Zhuang [mailto:[email protected]]
> > Sent: 2013??4??13?? 20:50
> > To: Neil Zhang
> > Cc: Grant Likely; [email protected];
> > [email protected]; Chao Xie
> > Subject: Re: [PATCH 1/4] ARM: mmp: add wakeup function for ICU
> >
> > On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]>
> > wrote:
> > > From: Chao Xie <[email protected]>
> > >
> > > PXA988 will use GIC as its interrupt controller, and ICU is used as
> > > wakeup logic. When AP subsystem is powered off, GIC will lose its
> > > context, the PMU will need ICU to wakeup the AP subsystem.
> > > When ICU works as wakeup logic, there is no need to know
> > > intc-nr-irqs, change the corresponding code.
> > >
> > > Signed-off-by: Chao Xie <[email protected]>
> > > Signed-off-by: Neil Zhang <[email protected]>
> > > ---
> > > .../devicetree/bindings/arm/mrvl/intc.txt | 9 ++++
> > > arch/arm/mach-mmp/irq.c | 51
> > ++++++++++++++++----
> > > 2 files changed, 50 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > > b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > > index 8b53273..58c0e74 100644
> > > --- a/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > > +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt
> > > @@ -15,6 +15,8 @@ Required properties:
> > > - interrupt-controller : Identifies the node as an interrupt controller.
> > > - #interrupt-cells : Specifies the number of cells needed to encode an
> > > interrupt source.
> > > +- mrvl,intc-wakeup : Specifies the address and value for global
> > > +mask in the
> > > + interrupt controller.
> > > - 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 @@ -39,6 +41,13 @@ Example:
> > > mrvl,intc-nr-irqs = <2>;
> > > };
> > >
> > > + intc: [email protected] {
> > > + compatible = "mrvl,mmp-intc";
> > > + reg = <0xd4282000 0x1000>;
> > > + mrvl,intc-wakeup = <0x114 0x3
> > > + 0x144 0x3>;
> > > + };
> > > +
> > > * Marvell Orion Interrupt controller
> > >
> > > Required properties
> > > diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
> index
> > > 3c71246..b8df948 100644
> > > --- a/arch/arm/mach-mmp/irq.c
> > > +++ b/arch/arm/mach-mmp/irq.c
> > > @@ -16,6 +16,7 @@
> > > #include <linux/init.h>
> > > #include <linux/irq.h>
> > > #include <linux/irqdomain.h>
> > > +#include <linux/irqchip/arm-gic.h>
> > > #include <linux/io.h>
> > > #include <linux/ioport.h>
> > > #include <linux/of_address.h>
> > > @@ -57,6 +58,7 @@ struct mmp_intc_conf { void __iomem
> > *mmp_icu_base;
> > > static struct icu_chip_data icu_data[MAX_ICU_NR]; static int
> > > max_icu_nr;
> > > +static bool mmp_icu_wakeup;
> > >
> > > extern void mmp2_clear_pmic_int(void);
> > >
> > > @@ -91,8 +93,11 @@ static void icu_mask_irq(struct irq_data *d)
> > > int hwirq;
> > > u32 r;
> > >
> > > - hwirq = d->irq - data->virq_base;
> > > - if (data == &icu_data[0]) {
> > > + if (mmp_icu_wakeup)
> > > + hwirq = d->hwirq;
> > > + else
> > > + hwirq = d->irq - data->virq_base;
> > > + if (data == &icu_data[0] || mmp_icu_wakeup) {
> > > r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> > > r &= ~data->conf_mask;
> > > r |= data->conf_disable; @@ -110,8 +115,11 @@
> > static
> > > void icu_unmask_irq(struct irq_data *d)
> > > int hwirq;
> > > u32 r;
> > >
> > > - hwirq = d->irq - data->virq_base;
> > > - if (data == &icu_data[0]) {
> > > + if (mmp_icu_wakeup)
> > > + hwirq = d->hwirq;
> > > + else
> > > + hwirq = d->irq - data->virq_base;
> > > + if (data == &icu_data[0] || mmp_icu_wakeup) {
> > > r = readl_relaxed(mmp_icu_base + (hwirq << 2));
> > > r &= ~data->conf_mask;
> > > r |= data->conf_enable; @@ -415,6 +423,8 @@
> void
> > > __init mmp_dt_irq_init(void)
> > > const struct of_device_id *of_id;
> > > struct mmp_intc_conf *conf;
> > > int nr_irqs, irq_base, ret, irq;
> > > + const __be32 *wakeup_reg;
> > > + int size, i;
> > >
> > > node = of_find_matching_node(NULL, intc_ids);
> > > if (!node) {
> > > @@ -424,18 +434,39 @@ void __init mmp_dt_irq_init(void)
> > > of_id = of_match_node(intc_ids, node);
> > > conf = of_id->data;
> > >
> > > - ret = of_property_read_u32(node, "mrvl,intc-nr-irqs",
> &nr_irqs);
> > > - if (ret) {
> > > - pr_err("Not found mrvl,intc-nr-irqs property\n");
> > > - return;
> > > - }
> > > -
> > > mmp_icu_base = of_iomap(node, 0);
> > > if (!mmp_icu_base) {
> > > pr_err("Failed to get interrupt controller register\n");
> > > return;
> > > }
> > >
> > > + /* ICU is only used as wake up logic. */
> > > + wakeup_reg = of_get_property(node, "mrvl,intc-wakeup",
> &size);
> > > + if (wakeup_reg) {
> > > + mmp_icu_wakeup = 1;
> > > + size /= sizeof(*wakeup_reg);
> > > + i = 0;
> > > + /* disable the global irq/fiq in icu for all cores. */
> > > + while (i < size) {
> > > + unsigned offset, val;
> > > +
> > > + offset = be32_to_cpup(wakeup_reg + i++);
> > > + val = be32_to_cpup(wakeup_reg + i++);
> > > + writel_relaxed(val, mmp_icu_base +
> offset);
> > > + }
> > > +
> > > + gic_arch_extn.irq_mask = icu_mask_irq;
> > > + gic_arch_extn.irq_unmask = icu_unmask_irq;
> > > +
> > > + return;
> > > + }
> >
> > Since it's totally different from original ICU irq initialization, I
> > suggest to create a new entry to handle this kind of wakeup event. And
> > we could create a new mask/unmask function.
>
> Ok, I'll update it.
Are you OK if use icu_mask_irq_wakeup / icu_unmask_irq_wakeup for the new functions.
>
> >
> > > +
> > > + ret = of_property_read_u32(node, "mrvl,intc-nr-irqs",
> &nr_irqs);
> > > + if (ret) {
> > > + pr_err("Not found mrvl,intc-nr-irqs property\n");
> > > + return;
> > > + }
> > > +
> > > irq_base = irq_alloc_descs(-1, 0, nr_irqs - NR_IRQS_LEGACY,
> 0);
> > > if (irq_base < 0) {
> > > pr_err("Failed to allocate IRQ numbers\n");
> > > --
> > > 1.7.4.1
> > >
>
> Best Regards,
> Neil Zhang

Best Regards,
Neil Zhang
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-04-16 15:13:44

by Haojian Zhuang

[permalink] [raw]
Subject: Re: [PATCH 1/4] ARM: mmp: add wakeup function for ICU

>> > From: Haojian Zhuang [mailto:[email protected]]
>> > Sent: 2013年4月13日 20:50
>> > To: Neil Zhang
>> > Cc: Grant Likely; [email protected];
>> > [email protected]; Chao Xie
>> > Subject: Re: [PATCH 1/4] ARM: mmp: add wakeup function for ICU
>> >
>> > On Thu, Apr 11, 2013 at 11:37 AM, Neil Zhang <[email protected]>
>> > wrote:
>> > > From: Chao Xie <[email protected]>
>> > >
>> > > PXA988 will use GIC as its interrupt controller, and ICU is used as
>> > > wakeup logic. When AP subsystem is powered off, GIC will lose its
>> > > context, the PMU will need ICU to wakeup the AP subsystem.
>> > > When ICU works as wakeup logic, there is no need to know
>> > > intc-nr-irqs, change the corresponding code.
>> > >
>> > > Signed-off-by: Chao Xie <[email protected]>
>> > > Signed-off-by: Neil Zhang <[email protected]>
>> > > ---
>> >
>> > Since it's totally different from original ICU irq initialization, I
>> > suggest to create a new entry to handle this kind of wakeup event. And
>> > we could create a new mask/unmask function.
>>
>> Ok, I'll update it.
> Are you OK if use icu_mask_irq_wakeup / icu_unmask_irq_wakeup for the new functions.

Yes, it's ok to me.