Skip to content

Commit 998fb7b

Browse files
dmcraciunctmarinas
authored andcommitted
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 <[email protected]> Acked-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 2bcdd8f commit 998fb7b

File tree

5 files changed

+47
-40
lines changed

5 files changed

+47
-40
lines changed

drivers/bus/fsl-mc/dprc-driver.c

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
592592
bool mc_io_created = false;
593593
bool msi_domain_set = false;
594594
u16 major_ver, minor_ver;
595+
struct irq_domain *mc_msi_domain;
595596

596597
if (!is_fsl_mc_bus_dprc(mc_dev))
597598
return -EINVAL;
@@ -621,31 +622,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
621622
return error;
622623

623624
mc_io_created = true;
625+
}
624626

625-
/*
626-
* Inherit parent MSI domain:
627-
*/
628-
dev_set_msi_domain(&mc_dev->dev,
629-
dev_get_msi_domain(parent_dev));
630-
msi_domain_set = true;
627+
mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev);
628+
if (!mc_msi_domain) {
629+
dev_warn(&mc_dev->dev,
630+
"WARNING: MC bus without interrupt support\n");
631631
} else {
632-
/*
633-
* This is a root DPRC
634-
*/
635-
struct irq_domain *mc_msi_domain;
636-
637-
if (dev_is_fsl_mc(parent_dev))
638-
return -EINVAL;
639-
640-
error = fsl_mc_find_msi_domain(parent_dev,
641-
&mc_msi_domain);
642-
if (error < 0) {
643-
dev_warn(&mc_dev->dev,
644-
"WARNING: MC bus without interrupt support\n");
645-
} else {
646-
dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
647-
msi_domain_set = true;
648-
}
632+
dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
633+
msi_domain_set = true;
649634
}
650635

651636
error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,

drivers/bus/fsl-mc/fsl-mc-bus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ EXPORT_SYMBOL_GPL(fsl_mc_get_version);
370370
/**
371371
* fsl_mc_get_root_dprc - function to traverse to the root dprc
372372
*/
373-
static void fsl_mc_get_root_dprc(struct device *dev,
374-
struct device **root_dprc_dev)
373+
void fsl_mc_get_root_dprc(struct device *dev,
374+
struct device **root_dprc_dev)
375375
{
376376
if (!dev) {
377377
*root_dprc_dev = NULL;

drivers/bus/fsl-mc/fsl-mc-msi.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,23 +177,30 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
177177
return domain;
178178
}
179179

180-
int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
181-
struct irq_domain **mc_msi_domain)
180+
struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
182181
{
183-
struct irq_domain *msi_domain;
184-
struct device_node *mc_of_node = mc_platform_dev->of_node;
182+
struct irq_domain *msi_domain = NULL;
183+
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
185184

186-
msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
187-
DOMAIN_BUS_FSL_MC_MSI);
188-
if (!msi_domain) {
189-
pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
190-
mc_of_node);
185+
msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
186+
DOMAIN_BUS_FSL_MC_MSI);
191187

192-
return -ENOENT;
188+
/*
189+
* if the msi-map property is missing assume that all the
190+
* child containers inherit the domain from the parent
191+
*/
192+
if (!msi_domain) {
193+
struct device *root_dprc_dev;
194+
struct device *bus_dev;
195+
196+
fsl_mc_get_root_dprc(dev, &root_dprc_dev);
197+
bus_dev = root_dprc_dev->parent;
198+
msi_domain = of_msi_get_domain(bus_dev,
199+
bus_dev->of_node,
200+
DOMAIN_BUS_FSL_MC_MSI);
193201
}
194202

195-
*mc_msi_domain = msi_domain;
196-
return 0;
203+
return msi_domain;
197204
}
198205

199206
static void fsl_mc_msi_free_descs(struct device *dev)

drivers/bus/fsl-mc/fsl-mc-private.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
595595

596596
void fsl_mc_msi_domain_free_irqs(struct device *dev);
597597

598-
int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
599-
struct irq_domain **mc_msi_domain);
598+
struct irq_domain *fsl_mc_find_msi_domain(struct device *dev);
600599

601600
int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
602601
unsigned int irq_count);
@@ -613,6 +612,9 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
613612

614613
bool fsl_mc_is_root_dprc(struct device *dev);
615614

615+
void fsl_mc_get_root_dprc(struct device *dev,
616+
struct device **root_dprc_dev);
617+
616618
struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
617619
struct fsl_mc_device *mc_bus_dev);
618620

drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ static struct irq_chip its_msi_irq_chip = {
2323
.irq_set_affinity = msi_domain_set_affinity
2424
};
2525

26+
static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
27+
struct fsl_mc_device *mc_dev)
28+
{
29+
struct device_node *of_node;
30+
u32 out_id;
31+
32+
of_node = irq_domain_get_of_node(domain);
33+
out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
34+
35+
return out_id;
36+
}
37+
2638
static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
2739
struct device *dev,
2840
int nvec, msi_alloc_info_t *info)
@@ -43,7 +55,8 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
4355
* NOTE: This device id corresponds to the IOMMU stream ID
4456
* associated with the DPRC object (ICID).
4557
*/
46-
info->scratchpad[0].ul = mc_bus_dev->icid;
58+
info->scratchpad[0].ul = fsl_mc_msi_domain_get_msi_id(msi_domain,
59+
mc_bus_dev);
4760
msi_info = msi_get_domain_info(msi_domain->parent);
4861

4962
/* Allocate at least 32 MSIs, and always as a power of 2 */

0 commit comments

Comments
 (0)