summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig1
-rw-r--r--drivers/acpi/nfit.c55
-rw-r--r--drivers/acpi/nfit.h16
3 files changed, 43 insertions, 29 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 114cf48085ab..4baeb853e0c3 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -410,6 +410,7 @@ config ACPI_NFIT
410 tristate "ACPI NVDIMM Firmware Interface Table (NFIT)" 410 tristate "ACPI NVDIMM Firmware Interface Table (NFIT)"
411 depends on PHYS_ADDR_T_64BIT 411 depends on PHYS_ADDR_T_64BIT
412 depends on BLK_DEV 412 depends on BLK_DEV
413 depends on ARCH_HAS_MMIO_FLUSH
413 select LIBNVDIMM 414 select LIBNVDIMM
414 help 415 help
415 Infrastructure to probe ACPI 6 compliant platforms for 416 Infrastructure to probe ACPI 6 compliant platforms for
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index 7c2638f914a9..56fff0141636 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -1017,7 +1017,7 @@ static u64 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw)
1017 if (mmio->num_lines) 1017 if (mmio->num_lines)
1018 offset = to_interleave_offset(offset, mmio); 1018 offset = to_interleave_offset(offset, mmio);
1019 1019
1020 return readq(mmio->base + offset); 1020 return readq(mmio->addr.base + offset);
1021} 1021}
1022 1022
1023static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw, 1023static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
@@ -1042,11 +1042,11 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
1042 if (mmio->num_lines) 1042 if (mmio->num_lines)
1043 offset = to_interleave_offset(offset, mmio); 1043 offset = to_interleave_offset(offset, mmio);
1044 1044
1045 writeq(cmd, mmio->base + offset); 1045 writeq(cmd, mmio->addr.base + offset);
1046 wmb_blk(nfit_blk); 1046 wmb_blk(nfit_blk);
1047 1047
1048 if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH) 1048 if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH)
1049 readq(mmio->base + offset); 1049 readq(mmio->addr.base + offset);
1050} 1050}
1051 1051
1052static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk, 1052static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
@@ -1078,11 +1078,16 @@ static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
1078 } 1078 }
1079 1079
1080 if (rw) 1080 if (rw)
1081 memcpy_to_pmem(mmio->aperture + offset, 1081 memcpy_to_pmem(mmio->addr.aperture + offset,
1082 iobuf + copied, c); 1082 iobuf + copied, c);
1083 else 1083 else {
1084 if (nfit_blk->dimm_flags & ND_BLK_READ_FLUSH)
1085 mmio_flush_range((void __force *)
1086 mmio->addr.aperture + offset, c);
1087
1084 memcpy_from_pmem(iobuf + copied, 1088 memcpy_from_pmem(iobuf + copied,
1085 mmio->aperture + offset, c); 1089 mmio->addr.aperture + offset, c);
1090 }
1086 1091
1087 copied += c; 1092 copied += c;
1088 len -= c; 1093 len -= c;
@@ -1129,7 +1134,10 @@ static void nfit_spa_mapping_release(struct kref *kref)
1129 1134
1130 WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex)); 1135 WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex));
1131 dev_dbg(acpi_desc->dev, "%s: SPA%d\n", __func__, spa->range_index); 1136 dev_dbg(acpi_desc->dev, "%s: SPA%d\n", __func__, spa->range_index);
1132 iounmap(spa_map->iomem); 1137 if (spa_map->type == SPA_MAP_APERTURE)
1138 memunmap((void __force *)spa_map->addr.aperture);
1139 else
1140 iounmap(spa_map->addr.base);
1133 release_mem_region(spa->address, spa->length); 1141 release_mem_region(spa->address, spa->length);
1134 list_del(&spa_map->list); 1142 list_del(&spa_map->list);
1135 kfree(spa_map); 1143 kfree(spa_map);
@@ -1175,7 +1183,7 @@ static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc,
1175 spa_map = find_spa_mapping(acpi_desc, spa); 1183 spa_map = find_spa_mapping(acpi_desc, spa);
1176 if (spa_map) { 1184 if (spa_map) {
1177 kref_get(&spa_map->kref); 1185 kref_get(&spa_map->kref);
1178 return spa_map->iomem; 1186 return spa_map->addr.base;
1179 } 1187 }
1180 1188
1181 spa_map = kzalloc(sizeof(*spa_map), GFP_KERNEL); 1189 spa_map = kzalloc(sizeof(*spa_map), GFP_KERNEL);
@@ -1191,20 +1199,19 @@ static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc,
1191 if (!res) 1199 if (!res)
1192 goto err_mem; 1200 goto err_mem;
1193 1201
1194 if (type == SPA_MAP_APERTURE) { 1202 spa_map->type = type;
1195 /* 1203 if (type == SPA_MAP_APERTURE)
1196 * TODO: memremap_pmem() support, but that requires cache 1204 spa_map->addr.aperture = (void __pmem *)memremap(start, n,
1197 * flushing when the aperture is moved. 1205 ARCH_MEMREMAP_PMEM);
1198 */ 1206 else
1199 spa_map->iomem = ioremap_wc(start, n); 1207 spa_map->addr.base = ioremap_nocache(start, n);
1200 } else 1208
1201 spa_map->iomem = ioremap_nocache(start, n);
1202 1209
1203 if (!spa_map->iomem) 1210 if (!spa_map->addr.base)
1204 goto err_map; 1211 goto err_map;
1205 1212
1206 list_add_tail(&spa_map->list, &acpi_desc->spa_maps); 1213 list_add_tail(&spa_map->list, &acpi_desc->spa_maps);
1207 return spa_map->iomem; 1214 return spa_map->addr.base;
1208 1215
1209 err_map: 1216 err_map:
1210 release_mem_region(start, n); 1217 release_mem_region(start, n);
@@ -1267,7 +1274,7 @@ static int acpi_nfit_blk_get_flags(struct nvdimm_bus_descriptor *nd_desc,
1267 nfit_blk->dimm_flags = flags.flags; 1274 nfit_blk->dimm_flags = flags.flags;
1268 else if (rc == -ENOTTY) { 1275 else if (rc == -ENOTTY) {
1269 /* fall back to a conservative default */ 1276 /* fall back to a conservative default */
1270 nfit_blk->dimm_flags = ND_BLK_DCR_LATCH; 1277 nfit_blk->dimm_flags = ND_BLK_DCR_LATCH | ND_BLK_READ_FLUSH;
1271 rc = 0; 1278 rc = 0;
1272 } else 1279 } else
1273 rc = -ENXIO; 1280 rc = -ENXIO;
@@ -1307,9 +1314,9 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus,
1307 /* map block aperture memory */ 1314 /* map block aperture memory */
1308 nfit_blk->bdw_offset = nfit_mem->bdw->offset; 1315 nfit_blk->bdw_offset = nfit_mem->bdw->offset;
1309 mmio = &nfit_blk->mmio[BDW]; 1316 mmio = &nfit_blk->mmio[BDW];
1310 mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw, 1317 mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw,
1311 SPA_MAP_APERTURE); 1318 SPA_MAP_APERTURE);
1312 if (!mmio->base) { 1319 if (!mmio->addr.base) {
1313 dev_dbg(dev, "%s: %s failed to map bdw\n", __func__, 1320 dev_dbg(dev, "%s: %s failed to map bdw\n", __func__,
1314 nvdimm_name(nvdimm)); 1321 nvdimm_name(nvdimm));
1315 return -ENOMEM; 1322 return -ENOMEM;
@@ -1330,9 +1337,9 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus,
1330 nfit_blk->cmd_offset = nfit_mem->dcr->command_offset; 1337 nfit_blk->cmd_offset = nfit_mem->dcr->command_offset;
1331 nfit_blk->stat_offset = nfit_mem->dcr->status_offset; 1338 nfit_blk->stat_offset = nfit_mem->dcr->status_offset;
1332 mmio = &nfit_blk->mmio[DCR]; 1339 mmio = &nfit_blk->mmio[DCR];
1333 mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr, 1340 mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr,
1334 SPA_MAP_CONTROL); 1341 SPA_MAP_CONTROL);
1335 if (!mmio->base) { 1342 if (!mmio->addr.base) {
1336 dev_dbg(dev, "%s: %s failed to map dcr\n", __func__, 1343 dev_dbg(dev, "%s: %s failed to map dcr\n", __func__,
1337 nvdimm_name(nvdimm)); 1344 nvdimm_name(nvdimm));
1338 return -ENOMEM; 1345 return -ENOMEM;
@@ -1399,7 +1406,7 @@ static void acpi_nfit_blk_region_disable(struct nvdimm_bus *nvdimm_bus,
1399 for (i = 0; i < 2; i++) { 1406 for (i = 0; i < 2; i++) {
1400 struct nfit_blk_mmio *mmio = &nfit_blk->mmio[i]; 1407 struct nfit_blk_mmio *mmio = &nfit_blk->mmio[i];
1401 1408
1402 if (mmio->base) 1409 if (mmio->addr.base)
1403 nfit_spa_unmap(acpi_desc, mmio->spa); 1410 nfit_spa_unmap(acpi_desc, mmio->spa);
1404 } 1411 }
1405 nd_blk_region_set_provider_data(ndbr, NULL); 1412 nd_blk_region_set_provider_data(ndbr, NULL);
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index f2c2bb751882..7e740156b9c2 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -41,6 +41,7 @@ enum nfit_uuids {
41}; 41};
42 42
43enum { 43enum {
44 ND_BLK_READ_FLUSH = 1,
44 ND_BLK_DCR_LATCH = 2, 45 ND_BLK_DCR_LATCH = 2,
45}; 46};
46 47
@@ -117,12 +118,16 @@ enum nd_blk_mmio_selector {
117 DCR, 118 DCR,
118}; 119};
119 120
121struct nd_blk_addr {
122 union {
123 void __iomem *base;
124 void __pmem *aperture;
125 };
126};
127
120struct nfit_blk { 128struct nfit_blk {
121 struct nfit_blk_mmio { 129 struct nfit_blk_mmio {
122 union { 130 struct nd_blk_addr addr;
123 void __iomem *base;
124 void __pmem *aperture;
125 };
126 u64 size; 131 u64 size;
127 u64 base_offset; 132 u64 base_offset;
128 u32 line_size; 133 u32 line_size;
@@ -149,7 +154,8 @@ struct nfit_spa_mapping {
149 struct acpi_nfit_system_address *spa; 154 struct acpi_nfit_system_address *spa;
150 struct list_head list; 155 struct list_head list;
151 struct kref kref; 156 struct kref kref;
152 void __iomem *iomem; 157 enum spa_map_type type;
158 struct nd_blk_addr addr;
153}; 159};
154 160
155static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref) 161static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref)