acpi: nfit: Add support for detect platform CPU cache flush on power loss
[sfrench/cifs-2.6.git] / drivers / acpi / nfit / core.c
index abeb4df4f22e43d7f0d1398af9962135a37af4b6..dc775823aea0d4f03f8e83e1e021b846989cfeba 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;
@@ -2656,6 +2672,9 @@ 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);
+
        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 +3483,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]);