mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
fsl-mc: Add minimal infrastructure to use platform MSI
Add the tiny bit of infrastructure required to use platform MSI instead of the current hack. This means providing a write_msi_msg callback, as well as irq domain and devid retrieval helpers. Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com> # LX2160ARDB, LS2088ARDB Tested-by: Sascha Bischoff <sascha.bischoff@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Acked-by: Thomas Gleixner <tglx@kernel.org> Link: https://lore.kernel.org/r/20260224100936.3752303-3-maz@kernel.org Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
This commit is contained in:
committed by
Christophe Leroy (CS GROUP)
parent
1fb7392ee3
commit
0c9f522f2d
@@ -110,13 +110,8 @@ static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function is invoked with interrupts disabled
|
||||
*/
|
||||
static void fsl_mc_msi_write_msg(struct irq_data *irq_data,
|
||||
struct msi_msg *msg)
|
||||
static void fsl_mc_write_msi_msg(struct msi_desc *msi_desc, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data);
|
||||
struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(msi_desc->dev);
|
||||
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
|
||||
struct fsl_mc_device_irq *mc_dev_irq =
|
||||
@@ -130,6 +125,17 @@ static void fsl_mc_msi_write_msg(struct irq_data *irq_data,
|
||||
__fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq, msi_desc);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function is invoked with interrupts disabled
|
||||
*/
|
||||
static void fsl_mc_msi_write_msg(struct irq_data *irq_data,
|
||||
struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data);
|
||||
|
||||
fsl_mc_write_msi_msg(msi_desc, msg);
|
||||
}
|
||||
|
||||
static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info)
|
||||
{
|
||||
struct irq_chip *chip = info->chip;
|
||||
@@ -209,6 +215,20 @@ struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
|
||||
return msi_domain;
|
||||
}
|
||||
|
||||
struct irq_domain *fsl_mc_get_msi_parent(struct device *dev)
|
||||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
struct device *root_dprc_dev;
|
||||
struct device *bus_dev;
|
||||
|
||||
fsl_mc_get_root_dprc(dev, &root_dprc_dev);
|
||||
bus_dev = root_dprc_dev->parent;
|
||||
|
||||
return (bus_dev->of_node ?
|
||||
of_msi_get_domain(bus_dev, bus_dev->of_node, DOMAIN_BUS_NEXUS) :
|
||||
iort_get_device_domain(bus_dev, mc_dev->icid, DOMAIN_BUS_NEXUS));
|
||||
}
|
||||
|
||||
int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count)
|
||||
{
|
||||
int error = msi_setup_device_data(dev);
|
||||
@@ -220,8 +240,10 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count)
|
||||
* NOTE: Calling this function will trigger the invocation of the
|
||||
* its_fsl_mc_msi_prepare() callback
|
||||
*/
|
||||
error = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, irq_count - 1);
|
||||
|
||||
if (!irq_domain_is_msi_parent(dev_get_msi_domain(dev)))
|
||||
error = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, irq_count - 1);
|
||||
else
|
||||
error = platform_device_msi_init_and_alloc_irqs(dev, irq_count, fsl_mc_write_msi_msg);
|
||||
if (error)
|
||||
dev_err(dev, "Failed to allocate IRQs\n");
|
||||
return error;
|
||||
@@ -231,3 +253,15 @@ void fsl_mc_msi_domain_free_irqs(struct device *dev)
|
||||
{
|
||||
msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
|
||||
}
|
||||
|
||||
u32 fsl_mc_get_msi_id(struct device *dev)
|
||||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
struct device *root_dprc_dev;
|
||||
|
||||
fsl_mc_get_root_dprc(dev, &root_dprc_dev);
|
||||
|
||||
return (root_dprc_dev->parent->of_node ?
|
||||
of_msi_xlate(dev, NULL, mc_dev->icid) :
|
||||
iort_msi_map_id(dev, mc_dev->icid));
|
||||
}
|
||||
|
||||
@@ -642,6 +642,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
|
||||
void fsl_mc_msi_domain_free_irqs(struct device *dev);
|
||||
|
||||
struct irq_domain *fsl_mc_find_msi_domain(struct device *dev);
|
||||
struct irq_domain *fsl_mc_get_msi_parent(struct device *dev);
|
||||
|
||||
int __must_check fsl_create_mc_io(struct device *dev,
|
||||
phys_addr_t mc_portal_phys_addr,
|
||||
|
||||
@@ -361,9 +361,11 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct fsl_mc_command *cmd);
|
||||
|
||||
#ifdef CONFIG_FSL_MC_BUS
|
||||
#define dev_is_fsl_mc(_dev) ((_dev)->bus == &fsl_mc_bus_type)
|
||||
u32 fsl_mc_get_msi_id(struct device *dev);
|
||||
#else
|
||||
/* If fsl-mc bus is not present device cannot belong to fsl-mc bus */
|
||||
#define dev_is_fsl_mc(_dev) (0)
|
||||
#define fsl_mc_get_msi_id(_dev) (0)
|
||||
#endif
|
||||
|
||||
/* Macro to check if a device is a container device */
|
||||
|
||||
Reference in New Issue
Block a user