mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 04:01:48 -04:00
libnvdimm for 4.3:
1/ Introduce ZONE_DEVICE and devm_memremap_pages() as a generic
mechanism for adding device-driver-discovered memory regions to the
kernel's direct map. This facility is used by the pmem driver to
enable pfn_to_page() operations on the page frames returned by DAX
('direct_access' in 'struct block_device_operations'). For now, the
'memmap' allocation for these "device" pages comes from "System
RAM". Support for allocating the memmap from device memory will
arrive in a later kernel.
2/ Introduce memremap() to replace usages of ioremap_cache() and
ioremap_wt(). memremap() drops the __iomem annotation for these
mappings to memory that do not have i/o side effects. The
replacement of ioremap_cache() with memremap() is limited to the
pmem driver to ease merging the api change in v4.3. Completion of
the conversion is targeted for v4.4.
3/ Similar to the usage of memcpy_to_pmem() + wmb_pmem() in the pmem
driver, update the VFS DAX implementation and PMEM api to provide
persistence guarantees for kernel operations on a DAX mapping.
4/ Convert the ACPI NFIT 'BLK' driver to map the block apertures as
cacheable to improve performance.
5/ Miscellaneous updates and fixes to libnvdimm including support
for issuing "address range scrub" commands, clarifying the optimal
'sector size' of pmem devices, a clarification of the usage of the
ACPI '_STA' (status) property for DIMM devices, and other minor
fixes.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJV6Nx7AAoJEB7SkWpmfYgCWyYQAI5ju6Gvw27RNFtPovHcZUf5
JGnxXejI6/AqeTQ+IulgprxtEUCrXOHjCDA5dkjr1qvsoqK1qxug+vJHOZLgeW0R
OwDtmdW4Qrgeqm+CPoxETkorJ8wDOc8mol81kTiMgeV3UqbYeeHIiTAmwe7VzZ0C
nNdCRDm5g8dHCjTKcvK3rvozgyoNoWeBiHkPe76EbnxDICxCB5dak7XsVKNMIVFQ
NuYlnw6IYN7+rMHgpgpRux38NtIW8VlYPWTmHExejc2mlioWMNBG/bmtwLyJ6M3e
zliz4/cnonTMUaizZaVozyinTa65m7wcnpjK+vlyGV2deDZPJpDRvSOtB0lH30bR
1gy+qrKzuGKpaN6thOISxFLLjmEeYwzYd7SvC9n118r32qShz+opN9XX0WmWSFlA
sajE1ehm4M7s5pkMoa/dRnAyR8RUPu4RNINdQ/Z9jFfAOx+Q26rLdQXwf9+uqbEb
bIeSQwOteK5vYYCstvpAcHSMlJAglzIX5UfZBvtEIJN7rlb0VhmGWfxAnTu+ktG1
o9cqAt+J4146xHaFwj5duTsyKhWb8BL9+xqbKPNpXEp+PbLsrnE/+WkDLFD67jxz
dgIoK60mGnVXp+16I2uMqYYDgAyO5zUdmM4OygOMnZNa1mxesjbDJC6Wat1Wsndn
slsw6DkrWT60CRE42nbK
=o57/
-----END PGP SIGNATURE-----
Merge tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams:
"This update has successfully completed a 0day-kbuild run and has
appeared in a linux-next release. The changes outside of the typical
drivers/nvdimm/ and drivers/acpi/nfit.[ch] paths are related to the
removal of IORESOURCE_CACHEABLE, the introduction of memremap(), and
the introduction of ZONE_DEVICE + devm_memremap_pages().
Summary:
- Introduce ZONE_DEVICE and devm_memremap_pages() as a generic
mechanism for adding device-driver-discovered memory regions to the
kernel's direct map.
This facility is used by the pmem driver to enable pfn_to_page()
operations on the page frames returned by DAX ('direct_access' in
'struct block_device_operations').
For now, the 'memmap' allocation for these "device" pages comes
from "System RAM". Support for allocating the memmap from device
memory will arrive in a later kernel.
- Introduce memremap() to replace usages of ioremap_cache() and
ioremap_wt(). memremap() drops the __iomem annotation for these
mappings to memory that do not have i/o side effects. The
replacement of ioremap_cache() with memremap() is limited to the
pmem driver to ease merging the api change in v4.3.
Completion of the conversion is targeted for v4.4.
- Similar to the usage of memcpy_to_pmem() + wmb_pmem() in the pmem
driver, update the VFS DAX implementation and PMEM api to provide
persistence guarantees for kernel operations on a DAX mapping.
- Convert the ACPI NFIT 'BLK' driver to map the block apertures as
cacheable to improve performance.
- Miscellaneous updates and fixes to libnvdimm including support for
issuing "address range scrub" commands, clarifying the optimal
'sector size' of pmem devices, a clarification of the usage of the
ACPI '_STA' (status) property for DIMM devices, and other minor
fixes"
* tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (34 commits)
libnvdimm, pmem: direct map legacy pmem by default
libnvdimm, pmem: 'struct page' for pmem
libnvdimm, pfn: 'struct page' provider infrastructure
x86, pmem: clarify that ARCH_HAS_PMEM_API implies PMEM mapped WB
add devm_memremap_pages
mm: ZONE_DEVICE for "device memory"
mm: move __phys_to_pfn and __pfn_to_phys to asm/generic/memory_model.h
dax: drop size parameter to ->direct_access()
nd_blk: change aperture mapping from WC to WB
nvdimm: change to use generic kvfree()
pmem, dax: have direct_access use __pmem annotation
dax: update I/O path to do proper PMEM flushing
pmem: add copy_from_iter_pmem() and clear_pmem()
pmem, x86: clean up conditional pmem includes
pmem: remove layer when calling arch_has_wmb_pmem()
pmem, x86: move x86 PMEM API to new pmem.h header
libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option
pmem: switch to devm_ allocations
devres: add devm_memremap
libnvdimm, btt: write and validate parent_uuid
...
This commit is contained in:
commit
12f03ee606
92 changed files with 2142 additions and 745 deletions
|
|
@ -417,6 +417,7 @@ config ACPI_NFIT
|
|||
tristate "ACPI NVDIMM Firmware Interface Table (NFIT)"
|
||||
depends on PHYS_ADDR_T_64BIT
|
||||
depends on BLK_DEV
|
||||
depends on ARCH_HAS_MMIO_FLUSH
|
||||
select LIBNVDIMM
|
||||
help
|
||||
Infrastructure to probe ACPI 6 compliant platforms for
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/sort.h>
|
||||
#include <linux/pmem.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include "nfit.h"
|
||||
|
||||
/*
|
||||
|
|
@ -764,9 +765,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
|
|||
struct acpi_device *adev, *adev_dimm;
|
||||
struct device *dev = acpi_desc->dev;
|
||||
const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
|
||||
unsigned long long sta;
|
||||
int i, rc = -ENODEV;
|
||||
acpi_status status;
|
||||
int i;
|
||||
|
||||
nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
|
||||
adev = to_acpi_dev(acpi_desc);
|
||||
|
|
@ -781,25 +780,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
|
|||
return force_enable_dimms ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_integer(adev_dimm->handle, "_STA", NULL, &sta);
|
||||
if (status == AE_NOT_FOUND) {
|
||||
dev_dbg(dev, "%s missing _STA, assuming enabled...\n",
|
||||
dev_name(&adev_dimm->dev));
|
||||
rc = 0;
|
||||
} else if (ACPI_FAILURE(status))
|
||||
dev_err(dev, "%s failed to retrieve_STA, disabling...\n",
|
||||
dev_name(&adev_dimm->dev));
|
||||
else if ((sta & ACPI_STA_DEVICE_ENABLED) == 0)
|
||||
dev_info(dev, "%s disabled by firmware\n",
|
||||
dev_name(&adev_dimm->dev));
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
|
||||
if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
|
||||
set_bit(i, &nfit_mem->dsm_mask);
|
||||
|
||||
return force_enable_dimms ? 0 : rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
|
||||
|
|
@ -868,6 +853,7 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
|
|||
struct acpi_device *adev;
|
||||
int i;
|
||||
|
||||
nd_desc->dsm_mask = acpi_desc->bus_dsm_force_en;
|
||||
adev = to_acpi_dev(acpi_desc);
|
||||
if (!adev)
|
||||
return;
|
||||
|
|
@ -1032,7 +1018,7 @@ static u32 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw)
|
|||
if (mmio->num_lines)
|
||||
offset = to_interleave_offset(offset, mmio);
|
||||
|
||||
return readl(mmio->base + offset);
|
||||
return readl(mmio->addr.base + offset);
|
||||
}
|
||||
|
||||
static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
|
||||
|
|
@ -1057,11 +1043,11 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
|
|||
if (mmio->num_lines)
|
||||
offset = to_interleave_offset(offset, mmio);
|
||||
|
||||
writeq(cmd, mmio->base + offset);
|
||||
writeq(cmd, mmio->addr.base + offset);
|
||||
wmb_blk(nfit_blk);
|
||||
|
||||
if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH)
|
||||
readq(mmio->base + offset);
|
||||
readq(mmio->addr.base + offset);
|
||||
}
|
||||
|
||||
static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
|
||||
|
|
@ -1093,11 +1079,16 @@ static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
|
|||
}
|
||||
|
||||
if (rw)
|
||||
memcpy_to_pmem(mmio->aperture + offset,
|
||||
memcpy_to_pmem(mmio->addr.aperture + offset,
|
||||
iobuf + copied, c);
|
||||
else
|
||||
else {
|
||||
if (nfit_blk->dimm_flags & ND_BLK_READ_FLUSH)
|
||||
mmio_flush_range((void __force *)
|
||||
mmio->addr.aperture + offset, c);
|
||||
|
||||
memcpy_from_pmem(iobuf + copied,
|
||||
mmio->aperture + offset, c);
|
||||
mmio->addr.aperture + offset, c);
|
||||
}
|
||||
|
||||
copied += c;
|
||||
len -= c;
|
||||
|
|
@ -1144,7 +1135,10 @@ static void nfit_spa_mapping_release(struct kref *kref)
|
|||
|
||||
WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex));
|
||||
dev_dbg(acpi_desc->dev, "%s: SPA%d\n", __func__, spa->range_index);
|
||||
iounmap(spa_map->iomem);
|
||||
if (spa_map->type == SPA_MAP_APERTURE)
|
||||
memunmap((void __force *)spa_map->addr.aperture);
|
||||
else
|
||||
iounmap(spa_map->addr.base);
|
||||
release_mem_region(spa->address, spa->length);
|
||||
list_del(&spa_map->list);
|
||||
kfree(spa_map);
|
||||
|
|
@ -1190,7 +1184,7 @@ static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc,
|
|||
spa_map = find_spa_mapping(acpi_desc, spa);
|
||||
if (spa_map) {
|
||||
kref_get(&spa_map->kref);
|
||||
return spa_map->iomem;
|
||||
return spa_map->addr.base;
|
||||
}
|
||||
|
||||
spa_map = kzalloc(sizeof(*spa_map), GFP_KERNEL);
|
||||
|
|
@ -1206,20 +1200,19 @@ static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc,
|
|||
if (!res)
|
||||
goto err_mem;
|
||||
|
||||
if (type == SPA_MAP_APERTURE) {
|
||||
/*
|
||||
* TODO: memremap_pmem() support, but that requires cache
|
||||
* flushing when the aperture is moved.
|
||||
*/
|
||||
spa_map->iomem = ioremap_wc(start, n);
|
||||
} else
|
||||
spa_map->iomem = ioremap_nocache(start, n);
|
||||
spa_map->type = type;
|
||||
if (type == SPA_MAP_APERTURE)
|
||||
spa_map->addr.aperture = (void __pmem *)memremap(start, n,
|
||||
ARCH_MEMREMAP_PMEM);
|
||||
else
|
||||
spa_map->addr.base = ioremap_nocache(start, n);
|
||||
|
||||
if (!spa_map->iomem)
|
||||
|
||||
if (!spa_map->addr.base)
|
||||
goto err_map;
|
||||
|
||||
list_add_tail(&spa_map->list, &acpi_desc->spa_maps);
|
||||
return spa_map->iomem;
|
||||
return spa_map->addr.base;
|
||||
|
||||
err_map:
|
||||
release_mem_region(start, n);
|
||||
|
|
@ -1282,7 +1275,7 @@ static int acpi_nfit_blk_get_flags(struct nvdimm_bus_descriptor *nd_desc,
|
|||
nfit_blk->dimm_flags = flags.flags;
|
||||
else if (rc == -ENOTTY) {
|
||||
/* fall back to a conservative default */
|
||||
nfit_blk->dimm_flags = ND_BLK_DCR_LATCH;
|
||||
nfit_blk->dimm_flags = ND_BLK_DCR_LATCH | ND_BLK_READ_FLUSH;
|
||||
rc = 0;
|
||||
} else
|
||||
rc = -ENXIO;
|
||||
|
|
@ -1322,9 +1315,9 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus,
|
|||
/* map block aperture memory */
|
||||
nfit_blk->bdw_offset = nfit_mem->bdw->offset;
|
||||
mmio = &nfit_blk->mmio[BDW];
|
||||
mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw,
|
||||
mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw,
|
||||
SPA_MAP_APERTURE);
|
||||
if (!mmio->base) {
|
||||
if (!mmio->addr.base) {
|
||||
dev_dbg(dev, "%s: %s failed to map bdw\n", __func__,
|
||||
nvdimm_name(nvdimm));
|
||||
return -ENOMEM;
|
||||
|
|
@ -1345,9 +1338,9 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus,
|
|||
nfit_blk->cmd_offset = nfit_mem->dcr->command_offset;
|
||||
nfit_blk->stat_offset = nfit_mem->dcr->status_offset;
|
||||
mmio = &nfit_blk->mmio[DCR];
|
||||
mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr,
|
||||
mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr,
|
||||
SPA_MAP_CONTROL);
|
||||
if (!mmio->base) {
|
||||
if (!mmio->addr.base) {
|
||||
dev_dbg(dev, "%s: %s failed to map dcr\n", __func__,
|
||||
nvdimm_name(nvdimm));
|
||||
return -ENOMEM;
|
||||
|
|
@ -1379,7 +1372,7 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!arch_has_pmem_api() && !nfit_blk->nvdimm_flush)
|
||||
if (!arch_has_wmb_pmem() && !nfit_blk->nvdimm_flush)
|
||||
dev_warn(dev, "unable to guarantee persistence of writes\n");
|
||||
|
||||
if (mmio->line_size == 0)
|
||||
|
|
@ -1414,7 +1407,7 @@ static void acpi_nfit_blk_region_disable(struct nvdimm_bus *nvdimm_bus,
|
|||
for (i = 0; i < 2; i++) {
|
||||
struct nfit_blk_mmio *mmio = &nfit_blk->mmio[i];
|
||||
|
||||
if (mmio->base)
|
||||
if (mmio->addr.base)
|
||||
nfit_spa_unmap(acpi_desc, mmio->spa);
|
||||
}
|
||||
nd_blk_region_set_provider_data(ndbr, NULL);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ enum nfit_uuids {
|
|||
};
|
||||
|
||||
enum {
|
||||
ND_BLK_READ_FLUSH = 1,
|
||||
ND_BLK_DCR_LATCH = 2,
|
||||
};
|
||||
|
||||
|
|
@ -107,6 +108,7 @@ struct acpi_nfit_desc {
|
|||
struct nvdimm_bus *nvdimm_bus;
|
||||
struct device *dev;
|
||||
unsigned long dimm_dsm_force_en;
|
||||
unsigned long bus_dsm_force_en;
|
||||
int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
|
||||
void *iobuf, u64 len, int rw);
|
||||
};
|
||||
|
|
@ -116,12 +118,16 @@ enum nd_blk_mmio_selector {
|
|||
DCR,
|
||||
};
|
||||
|
||||
struct nd_blk_addr {
|
||||
union {
|
||||
void __iomem *base;
|
||||
void __pmem *aperture;
|
||||
};
|
||||
};
|
||||
|
||||
struct nfit_blk {
|
||||
struct nfit_blk_mmio {
|
||||
union {
|
||||
void __iomem *base;
|
||||
void __pmem *aperture;
|
||||
};
|
||||
struct nd_blk_addr addr;
|
||||
u64 size;
|
||||
u64 base_offset;
|
||||
u32 line_size;
|
||||
|
|
@ -148,7 +154,8 @@ struct nfit_spa_mapping {
|
|||
struct acpi_nfit_system_address *spa;
|
||||
struct list_head list;
|
||||
struct kref kref;
|
||||
void __iomem *iomem;
|
||||
enum spa_map_type type;
|
||||
struct nd_blk_addr addr;
|
||||
};
|
||||
|
||||
static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref)
|
||||
|
|
|
|||
Loading…
Reference in a new issue