Commit 28026cf2 authored by Marc Zyngier's avatar Marc Zyngier Committed by Thomas Gleixner
Browse files

genirq/msi: Add .msi_teardown() callback as the reverse of .msi_prepare()



While the MSI ops do have a .msi_prepare() callback that is responsible for
setting up the relevant (usually per-device) allocation, there is no
callback reversing this setup.

For this purpose, add .msi_teardown() callback.

In order to avoid breaking the ITS driver that suffers from related issues,
do not call the callback just yet.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250513163144.2215824-2-maz@kernel.org
parent a1d8a830
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ struct msi_domain_info;
 * @msi_init:		Domain specific init function for MSI interrupts
 * @msi_free:		Domain specific function to free a MSI interrupts
 * @msi_prepare:	Prepare the allocation of the interrupts in the domain
 * @msi_teardown:	Reverse the effects of @msi_prepare
 * @prepare_desc:	Optional function to prepare the allocated MSI descriptor
 *			in the domain
 * @set_desc:		Set the msi descriptor for an interrupt
@@ -438,8 +439,9 @@ struct msi_domain_info;
 * @get_hwirq, @msi_init and @msi_free are callbacks used by the underlying
 * irqdomain.
 *
 * @msi_check, @msi_prepare, @prepare_desc and @set_desc are callbacks used by the
 * msi_domain_alloc/free_irqs*() variants.
 * @msi_check, @msi_prepare, @msi_teardown, @prepare_desc and
 * @set_desc are callbacks used by the msi_domain_alloc/free_irqs*()
 * variants.
 *
 * @domain_alloc_irqs, @domain_free_irqs can be used to override the
 * default allocation/free functions (__msi_domain_alloc/free_irqs). This
@@ -461,6 +463,8 @@ struct msi_domain_ops {
	int		(*msi_prepare)(struct irq_domain *domain,
				       struct device *dev, int nvec,
				       msi_alloc_info_t *arg);
	void		(*msi_teardown)(struct irq_domain *domain,
					msi_alloc_info_t *arg);
	void		(*prepare_desc)(struct irq_domain *domain, msi_alloc_info_t *arg,
					struct msi_desc *desc);
	void		(*set_desc)(msi_alloc_info_t *arg,
@@ -489,6 +493,7 @@ struct msi_domain_ops {
 * @handler:		Optional: associated interrupt flow handler
 * @handler_data:	Optional: associated interrupt flow handler data
 * @handler_name:	Optional: associated interrupt flow handler name
 * @alloc_data:		Optional: associated interrupt allocation data
 * @data:		Optional: domain specific data
 */
struct msi_domain_info {
@@ -501,6 +506,7 @@ struct msi_domain_info {
	irq_flow_handler_t		handler;
	void				*handler_data;
	const char			*handler_name;
	msi_alloc_info_t		*alloc_data;
	void				*data;
};

+8 −0
Original line number Diff line number Diff line
@@ -795,6 +795,11 @@ static int msi_domain_ops_prepare(struct irq_domain *domain, struct device *dev,
	return 0;
}

static void msi_domain_ops_teardown(struct irq_domain *domain,
				    msi_alloc_info_t *arg)
{
}

static void msi_domain_ops_set_desc(msi_alloc_info_t *arg,
				    struct msi_desc *desc)
{
@@ -820,6 +825,7 @@ static struct msi_domain_ops msi_domain_ops_default = {
	.get_hwirq		= msi_domain_ops_get_hwirq,
	.msi_init		= msi_domain_ops_init,
	.msi_prepare		= msi_domain_ops_prepare,
	.msi_teardown		= msi_domain_ops_teardown,
	.set_desc		= msi_domain_ops_set_desc,
};

@@ -841,6 +847,8 @@ static void msi_domain_update_dom_ops(struct msi_domain_info *info)
		ops->msi_init = msi_domain_ops_default.msi_init;
	if (ops->msi_prepare == NULL)
		ops->msi_prepare = msi_domain_ops_default.msi_prepare;
	if (ops->msi_teardown == NULL)
		ops->msi_teardown = msi_domain_ops_default.msi_teardown;
	if (ops->set_desc == NULL)
		ops->set_desc = msi_domain_ops_default.set_desc;
}