diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-07-27 08:29:36 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2015-08-13 10:06:40 -0400 |
commit | 4b3c7d10765403ab19628fb7d530b8ce1c50b81d (patch) | |
tree | d0dff12de7f9a34aa2b86479cc6d0180b6d7d642 | |
parent | 32924c76b0cbc67aa4cf0741f7bc6c37f097aaf3 (diff) |
iommu/tegra-smmu: Move flush_dcache to tegra-smmu.c
Drivers should not be using __cpuc_* functions nor outer_cache_flush()
directly. This change partly cleans up tegra-smmu.c.
The only difference between cache handling of the tegra variants is
Denver, which omits the call to outer_cache_flush(). This is due to
Denver being an ARM64 CPU, and the ARM64 architecture does not provide
this function. (This, in itself, is a good reason why these should not
be used.)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
[treding@nvidia.com: fix build failure on 64-bit ARM]
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | drivers/iommu/tegra-smmu.c | 30 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra114.c | 17 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra124.c | 30 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra30.c | 17 | ||||
-rw-r--r-- | include/soc/tegra/mc.h | 7 |
5 files changed, 25 insertions, 76 deletions
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index d649b06cc4ca..42b13c07aeef 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | #include <asm/cacheflush.h> | ||
20 | |||
19 | #include <soc/tegra/ahb.h> | 21 | #include <soc/tegra/ahb.h> |
20 | #include <soc/tegra/mc.h> | 22 | #include <soc/tegra/mc.h> |
21 | 23 | ||
@@ -145,6 +147,24 @@ static unsigned int iova_pt_index(unsigned long iova) | |||
145 | return (iova >> SMMU_PTE_SHIFT) & (SMMU_NUM_PTE - 1); | 147 | return (iova >> SMMU_PTE_SHIFT) & (SMMU_NUM_PTE - 1); |
146 | } | 148 | } |
147 | 149 | ||
150 | static void smmu_flush_dcache(struct page *page, unsigned long offset, | ||
151 | size_t size) | ||
152 | { | ||
153 | #ifdef CONFIG_ARM | ||
154 | phys_addr_t phys = page_to_phys(page) + offset; | ||
155 | #endif | ||
156 | void *virt = page_address(page) + offset; | ||
157 | |||
158 | #ifdef CONFIG_ARM | ||
159 | __cpuc_flush_dcache_area(virt, size); | ||
160 | outer_flush_range(phys, phys + size); | ||
161 | #endif | ||
162 | |||
163 | #ifdef CONFIG_ARM64 | ||
164 | __flush_dcache_area(virt, size); | ||
165 | #endif | ||
166 | } | ||
167 | |||
148 | static inline void smmu_flush_ptc(struct tegra_smmu *smmu, struct page *page, | 168 | static inline void smmu_flush_ptc(struct tegra_smmu *smmu, struct page *page, |
149 | unsigned long offset) | 169 | unsigned long offset) |
150 | { | 170 | { |
@@ -392,7 +412,7 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu, | |||
392 | if (err < 0) | 412 | if (err < 0) |
393 | return err; | 413 | return err; |
394 | 414 | ||
395 | smmu->soc->ops->flush_dcache(as->pd, 0, SMMU_SIZE_PD); | 415 | smmu_flush_dcache(as->pd, 0, SMMU_SIZE_PD); |
396 | smmu_flush_ptc(smmu, as->pd, 0); | 416 | smmu_flush_ptc(smmu, as->pd, 0); |
397 | smmu_flush_tlb_asid(smmu, as->id); | 417 | smmu_flush_tlb_asid(smmu, as->id); |
398 | 418 | ||
@@ -521,11 +541,11 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, | |||
521 | 541 | ||
522 | as->pts[pde] = page; | 542 | as->pts[pde] = page; |
523 | 543 | ||
524 | smmu->soc->ops->flush_dcache(page, 0, SMMU_SIZE_PT); | 544 | smmu_flush_dcache(page, 0, SMMU_SIZE_PT); |
525 | 545 | ||
526 | pd[pde] = SMMU_MK_PDE(page, SMMU_PDE_ATTR | SMMU_PDE_NEXT); | 546 | pd[pde] = SMMU_MK_PDE(page, SMMU_PDE_ATTR | SMMU_PDE_NEXT); |
527 | 547 | ||
528 | smmu->soc->ops->flush_dcache(as->pd, pde << 2, 4); | 548 | smmu_flush_dcache(as->pd, pde << 2, 4); |
529 | smmu_flush_ptc(smmu, as->pd, pde << 2); | 549 | smmu_flush_ptc(smmu, as->pd, pde << 2); |
530 | smmu_flush_tlb_section(smmu, as->id, iova); | 550 | smmu_flush_tlb_section(smmu, as->id, iova); |
531 | smmu_flush(smmu); | 551 | smmu_flush(smmu); |
@@ -562,7 +582,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) | |||
562 | pd[pde] = 0; | 582 | pd[pde] = 0; |
563 | 583 | ||
564 | /* Flush the page directory entry */ | 584 | /* Flush the page directory entry */ |
565 | smmu->soc->ops->flush_dcache(as->pd, offset, sizeof(*pd)); | 585 | smmu_flush_dcache(as->pd, offset, sizeof(*pd)); |
566 | smmu_flush_ptc(smmu, as->pd, offset); | 586 | smmu_flush_ptc(smmu, as->pd, offset); |
567 | smmu_flush_tlb_section(smmu, as->id, iova); | 587 | smmu_flush_tlb_section(smmu, as->id, iova); |
568 | smmu_flush(smmu); | 588 | smmu_flush(smmu); |
@@ -582,7 +602,7 @@ static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova, | |||
582 | 602 | ||
583 | *pte = val; | 603 | *pte = val; |
584 | 604 | ||
585 | smmu->soc->ops->flush_dcache(pte_page, offset, 4); | 605 | smmu_flush_dcache(pte_page, offset, 4); |
586 | smmu_flush_ptc(smmu, pte_page, offset); | 606 | smmu_flush_ptc(smmu, pte_page, offset); |
587 | smmu_flush_tlb_group(smmu, as->id, iova); | 607 | smmu_flush_tlb_group(smmu, as->id, iova); |
588 | smmu_flush(smmu); | 608 | smmu_flush(smmu); |
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c index 9f579589e800..7122f39be9cc 100644 --- a/drivers/memory/tegra/tegra114.c +++ b/drivers/memory/tegra/tegra114.c | |||
@@ -9,8 +9,6 @@ | |||
9 | #include <linux/of.h> | 9 | #include <linux/of.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | 11 | ||
12 | #include <asm/cacheflush.h> | ||
13 | |||
14 | #include <dt-bindings/memory/tegra114-mc.h> | 12 | #include <dt-bindings/memory/tegra114-mc.h> |
15 | 13 | ||
16 | #include "mc.h" | 14 | #include "mc.h" |
@@ -914,20 +912,6 @@ static const struct tegra_smmu_swgroup tegra114_swgroups[] = { | |||
914 | { .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 }, | 912 | { .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 }, |
915 | }; | 913 | }; |
916 | 914 | ||
917 | static void tegra114_flush_dcache(struct page *page, unsigned long offset, | ||
918 | size_t size) | ||
919 | { | ||
920 | phys_addr_t phys = page_to_phys(page) + offset; | ||
921 | void *virt = page_address(page) + offset; | ||
922 | |||
923 | __cpuc_flush_dcache_area(virt, size); | ||
924 | outer_flush_range(phys, phys + size); | ||
925 | } | ||
926 | |||
927 | static const struct tegra_smmu_ops tegra114_smmu_ops = { | ||
928 | .flush_dcache = tegra114_flush_dcache, | ||
929 | }; | ||
930 | |||
931 | static const struct tegra_smmu_soc tegra114_smmu_soc = { | 915 | static const struct tegra_smmu_soc tegra114_smmu_soc = { |
932 | .clients = tegra114_mc_clients, | 916 | .clients = tegra114_mc_clients, |
933 | .num_clients = ARRAY_SIZE(tegra114_mc_clients), | 917 | .num_clients = ARRAY_SIZE(tegra114_mc_clients), |
@@ -936,7 +920,6 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = { | |||
936 | .supports_round_robin_arbitration = false, | 920 | .supports_round_robin_arbitration = false, |
937 | .supports_request_limit = false, | 921 | .supports_request_limit = false, |
938 | .num_asids = 4, | 922 | .num_asids = 4, |
939 | .ops = &tegra114_smmu_ops, | ||
940 | }; | 923 | }; |
941 | 924 | ||
942 | const struct tegra_mc_soc tegra114_mc_soc = { | 925 | const struct tegra_mc_soc tegra114_mc_soc = { |
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c index 966e1557e6f4..ebda63283853 100644 --- a/drivers/memory/tegra/tegra124.c +++ b/drivers/memory/tegra/tegra124.c | |||
@@ -9,8 +9,6 @@ | |||
9 | #include <linux/of.h> | 9 | #include <linux/of.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | 11 | ||
12 | #include <asm/cacheflush.h> | ||
13 | |||
14 | #include <dt-bindings/memory/tegra124-mc.h> | 12 | #include <dt-bindings/memory/tegra124-mc.h> |
15 | 13 | ||
16 | #include "mc.h" | 14 | #include "mc.h" |
@@ -1002,20 +1000,6 @@ static const struct tegra_smmu_swgroup tegra124_swgroups[] = { | |||
1002 | }; | 1000 | }; |
1003 | 1001 | ||
1004 | #ifdef CONFIG_ARCH_TEGRA_124_SOC | 1002 | #ifdef CONFIG_ARCH_TEGRA_124_SOC |
1005 | static void tegra124_flush_dcache(struct page *page, unsigned long offset, | ||
1006 | size_t size) | ||
1007 | { | ||
1008 | phys_addr_t phys = page_to_phys(page) + offset; | ||
1009 | void *virt = page_address(page) + offset; | ||
1010 | |||
1011 | __cpuc_flush_dcache_area(virt, size); | ||
1012 | outer_flush_range(phys, phys + size); | ||
1013 | } | ||
1014 | |||
1015 | static const struct tegra_smmu_ops tegra124_smmu_ops = { | ||
1016 | .flush_dcache = tegra124_flush_dcache, | ||
1017 | }; | ||
1018 | |||
1019 | static const struct tegra_smmu_soc tegra124_smmu_soc = { | 1003 | static const struct tegra_smmu_soc tegra124_smmu_soc = { |
1020 | .clients = tegra124_mc_clients, | 1004 | .clients = tegra124_mc_clients, |
1021 | .num_clients = ARRAY_SIZE(tegra124_mc_clients), | 1005 | .num_clients = ARRAY_SIZE(tegra124_mc_clients), |
@@ -1024,7 +1008,6 @@ static const struct tegra_smmu_soc tegra124_smmu_soc = { | |||
1024 | .supports_round_robin_arbitration = true, | 1008 | .supports_round_robin_arbitration = true, |
1025 | .supports_request_limit = true, | 1009 | .supports_request_limit = true, |
1026 | .num_asids = 128, | 1010 | .num_asids = 128, |
1027 | .ops = &tegra124_smmu_ops, | ||
1028 | }; | 1011 | }; |
1029 | 1012 | ||
1030 | const struct tegra_mc_soc tegra124_mc_soc = { | 1013 | const struct tegra_mc_soc tegra124_mc_soc = { |
@@ -1039,18 +1022,6 @@ const struct tegra_mc_soc tegra124_mc_soc = { | |||
1039 | #endif /* CONFIG_ARCH_TEGRA_124_SOC */ | 1022 | #endif /* CONFIG_ARCH_TEGRA_124_SOC */ |
1040 | 1023 | ||
1041 | #ifdef CONFIG_ARCH_TEGRA_132_SOC | 1024 | #ifdef CONFIG_ARCH_TEGRA_132_SOC |
1042 | static void tegra132_flush_dcache(struct page *page, unsigned long offset, | ||
1043 | size_t size) | ||
1044 | { | ||
1045 | void *virt = page_address(page) + offset; | ||
1046 | |||
1047 | __flush_dcache_area(virt, size); | ||
1048 | } | ||
1049 | |||
1050 | static const struct tegra_smmu_ops tegra132_smmu_ops = { | ||
1051 | .flush_dcache = tegra132_flush_dcache, | ||
1052 | }; | ||
1053 | |||
1054 | static const struct tegra_smmu_soc tegra132_smmu_soc = { | 1025 | static const struct tegra_smmu_soc tegra132_smmu_soc = { |
1055 | .clients = tegra124_mc_clients, | 1026 | .clients = tegra124_mc_clients, |
1056 | .num_clients = ARRAY_SIZE(tegra124_mc_clients), | 1027 | .num_clients = ARRAY_SIZE(tegra124_mc_clients), |
@@ -1059,7 +1030,6 @@ static const struct tegra_smmu_soc tegra132_smmu_soc = { | |||
1059 | .supports_round_robin_arbitration = true, | 1030 | .supports_round_robin_arbitration = true, |
1060 | .supports_request_limit = true, | 1031 | .supports_request_limit = true, |
1061 | .num_asids = 128, | 1032 | .num_asids = 128, |
1062 | .ops = &tegra132_smmu_ops, | ||
1063 | }; | 1033 | }; |
1064 | 1034 | ||
1065 | const struct tegra_mc_soc tegra132_mc_soc = { | 1035 | const struct tegra_mc_soc tegra132_mc_soc = { |
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c index 1abcd8f6f3ba..3cb30b69d95b 100644 --- a/drivers/memory/tegra/tegra30.c +++ b/drivers/memory/tegra/tegra30.c | |||
@@ -9,8 +9,6 @@ | |||
9 | #include <linux/of.h> | 9 | #include <linux/of.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | 11 | ||
12 | #include <asm/cacheflush.h> | ||
13 | |||
14 | #include <dt-bindings/memory/tegra30-mc.h> | 12 | #include <dt-bindings/memory/tegra30-mc.h> |
15 | 13 | ||
16 | #include "mc.h" | 14 | #include "mc.h" |
@@ -936,20 +934,6 @@ static const struct tegra_smmu_swgroup tegra30_swgroups[] = { | |||
936 | { .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 }, | 934 | { .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 }, |
937 | }; | 935 | }; |
938 | 936 | ||
939 | static void tegra30_flush_dcache(struct page *page, unsigned long offset, | ||
940 | size_t size) | ||
941 | { | ||
942 | phys_addr_t phys = page_to_phys(page) + offset; | ||
943 | void *virt = page_address(page) + offset; | ||
944 | |||
945 | __cpuc_flush_dcache_area(virt, size); | ||
946 | outer_flush_range(phys, phys + size); | ||
947 | } | ||
948 | |||
949 | static const struct tegra_smmu_ops tegra30_smmu_ops = { | ||
950 | .flush_dcache = tegra30_flush_dcache, | ||
951 | }; | ||
952 | |||
953 | static const struct tegra_smmu_soc tegra30_smmu_soc = { | 937 | static const struct tegra_smmu_soc tegra30_smmu_soc = { |
954 | .clients = tegra30_mc_clients, | 938 | .clients = tegra30_mc_clients, |
955 | .num_clients = ARRAY_SIZE(tegra30_mc_clients), | 939 | .num_clients = ARRAY_SIZE(tegra30_mc_clients), |
@@ -958,7 +942,6 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = { | |||
958 | .supports_round_robin_arbitration = false, | 942 | .supports_round_robin_arbitration = false, |
959 | .supports_request_limit = false, | 943 | .supports_request_limit = false, |
960 | .num_asids = 4, | 944 | .num_asids = 4, |
961 | .ops = &tegra30_smmu_ops, | ||
962 | }; | 945 | }; |
963 | 946 | ||
964 | const struct tegra_mc_soc tegra30_mc_soc = { | 947 | const struct tegra_mc_soc tegra30_mc_soc = { |
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 1ab2813273cd..d6c3190ec852 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h | |||
@@ -51,11 +51,6 @@ struct tegra_smmu_swgroup { | |||
51 | unsigned int reg; | 51 | unsigned int reg; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct tegra_smmu_ops { | ||
55 | void (*flush_dcache)(struct page *page, unsigned long offset, | ||
56 | size_t size); | ||
57 | }; | ||
58 | |||
59 | struct tegra_smmu_soc { | 54 | struct tegra_smmu_soc { |
60 | const struct tegra_mc_client *clients; | 55 | const struct tegra_mc_client *clients; |
61 | unsigned int num_clients; | 56 | unsigned int num_clients; |
@@ -67,8 +62,6 @@ struct tegra_smmu_soc { | |||
67 | bool supports_request_limit; | 62 | bool supports_request_limit; |
68 | 63 | ||
69 | unsigned int num_asids; | 64 | unsigned int num_asids; |
70 | |||
71 | const struct tegra_smmu_ops *ops; | ||
72 | }; | 65 | }; |
73 | 66 | ||
74 | struct tegra_mc; | 67 | struct tegra_mc; |