2020-05-18 09:17:15

by Anup Patel

[permalink] [raw]
Subject: [PATCH v2 0/3] More improvements for multiple PLICs

This series does more improvements for supporting multiple PLIC
instances.

PATCH1 and PATCH2 are fixes whereas PATCH3 helps users distinguish
multiple PLIC instances in boot prints.

These patches are based up Linux-5.7-rc5 and can be found at
plic_imp_v2 branch at: https://github.com/avpatel/linux.git

To try this patches, we will need:
1. OpenSBI multi-PLIC and multi-CLINT support which can be found in
multi_plic_clint_v1 branch at:
https://github.com/avpatel/opensbi.git
2. QEMU RISC-V multi-socket support which can be found in
riscv_multi_socket_v1 branch at:
https://github.com/avpatel/qemu.git

Changes since v1:
- Re-arranged PATCHs to have fixes first
- Added Fixes tag to PATCH1 and PATCH2
- Use %pOFP in boot print to distinguish PLIC instance

Anup Patel (3):
irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()
irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is
present
irqchip/sifive-plic: Improve boot prints for multiple PLIC instances

drivers/irqchip/irq-sifive-plic.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)

--
2.25.1


2020-05-18 09:18:07

by Anup Patel

[permalink] [raw]
Subject: [PATCH v2 2/3] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present

For multiple PLIC instances, the plic_init() is called once for each
PLIC instance. Due to this we have two issues:
1. cpuhp_setup_state() is called multiple times
2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state()
is called before boot CPU PLIC handler is available.

This patch fixes both above issues.

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Cc: [email protected]
Signed-off-by: Anup Patel <[email protected]>
---
drivers/irqchip/irq-sifive-plic.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 9f7f8ce88c00..6c54abf5cc5e 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -76,6 +76,7 @@ struct plic_handler {
void __iomem *enable_base;
struct plic_priv *priv;
};
+static bool plic_cpuhp_setup_done;
static DEFINE_PER_CPU(struct plic_handler, plic_handlers);

static inline void plic_toggle(struct plic_handler *handler,
@@ -285,6 +286,7 @@ static int __init plic_init(struct device_node *node,
int error = 0, nr_contexts, nr_handlers = 0, i;
u32 nr_irqs;
struct plic_priv *priv;
+ struct plic_handler *handler;

priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -313,7 +315,6 @@ static int __init plic_init(struct device_node *node,

for (i = 0; i < nr_contexts; i++) {
struct of_phandle_args parent;
- struct plic_handler *handler;
irq_hw_number_t hwirq;
int cpu, hartid;

@@ -367,9 +368,18 @@ static int __init plic_init(struct device_node *node,
nr_handlers++;
}

- cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
+ /*
+ * We can have multiple PLIC instances so setup cpuhp state only
+ * when context handler for current/boot CPU is present.
+ */
+ handler = this_cpu_ptr(&plic_handlers);
+ if (handler->present && !plic_cpuhp_setup_done) {
+ cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
"irqchip/sifive/plic:starting",
plic_starting_cpu, plic_dying_cpu);
+ plic_cpuhp_setup_done = true;
+ }
+
pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
nr_irqs, nr_handlers, nr_contexts);
set_handle_irq(plic_handle_irq);
--
2.25.1

2020-05-18 09:18:22

by Anup Patel

[permalink] [raw]
Subject: [PATCH v2 3/3] irqchip/sifive-plic: Improve boot prints for multiple PLIC instances

We improve PLIC banner to help distinguish multiple PLIC instances
in boot time prints.

Signed-off-by: Anup Patel <[email protected]>
---
drivers/irqchip/irq-sifive-plic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 6c54abf5cc5e..d9c53f85a68e 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -380,8 +380,8 @@ static int __init plic_init(struct device_node *node,
plic_cpuhp_setup_done = true;
}

- pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
- nr_irqs, nr_handlers, nr_contexts);
+ pr_info("%pOFP: mapped %d interrupts with %d handlers for"
+ " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
set_handle_irq(plic_handle_irq);
return 0;

--
2.25.1

2020-05-18 09:19:22

by Anup Patel

[permalink] [raw]
Subject: [PATCH v2 1/3] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()

For multiple PLIC instances, each PLIC can only target a subset of
CPUs which is represented by "lmask" in the "struct plic_priv".

Currently, the default irq affinity for each PLIC interrupt is all
online CPUs which is illegal value for default irq affinity when we
have multiple PLIC instances. To fix this, we now set "lmask" as the
default irq affinity in for each interrupt in plic_irqdomain_map().

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Cc: [email protected]
Signed-off-by: Anup Patel <[email protected]>
---
drivers/irqchip/irq-sifive-plic.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 822e074c0600..9f7f8ce88c00 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -176,9 +176,12 @@ static struct irq_chip plic_chip = {
static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
+ struct plic_priv *priv = d->host_data;
+
irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
irq_set_noprobe(irq);
+ irq_set_affinity(irq, &priv->lmask);
return 0;
}

--
2.25.1

2020-05-21 22:08:01

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present

On Mon, 18 May 2020 02:14:40 PDT (-0700), Anup Patel wrote:
> For multiple PLIC instances, the plic_init() is called once for each
> PLIC instance. Due to this we have two issues:
> 1. cpuhp_setup_state() is called multiple times
> 2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state()
> is called before boot CPU PLIC handler is available.
>
> This patch fixes both above issues.
>
> Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
> Cc: [email protected]
> Signed-off-by: Anup Patel <[email protected]>
> ---
> drivers/irqchip/irq-sifive-plic.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> index 9f7f8ce88c00..6c54abf5cc5e 100644
> --- a/drivers/irqchip/irq-sifive-plic.c
> +++ b/drivers/irqchip/irq-sifive-plic.c
> @@ -76,6 +76,7 @@ struct plic_handler {
> void __iomem *enable_base;
> struct plic_priv *priv;
> };
> +static bool plic_cpuhp_setup_done;
> static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
>
> static inline void plic_toggle(struct plic_handler *handler,
> @@ -285,6 +286,7 @@ static int __init plic_init(struct device_node *node,
> int error = 0, nr_contexts, nr_handlers = 0, i;
> u32 nr_irqs;
> struct plic_priv *priv;
> + struct plic_handler *handler;
>
> priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> if (!priv)
> @@ -313,7 +315,6 @@ static int __init plic_init(struct device_node *node,
>
> for (i = 0; i < nr_contexts; i++) {
> struct of_phandle_args parent;
> - struct plic_handler *handler;
> irq_hw_number_t hwirq;
> int cpu, hartid;
>
> @@ -367,9 +368,18 @@ static int __init plic_init(struct device_node *node,
> nr_handlers++;
> }
>
> - cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
> + /*
> + * We can have multiple PLIC instances so setup cpuhp state only
> + * when context handler for current/boot CPU is present.
> + */
> + handler = this_cpu_ptr(&plic_handlers);
> + if (handler->present && !plic_cpuhp_setup_done) {
> + cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
> "irqchip/sifive/plic:starting",
> plic_starting_cpu, plic_dying_cpu);
> + plic_cpuhp_setup_done = true;

So presumably something else is preventing multiple plic_init() calls from
executing at the same time? Assuming that's the case

Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>

> + }
> +
> pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
> nr_irqs, nr_handlers, nr_contexts);
> set_handle_irq(plic_handle_irq);

2020-05-21 22:08:01

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()

On Mon, 18 May 2020 02:14:39 PDT (-0700), Anup Patel wrote:
> For multiple PLIC instances, each PLIC can only target a subset of
> CPUs which is represented by "lmask" in the "struct plic_priv".
>
> Currently, the default irq affinity for each PLIC interrupt is all
> online CPUs which is illegal value for default irq affinity when we
> have multiple PLIC instances. To fix this, we now set "lmask" as the
> default irq affinity in for each interrupt in plic_irqdomain_map().
>
> Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
> Cc: [email protected]
> Signed-off-by: Anup Patel <[email protected]>
> ---
> drivers/irqchip/irq-sifive-plic.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> index 822e074c0600..9f7f8ce88c00 100644
> --- a/drivers/irqchip/irq-sifive-plic.c
> +++ b/drivers/irqchip/irq-sifive-plic.c
> @@ -176,9 +176,12 @@ static struct irq_chip plic_chip = {
> static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
> irq_hw_number_t hwirq)
> {
> + struct plic_priv *priv = d->host_data;
> +
> irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
> handle_fasteoi_irq, NULL, NULL);

If you're going to re-spin this, d->host_data could be priv here.

> irq_set_noprobe(irq);
> + irq_set_affinity(irq, &priv->lmask);
> return 0;
> }

Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>

2020-05-21 22:08:12

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] irqchip/sifive-plic: Improve boot prints for multiple PLIC instances

On Mon, 18 May 2020 02:14:41 PDT (-0700), Anup Patel wrote:
> We improve PLIC banner to help distinguish multiple PLIC instances
> in boot time prints.
>
> Signed-off-by: Anup Patel <[email protected]>
> ---
> drivers/irqchip/irq-sifive-plic.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> index 6c54abf5cc5e..d9c53f85a68e 100644
> --- a/drivers/irqchip/irq-sifive-plic.c
> +++ b/drivers/irqchip/irq-sifive-plic.c
> @@ -380,8 +380,8 @@ static int __init plic_init(struct device_node *node,
> plic_cpuhp_setup_done = true;
> }
>
> - pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
> - nr_irqs, nr_handlers, nr_contexts);
> + pr_info("%pOFP: mapped %d interrupts with %d handlers for"
> + " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
> set_handle_irq(plic_handle_irq);
> return 0;

Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>

2020-05-21 22:09:32

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH v2 0/3] More improvements for multiple PLICs

On Mon, 18 May 2020 02:14:38 PDT (-0700), Anup Patel wrote:
> This series does more improvements for supporting multiple PLIC
> instances.
>
> PATCH1 and PATCH2 are fixes whereas PATCH3 helps users distinguish
> multiple PLIC instances in boot prints.
>
> These patches are based up Linux-5.7-rc5 and can be found at
> plic_imp_v2 branch at: https://github.com/avpatel/linux.git
>
> To try this patches, we will need:
> 1. OpenSBI multi-PLIC and multi-CLINT support which can be found in
> multi_plic_clint_v1 branch at:
> https://github.com/avpatel/opensbi.git
> 2. QEMU RISC-V multi-socket support which can be found in
> riscv_multi_socket_v1 branch at:
> https://github.com/avpatel/qemu.git
>
> Changes since v1:
> - Re-arranged PATCHs to have fixes first
> - Added Fixes tag to PATCH1 and PATCH2
> - Use %pOFP in boot print to distinguish PLIC instance
>
> Anup Patel (3):
> irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()
> irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is
> present
> irqchip/sifive-plic: Improve boot prints for multiple PLIC instances
>
> drivers/irqchip/irq-sifive-plic.c | 21 +++++++++++++++++----
> 1 file changed, 17 insertions(+), 4 deletions(-)

Thanks! Aside from that parallelism question this LGTM. IIRC Marc picked up
the last round, so I'm assuming this would go in through his tree as well.

2020-05-22 06:46:19

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()

On Fri, May 22, 2020 at 3:36 AM Palmer Dabbelt <[email protected]> wrote:
>
> On Mon, 18 May 2020 02:14:39 PDT (-0700), Anup Patel wrote:
> > For multiple PLIC instances, each PLIC can only target a subset of
> > CPUs which is represented by "lmask" in the "struct plic_priv".
> >
> > Currently, the default irq affinity for each PLIC interrupt is all
> > online CPUs which is illegal value for default irq affinity when we
> > have multiple PLIC instances. To fix this, we now set "lmask" as the
> > default irq affinity in for each interrupt in plic_irqdomain_map().
> >
> > Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
> > Cc: [email protected]
> > Signed-off-by: Anup Patel <[email protected]>
> > ---
> > drivers/irqchip/irq-sifive-plic.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> > index 822e074c0600..9f7f8ce88c00 100644
> > --- a/drivers/irqchip/irq-sifive-plic.c
> > +++ b/drivers/irqchip/irq-sifive-plic.c
> > @@ -176,9 +176,12 @@ static struct irq_chip plic_chip = {
> > static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
> > irq_hw_number_t hwirq)
> > {
> > + struct plic_priv *priv = d->host_data;
> > +
> > irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
> > handle_fasteoi_irq, NULL, NULL);
>
> If you're going to re-spin this, d->host_data could be priv here.

The controller's private data is named "host_data" for "struct irq_domain"
in Linux irq subsystem hence the usage.

>
> > irq_set_noprobe(irq);
> > + irq_set_affinity(irq, &priv->lmask);
> > return 0;
> > }
>
> Reviewed-by: Palmer Dabbelt <[email protected]>
> Acked-by: Palmer Dabbelt <[email protected]>

Thanks,
Anup

2020-05-22 06:51:21

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present

On Fri, May 22, 2020 at 3:36 AM Palmer Dabbelt <[email protected]> wrote:
>
> On Mon, 18 May 2020 02:14:40 PDT (-0700), Anup Patel wrote:
> > For multiple PLIC instances, the plic_init() is called once for each
> > PLIC instance. Due to this we have two issues:
> > 1. cpuhp_setup_state() is called multiple times
> > 2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state()
> > is called before boot CPU PLIC handler is available.
> >
> > This patch fixes both above issues.
> >
> > Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
> > Cc: [email protected]
> > Signed-off-by: Anup Patel <[email protected]>
> > ---
> > drivers/irqchip/irq-sifive-plic.c | 14 ++++++++++++--
> > 1 file changed, 12 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> > index 9f7f8ce88c00..6c54abf5cc5e 100644
> > --- a/drivers/irqchip/irq-sifive-plic.c
> > +++ b/drivers/irqchip/irq-sifive-plic.c
> > @@ -76,6 +76,7 @@ struct plic_handler {
> > void __iomem *enable_base;
> > struct plic_priv *priv;
> > };
> > +static bool plic_cpuhp_setup_done;
> > static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
> >
> > static inline void plic_toggle(struct plic_handler *handler,
> > @@ -285,6 +286,7 @@ static int __init plic_init(struct device_node *node,
> > int error = 0, nr_contexts, nr_handlers = 0, i;
> > u32 nr_irqs;
> > struct plic_priv *priv;
> > + struct plic_handler *handler;
> >
> > priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> > if (!priv)
> > @@ -313,7 +315,6 @@ static int __init plic_init(struct device_node *node,
> >
> > for (i = 0; i < nr_contexts; i++) {
> > struct of_phandle_args parent;
> > - struct plic_handler *handler;
> > irq_hw_number_t hwirq;
> > int cpu, hartid;
> >
> > @@ -367,9 +368,18 @@ static int __init plic_init(struct device_node *node,
> > nr_handlers++;
> > }
> >
> > - cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
> > + /*
> > + * We can have multiple PLIC instances so setup cpuhp state only
> > + * when context handler for current/boot CPU is present.
> > + */
> > + handler = this_cpu_ptr(&plic_handlers);
> > + if (handler->present && !plic_cpuhp_setup_done) {
> > + cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
> > "irqchip/sifive/plic:starting",
> > plic_starting_cpu, plic_dying_cpu);
> > + plic_cpuhp_setup_done = true;
>
> So presumably something else is preventing multiple plic_init() calls from
> executing at the same time? Assuming that's the case

AFAIK, interrupt controller and timer probing happens sequentially on
boot CPU before all secondary CPUs are brought-up.

>
> Reviewed-by: Palmer Dabbelt <[email protected]>
> Acked-by: Palmer Dabbelt <[email protected]>
>
> > + }
> > +
> > pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
> > nr_irqs, nr_handlers, nr_contexts);
> > set_handle_irq(plic_handle_irq);

Thanks,
Anup

2020-05-25 10:11:14

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH v2 0/3] More improvements for multiple PLICs

On Mon, 18 May 2020 14:44:38 +0530, Anup Patel wrote:
> This series does more improvements for supporting multiple PLIC
> instances.
>
> PATCH1 and PATCH2 are fixes whereas PATCH3 helps users distinguish
> multiple PLIC instances in boot prints.
>
> These patches are based up Linux-5.7-rc5 and can be found at
> plic_imp_v2 branch at: https://github.com/avpatel/linux.git
>
> [...]

Applied to irq/irqchip-next, thanks!

[1/3] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()
commit: 2458ed31e9b9ab40d78a452ab2650a0857556e85
[2/3] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present
commit: 2234ae846ccb9ebdf4c391824cb79e73674dceda
[3/3] irqchip/sifive-plic: Improve boot prints for multiple PLIC instances
commit: 0e375f51017bcc86c23979118b10445c424ef5ad

Cheers,

M.
--
Without deviation from the norm, progress is not possible.


Subject: [tip: irq/core] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present

The following commit has been merged into the irq/core branch of tip:

Commit-ID: 2234ae846ccb9ebdf4c391824cb79e73674dceda
Gitweb: https://git.kernel.org/tip/2234ae846ccb9ebdf4c391824cb79e73674dceda
Author: Anup Patel <[email protected]>
AuthorDate: Mon, 18 May 2020 14:44:40 +05:30
Committer: Marc Zyngier <[email protected]>
CommitterDate: Mon, 25 May 2020 10:36:53 +01:00

irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present

For multiple PLIC instances, the plic_init() is called once for each
PLIC instance. Due to this we have two issues:
1. cpuhp_setup_state() is called multiple times
2. plic_starting_cpu() can crash for boot CPU if cpuhp_setup_state()
is called before boot CPU PLIC handler is available.

Address both issues by only initializing the HP notifiers when
the boot CPU setup is complete.

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Signed-off-by: Anup Patel <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/r/[email protected]
---
drivers/irqchip/irq-sifive-plic.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 9f7f8ce..6c54abf 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -76,6 +76,7 @@ struct plic_handler {
void __iomem *enable_base;
struct plic_priv *priv;
};
+static bool plic_cpuhp_setup_done;
static DEFINE_PER_CPU(struct plic_handler, plic_handlers);

static inline void plic_toggle(struct plic_handler *handler,
@@ -285,6 +286,7 @@ static int __init plic_init(struct device_node *node,
int error = 0, nr_contexts, nr_handlers = 0, i;
u32 nr_irqs;
struct plic_priv *priv;
+ struct plic_handler *handler;

priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -313,7 +315,6 @@ static int __init plic_init(struct device_node *node,

for (i = 0; i < nr_contexts; i++) {
struct of_phandle_args parent;
- struct plic_handler *handler;
irq_hw_number_t hwirq;
int cpu, hartid;

@@ -367,9 +368,18 @@ done:
nr_handlers++;
}

- cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
+ /*
+ * We can have multiple PLIC instances so setup cpuhp state only
+ * when context handler for current/boot CPU is present.
+ */
+ handler = this_cpu_ptr(&plic_handlers);
+ if (handler->present && !plic_cpuhp_setup_done) {
+ cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
"irqchip/sifive/plic:starting",
plic_starting_cpu, plic_dying_cpu);
+ plic_cpuhp_setup_done = true;
+ }
+
pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
nr_irqs, nr_handlers, nr_contexts);
set_handle_irq(plic_handle_irq);

Subject: [tip: irq/core] irqchip/sifive-plic: Improve boot prints for multiple PLIC instances

The following commit has been merged into the irq/core branch of tip:

Commit-ID: 0e375f51017bcc86c23979118b10445c424ef5ad
Gitweb: https://git.kernel.org/tip/0e375f51017bcc86c23979118b10445c424ef5ad
Author: Anup Patel <[email protected]>
AuthorDate: Mon, 18 May 2020 14:44:41 +05:30
Committer: Marc Zyngier <[email protected]>
CommitterDate: Mon, 25 May 2020 10:38:25 +01:00

irqchip/sifive-plic: Improve boot prints for multiple PLIC instances

We improve PLIC banner to help distinguish multiple PLIC instances
in boot time prints.

Signed-off-by: Anup Patel <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/irqchip/irq-sifive-plic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 6c54abf..d9c53f8 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -380,8 +380,8 @@ done:
plic_cpuhp_setup_done = true;
}

- pr_info("mapped %d interrupts with %d handlers for %d contexts.\n",
- nr_irqs, nr_handlers, nr_contexts);
+ pr_info("%pOFP: mapped %d interrupts with %d handlers for"
+ " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
set_handle_irq(plic_handle_irq);
return 0;

Subject: [tip: irq/core] irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()

The following commit has been merged into the irq/core branch of tip:

Commit-ID: 2458ed31e9b9ab40d78a452ab2650a0857556e85
Gitweb: https://git.kernel.org/tip/2458ed31e9b9ab40d78a452ab2650a0857556e85
Author: Anup Patel <[email protected]>
AuthorDate: Mon, 18 May 2020 14:44:39 +05:30
Committer: Marc Zyngier <[email protected]>
CommitterDate: Mon, 25 May 2020 10:36:09 +01:00

irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()

For multiple PLIC instances, each PLIC can only target a subset of
CPUs which is represented by "lmask" in the "struct plic_priv".

Currently, the default irq affinity for each PLIC interrupt is all
online CPUs which is illegal value for default irq affinity when we
have multiple PLIC instances. To fix this, we now set "lmask" as the
default irq affinity in for each interrupt in plic_irqdomain_map().

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Signed-off-by: Anup Patel <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Reviewed-by: Palmer Dabbelt <[email protected]>
Acked-by: Palmer Dabbelt <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/r/[email protected]
---
drivers/irqchip/irq-sifive-plic.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 822e074..9f7f8ce 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -176,9 +176,12 @@ static struct irq_chip plic_chip = {
static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
+ struct plic_priv *priv = d->host_data;
+
irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
irq_set_noprobe(irq);
+ irq_set_affinity(irq, &priv->lmask);
return 0;
}