diff options
author | Dan Williams <dan.j.williams@intel.com> | 2016-05-18 13:06:48 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2016-05-18 13:06:48 -0400 |
commit | 2159669f581917c4d197d3ea183d3d85b47faf66 (patch) | |
tree | 9faa8bbf19fa1ea33e371b02cfa5a5b4507583de /drivers/acpi | |
parent | 594d6d96ea042366878aa7dc7f5711b8c245db5a (diff) | |
parent | 9dec4892ca9afd6aad3c9c9e6c17480ecbd04440 (diff) |
Merge branch 'for-4.7/libnvdimm' into libnvdimm-for-next
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/nfit.c | 74 | ||||
-rw-r--r-- | drivers/acpi/nfit.h | 1 |
2 files changed, 71 insertions, 4 deletions
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index 63cc9dbe4f3b..d60f73a63c3c 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c | |||
@@ -658,6 +658,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc, | |||
658 | if (!nfit_mem) | 658 | if (!nfit_mem) |
659 | return -ENOMEM; | 659 | return -ENOMEM; |
660 | INIT_LIST_HEAD(&nfit_mem->list); | 660 | INIT_LIST_HEAD(&nfit_mem->list); |
661 | nfit_mem->acpi_desc = acpi_desc; | ||
661 | list_add(&nfit_mem->list, &acpi_desc->dimms); | 662 | list_add(&nfit_mem->list, &acpi_desc->dimms); |
662 | } | 663 | } |
663 | 664 | ||
@@ -841,6 +842,18 @@ static ssize_t device_show(struct device *dev, | |||
841 | } | 842 | } |
842 | static DEVICE_ATTR_RO(device); | 843 | static DEVICE_ATTR_RO(device); |
843 | 844 | ||
845 | static int num_nvdimm_formats(struct nvdimm *nvdimm) | ||
846 | { | ||
847 | struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); | ||
848 | int formats = 0; | ||
849 | |||
850 | if (nfit_mem->memdev_pmem) | ||
851 | formats++; | ||
852 | if (nfit_mem->memdev_bdw) | ||
853 | formats++; | ||
854 | return formats; | ||
855 | } | ||
856 | |||
844 | static ssize_t format_show(struct device *dev, | 857 | static ssize_t format_show(struct device *dev, |
845 | struct device_attribute *attr, char *buf) | 858 | struct device_attribute *attr, char *buf) |
846 | { | 859 | { |
@@ -850,6 +863,55 @@ static ssize_t format_show(struct device *dev, | |||
850 | } | 863 | } |
851 | static DEVICE_ATTR_RO(format); | 864 | static DEVICE_ATTR_RO(format); |
852 | 865 | ||
866 | static ssize_t format1_show(struct device *dev, | ||
867 | struct device_attribute *attr, char *buf) | ||
868 | { | ||
869 | u32 handle; | ||
870 | ssize_t rc = -ENXIO; | ||
871 | struct nfit_mem *nfit_mem; | ||
872 | struct nfit_memdev *nfit_memdev; | ||
873 | struct acpi_nfit_desc *acpi_desc; | ||
874 | struct nvdimm *nvdimm = to_nvdimm(dev); | ||
875 | struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev); | ||
876 | |||
877 | nfit_mem = nvdimm_provider_data(nvdimm); | ||
878 | acpi_desc = nfit_mem->acpi_desc; | ||
879 | handle = to_nfit_memdev(dev)->device_handle; | ||
880 | |||
881 | /* assumes DIMMs have at most 2 published interface codes */ | ||
882 | mutex_lock(&acpi_desc->init_mutex); | ||
883 | list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { | ||
884 | struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev; | ||
885 | struct nfit_dcr *nfit_dcr; | ||
886 | |||
887 | if (memdev->device_handle != handle) | ||
888 | continue; | ||
889 | |||
890 | list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) { | ||
891 | if (nfit_dcr->dcr->region_index != memdev->region_index) | ||
892 | continue; | ||
893 | if (nfit_dcr->dcr->code == dcr->code) | ||
894 | continue; | ||
895 | rc = sprintf(buf, "%#x\n", nfit_dcr->dcr->code); | ||
896 | break; | ||
897 | } | ||
898 | if (rc != ENXIO) | ||
899 | break; | ||
900 | } | ||
901 | mutex_unlock(&acpi_desc->init_mutex); | ||
902 | return rc; | ||
903 | } | ||
904 | static DEVICE_ATTR_RO(format1); | ||
905 | |||
906 | static ssize_t formats_show(struct device *dev, | ||
907 | struct device_attribute *attr, char *buf) | ||
908 | { | ||
909 | struct nvdimm *nvdimm = to_nvdimm(dev); | ||
910 | |||
911 | return sprintf(buf, "%d\n", num_nvdimm_formats(nvdimm)); | ||
912 | } | ||
913 | static DEVICE_ATTR_RO(formats); | ||
914 | |||
853 | static ssize_t serial_show(struct device *dev, | 915 | static ssize_t serial_show(struct device *dev, |
854 | struct device_attribute *attr, char *buf) | 916 | struct device_attribute *attr, char *buf) |
855 | { | 917 | { |
@@ -879,6 +941,8 @@ static struct attribute *acpi_nfit_dimm_attributes[] = { | |||
879 | &dev_attr_vendor.attr, | 941 | &dev_attr_vendor.attr, |
880 | &dev_attr_device.attr, | 942 | &dev_attr_device.attr, |
881 | &dev_attr_format.attr, | 943 | &dev_attr_format.attr, |
944 | &dev_attr_formats.attr, | ||
945 | &dev_attr_format1.attr, | ||
882 | &dev_attr_serial.attr, | 946 | &dev_attr_serial.attr, |
883 | &dev_attr_rev_id.attr, | 947 | &dev_attr_rev_id.attr, |
884 | &dev_attr_flags.attr, | 948 | &dev_attr_flags.attr, |
@@ -889,11 +953,13 @@ static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj, | |||
889 | struct attribute *a, int n) | 953 | struct attribute *a, int n) |
890 | { | 954 | { |
891 | struct device *dev = container_of(kobj, struct device, kobj); | 955 | struct device *dev = container_of(kobj, struct device, kobj); |
956 | struct nvdimm *nvdimm = to_nvdimm(dev); | ||
892 | 957 | ||
893 | if (to_nfit_dcr(dev)) | 958 | if (!to_nfit_dcr(dev)) |
894 | return a->mode; | 959 | return 0; |
895 | else | 960 | if (a == &dev_attr_format1.attr && num_nvdimm_formats(nvdimm) <= 1) |
896 | return 0; | 961 | return 0; |
962 | return a->mode; | ||
897 | } | 963 | } |
898 | 964 | ||
899 | static struct attribute_group acpi_nfit_dimm_attribute_group = { | 965 | static struct attribute_group acpi_nfit_dimm_attribute_group = { |
@@ -2309,7 +2375,7 @@ static int acpi_nfit_add(struct acpi_device *adev) | |||
2309 | acpi_size sz; | 2375 | acpi_size sz; |
2310 | int rc; | 2376 | int rc; |
2311 | 2377 | ||
2312 | status = acpi_get_table_with_size("NFIT", 0, &tbl, &sz); | 2378 | status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz); |
2313 | if (ACPI_FAILURE(status)) { | 2379 | if (ACPI_FAILURE(status)) { |
2314 | /* This is ok, we could have an nvdimm hotplugged later */ | 2380 | /* This is ok, we could have an nvdimm hotplugged later */ |
2315 | dev_dbg(dev, "failed to find NFIT at startup\n"); | 2381 | dev_dbg(dev, "failed to find NFIT at startup\n"); |
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h index c75576b2d50e..5201840c1147 100644 --- a/drivers/acpi/nfit.h +++ b/drivers/acpi/nfit.h | |||
@@ -109,6 +109,7 @@ struct nfit_mem { | |||
109 | struct nfit_flush *nfit_flush; | 109 | struct nfit_flush *nfit_flush; |
110 | struct list_head list; | 110 | struct list_head list; |
111 | struct acpi_device *adev; | 111 | struct acpi_device *adev; |
112 | struct acpi_nfit_desc *acpi_desc; | ||
112 | unsigned long dsm_mask; | 113 | unsigned long dsm_mask; |
113 | }; | 114 | }; |
114 | 115 | ||