Skip to content

Commit 42d57fc

Browse files
YongWu-HFjoergroedel
authored andcommitted
iommu/mediatek: Initialise/Remove for multi bank dev
The registers for each bank of the IOMMU base are in order, delta is 0x1000. Initialise the base for each bank. For all the previous SoC, we only have bank0. thus use "do {} while()" to allow bank0 always go. When removing the device, Not always all the banks are initialised, it depend on if there is masters for that bank. Signed-off-by: Yong Wu <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Reviewed-by: Matthias Brugger <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 57fb481 commit 42d57fc

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

drivers/iommu/mtk_iommu.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
#define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f)
114114

115115
#define MTK_PROTECT_PA_ALIGN 256
116+
#define MTK_IOMMU_BANK_SZ 0x1000
116117

117118
#define PERICFG_IOMMU_1 0x714
118119

@@ -1112,7 +1113,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
11121113
struct component_match *match = NULL;
11131114
struct regmap *infracfg;
11141115
void *protect;
1115-
int ret, banks_num;
1116+
int ret, banks_num, i = 0;
11161117
u32 val;
11171118
char *p;
11181119
struct mtk_iommu_bank_data *bank;
@@ -1153,27 +1154,36 @@ static int mtk_iommu_probe(struct platform_device *pdev)
11531154
data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN);
11541155
}
11551156

1157+
banks_num = data->plat_data->banks_num;
11561158
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1159+
if (resource_size(res) < banks_num * MTK_IOMMU_BANK_SZ) {
1160+
dev_err(dev, "banknr %d. res %pR is not enough.\n", banks_num, res);
1161+
return -EINVAL;
1162+
}
11571163
base = devm_ioremap_resource(dev, res);
11581164
if (IS_ERR(base))
11591165
return PTR_ERR(base);
11601166
ioaddr = res->start;
11611167

1162-
banks_num = data->plat_data->banks_num;
11631168
data->bank = devm_kmalloc(dev, banks_num * sizeof(*data->bank), GFP_KERNEL);
11641169
if (!data->bank)
11651170
return -ENOMEM;
11661171

1167-
bank = &data->bank[0];
1168-
bank->id = 0;
1169-
bank->base = base;
1170-
bank->m4u_dom = NULL;
1171-
bank->irq = platform_get_irq(pdev, 0);
1172-
if (bank->irq < 0)
1173-
return bank->irq;
1174-
bank->parent_dev = dev;
1175-
bank->parent_data = data;
1176-
spin_lock_init(&bank->tlb_lock);
1172+
do {
1173+
if (!data->plat_data->banks_enable[i])
1174+
continue;
1175+
bank = &data->bank[i];
1176+
bank->id = i;
1177+
bank->base = base + i * MTK_IOMMU_BANK_SZ;
1178+
bank->m4u_dom = NULL;
1179+
1180+
bank->irq = platform_get_irq(pdev, i);
1181+
if (bank->irq < 0)
1182+
return bank->irq;
1183+
bank->parent_dev = dev;
1184+
bank->parent_data = data;
1185+
spin_lock_init(&bank->tlb_lock);
1186+
} while (++i < banks_num);
11771187

11781188
if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
11791189
data->bclk = devm_clk_get(dev, "bclk");
@@ -1261,7 +1271,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
12611271
static int mtk_iommu_remove(struct platform_device *pdev)
12621272
{
12631273
struct mtk_iommu_data *data = platform_get_drvdata(pdev);
1264-
struct mtk_iommu_bank_data *bank = &data->bank[0];
1274+
struct mtk_iommu_bank_data *bank;
1275+
int i;
12651276

12661277
iommu_device_sysfs_remove(&data->iommu);
12671278
iommu_device_unregister(&data->iommu);
@@ -1278,7 +1289,12 @@ static int mtk_iommu_remove(struct platform_device *pdev)
12781289
#endif
12791290
}
12801291
pm_runtime_disable(&pdev->dev);
1281-
devm_free_irq(&pdev->dev, bank->irq, bank);
1292+
for (i = 0; i < data->plat_data->banks_num; i++) {
1293+
bank = &data->bank[i];
1294+
if (!bank->m4u_dom)
1295+
continue;
1296+
devm_free_irq(&pdev->dev, bank->irq, bank);
1297+
}
12821298
return 0;
12831299
}
12841300

0 commit comments

Comments
 (0)