// SPDX-License-Identifier: GPL-2.0
/*
 * Texas Instruments' K3 Interrupt Aggregator irqchip driver
 *
 * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/
 *	Lokesh Vutla <lokeshvutla@ti.com>
 */

#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/msi.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/soc/ti/ti_sci_inta_msi.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include <asm-generic/msi.h>

#define TI_SCI_DEV_ID_MASK	0xffff
#define TI_SCI_DEV_ID_SHIFT	16
#define TI_SCI_IRQ_ID_MASK	0xffff
#define TI_SCI_IRQ_ID_SHIFT	0
#define HWIRQ_TO_DEVID(hwirq)	(((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \
				 (TI_SCI_DEV_ID_MASK))
#define HWIRQ_TO_IRQID(hwirq)	((hwirq) & (TI_SCI_IRQ_ID_MASK))
#define TO_HWIRQ(dev, index)	((((dev) & TI_SCI_DEV_ID_MASK) << \
				 TI_SCI_DEV_ID_SHIFT) | \
				((index) & TI_SCI_IRQ_ID_MASK))

#define MAX_EVENTS_PER_VINT	64
#define VINT_ENABLE_SET_OFFSET	0x0
#define VINT_ENABLE_CLR_OFFSET	0x8
#define VINT_STATUS_OFFSET	0x18
#define VINT_STATUS_MASKED_OFFSET	0x20

/**
 * struct ti_sci_inta_event_desc - Description of an event coming to
 *				   Interrupt Aggregator. This serves
 *				   as a mapping table for global event,
 *				   hwirq and vint bit.
 * @global_event:	Global event number corresponding to this event
 * @hwirq:		Hwirq of the incoming interrupt
 * @vint_bit:		Corresponding vint bit to which this event is attached.
 */
struct ti_sci_inta_event_desc {
	u16 global_event;
	u32 hwirq;
	u8 vint_bit;
};

/**
 * struct ti_sci_inta_vint_desc - Description of a virtual interrupt coming out
 *				  of Interrupt Aggregator.
 * @domain:		Pointer to IRQ domain to which this vint belongs.
 * @list:		List entry for the vint list
 * @event_map:		Bitmap to manage the allocation of events to vint.
 * @events:		Array of event descriptors assigned to this vint.
 * @parent_virq:	Linux IRQ number that gets attached to parent
 * @vint_id:		TISCI vint ID
 */
struct ti_sci_inta_vint_desc {
	struct irq_domain *domain;
	struct list_head list;
	DECLARE_BITMAP(event_map, MAX_EVENTS_PER_VINT);
	struct ti_sci_inta_event_desc events[MAX_EVENTS_PER_VINT];
	unsigned int parent_virq;
	u16 vint_id;
};

/**
 * struct ti_sci_inta_irq_domain - Structure representing a TISCI based
 *				   Interrupt Aggregator IRQ domain.
 * @sci:		Pointer to TISCI handle
 * @vint:		TISCI resource pointer representing IA interrupts.
 * @global_event:	TISCI resource pointer representing global events.
 * @vint_list:		List of the vints active in the system
 * @vint_mutex:		Mutex to protect vint_list
 * @base:		Base address of the memory mapped IO registers
 * @pdev:		Pointer to platform device.
 * @ti_sci_id:		TI-SCI device identifier
 * @unmapped_cnt:	Number of @unmapped_dev_ids entries
 * @unmapped_dev_ids:	Pointer to an array of TI-SCI device identifiers of
 *			unmapped event sources.
 *			Unmapped Events are not part of the Global Event Map and
 *			they are converted to Global event within INTA to be
 *			received by the same INTA to generate an interrupt.
 *			In case an interrupt request comes for a device which is
 *			generating Unmapped Event, we must use the INTA's TI-SCI
 *			device identifier in place of the source device
 *			identifier to let sysfw know where it has to program the
 *			Global Event number.
 */
struct ti_sci_inta_irq_domain {
	const struct ti_sci_handle *sci;
	struct ti_sci_resource *vint;
	struct ti_sci_resource *global_event;
	struct list_head vint_list;
	/* Mutex to protect vint list */
	struct mutex vint_mutex;
	void __iomem *base;
	struct platform_device *pdev;
	u32 ti_sci_id;

	int unmapped_cnt;
	u16 *unmapped_dev_ids;
};

#define to_vint_desc(e, i) container_of(e, struct ti_sci_inta_vint_desc, \
					events[i])

static u16 ti_sci_inta_get_dev_id(struct ti_sci_inta_irq_domain *inta, u32 hwirq)
{
	u16 dev_id = HWIRQ_TO_DEVID(hwirq);
	int i;

	if (inta->unmapped_cnt == 0)
		return dev_id;

	/*
	 * For devices sending Unmapped Events we must use the INTA's TI-SCI
	 * device identifier number to be able to convert it to a Global Event
	 * and map it to an interrupt.
	 */
	for (i = 0; i < inta->unmapped_cnt; i++) {
		if (dev_id == inta->unmapped_dev_ids[i]) {
			dev_id = inta->ti_sci_id;
			break;
		}
	}

	return dev_id;
}

/**
 * ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
 * @desc:	Pointer to irq_desc corresponding to the irq
 */
static void ti_sci_inta_irq_handler(struct irq_desc *desc)
{
	struct ti_sci_inta_vint_desc *vint_desc;
	struct ti_sci_inta_irq_domain *inta;
	struct irq_domain *domain;
	unsigned int bit;
	unsigned long val;

	vint_desc = irq_desc_get_handler_data(desc);
	domain = vint_desc->domain;
	inta = domain->host_data;

	chained_irq_enter(irq_desc_get_chip(desc), desc);

	val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 +
			    VINT_STATUS_MASKED_OFFSET);

	for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT)
		generic_handle_domain_irq(domain, vint_desc->events[bit].hwirq);

	chained_irq_exit(irq_desc_get_chip(desc), desc);
}

/**
 * ti_sci_inta_xlate_irq() - Translate hwirq to parent's hwirq.
 * @inta:	IRQ domain corresponding to Interrupt Aggregator
 * @irq:	Hardware irq corresponding to the above irq domain
 *
 * Return parent irq number if translation is available else -ENOENT.
 */
static int ti_sci_inta_xlate_irq(struct ti_sci_inta_irq_domain *inta,
				 u16 vint_id)
{
	struct device_node *np = dev_of_node(&inta->pdev->dev);
	u32 base, parent_base, size;
	const __be32 *range;
	int len;

	range = of_get_property(np, "ti,interrupt-ranges", &len);
	if (!range)
		return vint_id;

	for (len /= sizeof(*range); len >= 3; len -= 3) {
		base = be32_to_cpu(*range++);
		parent_base = be32_to_cpu(*range++);
		size = be32_to_cpu(*range++);

		if (base <= vint_id && vint_id < base + size)
			return vint_id - base + parent_base;
	}

	return -ENOENT;
}

/**
 * ti_sci_inta_alloc_parent_irq() - Allocate parent irq to Interrupt aggregator
 * @domain:	IRQ domain corresponding to Interrupt Aggregator
 *
 * Return 0 if all went well else corresponding error value.
 */
static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_domain *domain)
{
	struct ti_sci_inta_irq_domain *inta = domain->host_data;
	struct ti_sci_inta_vint_desc *vint_desc;
	struct irq_fwspec parent_fwspec;
	struct device_node *parent_node;
	unsigned int parent_virq;
	int p_hwirq, ret;
	u16 vint_id;

	vint_id = ti_sci_get_free_resource(inta->vint);
	if (vint_id == TI_SCI_RESOURCE_NULL)
		return ERR_PTR(-EINVAL);

	p_hwirq = ti_sci_inta_xlate_irq(inta, vint_id);
	if (p_hwirq < 0) {
		ret = p_hwirq;
		goto free_vint;
	}

	vint_desc = kzalloc(sizeof(*vint_desc), GFP_KERNEL);
	if (!vint_desc) {
		ret = -ENOMEM;
		goto free_vint;
	}

	vint_desc->domain = domain;
	vint_desc->vint_id = vint_id;
	INIT_LIST_HEAD(&vint_desc->list);

	parent_node = of_irq_find_parent(dev_of_node(&inta->pdev->dev));
	parent_fwspec.fwnode = of_node_to_fwnode(parent_node);

	if (of_device_is_compatible(parent_node, "arm,gic-v3")) {
		/* Parent is GIC */
		parent_fwspec.param_count = 3;
		parent_fwspec.param[0] = 0;
		parent_fwspec.param[1] = p_hwirq - 32;
		parent_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;
	} else {
		/* Parent is Interrupt Router */
		parent_fwspec.param_count = 1;
		parent_fwspec.param[0] = p_hwirq;
	}

	parent_virq = irq_create_fwspec_mapping(&parent_fwspec);
	if (parent_virq == 0) {
		dev_err(&inta->pdev->dev, "Parent IRQ allocation failed\n");
		ret = -EINVAL;
		goto free_vint_desc;

	}
	vint_desc->parent_virq = parent_virq;

	list_add_tail(&vint_desc->list, &inta->vint_list);
	irq_set_chained_handler_and_data(vint_desc->parent_virq,
					 ti_sci_inta_irq_handler, vint_desc);

	return vint_desc;
free_vint_desc:
	kfree(vint_desc);
free_vint:
	ti_sci_release_resource(inta->vint, vint_id);
	return ERR_PTR(ret);
}

/**
 * ti_sci_inta_alloc_event() - Attach an event to a IA vint.
 * @vint_desc:	Pointer to vint_desc to which the event gets attached
 * @free_bit:	Bit inside vint to which event gets attached
 * @hwirq:	hwirq of the input event
 *
 * Return event_desc pointer if all went ok else appropriate error value.
 */
static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_event(struct ti_sci_inta_vint_desc *vint_desc,
							      u16 free_bit,
							      u32 hwirq)
{
	struct ti_sci_inta_irq_domain *inta = vint_desc->domain->host_data;
	struct ti_sci_inta_event_desc *event_desc;
	u16 dev_id, dev_index;
	int err;

	dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
	dev_index = HWIRQ_TO_IRQID(hwirq);

	event_desc = &vint_desc->events[free_bit];
	event_desc->hwirq = hwirq;
	event_desc->vint_bit = free_bit;
	event_desc->global_event = ti_sci_get_free_resource(inta->global_event);
	if (event_desc->global_event == TI_SCI_RESOURCE_NULL)
		return ERR_PTR(-EINVAL);

	err = inta->sci->ops.rm_irq_ops.set_event_map(inta->sci,
						      dev_id, dev_index,
						      inta->ti_sci_id,
						      vint_desc->vint_id,
						      event_desc->global_event,
						      free_bit);
	if (err)
		goto free_global_event;

	return event_desc;
free_global_event:
	ti_sci_release_resource(inta->global_event, event_desc->global_event);
	return ERR_PTR(err);
}

/**
 * ti_sci_inta_alloc_irq() -  Allocate an irq within INTA domain
 * @domain:	irq_domain pointer corresponding to INTA
 * @hwirq:	hwirq of the input event
 *
 * Note: Allocation happens in the following manner:
 *	- Find a free bit available in any of the vints available in the list.
 *	- If not found, allocate a vint from the vint pool
 *	- Attach the free bit to input hwirq.
 * Return event_desc if all went ok else appropriate error value.
 */
static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_irq(struct irq_domain *domain,
							    u32 hwirq)
{
	struct ti_sci_inta_irq_domain *inta = domain->host_data;
	struct ti_sci_inta_vint_desc *vint_desc = NULL;
	struct ti_sci_inta_event_desc *event_desc;
	u16 free_bit;

	mutex_lock(&inta->vint_mutex);
	list_for_each_entry(vint_desc, &inta->vint_list, list) {
		free_bit = find_first_zero_bit(vint_desc->event_map,
					       MAX_EVENTS_PER_VINT);
		if (free_bit != MAX_EVENTS_PER_VINT) {
			set_bit(free_bit, vint_desc->event_map);
			goto alloc_event;
		}
	}

	/* No free bits available. Allocate a new vint */
	vint_desc = ti_sci_inta_alloc_parent_irq(domain);
	if (IS_ERR(vint_desc)) {
		event_desc = ERR_CAST(vint_desc);
		goto unlock;
	}

	free_bit = find_first_zero_bit(vint_desc->event_map,
				       MAX_EVENTS_PER_VINT);
	set_bit(free_bit, vint_desc->event_map);

alloc_event:
	event_desc = ti_sci_inta_alloc_event(vint_desc, free_bit, hwirq);
	if (IS_ERR(event_desc))
		clear_bit(free_bit, vint_desc->event_map);

unlock:
	mutex_unlock(&inta->vint_mutex);
	return event_desc;
}

/**
 * ti_sci_inta_free_parent_irq() - Free a parent irq to INTA
 * @inta:	Pointer to inta domain.
 * @vint_desc:	Pointer to vint_desc that needs to be freed.
 */
static void ti_sci_inta_free_parent_irq(struct ti_sci_inta_irq_domain *inta,
					struct ti_sci_inta_vint_desc *vint_desc)
{
	if (find_first_bit(vint_desc->event_map, MAX_EVENTS_PER_VINT) == MAX_EVENTS_PER_VINT) {
		list_del(&vint_desc->list);
		ti_sci_release_resource(inta->vint, vint_desc->vint_id);
		irq_dispose_mapping(vint_desc->parent_virq);
		kfree(vint_desc);
	}
}

/**
 * ti_sci_inta_free_irq() - Free an IRQ within INTA domain
 * @event_desc:	Pointer to event_desc that needs to be freed.
 * @hwirq:	Hwirq number within INTA domain that needs to be freed
 */
static void ti_sci_inta_free_irq(struct ti_sci_inta_event_desc *event_desc,
				 u32 hwirq)
{
	struct ti_sci_inta_vint_desc *vint_desc;
	struct ti_sci_inta_irq_domain *inta;
	u16 dev_id;

	vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
	inta = vint_desc->domain->host_data;
	dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
	/* free event irq */
	mutex_lock(&inta->vint_mutex);
	inta->sci->ops.rm_irq_ops.free_event_map(inta->sci,
						 dev_id, HWIRQ_TO_IRQID(hwirq),
						 inta->ti_sci_id,
						 vint_desc->vint_id,
						 event_desc->global_event,
						 event_desc->vint_bit);

	clear_bit(event_desc->vint_bit, vint_desc->event_map);
	ti_sci_release_resource(inta->global_event, event_desc->global_event);
	event_desc->global_event = TI_SCI_RESOURCE_NULL;
	event_desc->hwirq = 0;

	ti_sci_inta_free_parent_irq(inta, vint_desc);
	mutex_unlock(&inta->vint_mutex);
}

/**
 * ti_sci_inta_request_resources() - Allocate resources for input irq
 * @data: Pointer to corresponding irq_data
 *
 * Note: This is the core api where the actual allocation happens for input
 *	 hwirq. This allocation involves creating a parent irq for vint.
 *	 If this is done in irq_domain_ops.alloc() then a deadlock is reached
 *	 for allocation. So this allocation is being done in request_resources()
 *
 * Return: 0 if all went well else corresponding error.
 */
static int ti_sci_inta_request_resources(struct irq_data *data)
{
	struct ti_sci_inta_event_desc *event_desc;

	event_desc = ti_sci_inta_alloc_irq(data->domain, data->hwirq);
	if (IS_ERR(event_desc))
		return PTR_ERR(event_desc);

	data->chip_data = event_desc;

	return 0;
}

/**
 * ti_sci_inta_release_resources - Release resources for input irq
 * @data: Pointer to corresponding irq_data
 *
 * Note: Corresponding to request_resources(), all the unmapping and deletion
 *	 of parent vint irqs happens in this api.
 */
static void ti_sci_inta_release_resources(struct irq_data *data)
{
	struct ti_sci_inta_event_desc *event_desc;

	event_desc = irq_data_get_irq_chip_data(data);
	ti_sci_inta_free_irq(event_desc, data->hwirq);
}

/**
 * ti_sci_inta_manage_event() - Control the event based on the offset
 * @data:	Pointer to corresponding irq_data
 * @offset:	register offset using which event is controlled.
 */
static void ti_sci_inta_manage_event(struct irq_data *data, u32 offset)
{
	struct ti_sci_inta_event_desc *event_desc;
	struct ti_sci_inta_vint_desc *vint_desc;
	struct ti_sci_inta_irq_domain *inta;

	event_desc = irq_data_get_irq_chip_data(data);
	vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
	inta = data->domain->host_data;

	writeq_relaxed(BIT(event_desc->vint_bit),
		       inta->base + vint_desc->vint_id * 0x1000 + offset);
}

/**
 * ti_sci_inta_mask_irq() - Mask an event
 * @data:	Pointer to corresponding irq_data
 */
static void ti_sci_inta_mask_irq(struct irq_data *data)
{
	ti_sci_inta_manage_event(data, VINT_ENABLE_CLR_OFFSET);
}

/**
 * ti_sci_inta_unmask_irq() - Unmask an event
 * @data:	Pointer to corresponding irq_data
 */
static void ti_sci_inta_unmask_irq(struct irq_data *data)
{
	ti_sci_inta_manage_event(data, VINT_ENABLE_SET_OFFSET);
}

/**
 * ti_sci_inta_ack_irq() - Ack an event
 * @data:	Pointer to corresponding irq_data
 */
static void ti_sci_inta_ack_irq(struct irq_data *data)
{
	/*
	 * Do not clear the event if hardware is capable of sending
	 * a down event.
	 */
	if (irqd_get_trigger_type(data) != IRQF_TRIGGER_HIGH)
		ti_sci_inta_manage_event(data, VINT_STATUS_OFFSET);
}

static int ti_sci_inta_set_affinity(struct irq_data *d,
				    const struct cpumask *mask_val, bool force)
{
	return -EINVAL;
}

/**
 * ti_sci_inta_set_type() - Update the trigger type of the irq.
 * @data:	Pointer to corresponding irq_data
 * @type:	Trigger type as specified by user
 *
 * Note: This updates the handle_irq callback for level msi.
 *
 * Return 0 if all went well else appropriate error.
 */
static int ti_sci_inta_set_type(struct irq_data *data, unsigned int type)
{
	/*
	 * .alloc default sets handle_edge_irq. But if the user specifies
	 * that IRQ is level MSI, then update the handle to handle_level_irq
	 */
	switch (type & IRQ_TYPE_SENSE_MASK) {
	case IRQF_TRIGGER_HIGH:
		irq_set_handler_locked(data, handle_level_irq);
		return 0;
	case IRQF_TRIGGER_RISING:
		return 0;
	default:
		return -EINVAL;
	}
}

static struct irq_chip ti_sci_inta_irq_chip = {
	.name			= "INTA",
	.irq_ack		= ti_sci_inta_ack_irq,
	.irq_mask		= ti_sci_inta_mask_irq,
	.irq_set_type		= ti_sci_inta_set_type,
	.irq_unmask		= ti_sci_inta_unmask_irq,
	.irq_set_affinity	= ti_sci_inta_set_affinity,
	.irq_request_resources	= ti_sci_inta_request_resources,
	.irq_release_resources	= ti_sci_inta_release_resources,
};

/**
 * ti_sci_inta_irq_domain_free() - Free an IRQ from the IRQ domain
 * @domain:	Domain to which the irqs belong
 * @virq:	base linux virtual IRQ to be freed.
 * @nr_irqs:	Number of continuous irqs to be freed
 */
static void ti_sci_inta_irq_domain_free(struct irq_domain *domain,
					unsigned int virq, unsigned int nr_irqs)
{
	struct irq_data *data = irq_domain_get_irq_data(domain, virq);

	irq_domain_reset_irq_data(data);
}

/**
 * ti_sci_inta_irq_domain_alloc() - Allocate Interrupt aggregator IRQs
 * @domain:	Point to the interrupt aggregator IRQ domain
 * @virq:	Corresponding Linux virtual IRQ number
 * @nr_irqs:	Continuous irqs to be allocated
 * @data:	Pointer to firmware specifier
 *
 * No actual allocation happens here.
 *
 * Return 0 if all went well else appropriate error value.
 */
static int ti_sci_inta_irq_domain_alloc(struct irq_domain *domain,
					unsigned int virq, unsigned int nr_irqs,
					void *data)
{
	msi_alloc_info_t *arg = data;

	irq_domain_set_info(domain, virq, arg->hwirq, &ti_sci_inta_irq_chip,
			    NULL, handle_edge_irq, NULL, NULL);

	return 0;
}

static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = {
	.free		= ti_sci_inta_irq_domain_free,
	.alloc		= ti_sci_inta_irq_domain_alloc,
};

static struct irq_chip ti_sci_inta_msi_irq_chip = {
	.name			= "MSI-INTA",
	.flags			= IRQCHIP_SUPPORTS_LEVEL_MSI,
};

static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg,
				     struct msi_desc *desc)
{
	struct platform_device *pdev = to_platform_device(desc->dev);

	arg->desc = desc;
	arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
}

static struct msi_domain_ops ti_sci_inta_msi_ops = {
	.set_desc	= ti_sci_inta_msi_set_desc,
};

static struct msi_domain_info ti_sci_inta_msi_domain_info = {
	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
		   MSI_FLAG_LEVEL_CAPABLE),
	.ops	= &ti_sci_inta_msi_ops,
	.chip	= &ti_sci_inta_msi_irq_chip,
};

static int ti_sci_inta_get_unmapped_sources(struct ti_sci_inta_irq_domain *inta)
{
	struct device *dev = &inta->pdev->dev;
	struct device_node *node = dev_of_node(dev);
	struct of_phandle_iterator it;
	int count, err, ret, i;

	count = of_count_phandle_with_args(node, "ti,unmapped-event-sources", NULL);
	if (count <= 0)
		return 0;

	inta->unmapped_dev_ids = devm_kcalloc(dev, count,
					      sizeof(*inta->unmapped_dev_ids),
					      GFP_KERNEL);
	if (!inta->unmapped_dev_ids)
		return -ENOMEM;

	i = 0;
	of_for_each_phandle(&it, err, node, "ti,unmapped-event-sources", NULL, 0) {
		u32 dev_id;

		ret = of_property_read_u32(it.node, "ti,sci-dev-id", &dev_id);
		if (ret) {
			dev_err(dev, "ti,sci-dev-id read failure for %pOFf\n", it.node);
			of_node_put(it.node);
			return ret;
		}
		inta->unmapped_dev_ids[i++] = dev_id;
	}

	inta->unmapped_cnt = count;

	return 0;
}

static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
{
	struct irq_domain *parent_domain, *domain, *msi_domain;
	struct device_node *parent_node, *node;
	struct ti_sci_inta_irq_domain *inta;
	struct device *dev = &pdev->dev;
	int ret;

	node = dev_of_node(dev);
	parent_node = of_irq_find_parent(node);
	if (!parent_node) {
		dev_err(dev, "Failed to get IRQ parent node\n");
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent_node);
	if (!parent_domain)
		return -EPROBE_DEFER;

	inta = devm_kzalloc(dev, sizeof(*inta), GFP_KERNEL);
	if (!inta)
		return -ENOMEM;

	inta->pdev = pdev;
	inta->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
	if (IS_ERR(inta->sci))
		return dev_err_probe(dev, PTR_ERR(inta->sci),
				     "ti,sci read fail\n");

	ret = of_property_read_u32(dev->of_node, "ti,sci-dev-id", &inta->ti_sci_id);
	if (ret) {
		dev_err(dev, "missing 'ti,sci-dev-id' property\n");
		return -EINVAL;
	}

	inta->vint = devm_ti_sci_get_resource(inta->sci, dev, inta->ti_sci_id,
					      TI_SCI_RESASG_SUBTYPE_IA_VINT);
	if (IS_ERR(inta->vint)) {
		dev_err(dev, "VINT resource allocation failed\n");
		return PTR_ERR(inta->vint);
	}

	inta->global_event = devm_ti_sci_get_resource(inta->sci, dev, inta->ti_sci_id,
						      TI_SCI_RESASG_SUBTYPE_GLOBAL_EVENT_SEVT);
	if (IS_ERR(inta->global_event)) {
		dev_err(dev, "Global event resource allocation failed\n");
		return PTR_ERR(inta->global_event);
	}

	inta->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(inta->base))
		return PTR_ERR(inta->base);

	ret = ti_sci_inta_get_unmapped_sources(inta);
	if (ret)
		return ret;

	domain = irq_domain_add_linear(dev_of_node(dev),
				       ti_sci_get_num_resources(inta->vint),
				       &ti_sci_inta_irq_domain_ops, inta);
	if (!domain) {
		dev_err(dev, "Failed to allocate IRQ domain\n");
		return -ENOMEM;
	}

	msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node),
						&ti_sci_inta_msi_domain_info,
						domain);
	if (!msi_domain) {
		irq_domain_remove(domain);
		dev_err(dev, "Failed to allocate msi domain\n");
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&inta->vint_list);
	mutex_init(&inta->vint_mutex);

	dev_info(dev, "Interrupt Aggregator domain %d created\n", inta->ti_sci_id);

	return 0;
}

static const struct of_device_id ti_sci_inta_irq_domain_of_match[] = {
	{ .compatible = "ti,sci-inta", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, ti_sci_inta_irq_domain_of_match);

static struct platform_driver ti_sci_inta_irq_domain_driver = {
	.probe = ti_sci_inta_irq_domain_probe,
	.driver = {
		.name = "ti-sci-inta",
		.of_match_table = ti_sci_inta_irq_domain_of_match,
	},
};
module_platform_driver(ti_sci_inta_irq_domain_driver);

MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ti.com>");
MODULE_DESCRIPTION("K3 Interrupt Aggregator driver over TI SCI protocol");
MODULE_LICENSE("GPL v2");
