{}
 };
 
+static int plic_parse_context_parent(struct platform_device *pdev, u32 context,
+                                    u32 *parent_hwirq, int *parent_cpu)
+{
+       struct device *dev = &pdev->dev;
+       struct of_phandle_args parent;
+       unsigned long hartid;
+       int rc;
+
+       /*
+        * Currently, only OF fwnode is supported so extend this
+        * function for ACPI support.
+        */
+       if (!is_of_node(dev->fwnode))
+               return -EINVAL;
+
+       rc = of_irq_parse_one(to_of_node(dev->fwnode), context, &parent);
+       if (rc)
+               return rc;
+
+       rc = riscv_of_parent_hartid(parent.np, &hartid);
+       if (rc)
+               return rc;
+
+       *parent_hwirq = parent.args[0];
+       *parent_cpu = riscv_hartid_to_cpuid(hartid);
+       return 0;
+}
+
 static int plic_probe(struct platform_device *pdev)
 {
-       int error = 0, nr_contexts, nr_handlers = 0, i;
+       int error = 0, nr_contexts, nr_handlers = 0, cpu, i;
        struct device *dev = &pdev->dev;
        unsigned long plic_quirks = 0;
        struct plic_handler *handler;
+       u32 nr_irqs, parent_hwirq;
        struct irq_domain *domain;
        struct plic_priv *priv;
+       irq_hw_number_t hwirq;
        bool cpuhp_setup;
-       unsigned int cpu;
-       u32 nr_irqs;
 
        if (is_of_node(dev->fwnode)) {
                const struct of_device_id *id;
                return -EINVAL;
 
        for (i = 0; i < nr_contexts; i++) {
-               struct of_phandle_args parent;
-               irq_hw_number_t hwirq;
-               int cpu;
-               unsigned long hartid;
-
-               if (of_irq_parse_one(to_of_node(dev->fwnode), i, &parent)) {
-                       dev_err(dev, "failed to parse parent for context %d.\n", i);
+               error = plic_parse_context_parent(pdev, i, &parent_hwirq, &cpu);
+               if (error) {
+                       dev_warn(dev, "hwirq for context%d not found\n", i);
                        continue;
                }
 
                 * Skip contexts other than external interrupts for our
                 * privilege level.
                 */
-               if (parent.args[0] != RV_IRQ_EXT) {
+               if (parent_hwirq != RV_IRQ_EXT) {
                        /* Disable S-mode enable bits if running in M-mode. */
                        if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
                                void __iomem *enable_base = priv->regs +
                        continue;
                }
 
-               error = riscv_of_parent_hartid(parent.np, &hartid);
-               if (error < 0) {
-                       dev_warn(dev, "failed to parse hart ID for context %d.\n", i);
-                       continue;
-               }
-
-               cpu = riscv_hartid_to_cpuid(hartid);
                if (cpu < 0) {
                        dev_warn(dev, "Invalid cpuid for context %d\n", i);
                        continue;
                handler->enable_save = devm_kcalloc(dev, DIV_ROUND_UP(nr_irqs, 32),
                                                    sizeof(*handler->enable_save), GFP_KERNEL);
                if (!handler->enable_save)
-                       return -ENOMEM;
+                       goto fail_cleanup_contexts;
 done:
                for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
                        plic_toggle(handler, hwirq, 0);
        priv->irqdomain = irq_domain_add_linear(to_of_node(dev->fwnode), nr_irqs + 1,
                                                &plic_irqdomain_ops, priv);
        if (WARN_ON(!priv->irqdomain))
-               return -ENOMEM;
+               goto fail_cleanup_contexts;
 
        /*
         * We can have multiple PLIC instances so setup cpuhp state
        dev_info(dev, "mapped %d interrupts with %d handlers for %d contexts.\n",
                 nr_irqs, nr_handlers, nr_contexts);
        return 0;
+
+fail_cleanup_contexts:
+       for (i = 0; i < nr_contexts; i++) {
+               if (plic_parse_context_parent(pdev, i, &parent_hwirq, &cpu))
+                       continue;
+               if (parent_hwirq != RV_IRQ_EXT || cpu < 0)
+                       continue;
+
+               handler = per_cpu_ptr(&plic_handlers, cpu);
+               handler->present = false;
+               handler->hart_base = NULL;
+               handler->enable_base = NULL;
+               handler->enable_save = NULL;
+               handler->priv = NULL;
+       }
+       return -ENOMEM;
 }
 
 static struct platform_driver plic_driver = {