// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
 * Copyright (C) 2022 Ventana Micro Systems Inc.
 */

#define pr_fmt(fmt) "riscv-imsic: " fmt
#include <linux/cpu.h>
#include <linux/bitmap.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/smp.h>
#include <asm/hwcap.h>

#include "irq-riscv-imsic-state.h"

#define IMSIC_DISABLE_EIDELIVERY		0
#define IMSIC_ENABLE_EIDELIVERY			1
#define IMSIC_DISABLE_EITHRESHOLD		1
#define IMSIC_ENABLE_EITHRESHOLD		0

static inline void imsic_csr_write(unsigned long reg, unsigned long val)
{
	csr_write(CSR_ISELECT, reg);
	csr_write(CSR_IREG, val);
}

static inline unsigned long imsic_csr_read(unsigned long reg)
{
	csr_write(CSR_ISELECT, reg);
	return csr_read(CSR_IREG);
}

static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
{
	csr_write(CSR_ISELECT, reg);
	return csr_read_clear(CSR_IREG, val);
}

static inline void imsic_csr_set(unsigned long reg, unsigned long val)
{
	csr_write(CSR_ISELECT, reg);
	csr_set(CSR_IREG, val);
}

static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
{
	csr_write(CSR_ISELECT, reg);
	csr_clear(CSR_IREG, val);
}

struct imsic_priv *imsic;

const struct imsic_global_config *imsic_get_global_config(void)
{
	return imsic ? &imsic->global : NULL;
}
EXPORT_SYMBOL_GPL(imsic_get_global_config);

static bool __imsic_eix_read_clear(unsigned long id, bool pend)
{
	unsigned long isel, imask;

	isel = id / BITS_PER_LONG;
	isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
	isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
	imask = BIT(id & (__riscv_xlen - 1));

	return !!(imsic_csr_read_clear(isel, imask) & imask);
}

static inline bool __imsic_id_read_clear_enabled(unsigned long id)
{
	return __imsic_eix_read_clear(id, false);
}

static inline bool __imsic_id_read_clear_pending(unsigned long id)
{
	return __imsic_eix_read_clear(id, true);
}

void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
{
	unsigned long id = base_id, last_id = base_id + num_id;
	unsigned long i, isel, ireg;

	while (id < last_id) {
		isel = id / BITS_PER_LONG;
		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
		isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;

		/*
		 * Prepare the ID mask to be programmed in the
		 * IMSIC EIEx and EIPx registers. These registers
		 * are XLEN-wide and we must not touch IDs which
		 * are < base_id and >= (base_id + num_id).
		 */
		ireg = 0;
		for (i = id & (__riscv_xlen - 1); id < last_id && i < __riscv_xlen; i++) {
			ireg |= BIT(i);
			id++;
		}

		/*
		 * The IMSIC EIEx and EIPx registers are indirectly
		 * accessed via using ISELECT and IREG CSRs so we
		 * need to access these CSRs without getting preempted.
		 *
		 * All existing users of this function call this
		 * function with local IRQs disabled so we don't
		 * need to do anything special here.
		 */
		if (val)
			imsic_csr_set(isel, ireg);
		else
			imsic_csr_clear(isel, ireg);
	}
}

static void __imsic_local_sync(struct imsic_local_priv *lpriv)
{
	struct imsic_local_config *mlocal;
	struct imsic_vector *vec, *mvec;
	int i;

	lockdep_assert_held(&lpriv->lock);

	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
		if (!i || i == IMSIC_IPI_ID)
			goto skip;
		vec = &lpriv->vectors[i];

		if (READ_ONCE(vec->enable))
			__imsic_id_set_enable(i);
		else
			__imsic_id_clear_enable(i);

		/*
		 * If the ID was being moved to a new ID on some other CPU
		 * then we can get a MSI during the movement so check the
		 * ID pending bit and re-trigger the new ID on other CPU
		 * using MMIO write.
		 */
		mvec = READ_ONCE(vec->move);
		WRITE_ONCE(vec->move, NULL);
		if (mvec && mvec != vec) {
			if (__imsic_id_read_clear_pending(i)) {
				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
				writel_relaxed(mvec->local_id, mlocal->msi_va);
			}

			imsic_vector_free(&lpriv->vectors[i]);
		}

skip:
		bitmap_clear(lpriv->dirty_bitmap, i, 1);
	}
}

void imsic_local_sync_all(void)
{
	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
	unsigned long flags;

	raw_spin_lock_irqsave(&lpriv->lock, flags);
	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
	__imsic_local_sync(lpriv);
	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
}

void imsic_local_delivery(bool enable)
{
	if (enable) {
		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
		return;
	}

	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
}

#ifdef CONFIG_SMP
static void imsic_local_timer_callback(struct timer_list *timer)
{
	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
	unsigned long flags;

	raw_spin_lock_irqsave(&lpriv->lock, flags);
	__imsic_local_sync(lpriv);
	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
}

static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
{
	lockdep_assert_held(&lpriv->lock);

	/*
	 * The spinlock acquire/release semantics ensure that changes
	 * to vector enable, vector move and dirty bitmap are visible
	 * to the target CPU.
	 */

	/*
	 * We schedule a timer on the target CPU if the target CPU is not
	 * same as the current CPU. An offline CPU will unconditionally
	 * synchronize IDs through imsic_starting_cpu() when the
	 * CPU is brought up.
	 */
	if (cpu_online(cpu)) {
		if (cpu == smp_processor_id()) {
			__imsic_local_sync(lpriv);
			return;
		}

		if (!timer_pending(&lpriv->timer)) {
			lpriv->timer.expires = jiffies + 1;
			add_timer_on(&lpriv->timer, cpu);
		}
	}
}
#else
static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
{
	lockdep_assert_held(&lpriv->lock);
	__imsic_local_sync(lpriv);
}
#endif

void imsic_vector_mask(struct imsic_vector *vec)
{
	struct imsic_local_priv *lpriv;

	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
		return;

	/*
	 * This function is called through Linux irq subsystem with
	 * irqs disabled so no need to save/restore irq flags.
	 */

	raw_spin_lock(&lpriv->lock);

	WRITE_ONCE(vec->enable, false);
	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
	__imsic_remote_sync(lpriv, vec->cpu);

	raw_spin_unlock(&lpriv->lock);
}

void imsic_vector_unmask(struct imsic_vector *vec)
{
	struct imsic_local_priv *lpriv;

	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
		return;

	/*
	 * This function is called through Linux irq subsystem with
	 * irqs disabled so no need to save/restore irq flags.
	 */

	raw_spin_lock(&lpriv->lock);

	WRITE_ONCE(vec->enable, true);
	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
	__imsic_remote_sync(lpriv, vec->cpu);

	raw_spin_unlock(&lpriv->lock);
}

static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
				     bool new_enable, struct imsic_vector *new_move)
{
	unsigned long flags;
	bool enabled;

	raw_spin_lock_irqsave(&lpriv->lock, flags);

	/* Update enable and move details */
	enabled = READ_ONCE(vec->enable);
	WRITE_ONCE(vec->enable, new_enable);
	WRITE_ONCE(vec->move, new_move);

	/* Mark the vector as dirty and synchronize */
	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
	__imsic_remote_sync(lpriv, vec->cpu);

	raw_spin_unlock_irqrestore(&lpriv->lock, flags);

	return enabled;
}

void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
{
	struct imsic_local_priv *old_lpriv, *new_lpriv;
	bool enabled;

	if (WARN_ON_ONCE(old_vec->cpu == new_vec->cpu))
		return;

	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
	if (WARN_ON_ONCE(&old_lpriv->vectors[old_vec->local_id] != old_vec))
		return;

	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
	if (WARN_ON_ONCE(&new_lpriv->vectors[new_vec->local_id] != new_vec))
		return;

	/*
	 * Move and re-trigger the new vector based on the pending
	 * state of the old vector because we might get a device
	 * interrupt on the old vector while device was being moved
	 * to the new vector.
	 */
	enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
	imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
}

#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
{
	struct imsic_local_priv *lpriv;
	struct imsic_vector *mvec;
	bool is_enabled;

	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
		return;

	is_enabled = imsic_vector_isenabled(vec);
	mvec = imsic_vector_get_move(vec);

	seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
	seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
	seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
		   (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
	seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", is_enabled ? 1 : 0);
	seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", mvec ? 1 : 0);
	if (mvec) {
		seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
		seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
	}
}

void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
{
	irq_matrix_debug_show(m, imsic->matrix, ind);
}
#endif

struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
{
	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);

	if (!lpriv || imsic->global.nr_ids < local_id)
		return NULL;

	return &lpriv->vectors[local_id];
}

struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
{
	struct imsic_vector *vec = NULL;
	struct imsic_local_priv *lpriv;
	unsigned long flags;
	unsigned int cpu;
	int local_id;

	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
	if (local_id < 0)
		return NULL;

	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
	vec = &lpriv->vectors[local_id];
	vec->hwirq = hwirq;
	vec->enable = false;
	vec->move = NULL;

	return vec;
}

void imsic_vector_free(struct imsic_vector *vec)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
	vec->hwirq = UINT_MAX;
	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
}

static void __init imsic_local_cleanup(void)
{
	struct imsic_local_priv *lpriv;
	int cpu;

	for_each_possible_cpu(cpu) {
		lpriv = per_cpu_ptr(imsic->lpriv, cpu);

		bitmap_free(lpriv->dirty_bitmap);
		kfree(lpriv->vectors);
	}

	free_percpu(imsic->lpriv);
}

static int __init imsic_local_init(void)
{
	struct imsic_global_config *global = &imsic->global;
	struct imsic_local_priv *lpriv;
	struct imsic_vector *vec;
	int cpu, i;

	/* Allocate per-CPU private state */
	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
	if (!imsic->lpriv)
		return -ENOMEM;

	/* Setup per-CPU private state */
	for_each_possible_cpu(cpu) {
		lpriv = per_cpu_ptr(imsic->lpriv, cpu);

		raw_spin_lock_init(&lpriv->lock);

		/* Allocate dirty bitmap */
		lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
		if (!lpriv->dirty_bitmap)
			goto fail_local_cleanup;

#ifdef CONFIG_SMP
		/* Setup lazy timer for synchronization */
		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
#endif

		/* Allocate vector array */
		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
					 GFP_KERNEL);
		if (!lpriv->vectors)
			goto fail_local_cleanup;

		/* Setup vector array */
		for (i = 0; i <= global->nr_ids; i++) {
			vec = &lpriv->vectors[i];
			vec->cpu = cpu;
			vec->local_id = i;
			vec->hwirq = UINT_MAX;
		}
	}

	return 0;

fail_local_cleanup:
	imsic_local_cleanup();
	return -ENOMEM;
}

void imsic_state_online(void)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
	irq_matrix_online(imsic->matrix);
	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
}

void imsic_state_offline(void)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
	irq_matrix_offline(imsic->matrix);
	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);

#ifdef CONFIG_SMP
	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);

	raw_spin_lock_irqsave(&lpriv->lock, flags);
	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
#endif
}

static int __init imsic_matrix_init(void)
{
	struct imsic_global_config *global = &imsic->global;

	raw_spin_lock_init(&imsic->matrix_lock);
	imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
					 0, global->nr_ids + 1);
	if (!imsic->matrix)
		return -ENOMEM;

	/* Reserve ID#0 because it is special and never implemented */
	irq_matrix_assign_system(imsic->matrix, 0, false);

	/* Reserve IPI ID because it is special and used internally */
	irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);

	return 0;
}

static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
					  u32 index, unsigned long *hartid)
{
	struct of_phandle_args parent;
	int rc;

	/*
	 * Currently, only OF fwnode is supported so extend this
	 * function for ACPI support.
	 */
	if (!is_of_node(fwnode))
		return -EINVAL;

	rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
	if (rc)
		return rc;

	/*
	 * Skip interrupts other than external interrupts for
	 * current privilege level.
	 */
	if (parent.args[0] != RV_IRQ_EXT)
		return -EINVAL;

	return riscv_of_parent_hartid(parent.np, hartid);
}

static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
					  u32 index, struct resource *res)
{
	/*
	 * Currently, only OF fwnode is supported so extend this
	 * function for ACPI support.
	 */
	if (!is_of_node(fwnode))
		return -EINVAL;

	return of_address_to_resource(to_of_node(fwnode), index, res);
}

static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
				     struct imsic_global_config *global,
				     u32 *nr_parent_irqs,
				     u32 *nr_mmios)
{
	unsigned long hartid;
	struct resource res;
	int rc;
	u32 i;

	/*
	 * Currently, only OF fwnode is supported so extend this
	 * function for ACPI support.
	 */
	if (!is_of_node(fwnode))
		return -EINVAL;

	*nr_parent_irqs = 0;
	*nr_mmios = 0;

	/* Find number of parent interrupts */
	while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
		(*nr_parent_irqs)++;
	if (!*nr_parent_irqs) {
		pr_err("%pfwP: no parent irqs available\n", fwnode);
		return -EINVAL;
	}

	/* Find number of guest index bits in MSI address */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
				  &global->guest_index_bits);
	if (rc)
		global->guest_index_bits = 0;

	/* Find number of HART index bits */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
				  &global->hart_index_bits);
	if (rc) {
		/* Assume default value */
		global->hart_index_bits = __fls(*nr_parent_irqs);
		if (BIT(global->hart_index_bits) < *nr_parent_irqs)
			global->hart_index_bits++;
	}

	/* Find number of group index bits */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
				  &global->group_index_bits);
	if (rc)
		global->group_index_bits = 0;

	/*
	 * Find first bit position of group index.
	 * If not specified assumed the default APLIC-IMSIC configuration.
	 */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
				  &global->group_index_shift);
	if (rc)
		global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;

	/* Find number of interrupt identities */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
				  &global->nr_ids);
	if (rc) {
		pr_err("%pfwP: number of interrupt identities not found\n", fwnode);
		return rc;
	}

	/* Find number of guest interrupt identities */
	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
				  &global->nr_guest_ids);
	if (rc)
		global->nr_guest_ids = global->nr_ids;

	/* Sanity check guest index bits */
	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
	if (i < global->guest_index_bits) {
		pr_err("%pfwP: guest index bits too big\n", fwnode);
		return -EINVAL;
	}

	/* Sanity check HART index bits */
	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
	if (i < global->hart_index_bits) {
		pr_err("%pfwP: HART index bits too big\n", fwnode);
		return -EINVAL;
	}

	/* Sanity check group index bits */
	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
	    global->guest_index_bits - global->hart_index_bits;
	if (i < global->group_index_bits) {
		pr_err("%pfwP: group index bits too big\n", fwnode);
		return -EINVAL;
	}

	/* Sanity check group index shift */
	i = global->group_index_bits + global->group_index_shift - 1;
	if (i >= BITS_PER_LONG) {
		pr_err("%pfwP: group index shift too big\n", fwnode);
		return -EINVAL;
	}

	/* Sanity check number of interrupt identities */
	if (global->nr_ids < IMSIC_MIN_ID ||
	    global->nr_ids >= IMSIC_MAX_ID ||
	    (global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
		pr_err("%pfwP: invalid number of interrupt identities\n", fwnode);
		return -EINVAL;
	}

	/* Sanity check number of guest interrupt identities */
	if (global->nr_guest_ids < IMSIC_MIN_ID ||
	    global->nr_guest_ids >= IMSIC_MAX_ID ||
	    (global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
		pr_err("%pfwP: invalid number of guest interrupt identities\n", fwnode);
		return -EINVAL;
	}

	/* Compute base address */
	rc = imsic_get_mmio_resource(fwnode, 0, &res);
	if (rc) {
		pr_err("%pfwP: first MMIO resource not found\n", fwnode);
		return -EINVAL;
	}
	global->base_addr = res.start;
	global->base_addr &= ~(BIT(global->guest_index_bits +
				   global->hart_index_bits +
				   IMSIC_MMIO_PAGE_SHIFT) - 1);
	global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
			       global->group_index_shift);

	/* Find number of MMIO register sets */
	while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
		(*nr_mmios)++;

	return 0;
}

int __init imsic_setup_state(struct fwnode_handle *fwnode)
{
	u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
	struct imsic_global_config *global;
	struct imsic_local_config *local;
	void __iomem **mmios_va = NULL;
	struct resource *mmios = NULL;
	unsigned long reloff, hartid;
	phys_addr_t base_addr;
	int rc, cpu;

	/*
	 * Only one IMSIC instance allowed in a platform for clean
	 * implementation of SMP IRQ affinity and per-CPU IPIs.
	 *
	 * This means on a multi-socket (or multi-die) platform we
	 * will have multiple MMIO regions for one IMSIC instance.
	 */
	if (imsic) {
		pr_err("%pfwP: already initialized hence ignoring\n", fwnode);
		return -EALREADY;
	}

	if (!riscv_isa_extension_available(NULL, SxAIA)) {
		pr_err("%pfwP: AIA support not available\n", fwnode);
		return -ENODEV;
	}

	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
	if (!imsic)
		return -ENOMEM;
	imsic->fwnode = fwnode;
	global = &imsic->global;

	global->local = alloc_percpu(typeof(*global->local));
	if (!global->local) {
		rc = -ENOMEM;
		goto out_free_priv;
	}

	/* Parse IMSIC fwnode */
	rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
	if (rc)
		goto out_free_local;

	/* Allocate MMIO resource array */
	mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
	if (!mmios) {
		rc = -ENOMEM;
		goto out_free_local;
	}

	/* Allocate MMIO virtual address array */
	mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
	if (!mmios_va) {
		rc = -ENOMEM;
		goto out_iounmap;
	}

	/* Parse and map MMIO register sets */
	for (i = 0; i < nr_mmios; i++) {
		rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
		if (rc) {
			pr_err("%pfwP: unable to parse MMIO regset %d\n", fwnode, i);
			goto out_iounmap;
		}

		base_addr = mmios[i].start;
		base_addr &= ~(BIT(global->guest_index_bits +
				   global->hart_index_bits +
				   IMSIC_MMIO_PAGE_SHIFT) - 1);
		base_addr &= ~((BIT(global->group_index_bits) - 1) <<
			       global->group_index_shift);
		if (base_addr != global->base_addr) {
			rc = -EINVAL;
			pr_err("%pfwP: address mismatch for regset %d\n", fwnode, i);
			goto out_iounmap;
		}

		mmios_va[i] = ioremap(mmios[i].start, resource_size(&mmios[i]));
		if (!mmios_va[i]) {
			rc = -EIO;
			pr_err("%pfwP: unable to map MMIO regset %d\n", fwnode, i);
			goto out_iounmap;
		}
	}

	/* Initialize local (or per-CPU )state */
	rc = imsic_local_init();
	if (rc) {
		pr_err("%pfwP: failed to initialize local state\n",
		       fwnode);
		goto out_iounmap;
	}

	/* Configure handlers for target CPUs */
	for (i = 0; i < nr_parent_irqs; i++) {
		rc = imsic_get_parent_hartid(fwnode, i, &hartid);
		if (rc) {
			pr_warn("%pfwP: hart ID for parent irq%d not found\n", fwnode, i);
			continue;
		}

		cpu = riscv_hartid_to_cpuid(hartid);
		if (cpu < 0) {
			pr_warn("%pfwP: invalid cpuid for parent irq%d\n", fwnode, i);
			continue;
		}

		/* Find MMIO location of MSI page */
		index = nr_mmios;
		reloff = i * BIT(global->guest_index_bits) *
			 IMSIC_MMIO_PAGE_SZ;
		for (j = 0; nr_mmios; j++) {
			if (reloff < resource_size(&mmios[j])) {
				index = j;
				break;
			}

			/*
			 * MMIO region size may not be aligned to
			 * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ
			 * if holes are present.
			 */
			reloff -= ALIGN(resource_size(&mmios[j]),
			BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ);
		}
		if (index >= nr_mmios) {
			pr_warn("%pfwP: MMIO not found for parent irq%d\n", fwnode, i);
			continue;
		}

		local = per_cpu_ptr(global->local, cpu);
		local->msi_pa = mmios[index].start + reloff;
		local->msi_va = mmios_va[index] + reloff;

		nr_handlers++;
	}

	/* If no CPU handlers found then can't take interrupts */
	if (!nr_handlers) {
		pr_err("%pfwP: No CPU handlers found\n", fwnode);
		rc = -ENODEV;
		goto out_local_cleanup;
	}

	/* Initialize matrix allocator */
	rc = imsic_matrix_init();
	if (rc) {
		pr_err("%pfwP: failed to create matrix allocator\n", fwnode);
		goto out_local_cleanup;
	}

	/* We don't need MMIO arrays anymore so let's free-up */
	kfree(mmios_va);
	kfree(mmios);

	return 0;

out_local_cleanup:
	imsic_local_cleanup();
out_iounmap:
	for (i = 0; i < nr_mmios; i++) {
		if (mmios_va[i])
			iounmap(mmios_va[i]);
	}
	kfree(mmios_va);
	kfree(mmios);
out_free_local:
	free_percpu(imsic->global.local);
out_free_priv:
	kfree(imsic);
	imsic = NULL;
	return rc;
}
