1717#include <linux/init.h>
1818#include <linux/iommu.h>
1919#include <linux/kernel.h>
20+ #include <linux/pci.h>
2021
2122#include "iommu-bits.h"
2223#include "iommu.h"
@@ -36,6 +37,60 @@ static void riscv_iommu_disable(struct riscv_iommu_device *iommu)
3637 riscv_iommu_writel (iommu , RISCV_IOMMU_REG_PQCSR , 0 );
3738}
3839
40+ static int riscv_iommu_attach_identity_domain (struct iommu_domain * iommu_domain ,
41+ struct device * dev )
42+ {
43+ /* Global pass-through already enabled, do nothing for now. */
44+ return 0 ;
45+ }
46+
47+ static struct iommu_domain riscv_iommu_identity_domain = {
48+ .type = IOMMU_DOMAIN_IDENTITY ,
49+ .ops = & (const struct iommu_domain_ops ) {
50+ .attach_dev = riscv_iommu_attach_identity_domain ,
51+ }
52+ };
53+
54+ static int riscv_iommu_device_domain_type (struct device * dev )
55+ {
56+ return IOMMU_DOMAIN_IDENTITY ;
57+ }
58+
59+ static struct iommu_group * riscv_iommu_device_group (struct device * dev )
60+ {
61+ if (dev_is_pci (dev ))
62+ return pci_device_group (dev );
63+ return generic_device_group (dev );
64+ }
65+
66+ static int riscv_iommu_of_xlate (struct device * dev , const struct of_phandle_args * args )
67+ {
68+ return iommu_fwspec_add_ids (dev , args -> args , 1 );
69+ }
70+
71+ static struct iommu_device * riscv_iommu_probe_device (struct device * dev )
72+ {
73+ struct iommu_fwspec * fwspec = dev_iommu_fwspec_get (dev );
74+ struct riscv_iommu_device * iommu ;
75+
76+ if (!fwspec || !fwspec -> iommu_fwnode -> dev || !fwspec -> num_ids )
77+ return ERR_PTR (- ENODEV );
78+
79+ iommu = dev_get_drvdata (fwspec -> iommu_fwnode -> dev );
80+ if (!iommu )
81+ return ERR_PTR (- ENODEV );
82+
83+ return & iommu -> iommu ;
84+ }
85+
86+ static const struct iommu_ops riscv_iommu_ops = {
87+ .of_xlate = riscv_iommu_of_xlate ,
88+ .identity_domain = & riscv_iommu_identity_domain ,
89+ .def_domain_type = riscv_iommu_device_domain_type ,
90+ .device_group = riscv_iommu_device_group ,
91+ .probe_device = riscv_iommu_probe_device ,
92+ };
93+
3994static int riscv_iommu_init_check (struct riscv_iommu_device * iommu )
4095{
4196 u64 ddtp ;
@@ -74,6 +129,7 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
74129
75130void riscv_iommu_remove (struct riscv_iommu_device * iommu )
76131{
132+ iommu_device_unregister (& iommu -> iommu );
77133 iommu_device_sysfs_remove (& iommu -> iommu );
78134}
79135
@@ -99,5 +155,15 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu)
99155 return dev_err_probe (iommu -> dev , rc ,
100156 "cannot register sysfs interface\n" );
101157
158+ rc = iommu_device_register (& iommu -> iommu , & riscv_iommu_ops , iommu -> dev );
159+ if (rc ) {
160+ dev_err_probe (iommu -> dev , rc , "cannot register iommu interface\n" );
161+ goto err_remove_sysfs ;
162+ }
163+
102164 return 0 ;
165+
166+ err_remove_sysfs :
167+ iommu_device_sysfs_remove (& iommu -> iommu );
168+ return rc ;
103169}
0 commit comments