Skip to content

Commit 77a4419

Browse files
Xu Lujoergroedel
authored andcommitted
iommu/riscv: Add shutdown function for iommu driver
This commit supplies shutdown callback for iommu driver. The shutdown callback resets necessary registers so that newly booted kernel can pass riscv_iommu_init_check() after kexec. Also, the shutdown callback resets iommu mode to bare instead of off so that new kernel can still use PCIE devices even when CONFIG_RISCV_IOMMU is not enabled. Signed-off-by: Xu Lu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 8d8d375 commit 77a4419

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

drivers/iommu/riscv/iommu-pci.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ static void riscv_iommu_pci_remove(struct pci_dev *pdev)
101101
riscv_iommu_remove(iommu);
102102
}
103103

104+
static void riscv_iommu_pci_shutdown(struct pci_dev *pdev)
105+
{
106+
struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
107+
108+
riscv_iommu_disable(iommu);
109+
}
110+
104111
static const struct pci_device_id riscv_iommu_pci_tbl[] = {
105112
{PCI_VDEVICE(REDHAT, PCI_DEVICE_ID_REDHAT_RISCV_IOMMU), 0},
106113
{PCI_VDEVICE(RIVOS, PCI_DEVICE_ID_RIVOS_RISCV_IOMMU_GA), 0},
@@ -112,6 +119,7 @@ static struct pci_driver riscv_iommu_pci_driver = {
112119
.id_table = riscv_iommu_pci_tbl,
113120
.probe = riscv_iommu_pci_probe,
114121
.remove = riscv_iommu_pci_remove,
122+
.shutdown = riscv_iommu_pci_shutdown,
115123
.driver = {
116124
.suppress_bind_attrs = true,
117125
},

drivers/iommu/riscv/iommu-platform.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ static void riscv_iommu_platform_remove(struct platform_device *pdev)
140140
platform_device_msi_free_irqs_all(&pdev->dev);
141141
};
142142

143+
static void riscv_iommu_platform_shutdown(struct platform_device *pdev)
144+
{
145+
riscv_iommu_disable(dev_get_drvdata(&pdev->dev));
146+
};
147+
143148
static const struct of_device_id riscv_iommu_of_match[] = {
144149
{.compatible = "riscv,iommu",},
145150
{},
@@ -148,6 +153,7 @@ static const struct of_device_id riscv_iommu_of_match[] = {
148153
static struct platform_driver riscv_iommu_platform_driver = {
149154
.probe = riscv_iommu_platform_probe,
150155
.remove = riscv_iommu_platform_remove,
156+
.shutdown = riscv_iommu_platform_shutdown,
151157
.driver = {
152158
.name = "riscv,iommu",
153159
.of_match_table = riscv_iommu_of_match,

drivers/iommu/riscv/iommu.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,9 +651,11 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm
651651
* This is best effort IOMMU translation shutdown flow.
652652
* Disable IOMMU without waiting for hardware response.
653653
*/
654-
static void riscv_iommu_disable(struct riscv_iommu_device *iommu)
654+
void riscv_iommu_disable(struct riscv_iommu_device *iommu)
655655
{
656-
riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_DDTP, 0);
656+
riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_DDTP,
657+
FIELD_PREP(RISCV_IOMMU_DDTP_IOMMU_MODE,
658+
RISCV_IOMMU_DDTP_IOMMU_MODE_BARE));
657659
riscv_iommu_writel(iommu, RISCV_IOMMU_REG_CQCSR, 0);
658660
riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FQCSR, 0);
659661
riscv_iommu_writel(iommu, RISCV_IOMMU_REG_PQCSR, 0);

drivers/iommu/riscv/iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct riscv_iommu_device {
6464

6565
int riscv_iommu_init(struct riscv_iommu_device *iommu);
6666
void riscv_iommu_remove(struct riscv_iommu_device *iommu);
67+
void riscv_iommu_disable(struct riscv_iommu_device *iommu);
6768

6869
#define riscv_iommu_readl(iommu, addr) \
6970
readl_relaxed((iommu)->reg + (addr))

0 commit comments

Comments
 (0)