mirror of
https://github.com/torvalds/linux.git
synced 2025-01-01 15:51:46 +00:00
bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver
The DPRC driver is not taking into account the msi-map property and assumes that the icid is the same as the stream ID. Although this assumption is correct, generalize the code to include a translation between icid and streamID. Furthermore do not just copy the MSI domain from parent (for child containers), but use the information provided by the msi-map property. If the msi-map property is missing from the device tree retain the old behaviour for backward compatibility ie the child DPRC objects inherit the MSI domain from the parent. Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20200619082013.13661-12-lorenzo.pieralisi@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
2bcdd8f2c0
commit
998fb7badf
@ -592,6 +592,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
|
||||
bool mc_io_created = false;
|
||||
bool msi_domain_set = false;
|
||||
u16 major_ver, minor_ver;
|
||||
struct irq_domain *mc_msi_domain;
|
||||
|
||||
if (!is_fsl_mc_bus_dprc(mc_dev))
|
||||
return -EINVAL;
|
||||
@ -621,31 +622,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
|
||||
return error;
|
||||
|
||||
mc_io_created = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inherit parent MSI domain:
|
||||
*/
|
||||
dev_set_msi_domain(&mc_dev->dev,
|
||||
dev_get_msi_domain(parent_dev));
|
||||
msi_domain_set = true;
|
||||
mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev);
|
||||
if (!mc_msi_domain) {
|
||||
dev_warn(&mc_dev->dev,
|
||||
"WARNING: MC bus without interrupt support\n");
|
||||
} else {
|
||||
/*
|
||||
* This is a root DPRC
|
||||
*/
|
||||
struct irq_domain *mc_msi_domain;
|
||||
|
||||
if (dev_is_fsl_mc(parent_dev))
|
||||
return -EINVAL;
|
||||
|
||||
error = fsl_mc_find_msi_domain(parent_dev,
|
||||
&mc_msi_domain);
|
||||
if (error < 0) {
|
||||
dev_warn(&mc_dev->dev,
|
||||
"WARNING: MC bus without interrupt support\n");
|
||||
} else {
|
||||
dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
|
||||
msi_domain_set = true;
|
||||
}
|
||||
dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
|
||||
msi_domain_set = true;
|
||||
}
|
||||
|
||||
error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
|
||||
|
@ -370,8 +370,8 @@ EXPORT_SYMBOL_GPL(fsl_mc_get_version);
|
||||
/**
|
||||
* fsl_mc_get_root_dprc - function to traverse to the root dprc
|
||||
*/
|
||||
static void fsl_mc_get_root_dprc(struct device *dev,
|
||||
struct device **root_dprc_dev)
|
||||
void fsl_mc_get_root_dprc(struct device *dev,
|
||||
struct device **root_dprc_dev)
|
||||
{
|
||||
if (!dev) {
|
||||
*root_dprc_dev = NULL;
|
||||
|
@ -177,23 +177,30 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
|
||||
return domain;
|
||||
}
|
||||
|
||||
int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
|
||||
struct irq_domain **mc_msi_domain)
|
||||
struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
|
||||
{
|
||||
struct irq_domain *msi_domain;
|
||||
struct device_node *mc_of_node = mc_platform_dev->of_node;
|
||||
struct irq_domain *msi_domain = NULL;
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
|
||||
msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
|
||||
DOMAIN_BUS_FSL_MC_MSI);
|
||||
msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
|
||||
DOMAIN_BUS_FSL_MC_MSI);
|
||||
|
||||
/*
|
||||
* if the msi-map property is missing assume that all the
|
||||
* child containers inherit the domain from the parent
|
||||
*/
|
||||
if (!msi_domain) {
|
||||
pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
|
||||
mc_of_node);
|
||||
struct device *root_dprc_dev;
|
||||
struct device *bus_dev;
|
||||
|
||||
return -ENOENT;
|
||||
fsl_mc_get_root_dprc(dev, &root_dprc_dev);
|
||||
bus_dev = root_dprc_dev->parent;
|
||||
msi_domain = of_msi_get_domain(bus_dev,
|
||||
bus_dev->of_node,
|
||||
DOMAIN_BUS_FSL_MC_MSI);
|
||||
}
|
||||
|
||||
*mc_msi_domain = msi_domain;
|
||||
return 0;
|
||||
return msi_domain;
|
||||
}
|
||||
|
||||
static void fsl_mc_msi_free_descs(struct device *dev)
|
||||
|
@ -595,8 +595,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
|
||||
|
||||
void fsl_mc_msi_domain_free_irqs(struct device *dev);
|
||||
|
||||
int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
|
||||
struct irq_domain **mc_msi_domain);
|
||||
struct irq_domain *fsl_mc_find_msi_domain(struct device *dev);
|
||||
|
||||
int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
|
||||
unsigned int irq_count);
|
||||
@ -613,6 +612,9 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
|
||||
|
||||
bool fsl_mc_is_root_dprc(struct device *dev);
|
||||
|
||||
void fsl_mc_get_root_dprc(struct device *dev,
|
||||
struct device **root_dprc_dev);
|
||||
|
||||
struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
|
||||
struct fsl_mc_device *mc_bus_dev);
|
||||
|
||||
|
@ -23,6 +23,18 @@ static struct irq_chip its_msi_irq_chip = {
|
||||
.irq_set_affinity = msi_domain_set_affinity
|
||||
};
|
||||
|
||||
static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
|
||||
struct fsl_mc_device *mc_dev)
|
||||
{
|
||||
struct device_node *of_node;
|
||||
u32 out_id;
|
||||
|
||||
of_node = irq_domain_get_of_node(domain);
|
||||
out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
|
||||
|
||||
return out_id;
|
||||
}
|
||||
|
||||
static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
|
||||
struct device *dev,
|
||||
int nvec, msi_alloc_info_t *info)
|
||||
@ -43,7 +55,8 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
|
||||
* NOTE: This device id corresponds to the IOMMU stream ID
|
||||
* associated with the DPRC object (ICID).
|
||||
*/
|
||||
info->scratchpad[0].ul = mc_bus_dev->icid;
|
||||
info->scratchpad[0].ul = fsl_mc_msi_domain_get_msi_id(msi_domain,
|
||||
mc_bus_dev);
|
||||
msi_info = msi_get_domain_info(msi_domain->parent);
|
||||
|
||||
/* Allocate at least 32 MSIs, and always as a power of 2 */
|
||||
|
Loading…
Reference in New Issue
Block a user