lkml.org 
[lkml]   [2020]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/3] irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present
    Date
    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: stable@vger.kernel.org
    Signed-off-by: Anup Patel <anup.patel@wdc.com>
    ---
    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
    \
     
     \ /
      Last update: 2020-05-18 11:15    [W:2.509 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site