Merge branch 'for-4.16/nfit' into libnvdimm-for-next
[sfrench/cifs-2.6.git] / drivers / acpi / nfit / core.c
index abeb4df4f22e43d7f0d1398af9962135a37af4b6..bbe48ad20886c8530fe525ffe9f35725d1df1ddc 100644 (file)
@@ -838,6 +838,18 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
        return true;
 }
 
+static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc,
+               struct acpi_nfit_capabilities *pcap)
+{
+       struct device *dev = acpi_desc->dev;
+       u32 mask;
+
+       mask = (1 << (pcap->highest_capability + 1)) - 1;
+       acpi_desc->platform_cap = pcap->capabilities & mask;
+       dev_dbg(dev, "%s: cap: %#x\n", __func__, acpi_desc->platform_cap);
+       return true;
+}
+
 static void *add_table(struct acpi_nfit_desc *acpi_desc,
                struct nfit_table_prev *prev, void *table, const void *end)
 {
@@ -883,6 +895,10 @@ static void *add_table(struct acpi_nfit_desc *acpi_desc,
        case ACPI_NFIT_TYPE_SMBIOS:
                dev_dbg(dev, "%s: smbios\n", __func__);
                break;
+       case ACPI_NFIT_TYPE_CAPABILITIES:
+               if (!add_platform_cap(acpi_desc, table))
+                       return err;
+               break;
        default:
                dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type);
                break;
@@ -1867,6 +1883,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                struct kernfs_node *nfit_kernfs;
 
                nvdimm = nfit_mem->nvdimm;
+               if (!nvdimm)
+                       continue;
+
                nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
                if (nfit_kernfs)
                        nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
@@ -2656,6 +2675,12 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
        else
                ndr_desc->numa_node = NUMA_NO_NODE;
 
+       if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
+               set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags);
+
+       if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH)
+               set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags);
+
        list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
                struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
                struct nd_mapping_desc *mapping;
@@ -3464,6 +3489,7 @@ static __init int nfit_init(void)
        BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9);
        BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80);
        BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40);
+       BUILD_BUG_ON(sizeof(struct acpi_nfit_capabilities) != 16);
 
        guid_parse(UUID_VOLATILE_MEMORY, &nfit_uuid[NFIT_SPA_VOLATILE]);
        guid_parse(UUID_PERSISTENT_MEMORY, &nfit_uuid[NFIT_SPA_PM]);