aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-03-09 20:15:43 -0500
committerDan Williams <dan.j.williams@intel.com>2016-03-09 20:15:43 -0500
commit489011652a2d5555901def04c24d68874e8ba9a1 (patch)
treef4d000e5ae63350016d12e6ccb52b0809bb814df /drivers/acpi
parent59e6473980f321c16299e12db69d1fabc2644a6f (diff)
parentff8e92d5d94b99aab39f439d532cba435947dfc0 (diff)
Merge branch 'for-4.6/pfn' into libnvdimm-for-next
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpi_platform.c2
-rw-r--r--drivers/acpi/apei/einj.c15
-rw-r--r--drivers/acpi/nfit.c50
3 files changed, 62 insertions, 5 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 296b7a14893a..b6f7fa3a1d40 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -62,7 +62,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
62 if (count < 0) { 62 if (count < 0) {
63 return NULL; 63 return NULL;
64 } else if (count > 0) { 64 } else if (count > 0) {
65 resources = kmalloc(count * sizeof(struct resource), 65 resources = kzalloc(count * sizeof(struct resource),
66 GFP_KERNEL); 66 GFP_KERNEL);
67 if (!resources) { 67 if (!resources) {
68 dev_err(&adev->dev, "No memory for resources\n"); 68 dev_err(&adev->dev, "No memory for resources\n");
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 0431883653be..559c1173de1c 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -519,7 +519,7 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
519 u64 param3, u64 param4) 519 u64 param3, u64 param4)
520{ 520{
521 int rc; 521 int rc;
522 unsigned long pfn; 522 u64 base_addr, size;
523 523
524 /* If user manually set "flags", make sure it is legal */ 524 /* If user manually set "flags", make sure it is legal */
525 if (flags && (flags & 525 if (flags && (flags &
@@ -545,10 +545,17 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
545 /* 545 /*
546 * Disallow crazy address masks that give BIOS leeway to pick 546 * Disallow crazy address masks that give BIOS leeway to pick
547 * injection address almost anywhere. Insist on page or 547 * injection address almost anywhere. Insist on page or
548 * better granularity and that target address is normal RAM. 548 * better granularity and that target address is normal RAM or
549 * NVDIMM.
549 */ 550 */
550 pfn = PFN_DOWN(param1 & param2); 551 base_addr = param1 & param2;
551 if (!page_is_ram(pfn) || ((param2 & PAGE_MASK) != PAGE_MASK)) 552 size = ~param2 + 1;
553
554 if (((param2 & PAGE_MASK) != PAGE_MASK) ||
555 ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
556 != REGION_INTERSECTS) &&
557 (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
558 != REGION_INTERSECTS)))
552 return -EINVAL; 559 return -EINVAL;
553 560
554inject: 561inject:
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index c067d7414007..d0f35e63640b 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -1658,6 +1658,48 @@ static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
1658 return 0; 1658 return 0;
1659} 1659}
1660 1660
1661static void acpi_nfit_remove_resource(void *data)
1662{
1663 struct resource *res = data;
1664
1665 remove_resource(res);
1666}
1667
1668static int acpi_nfit_insert_resource(struct acpi_nfit_desc *acpi_desc,
1669 struct nd_region_desc *ndr_desc)
1670{
1671 struct resource *res, *nd_res = ndr_desc->res;
1672 int is_pmem, ret;
1673
1674 /* No operation if the region is already registered as PMEM */
1675 is_pmem = region_intersects(nd_res->start, resource_size(nd_res),
1676 IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY);
1677 if (is_pmem == REGION_INTERSECTS)
1678 return 0;
1679
1680 res = devm_kzalloc(acpi_desc->dev, sizeof(*res), GFP_KERNEL);
1681 if (!res)
1682 return -ENOMEM;
1683
1684 res->name = "Persistent Memory";
1685 res->start = nd_res->start;
1686 res->end = nd_res->end;
1687 res->flags = IORESOURCE_MEM;
1688 res->desc = IORES_DESC_PERSISTENT_MEMORY;
1689
1690 ret = insert_resource(&iomem_resource, res);
1691 if (ret)
1692 return ret;
1693
1694 ret = devm_add_action(acpi_desc->dev, acpi_nfit_remove_resource, res);
1695 if (ret) {
1696 remove_resource(res);
1697 return ret;
1698 }
1699
1700 return 0;
1701}
1702
1661static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, 1703static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
1662 struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc, 1704 struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc,
1663 struct acpi_nfit_memory_map *memdev, 1705 struct acpi_nfit_memory_map *memdev,
@@ -1773,6 +1815,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
1773 1815
1774 nvdimm_bus = acpi_desc->nvdimm_bus; 1816 nvdimm_bus = acpi_desc->nvdimm_bus;
1775 if (nfit_spa_type(spa) == NFIT_SPA_PM) { 1817 if (nfit_spa_type(spa) == NFIT_SPA_PM) {
1818 rc = acpi_nfit_insert_resource(acpi_desc, ndr_desc);
1819 if (rc) {
1820 dev_warn(acpi_desc->dev,
1821 "failed to insert pmem resource to iomem: %d\n",
1822 rc);
1823 goto out;
1824 }
1825
1776 nfit_spa->nd_region = nvdimm_pmem_region_create(nvdimm_bus, 1826 nfit_spa->nd_region = nvdimm_pmem_region_create(nvdimm_bus,
1777 ndr_desc); 1827 ndr_desc);
1778 if (!nfit_spa->nd_region) 1828 if (!nfit_spa->nd_region)