Skip to content

Commit 021bb84

Browse files
rmurphy-armwildea01
authored andcommitted
iommu/arm-smmu: Wire up generic configuration support
With everything else now in place, fill in an of_xlate callback and the appropriate registration to plumb into the generic configuration machinery, and watch everything just work. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent d0acbb7 commit 021bb84

File tree

1 file changed

+108
-60
lines changed

1 file changed

+108
-60
lines changed

drivers/iommu/arm-smmu.c

Lines changed: 108 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ struct arm_smmu_option_prop {
418418

419419
static atomic_t cavium_smmu_context_count = ATOMIC_INIT(0);
420420

421+
static bool using_legacy_binding, using_generic_binding;
422+
421423
static struct arm_smmu_option_prop arm_smmu_options[] = {
422424
{ ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" },
423425
{ 0, NULL},
@@ -817,12 +819,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
817819
if (smmu_domain->smmu)
818820
goto out_unlock;
819821

820-
/* We're bypassing these SIDs, so don't allocate an actual context */
821-
if (domain->type == IOMMU_DOMAIN_DMA) {
822-
smmu_domain->smmu = smmu;
823-
goto out_unlock;
824-
}
825-
826822
/*
827823
* Mapping the requested stage onto what we support is surprisingly
828824
* complicated, mainly because the spec allows S1+S2 SMMUs without
@@ -981,7 +977,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
981977
void __iomem *cb_base;
982978
int irq;
983979

984-
if (!smmu || domain->type == IOMMU_DOMAIN_DMA)
980+
if (!smmu)
985981
return;
986982

987983
/*
@@ -1015,8 +1011,8 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
10151011
if (!smmu_domain)
10161012
return NULL;
10171013

1018-
if (type == IOMMU_DOMAIN_DMA &&
1019-
iommu_get_dma_cookie(&smmu_domain->domain)) {
1014+
if (type == IOMMU_DOMAIN_DMA && (using_legacy_binding ||
1015+
iommu_get_dma_cookie(&smmu_domain->domain))) {
10201016
kfree(smmu_domain);
10211017
return NULL;
10221018
}
@@ -1133,19 +1129,22 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
11331129
mutex_lock(&smmu->stream_map_mutex);
11341130
/* Figure out a viable stream map entry allocation */
11351131
for_each_cfg_sme(fwspec, i, idx) {
1132+
u16 sid = fwspec->ids[i];
1133+
u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
1134+
11361135
if (idx != INVALID_SMENDX) {
11371136
ret = -EEXIST;
11381137
goto out_err;
11391138
}
11401139

1141-
ret = arm_smmu_find_sme(smmu, fwspec->ids[i], 0);
1140+
ret = arm_smmu_find_sme(smmu, sid, mask);
11421141
if (ret < 0)
11431142
goto out_err;
11441143

11451144
idx = ret;
11461145
if (smrs && smmu->s2crs[idx].count == 0) {
1147-
smrs[idx].id = fwspec->ids[i];
1148-
smrs[idx].mask = 0; /* We don't currently share SMRs */
1146+
smrs[idx].id = sid;
1147+
smrs[idx].mask = mask;
11491148
smrs[idx].valid = true;
11501149
}
11511150
smmu->s2crs[idx].count++;
@@ -1203,15 +1202,6 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
12031202
u8 cbndx = smmu_domain->cfg.cbndx;
12041203
int i, idx;
12051204

1206-
/*
1207-
* FIXME: This won't be needed once we have IOMMU-backed DMA ops
1208-
* for all devices behind the SMMU. Note that we need to take
1209-
* care configuring SMRs for devices both a platform_device and
1210-
* and a PCI device (i.e. a PCI host controller)
1211-
*/
1212-
if (smmu_domain->domain.type == IOMMU_DOMAIN_DMA)
1213-
type = S2CR_TYPE_BYPASS;
1214-
12151205
for_each_cfg_sme(fwspec, i, idx) {
12161206
if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx)
12171207
continue;
@@ -1373,25 +1363,50 @@ static bool arm_smmu_capable(enum iommu_cap cap)
13731363
}
13741364
}
13751365

1366+
static int arm_smmu_match_node(struct device *dev, void *data)
1367+
{
1368+
return dev->of_node == data;
1369+
}
1370+
1371+
static struct arm_smmu_device *arm_smmu_get_by_node(struct device_node *np)
1372+
{
1373+
struct device *dev = driver_find_device(&arm_smmu_driver.driver, NULL,
1374+
np, arm_smmu_match_node);
1375+
put_device(dev);
1376+
return dev ? dev_get_drvdata(dev) : NULL;
1377+
}
1378+
13761379
static int arm_smmu_add_device(struct device *dev)
13771380
{
13781381
struct arm_smmu_device *smmu;
13791382
struct arm_smmu_master_cfg *cfg;
1380-
struct iommu_fwspec *fwspec;
1383+
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
13811384
int i, ret;
13821385

1383-
ret = arm_smmu_register_legacy_master(dev, &smmu);
1384-
fwspec = dev->iommu_fwspec;
1385-
if (ret)
1386-
goto out_free;
1386+
if (using_legacy_binding) {
1387+
ret = arm_smmu_register_legacy_master(dev, &smmu);
1388+
fwspec = dev->iommu_fwspec;
1389+
if (ret)
1390+
goto out_free;
1391+
} else if (fwspec) {
1392+
smmu = arm_smmu_get_by_node(to_of_node(fwspec->iommu_fwnode));
1393+
} else {
1394+
return -ENODEV;
1395+
}
13871396

13881397
ret = -EINVAL;
13891398
for (i = 0; i < fwspec->num_ids; i++) {
13901399
u16 sid = fwspec->ids[i];
1400+
u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
13911401

13921402
if (sid & ~smmu->streamid_mask) {
13931403
dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
1394-
sid, cfg->smmu->streamid_mask);
1404+
sid, smmu->streamid_mask);
1405+
goto out_free;
1406+
}
1407+
if (mask & ~smmu->smr_mask_mask) {
1408+
dev_err(dev, "SMR mask 0x%x out of range for SMMU (0x%x)\n",
1409+
sid, smmu->smr_mask_mask);
13951410
goto out_free;
13961411
}
13971412
}
@@ -1503,6 +1518,19 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
15031518
return ret;
15041519
}
15051520

1521+
static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
1522+
{
1523+
u32 fwid = 0;
1524+
1525+
if (args->args_count > 0)
1526+
fwid |= (u16)args->args[0];
1527+
1528+
if (args->args_count > 1)
1529+
fwid |= (u16)args->args[1] << SMR_MASK_SHIFT;
1530+
1531+
return iommu_fwspec_add_ids(dev, &fwid, 1);
1532+
}
1533+
15061534
static struct iommu_ops arm_smmu_ops = {
15071535
.capable = arm_smmu_capable,
15081536
.domain_alloc = arm_smmu_domain_alloc,
@@ -1517,6 +1545,7 @@ static struct iommu_ops arm_smmu_ops = {
15171545
.device_group = arm_smmu_device_group,
15181546
.domain_get_attr = arm_smmu_domain_get_attr,
15191547
.domain_set_attr = arm_smmu_domain_set_attr,
1548+
.of_xlate = arm_smmu_of_xlate,
15201549
.pgsize_bitmap = -1UL, /* Restricted during device attach */
15211550
};
15221551

@@ -1870,6 +1899,19 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
18701899
struct arm_smmu_device *smmu;
18711900
struct device *dev = &pdev->dev;
18721901
int num_irqs, i, err;
1902+
bool legacy_binding;
1903+
1904+
legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL);
1905+
if (legacy_binding && !using_generic_binding) {
1906+
if (!using_legacy_binding)
1907+
pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
1908+
using_legacy_binding = true;
1909+
} else if (!legacy_binding && !using_legacy_binding) {
1910+
using_generic_binding = true;
1911+
} else {
1912+
dev_err(dev, "not probing due to mismatched DT properties\n");
1913+
return -ENODEV;
1914+
}
18731915

18741916
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
18751917
if (!smmu) {
@@ -1954,6 +1996,20 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
19541996
of_iommu_set_ops(dev->of_node, &arm_smmu_ops);
19551997
platform_set_drvdata(pdev, smmu);
19561998
arm_smmu_device_reset(smmu);
1999+
2000+
/* Oh, for a proper bus abstraction */
2001+
if (!iommu_present(&platform_bus_type))
2002+
bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
2003+
#ifdef CONFIG_ARM_AMBA
2004+
if (!iommu_present(&amba_bustype))
2005+
bus_set_iommu(&amba_bustype, &arm_smmu_ops);
2006+
#endif
2007+
#ifdef CONFIG_PCI
2008+
if (!iommu_present(&pci_bus_type)) {
2009+
pci_request_acs();
2010+
bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
2011+
}
2012+
#endif
19572013
return 0;
19582014
}
19592015

@@ -1983,41 +2039,14 @@ static struct platform_driver arm_smmu_driver = {
19832039

19842040
static int __init arm_smmu_init(void)
19852041
{
1986-
struct device_node *np;
1987-
int ret;
1988-
1989-
/*
1990-
* Play nice with systems that don't have an ARM SMMU by checking that
1991-
* an ARM SMMU exists in the system before proceeding with the driver
1992-
* and IOMMU bus operation registration.
1993-
*/
1994-
np = of_find_matching_node(NULL, arm_smmu_of_match);
1995-
if (!np)
1996-
return 0;
1997-
1998-
of_node_put(np);
1999-
2000-
ret = platform_driver_register(&arm_smmu_driver);
2001-
if (ret)
2002-
return ret;
2003-
2004-
/* Oh, for a proper bus abstraction */
2005-
if (!iommu_present(&platform_bus_type))
2006-
bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
2007-
2008-
#ifdef CONFIG_ARM_AMBA
2009-
if (!iommu_present(&amba_bustype))
2010-
bus_set_iommu(&amba_bustype, &arm_smmu_ops);
2011-
#endif
2042+
static bool registered;
2043+
int ret = 0;
20122044

2013-
#ifdef CONFIG_PCI
2014-
if (!iommu_present(&pci_bus_type)) {
2015-
pci_request_acs();
2016-
bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
2045+
if (!registered) {
2046+
ret = platform_driver_register(&arm_smmu_driver);
2047+
registered = !ret;
20172048
}
2018-
#endif
2019-
2020-
return 0;
2049+
return ret;
20212050
}
20222051

20232052
static void __exit arm_smmu_exit(void)
@@ -2028,6 +2057,25 @@ static void __exit arm_smmu_exit(void)
20282057
subsys_initcall(arm_smmu_init);
20292058
module_exit(arm_smmu_exit);
20302059

2060+
static int __init arm_smmu_of_init(struct device_node *np)
2061+
{
2062+
int ret = arm_smmu_init();
2063+
2064+
if (ret)
2065+
return ret;
2066+
2067+
if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
2068+
return -ENODEV;
2069+
2070+
return 0;
2071+
}
2072+
IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
2073+
IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", arm_smmu_of_init);
2074+
IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", arm_smmu_of_init);
2075+
IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
2076+
IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
2077+
IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
2078+
20312079
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
20322080
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
20332081
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)