Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
894901b5
Commit
894901b5
authored
7 years ago
by
Joerg Roedel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'iommu/fixes' into arm/mediatek
parents
46cc815d
2926a2aa
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
79 additions
and
28 deletions
+79
-28
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu.c
+1
-0
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_init.c
+1
-1
drivers/iommu/amd_iommu_types.h
drivers/iommu/amd_iommu_types.h
+3
-1
drivers/iommu/arm-smmu.c
drivers/iommu/arm-smmu.c
+19
-4
drivers/iommu/intel-iommu.c
drivers/iommu/intel-iommu.c
+3
-1
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm-v7s.c
+6
-0
drivers/iommu/io-pgtable-arm.c
drivers/iommu/io-pgtable-arm.c
+7
-0
drivers/iommu/io-pgtable.h
drivers/iommu/io-pgtable.h
+1
-8
drivers/iommu/iommu-sysfs.c
drivers/iommu/iommu-sysfs.c
+20
-12
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu.c
+6
-0
drivers/iommu/mtk_iommu.h
drivers/iommu/mtk_iommu.h
+1
-0
include/linux/iommu.h
include/linux/iommu.h
+11
-1
No files found.
drivers/iommu/amd_iommu.c
View file @
894901b5
...
@@ -4452,6 +4452,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
...
@@ -4452,6 +4452,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
/* Setting */
/* Setting */
irte
->
hi
.
fields
.
ga_root_ptr
=
(
pi_data
->
base
>>
12
);
irte
->
hi
.
fields
.
ga_root_ptr
=
(
pi_data
->
base
>>
12
);
irte
->
hi
.
fields
.
vector
=
vcpu_pi_info
->
vector
;
irte
->
hi
.
fields
.
vector
=
vcpu_pi_info
->
vector
;
irte
->
lo
.
fields_vapic
.
ga_log_intr
=
1
;
irte
->
lo
.
fields_vapic
.
guest_mode
=
1
;
irte
->
lo
.
fields_vapic
.
guest_mode
=
1
;
irte
->
lo
.
fields_vapic
.
ga_tag
=
pi_data
->
ga_tag
;
irte
->
lo
.
fields_vapic
.
ga_tag
=
pi_data
->
ga_tag
;
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/amd_iommu_init.c
View file @
894901b5
...
@@ -2440,11 +2440,11 @@ static int __init state_next(void)
...
@@ -2440,11 +2440,11 @@ static int __init state_next(void)
break
;
break
;
case
IOMMU_ACPI_FINISHED
:
case
IOMMU_ACPI_FINISHED
:
early_enable_iommus
();
early_enable_iommus
();
register_syscore_ops
(
&
amd_iommu_syscore_ops
);
x86_platform
.
iommu_shutdown
=
disable_iommus
;
x86_platform
.
iommu_shutdown
=
disable_iommus
;
init_state
=
IOMMU_ENABLED
;
init_state
=
IOMMU_ENABLED
;
break
;
break
;
case
IOMMU_ENABLED
:
case
IOMMU_ENABLED
:
register_syscore_ops
(
&
amd_iommu_syscore_ops
);
ret
=
amd_iommu_init_pci
();
ret
=
amd_iommu_init_pci
();
init_state
=
ret
?
IOMMU_INIT_ERROR
:
IOMMU_PCI_INIT
;
init_state
=
ret
?
IOMMU_INIT_ERROR
:
IOMMU_PCI_INIT
;
enable_iommus_v2
();
enable_iommus_v2
();
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/amd_iommu_types.h
View file @
894901b5
...
@@ -574,7 +574,9 @@ struct amd_iommu {
...
@@ -574,7 +574,9 @@ struct amd_iommu {
static
inline
struct
amd_iommu
*
dev_to_amd_iommu
(
struct
device
*
dev
)
static
inline
struct
amd_iommu
*
dev_to_amd_iommu
(
struct
device
*
dev
)
{
{
return
container_of
(
dev
,
struct
amd_iommu
,
iommu
.
dev
);
struct
iommu_device
*
iommu
=
dev_to_iommu_device
(
dev
);
return
container_of
(
iommu
,
struct
amd_iommu
,
iommu
);
}
}
#define ACPIHID_UID_LEN 256
#define ACPIHID_UID_LEN 256
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/arm-smmu.c
View file @
894901b5
...
@@ -400,6 +400,8 @@ struct arm_smmu_device {
...
@@ -400,6 +400,8 @@ struct arm_smmu_device {
u32
cavium_id_base
;
/* Specific to Cavium */
u32
cavium_id_base
;
/* Specific to Cavium */
spinlock_t
global_sync_lock
;
/* IOMMU core code handle */
/* IOMMU core code handle */
struct
iommu_device
iommu
;
struct
iommu_device
iommu
;
};
};
...
@@ -436,7 +438,7 @@ struct arm_smmu_domain {
...
@@ -436,7 +438,7 @@ struct arm_smmu_domain {
struct
arm_smmu_cfg
cfg
;
struct
arm_smmu_cfg
cfg
;
enum
arm_smmu_domain_stage
stage
;
enum
arm_smmu_domain_stage
stage
;
struct
mutex
init_mutex
;
/* Protects smmu pointer */
struct
mutex
init_mutex
;
/* Protects smmu pointer */
spinlock_t
cb_lock
;
/* Serialises ATS1* ops */
spinlock_t
cb_lock
;
/* Serialises ATS1* ops
and TLB syncs
*/
struct
iommu_domain
domain
;
struct
iommu_domain
domain
;
};
};
...
@@ -602,9 +604,12 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
...
@@ -602,9 +604,12 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
static
void
arm_smmu_tlb_sync_global
(
struct
arm_smmu_device
*
smmu
)
static
void
arm_smmu_tlb_sync_global
(
struct
arm_smmu_device
*
smmu
)
{
{
void
__iomem
*
base
=
ARM_SMMU_GR0
(
smmu
);
void
__iomem
*
base
=
ARM_SMMU_GR0
(
smmu
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
smmu
->
global_sync_lock
,
flags
);
__arm_smmu_tlb_sync
(
smmu
,
base
+
ARM_SMMU_GR0_sTLBGSYNC
,
__arm_smmu_tlb_sync
(
smmu
,
base
+
ARM_SMMU_GR0_sTLBGSYNC
,
base
+
ARM_SMMU_GR0_sTLBGSTATUS
);
base
+
ARM_SMMU_GR0_sTLBGSTATUS
);
spin_unlock_irqrestore
(
&
smmu
->
global_sync_lock
,
flags
);
}
}
static
void
arm_smmu_tlb_sync_context
(
void
*
cookie
)
static
void
arm_smmu_tlb_sync_context
(
void
*
cookie
)
...
@@ -612,9 +617,12 @@ static void arm_smmu_tlb_sync_context(void *cookie)
...
@@ -612,9 +617,12 @@ static void arm_smmu_tlb_sync_context(void *cookie)
struct
arm_smmu_domain
*
smmu_domain
=
cookie
;
struct
arm_smmu_domain
*
smmu_domain
=
cookie
;
struct
arm_smmu_device
*
smmu
=
smmu_domain
->
smmu
;
struct
arm_smmu_device
*
smmu
=
smmu_domain
->
smmu
;
void
__iomem
*
base
=
ARM_SMMU_CB
(
smmu
,
smmu_domain
->
cfg
.
cbndx
);
void
__iomem
*
base
=
ARM_SMMU_CB
(
smmu
,
smmu_domain
->
cfg
.
cbndx
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
smmu_domain
->
cb_lock
,
flags
);
__arm_smmu_tlb_sync
(
smmu
,
base
+
ARM_SMMU_CB_TLBSYNC
,
__arm_smmu_tlb_sync
(
smmu
,
base
+
ARM_SMMU_CB_TLBSYNC
,
base
+
ARM_SMMU_CB_TLBSTATUS
);
base
+
ARM_SMMU_CB_TLBSTATUS
);
spin_unlock_irqrestore
(
&
smmu_domain
->
cb_lock
,
flags
);
}
}
static
void
arm_smmu_tlb_sync_vmid
(
void
*
cookie
)
static
void
arm_smmu_tlb_sync_vmid
(
void
*
cookie
)
...
@@ -1511,6 +1519,12 @@ static int arm_smmu_add_device(struct device *dev)
...
@@ -1511,6 +1519,12 @@ static int arm_smmu_add_device(struct device *dev)
if
(
using_legacy_binding
)
{
if
(
using_legacy_binding
)
{
ret
=
arm_smmu_register_legacy_master
(
dev
,
&
smmu
);
ret
=
arm_smmu_register_legacy_master
(
dev
,
&
smmu
);
/*
* If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
* will allocate/initialise a new one. Thus we need to update fwspec for
* later use.
*/
fwspec
=
dev
->
iommu_fwspec
;
fwspec
=
dev
->
iommu_fwspec
;
if
(
ret
)
if
(
ret
)
goto
out_free
;
goto
out_free
;
...
@@ -1550,15 +1564,15 @@ static int arm_smmu_add_device(struct device *dev)
...
@@ -1550,15 +1564,15 @@ static int arm_smmu_add_device(struct device *dev)
ret
=
arm_smmu_master_alloc_smes
(
dev
);
ret
=
arm_smmu_master_alloc_smes
(
dev
);
if
(
ret
)
if
(
ret
)
goto
out_free
;
goto
out_
cfg_
free
;
iommu_device_link
(
&
smmu
->
iommu
,
dev
);
iommu_device_link
(
&
smmu
->
iommu
,
dev
);
return
0
;
return
0
;
out_cfg_free:
kfree
(
cfg
);
out_free:
out_free:
if
(
fwspec
)
kfree
(
fwspec
->
iommu_priv
);
iommu_fwspec_free
(
dev
);
iommu_fwspec_free
(
dev
);
return
ret
;
return
ret
;
}
}
...
@@ -1925,6 +1939,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
...
@@ -1925,6 +1939,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
smmu
->
num_mapping_groups
=
size
;
smmu
->
num_mapping_groups
=
size
;
mutex_init
(
&
smmu
->
stream_map_mutex
);
mutex_init
(
&
smmu
->
stream_map_mutex
);
spin_lock_init
(
&
smmu
->
global_sync_lock
);
if
(
smmu
->
version
<
ARM_SMMU_V2
||
!
(
id
&
ID0_PTFS_NO_AARCH32
))
{
if
(
smmu
->
version
<
ARM_SMMU_V2
||
!
(
id
&
ID0_PTFS_NO_AARCH32
))
{
smmu
->
features
|=
ARM_SMMU_FEAT_FMT_AARCH32_L
;
smmu
->
features
|=
ARM_SMMU_FEAT_FMT_AARCH32_L
;
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/intel-iommu.c
View file @
894901b5
...
@@ -4736,7 +4736,9 @@ static void intel_disable_iommus(void)
...
@@ -4736,7 +4736,9 @@ static void intel_disable_iommus(void)
static
inline
struct
intel_iommu
*
dev_to_intel_iommu
(
struct
device
*
dev
)
static
inline
struct
intel_iommu
*
dev_to_intel_iommu
(
struct
device
*
dev
)
{
{
return
container_of
(
dev
,
struct
intel_iommu
,
iommu
.
dev
);
struct
iommu_device
*
iommu_dev
=
dev_to_iommu_device
(
dev
);
return
container_of
(
iommu_dev
,
struct
intel_iommu
,
iommu
);
}
}
static
ssize_t
intel_iommu_show_version
(
struct
device
*
dev
,
static
ssize_t
intel_iommu_show_version
(
struct
device
*
dev
,
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/io-pgtable-arm-v7s.c
View file @
894901b5
...
@@ -479,6 +479,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
...
@@ -479,6 +479,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
if
(
!
(
prot
&
(
IOMMU_READ
|
IOMMU_WRITE
)))
if
(
!
(
prot
&
(
IOMMU_READ
|
IOMMU_WRITE
)))
return
0
;
return
0
;
if
(
WARN_ON
(
upper_32_bits
(
iova
)
||
upper_32_bits
(
paddr
)))
return
-
ERANGE
;
ret
=
__arm_v7s_map
(
data
,
iova
,
paddr
,
size
,
prot
,
1
,
data
->
pgd
);
ret
=
__arm_v7s_map
(
data
,
iova
,
paddr
,
size
,
prot
,
1
,
data
->
pgd
);
/*
/*
* Synchronise all PTE updates for the new mapping before there's
* Synchronise all PTE updates for the new mapping before there's
...
@@ -659,6 +662,9 @@ static int arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
...
@@ -659,6 +662,9 @@ static int arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
struct
arm_v7s_io_pgtable
*
data
=
io_pgtable_ops_to_data
(
ops
);
struct
arm_v7s_io_pgtable
*
data
=
io_pgtable_ops_to_data
(
ops
);
size_t
unmapped
;
size_t
unmapped
;
if
(
WARN_ON
(
upper_32_bits
(
iova
)))
return
0
;
unmapped
=
__arm_v7s_unmap
(
data
,
iova
,
size
,
1
,
data
->
pgd
);
unmapped
=
__arm_v7s_unmap
(
data
,
iova
,
size
,
1
,
data
->
pgd
);
if
(
unmapped
)
if
(
unmapped
)
io_pgtable_tlb_sync
(
&
data
->
iop
);
io_pgtable_tlb_sync
(
&
data
->
iop
);
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/io-pgtable-arm.c
View file @
894901b5
...
@@ -452,6 +452,10 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
...
@@ -452,6 +452,10 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
if
(
!
(
iommu_prot
&
(
IOMMU_READ
|
IOMMU_WRITE
)))
if
(
!
(
iommu_prot
&
(
IOMMU_READ
|
IOMMU_WRITE
)))
return
0
;
return
0
;
if
(
WARN_ON
(
iova
>=
(
1ULL
<<
data
->
iop
.
cfg
.
ias
)
||
paddr
>=
(
1ULL
<<
data
->
iop
.
cfg
.
oas
)))
return
-
ERANGE
;
prot
=
arm_lpae_prot_to_pte
(
data
,
iommu_prot
);
prot
=
arm_lpae_prot_to_pte
(
data
,
iommu_prot
);
ret
=
__arm_lpae_map
(
data
,
iova
,
paddr
,
size
,
prot
,
lvl
,
ptep
);
ret
=
__arm_lpae_map
(
data
,
iova
,
paddr
,
size
,
prot
,
lvl
,
ptep
);
/*
/*
...
@@ -610,6 +614,9 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
...
@@ -610,6 +614,9 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
arm_lpae_iopte
*
ptep
=
data
->
pgd
;
arm_lpae_iopte
*
ptep
=
data
->
pgd
;
int
lvl
=
ARM_LPAE_START_LVL
(
data
);
int
lvl
=
ARM_LPAE_START_LVL
(
data
);
if
(
WARN_ON
(
iova
>=
(
1ULL
<<
data
->
iop
.
cfg
.
ias
)))
return
0
;
unmapped
=
__arm_lpae_unmap
(
data
,
iova
,
size
,
lvl
,
ptep
);
unmapped
=
__arm_lpae_unmap
(
data
,
iova
,
size
,
lvl
,
ptep
);
if
(
unmapped
)
if
(
unmapped
)
io_pgtable_tlb_sync
(
&
data
->
iop
);
io_pgtable_tlb_sync
(
&
data
->
iop
);
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/io-pgtable.h
View file @
894901b5
...
@@ -158,14 +158,12 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops);
...
@@ -158,14 +158,12 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops);
* @fmt: The page table format.
* @fmt: The page table format.
* @cookie: An opaque token provided by the IOMMU driver and passed back to
* @cookie: An opaque token provided by the IOMMU driver and passed back to
* any callback routines.
* any callback routines.
* @tlb_sync_pending: Private flag for optimising out redundant syncs.
* @cfg: A copy of the page table configuration.
* @cfg: A copy of the page table configuration.
* @ops: The page table operations in use for this set of page tables.
* @ops: The page table operations in use for this set of page tables.
*/
*/
struct
io_pgtable
{
struct
io_pgtable
{
enum
io_pgtable_fmt
fmt
;
enum
io_pgtable_fmt
fmt
;
void
*
cookie
;
void
*
cookie
;
bool
tlb_sync_pending
;
struct
io_pgtable_cfg
cfg
;
struct
io_pgtable_cfg
cfg
;
struct
io_pgtable_ops
ops
;
struct
io_pgtable_ops
ops
;
};
};
...
@@ -175,22 +173,17 @@ struct io_pgtable {
...
@@ -175,22 +173,17 @@ struct io_pgtable {
static
inline
void
io_pgtable_tlb_flush_all
(
struct
io_pgtable
*
iop
)
static
inline
void
io_pgtable_tlb_flush_all
(
struct
io_pgtable
*
iop
)
{
{
iop
->
cfg
.
tlb
->
tlb_flush_all
(
iop
->
cookie
);
iop
->
cfg
.
tlb
->
tlb_flush_all
(
iop
->
cookie
);
iop
->
tlb_sync_pending
=
true
;
}
}
static
inline
void
io_pgtable_tlb_add_flush
(
struct
io_pgtable
*
iop
,
static
inline
void
io_pgtable_tlb_add_flush
(
struct
io_pgtable
*
iop
,
unsigned
long
iova
,
size_t
size
,
size_t
granule
,
bool
leaf
)
unsigned
long
iova
,
size_t
size
,
size_t
granule
,
bool
leaf
)
{
{
iop
->
cfg
.
tlb
->
tlb_add_flush
(
iova
,
size
,
granule
,
leaf
,
iop
->
cookie
);
iop
->
cfg
.
tlb
->
tlb_add_flush
(
iova
,
size
,
granule
,
leaf
,
iop
->
cookie
);
iop
->
tlb_sync_pending
=
true
;
}
}
static
inline
void
io_pgtable_tlb_sync
(
struct
io_pgtable
*
iop
)
static
inline
void
io_pgtable_tlb_sync
(
struct
io_pgtable
*
iop
)
{
{
if
(
iop
->
tlb_sync_pending
)
{
iop
->
cfg
.
tlb
->
tlb_sync
(
iop
->
cookie
);
iop
->
cfg
.
tlb
->
tlb_sync
(
iop
->
cookie
);
iop
->
tlb_sync_pending
=
false
;
}
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/iommu-sysfs.c
View file @
894901b5
...
@@ -62,32 +62,40 @@ int iommu_device_sysfs_add(struct iommu_device *iommu,
...
@@ -62,32 +62,40 @@ int iommu_device_sysfs_add(struct iommu_device *iommu,
va_list
vargs
;
va_list
vargs
;
int
ret
;
int
ret
;
device_initialize
(
&
iommu
->
dev
);
iommu
->
dev
=
kzalloc
(
sizeof
(
*
iommu
->
dev
),
GFP_KERNEL
);
if
(
!
iommu
->
dev
)
return
-
ENOMEM
;
iommu
->
dev
.
class
=
&
iommu_class
;
device_initialize
(
iommu
->
dev
);
iommu
->
dev
.
parent
=
parent
;
iommu
->
dev
.
groups
=
groups
;
iommu
->
dev
->
class
=
&
iommu_class
;
iommu
->
dev
->
parent
=
parent
;
iommu
->
dev
->
groups
=
groups
;
va_start
(
vargs
,
fmt
);
va_start
(
vargs
,
fmt
);
ret
=
kobject_set_name_vargs
(
&
iommu
->
dev
.
kobj
,
fmt
,
vargs
);
ret
=
kobject_set_name_vargs
(
&
iommu
->
dev
->
kobj
,
fmt
,
vargs
);
va_end
(
vargs
);
va_end
(
vargs
);
if
(
ret
)
if
(
ret
)
goto
error
;
goto
error
;
ret
=
device_add
(
&
iommu
->
dev
);
ret
=
device_add
(
iommu
->
dev
);
if
(
ret
)
if
(
ret
)
goto
error
;
goto
error
;
dev_set_drvdata
(
iommu
->
dev
,
iommu
);
return
0
;
return
0
;
error:
error:
put_device
(
&
iommu
->
dev
);
put_device
(
iommu
->
dev
);
return
ret
;
return
ret
;
}
}
void
iommu_device_sysfs_remove
(
struct
iommu_device
*
iommu
)
void
iommu_device_sysfs_remove
(
struct
iommu_device
*
iommu
)
{
{
device_unregister
(
&
iommu
->
dev
);
dev_set_drvdata
(
iommu
->
dev
,
NULL
);
device_unregister
(
iommu
->
dev
);
iommu
->
dev
=
NULL
;
}
}
/*
/*
* IOMMU drivers can indicate a device is managed by a given IOMMU using
* IOMMU drivers can indicate a device is managed by a given IOMMU using
...
@@ -102,14 +110,14 @@ int iommu_device_link(struct iommu_device *iommu, struct device *link)
...
@@ -102,14 +110,14 @@ int iommu_device_link(struct iommu_device *iommu, struct device *link)
if
(
!
iommu
||
IS_ERR
(
iommu
))
if
(
!
iommu
||
IS_ERR
(
iommu
))
return
-
ENODEV
;
return
-
ENODEV
;
ret
=
sysfs_add_link_to_group
(
&
iommu
->
dev
.
kobj
,
"devices"
,
ret
=
sysfs_add_link_to_group
(
&
iommu
->
dev
->
kobj
,
"devices"
,
&
link
->
kobj
,
dev_name
(
link
));
&
link
->
kobj
,
dev_name
(
link
));
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
ret
=
sysfs_create_link_nowarn
(
&
link
->
kobj
,
&
iommu
->
dev
.
kobj
,
"iommu"
);
ret
=
sysfs_create_link_nowarn
(
&
link
->
kobj
,
&
iommu
->
dev
->
kobj
,
"iommu"
);
if
(
ret
)
if
(
ret
)
sysfs_remove_link_from_group
(
&
iommu
->
dev
.
kobj
,
"devices"
,
sysfs_remove_link_from_group
(
&
iommu
->
dev
->
kobj
,
"devices"
,
dev_name
(
link
));
dev_name
(
link
));
return
ret
;
return
ret
;
...
@@ -121,5 +129,5 @@ void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
...
@@ -121,5 +129,5 @@ void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
return
;
return
;
sysfs_remove_link
(
&
link
->
kobj
,
"iommu"
);
sysfs_remove_link
(
&
link
->
kobj
,
"iommu"
);
sysfs_remove_link_from_group
(
&
iommu
->
dev
.
kobj
,
"devices"
,
dev_name
(
link
));
sysfs_remove_link_from_group
(
&
iommu
->
dev
->
kobj
,
"devices"
,
dev_name
(
link
));
}
}
This diff is collapsed.
Click to expand it.
drivers/iommu/mtk_iommu.c
View file @
894901b5
...
@@ -129,6 +129,7 @@ static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size,
...
@@ -129,6 +129,7 @@ static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size,
writel_relaxed
(
iova
,
data
->
base
+
REG_MMU_INVLD_START_A
);
writel_relaxed
(
iova
,
data
->
base
+
REG_MMU_INVLD_START_A
);
writel_relaxed
(
iova
+
size
-
1
,
data
->
base
+
REG_MMU_INVLD_END_A
);
writel_relaxed
(
iova
+
size
-
1
,
data
->
base
+
REG_MMU_INVLD_END_A
);
writel_relaxed
(
F_MMU_INV_RANGE
,
data
->
base
+
REG_MMU_INVALIDATE
);
writel_relaxed
(
F_MMU_INV_RANGE
,
data
->
base
+
REG_MMU_INVALIDATE
);
data
->
tlb_flush_active
=
true
;
}
}
static
void
mtk_iommu_tlb_sync
(
void
*
cookie
)
static
void
mtk_iommu_tlb_sync
(
void
*
cookie
)
...
@@ -137,6 +138,10 @@ static void mtk_iommu_tlb_sync(void *cookie)
...
@@ -137,6 +138,10 @@ static void mtk_iommu_tlb_sync(void *cookie)
int
ret
;
int
ret
;
u32
tmp
;
u32
tmp
;
/* Avoid timing out if there's nothing to wait for */
if
(
!
data
->
tlb_flush_active
)
return
;
ret
=
readl_poll_timeout_atomic
(
data
->
base
+
REG_MMU_CPE_DONE
,
tmp
,
ret
=
readl_poll_timeout_atomic
(
data
->
base
+
REG_MMU_CPE_DONE
,
tmp
,
tmp
!=
0
,
10
,
100000
);
tmp
!=
0
,
10
,
100000
);
if
(
ret
)
{
if
(
ret
)
{
...
@@ -146,6 +151,7 @@ static void mtk_iommu_tlb_sync(void *cookie)
...
@@ -146,6 +151,7 @@ static void mtk_iommu_tlb_sync(void *cookie)
}
}
/* Clear the CPE status */
/* Clear the CPE status */
writel_relaxed
(
0
,
data
->
base
+
REG_MMU_CPE_DONE
);
writel_relaxed
(
0
,
data
->
base
+
REG_MMU_CPE_DONE
);
data
->
tlb_flush_active
=
false
;
}
}
static
const
struct
iommu_gather_ops
mtk_iommu_gather_ops
=
{
static
const
struct
iommu_gather_ops
mtk_iommu_gather_ops
=
{
...
...
This diff is collapsed.
Click to expand it.
drivers/iommu/mtk_iommu.h
View file @
894901b5
...
@@ -47,6 +47,7 @@ struct mtk_iommu_data {
...
@@ -47,6 +47,7 @@ struct mtk_iommu_data {
struct
iommu_group
*
m4u_group
;
struct
iommu_group
*
m4u_group
;
struct
mtk_smi_iommu
smi_imu
;
/* SMI larb iommu info */
struct
mtk_smi_iommu
smi_imu
;
/* SMI larb iommu info */
bool
enable_4GB
;
bool
enable_4GB
;
bool
tlb_flush_active
;
struct
iommu_device
iommu
;
struct
iommu_device
iommu
;
};
};
...
...
This diff is collapsed.
Click to expand it.
include/linux/iommu.h
View file @
894901b5
...
@@ -240,7 +240,7 @@ struct iommu_device {
...
@@ -240,7 +240,7 @@ struct iommu_device {
struct
list_head
list
;
struct
list_head
list
;
const
struct
iommu_ops
*
ops
;
const
struct
iommu_ops
*
ops
;
struct
fwnode_handle
*
fwnode
;
struct
fwnode_handle
*
fwnode
;
struct
device
dev
;
struct
device
*
dev
;
};
};
int
iommu_device_register
(
struct
iommu_device
*
iommu
);
int
iommu_device_register
(
struct
iommu_device
*
iommu
);
...
@@ -265,6 +265,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
...
@@ -265,6 +265,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
iommu
->
fwnode
=
fwnode
;
iommu
->
fwnode
=
fwnode
;
}
}
static
inline
struct
iommu_device
*
dev_to_iommu_device
(
struct
device
*
dev
)
{
return
(
struct
iommu_device
*
)
dev_get_drvdata
(
dev
);
}
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1
/* Device added */
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1
/* Device added */
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2
/* Pre Device removed */
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2
/* Pre Device removed */
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3
/* Pre Driver bind */
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3
/* Pre Driver bind */
...
@@ -589,6 +594,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
...
@@ -589,6 +594,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
{
{
}
}
static
inline
struct
iommu_device
*
dev_to_iommu_device
(
struct
device
*
dev
)
{
return
NULL
;
}
static
inline
void
iommu_device_unregister
(
struct
iommu_device
*
iommu
)
static
inline
void
iommu_device_unregister
(
struct
iommu_device
*
iommu
)
{
{
}
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment