This series fixes some issues in rockchip iommu driver, and add of_iommu
support in it.
Changes in v6:
Add clk names, and modify all iommu nodes in all existing rockchip dts
Fix dt-binding as Robin suggested.
Use aclk and iface clk as Rob and Robin suggested, and split binding
patch.
Changes in v5:
Use out labels to save the duplication between the error and success paths.
Use RK_MMU_POLL_PERIOD_US instead of 100.
Remove clk names.
Use clk_bulk APIs.
Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().
Changes in v4:
Rewrite commit message.
Changes in v3:
Also remove remove() and module_exit() as Tomasz suggested.
Loop platform_get_irq() as Robin suggested.
Add struct rk_iommudata.
Squash iommu/rockchip: Use iommu_group_get_for_dev() for add_device
Only call startup() and shutdown() when iommu attached.
Remove pm_mutex.
Check runtime PM disabled.
Check pm_runtime in rk_iommu_irq().
Remove rk_iommudata->domain.
Changes in v2:
Move irq request to probe(in patch[0])
Move bus_set_iommu() to rk_iommu_probe().
Jeffy Chen (10):
iommu/rockchip: Prohibit unbind and remove
iommu/rockchip: Fix error handling in probe
iommu/rockchip: Request irqs in rk_iommu_probe()
ARM: dts: rockchip: add clocks in iommu nodes
dt-bindings: iommu/rockchip: Add clock property
iommu/rockchip: Use IOMMU device for dma mapping operations
iommu/rockchip: Use OF_IOMMU to attach devices automatically
iommu/rockchip: Fix error handling in init
iommu/rockchip: Add runtime PM support
iommu/rockchip: Support sharing IOMMU between masters
Tomasz Figa (4):
iommu/rockchip: Fix error handling in attach
iommu/rockchip: Use iopoll helpers to wait for hardware
iommu/rockchip: Fix TLB flush of secondary IOMMUs
iommu/rockchip: Control clocks needed to access the IOMMU
.../devicetree/bindings/iommu/rockchip,iommu.txt | 7 +
arch/arm/boot/dts/rk3036.dtsi | 2 +
arch/arm/boot/dts/rk322x.dtsi | 8 +
arch/arm/boot/dts/rk3288.dtsi | 12 +
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 +
arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 +
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 +-
drivers/iommu/rockchip-iommu.c | 600 +++++++++++----------
8 files changed, 374 insertions(+), 289 deletions(-)
--
2.11.0
Add missing iommu_device_sysfs_remove in error path.
Signed-off-by: Jeffy Chen <[email protected]>
Reviewed-by: Tomasz Figa <[email protected]>
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/iommu/rockchip-iommu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 16cd8780c289..c2ef3cbd4401 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,8 +1193,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
err = iommu_device_register(&iommu->iommu);
+ if (err) {
+ iommu_device_sysfs_remove(&iommu->iommu);
+ return err;
+ }
- return err;
+ return 0;
}
static const struct of_device_id rk_iommu_dt_ids[] = {
--
2.11.0
Move request_irq to the end of rk_iommu_probe().
Suggested-by: Robin Murphy <[email protected]>
Signed-off-by: Jeffy Chen <[email protected]>
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
Loop platform_get_irq() as Robin suggested.
Changes in v2: None
drivers/iommu/rockchip-iommu.c | 38 +++++++++-----------------------------
1 file changed, 9 insertions(+), 29 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index c2ef3cbd4401..b743d82e6fe1 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -90,8 +90,6 @@ struct rk_iommu {
struct device *dev;
void __iomem **bases;
int num_mmu;
- int *irq;
- int num_irq;
bool reset_disabled;
struct iommu_device iommu;
struct list_head node; /* entry in rk_iommu_domain.iommus */
@@ -830,13 +828,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
iommu->domain = domain;
- for (i = 0; i < iommu->num_irq; i++) {
- ret = devm_request_irq(iommu->dev, iommu->irq[i], rk_iommu_irq,
- IRQF_SHARED, dev_name(dev), iommu);
- if (ret)
- return ret;
- }
-
for (i = 0; i < iommu->num_mmu; i++) {
rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
rk_domain->dt_dma);
@@ -885,9 +876,6 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
}
rk_iommu_disable_stall(iommu);
- for (i = 0; i < iommu->num_irq; i++)
- devm_free_irq(iommu->dev, iommu->irq[i], iommu);
-
iommu->domain = NULL;
dev_dbg(dev, "Detached from iommu domain\n");
@@ -1138,7 +1126,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
struct rk_iommu *iommu;
struct resource *res;
int num_res = pdev->num_resources;
- int err, i;
+ int err, i, irq;
iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
if (!iommu)
@@ -1165,23 +1153,15 @@ static int rk_iommu_probe(struct platform_device *pdev)
if (iommu->num_mmu == 0)
return PTR_ERR(iommu->bases[0]);
- iommu->num_irq = platform_irq_count(pdev);
- if (iommu->num_irq < 0)
- return iommu->num_irq;
- if (iommu->num_irq == 0)
- return -ENXIO;
+ i = 0;
+ while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) {
+ if (irq < 0)
+ return irq;
- iommu->irq = devm_kcalloc(dev, iommu->num_irq, sizeof(*iommu->irq),
- GFP_KERNEL);
- if (!iommu->irq)
- return -ENOMEM;
-
- for (i = 0; i < iommu->num_irq; i++) {
- iommu->irq[i] = platform_get_irq(pdev, i);
- if (iommu->irq[i] < 0) {
- dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq[i]);
- return -ENXIO;
- }
+ err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
+ IRQF_SHARED, dev_name(dev), iommu);
+ if (err)
+ return err;
}
iommu->reset_disabled = device_property_read_bool(dev,
--
2.11.0
From: Tomasz Figa <[email protected]>
Currently if the driver encounters an error while attaching device, it
will leave the IOMMU in an inconsistent state. Even though it shouldn't
really happen in reality, let's just add proper error path to keep
things consistent.
Signed-off-by: Tomasz Figa <[email protected]>
Signed-off-by: Jeffy Chen <[email protected]>
Reviewed-by: Robin Murphy <[email protected]>
---
Changes in v6: None
Changes in v5:
Use out labels to save the duplication between the error and success paths.
Changes in v4: None
Changes in v3: None
Changes in v2:
Move irq request to probe(in patch[0])
drivers/iommu/rockchip-iommu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index b743d82e6fe1..f7ff3a3645ea 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -824,7 +824,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
ret = rk_iommu_force_reset(iommu);
if (ret)
- return ret;
+ goto out_disable_stall;
iommu->domain = domain;
@@ -837,7 +837,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
ret = rk_iommu_enable_paging(iommu);
if (ret)
- return ret;
+ goto out_disable_stall;
spin_lock_irqsave(&rk_domain->iommus_lock, flags);
list_add_tail(&iommu->node, &rk_domain->iommus);
@@ -845,9 +845,9 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
dev_dbg(dev, "Attached to iommu domain\n");
+out_disable_stall:
rk_iommu_disable_stall(iommu);
-
- return 0;
+ return ret;
}
static void rk_iommu_detach_device(struct iommu_domain *domain,
--
2.11.0
From: Tomasz Figa <[email protected]>
Due to the bug in current code, only first IOMMU has the TLB lines
flushed in rk_iommu_zap_lines. This patch fixes the inner loop to
execute for all IOMMUs and properly flush the TLB.
Signed-off-by: Tomasz Figa <[email protected]>
Signed-off-by: Jeffy Chen <[email protected]>
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/iommu/rockchip-iommu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index baba283ccdf9..c4131ca792e0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -274,19 +274,21 @@ static void rk_iommu_base_command(void __iomem *base, u32 command)
{
writel(command, base + RK_MMU_COMMAND);
}
-static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova,
+static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova_start,
size_t size)
{
int i;
-
- dma_addr_t iova_end = iova + size;
+ dma_addr_t iova_end = iova_start + size;
/*
* TODO(djkurtz): Figure out when it is more efficient to shootdown the
* entire iotlb rather than iterate over individual iovas.
*/
- for (i = 0; i < iommu->num_mmu; i++)
- for (; iova < iova_end; iova += SPAGE_SIZE)
+ for (i = 0; i < iommu->num_mmu; i++) {
+ dma_addr_t iova;
+
+ for (iova = iova_start; iova < iova_end; iova += SPAGE_SIZE)
rk_iommu_write(iommu->bases[i], RK_MMU_ZAP_ONE_LINE, iova);
+ }
}
static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
--
2.11.0
From: Tomasz Figa <[email protected]>
This patch converts the rockchip-iommu driver to use the in-kernel
iopoll helpers to wait for certain status bits to change in registers
instead of an open-coded custom macro.
Signed-off-by: Tomasz Figa <[email protected]>
Signed-off-by: Jeffy Chen <[email protected]>
Reviewed-by: Robin Murphy <[email protected]>
---
Changes in v6: None
Changes in v5:
Use RK_MMU_POLL_PERIOD_US instead of 100.
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/iommu/rockchip-iommu.c | 75 ++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 36 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index f7ff3a3645ea..baba283ccdf9 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -13,7 +13,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iommu.h>
-#include <linux/jiffies.h>
+#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -36,7 +36,10 @@
#define RK_MMU_AUTO_GATING 0x24
#define DTE_ADDR_DUMMY 0xCAFEBABE
-#define FORCE_RESET_TIMEOUT 100 /* ms */
+
+#define RK_MMU_POLL_PERIOD_US 100
+#define RK_MMU_FORCE_RESET_TIMEOUT_US 100000
+#define RK_MMU_POLL_TIMEOUT_US 1000
/* RK_MMU_STATUS fields */
#define RK_MMU_STATUS_PAGING_ENABLED BIT(0)
@@ -73,8 +76,6 @@
*/
#define RK_IOMMU_PGSIZE_BITMAP 0x007ff000
-#define IOMMU_REG_POLL_COUNT_FAST 1000
-
struct rk_iommu_domain {
struct list_head iommus;
struct platform_device *pdev;
@@ -109,27 +110,6 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
return container_of(dom, struct rk_iommu_domain, domain);
}
-/**
- * Inspired by _wait_for in intel_drv.h
- * This is NOT safe for use in interrupt context.
- *
- * Note that it's important that we check the condition again after having
- * timed out, since the timeout could be due to preemption or similar and
- * we've never had a chance to check the condition before the timeout.
- */
-#define rk_wait_for(COND, MS) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
- int ret__ = 0; \
- while (!(COND)) { \
- if (time_after(jiffies, timeout__)) { \
- ret__ = (COND) ? 0 : -ETIMEDOUT; \
- break; \
- } \
- usleep_range(50, 100); \
- } \
- ret__; \
-})
-
/*
* The Rockchip rk3288 iommu uses a 2-level page table.
* The first level is the "Directory Table" (DT).
@@ -333,9 +313,21 @@ static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu)
return enable;
}
+static bool rk_iommu_is_reset_done(struct rk_iommu *iommu)
+{
+ bool done = true;
+ int i;
+
+ for (i = 0; i < iommu->num_mmu; i++)
+ done &= rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0;
+
+ return done;
+}
+
static int rk_iommu_enable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_stall_active(iommu))
return 0;
@@ -346,7 +338,9 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
- ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ val, RK_MMU_POLL_PERIOD_US,
+ RK_MMU_POLL_TIMEOUT_US);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
@@ -358,13 +352,16 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
static int rk_iommu_disable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_stall_active(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL);
- ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ !val, RK_MMU_POLL_PERIOD_US,
+ RK_MMU_POLL_TIMEOUT_US);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
@@ -376,13 +373,16 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
static int rk_iommu_enable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING);
- ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ val, RK_MMU_POLL_PERIOD_US,
+ RK_MMU_POLL_TIMEOUT_US);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
@@ -394,13 +394,16 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
static int rk_iommu_disable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING);
- ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ !val, RK_MMU_POLL_PERIOD_US,
+ RK_MMU_POLL_TIMEOUT_US);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
@@ -413,6 +416,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
{
int ret, i;
u32 dte_addr;
+ bool val;
if (iommu->reset_disabled)
return 0;
@@ -433,13 +437,12 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET);
- for (i = 0; i < iommu->num_mmu; i++) {
- ret = rk_wait_for(rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0x00000000,
- FORCE_RESET_TIMEOUT);
- if (ret) {
- dev_err(iommu->dev, "FORCE_RESET command timed out\n");
- return ret;
- }
+ ret = readx_poll_timeout(rk_iommu_is_reset_done, iommu, val,
+ val, RK_MMU_FORCE_RESET_TIMEOUT_US,
+ RK_MMU_POLL_TIMEOUT_US);
+ if (ret) {
+ dev_err(iommu->dev, "FORCE_RESET command timed out\n");
+ return ret;
}
return 0;
--
2.11.0
Add clocks in iommu nodes, since we are going to control clocks in
rockchip iommu driver.
Signed-off-by: Jeffy Chen <[email protected]>
---
Changes in v6:
Add clk names, and modify all iommu nodes in all existing rockchip dts
Changes in v5:
Remove clk names.
Changes in v4: None
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/rk3036.dtsi | 2 ++
arch/arm/boot/dts/rk322x.dtsi | 8 ++++++++
arch/arm/boot/dts/rk3288.dtsi | 12 ++++++++++++
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 ++++++++++
arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++++++
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 ++++++++++++--
6 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
index a97458112ff6..567a6a725f9c 100644
--- a/arch/arm/boot/dts/rk3036.dtsi
+++ b/arch/arm/boot/dts/rk3036.dtsi
@@ -197,6 +197,8 @@
reg = <0x10118300 0x100>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vop_mmu";
+ clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index df1e47858675..be80e9a2c9af 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -584,6 +584,8 @@
reg = <0x20020800 0x100>;
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vpu_mmu";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk", "iface";
iommu-cells = <0>;
status = "disabled";
};
@@ -593,6 +595,8 @@
reg = <0x20030480 0x40>, <0x200304c0 0x40>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vdec_mmu";
+ clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
+ clock-names = "aclk", "iface";
iommu-cells = <0>;
status = "disabled";
};
@@ -602,6 +606,8 @@
reg = <0x20053f00 0x100>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vop_mmu";
+ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+ clock-names = "aclk", "iface";
iommu-cells = <0>;
status = "disabled";
};
@@ -611,6 +617,8 @@
reg = <0x20070800 0x100>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "iep_mmu";
+ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+ clock-names = "aclk", "iface";
iommu-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 6102e4e7f35c..ad77c8eb3c38 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -958,6 +958,8 @@
reg = <0x0 0xff900800 0x0 0x40>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "iep_mmu";
+ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -967,6 +969,8 @@
reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "isp_mmu";
+ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
rockchip,disable-mmu-reset;
status = "disabled";
@@ -1026,6 +1030,8 @@
reg = <0x0 0xff930300 0x0 0x100>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vopb_mmu";
+ clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
+ clock-names = "aclk", "iface";
power-domains = <&power RK3288_PD_VIO>;
#iommu-cells = <0>;
status = "disabled";
@@ -1074,6 +1080,8 @@
reg = <0x0 0xff940300 0x0 0x100>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vopl_mmu";
+ clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
+ clock-names = "aclk", "iface";
power-domains = <&power RK3288_PD_VIO>;
#iommu-cells = <0>;
status = "disabled";
@@ -1204,6 +1212,8 @@
reg = <0x0 0xff9a0800 0x0 0x100>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vpu_mmu";
+ clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -1213,6 +1223,8 @@
reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>;
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hevc_mmu";
+ clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index be2bfbc6b483..b8e9da15e00c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -595,6 +595,8 @@
reg = <0x0 0xff330200 0 0x100>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "h265e_mmu";
+ clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -604,6 +606,8 @@
reg = <0x0 0xff340800 0x0 0x40>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vepu_mmu";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -613,6 +617,8 @@
reg = <0x0 0xff350800 0x0 0x40>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vpu_mmu";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -622,6 +628,8 @@
reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "rkvdec_mmu";
+ clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -631,6 +639,8 @@
reg = <0x0 0xff373f00 0x0 0x100>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vop_mmu";
+ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index 03458ac44201..ad91ced78649 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -742,6 +742,8 @@
reg = <0x0 0xff900800 0x0 0x100>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "iep_mmu";
+ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -752,6 +754,8 @@
<0x0 0xff915000 0x0 0x100>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "isp_mmu";
+ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
rockchip,disable-mmu-reset;
status = "disabled";
@@ -762,6 +766,8 @@
reg = <0x0 0xff930300 0x0 0x100>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vop_mmu";
+ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -772,6 +778,8 @@
<0x0 0xff9a0480 0x0 0x40>;
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hevc_mmu";
+ clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -782,6 +790,8 @@
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vepu_mmu", "vdpu_mmu";
+ clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index da0078eda485..8cb4ed5d43cc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1234,6 +1234,8 @@
reg = <0x0 0xff650800 0x0 0x40>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "vpu_mmu";
+ clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -1243,6 +1245,8 @@
reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "vdec_mmu";
+ clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -1252,6 +1256,8 @@
reg = <0x0 0xff670800 0x0 0x40>;
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "iep_mmu";
+ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
status = "disabled";
};
@@ -1597,7 +1603,7 @@
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "vopl_mmu";
clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
- clock-names = "aclk", "hclk";
+ clock-names = "aclk", "iface";
power-domains = <&power RK3399_PD_VOPL>;
#iommu-cells = <0>;
status = "disabled";
@@ -1654,7 +1660,7 @@
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "vopb_mmu";
clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
- clock-names = "aclk", "hclk";
+ clock-names = "aclk", "iface";
power-domains = <&power RK3399_PD_VOPB>;
#iommu-cells = <0>;
status = "disabled";
@@ -1665,6 +1671,8 @@
reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "isp0_mmu";
+ clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
rockchip,disable-mmu-reset;
status = "disabled";
@@ -1675,6 +1683,8 @@
reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "isp1_mmu";
+ clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>;
+ clock-names = "aclk", "iface";
#iommu-cells = <0>;
rockchip,disable-mmu-reset;
status = "disabled";
--
2.11.0
Removal of IOMMUs cannot be done reliably.
This is similar to exynos iommu driver.
Signed-off-by: Jeffy Chen <[email protected]>
Reviewed-by: Tomasz Figa <[email protected]>
---
Changes in v6: None
Changes in v5: None
Changes in v4:
Rewrite commit message.
Changes in v3:
Also remove remove() and module_exit() as Tomasz suggested.
Changes in v2: None
drivers/iommu/rockchip-iommu.c | 21 +--------------------
1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9d991c2d8767..16cd8780c289 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1197,18 +1197,6 @@ static int rk_iommu_probe(struct platform_device *pdev)
return err;
}
-static int rk_iommu_remove(struct platform_device *pdev)
-{
- struct rk_iommu *iommu = platform_get_drvdata(pdev);
-
- if (iommu) {
- iommu_device_sysfs_remove(&iommu->iommu);
- iommu_device_unregister(&iommu->iommu);
- }
-
- return 0;
-}
-
static const struct of_device_id rk_iommu_dt_ids[] = {
{ .compatible = "rockchip,iommu" },
{ /* sentinel */ }
@@ -1217,10 +1205,10 @@ MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids);
static struct platform_driver rk_iommu_driver = {
.probe = rk_iommu_probe,
- .remove = rk_iommu_remove,
.driver = {
.name = "rk_iommu",
.of_match_table = rk_iommu_dt_ids,
+ .suppress_bind_attrs = true,
},
};
@@ -1248,14 +1236,7 @@ static int __init rk_iommu_init(void)
platform_driver_unregister(&rk_iommu_domain_driver);
return ret;
}
-static void __exit rk_iommu_exit(void)
-{
- platform_driver_unregister(&rk_iommu_driver);
- platform_driver_unregister(&rk_iommu_domain_driver);
-}
-
subsys_initcall(rk_iommu_init);
-module_exit(rk_iommu_exit);
MODULE_DESCRIPTION("IOMMU API for Rockchip");
MODULE_AUTHOR("Simon Xue <[email protected]> and Daniel Kurtz <[email protected]>");
--
2.11.0