fc38b49eff7d306d247f48406b3bbb06fc745852
[linux-drm-fsl-dcu.git] / drivers / acpi / nfit.c
1 /*
2  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  */
13 #include <linux/list_sort.h>
14 #include <linux/libnvdimm.h>
15 #include <linux/module.h>
16 #include <linux/ndctl.h>
17 #include <linux/list.h>
18 #include <linux/acpi.h>
19 #include <linux/sort.h>
20 #include "nfit.h"
21
22 static bool force_enable_dimms;
23 module_param(force_enable_dimms, bool, S_IRUGO|S_IWUSR);
24 MODULE_PARM_DESC(force_enable_dimms, "Ignore _STA (ACPI DIMM device) status");
25
26 static u8 nfit_uuid[NFIT_UUID_MAX][16];
27
28 static const u8 *to_nfit_uuid(enum nfit_uuids id)
29 {
30         return nfit_uuid[id];
31 }
32
33 static struct acpi_nfit_desc *to_acpi_nfit_desc(
34                 struct nvdimm_bus_descriptor *nd_desc)
35 {
36         return container_of(nd_desc, struct acpi_nfit_desc, nd_desc);
37 }
38
39 static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
40 {
41         struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
42
43         /*
44          * If provider == 'ACPI.NFIT' we can assume 'dev' is a struct
45          * acpi_device.
46          */
47         if (!nd_desc->provider_name
48                         || strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
49                 return NULL;
50
51         return to_acpi_device(acpi_desc->dev);
52 }
53
54 static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
55                 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
56                 unsigned int buf_len)
57 {
58         struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
59         const struct nd_cmd_desc *desc = NULL;
60         union acpi_object in_obj, in_buf, *out_obj;
61         struct device *dev = acpi_desc->dev;
62         const char *cmd_name, *dimm_name;
63         unsigned long dsm_mask;
64         acpi_handle handle;
65         const u8 *uuid;
66         u32 offset;
67         int rc, i;
68
69         if (nvdimm) {
70                 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
71                 struct acpi_device *adev = nfit_mem->adev;
72
73                 if (!adev)
74                         return -ENOTTY;
75                 dimm_name = dev_name(&adev->dev);
76                 cmd_name = nvdimm_cmd_name(cmd);
77                 dsm_mask = nfit_mem->dsm_mask;
78                 desc = nd_cmd_dimm_desc(cmd);
79                 uuid = to_nfit_uuid(NFIT_DEV_DIMM);
80                 handle = adev->handle;
81         } else {
82                 struct acpi_device *adev = to_acpi_dev(acpi_desc);
83
84                 cmd_name = nvdimm_bus_cmd_name(cmd);
85                 dsm_mask = nd_desc->dsm_mask;
86                 desc = nd_cmd_bus_desc(cmd);
87                 uuid = to_nfit_uuid(NFIT_DEV_BUS);
88                 handle = adev->handle;
89                 dimm_name = "bus";
90         }
91
92         if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
93                 return -ENOTTY;
94
95         if (!test_bit(cmd, &dsm_mask))
96                 return -ENOTTY;
97
98         in_obj.type = ACPI_TYPE_PACKAGE;
99         in_obj.package.count = 1;
100         in_obj.package.elements = &in_buf;
101         in_buf.type = ACPI_TYPE_BUFFER;
102         in_buf.buffer.pointer = buf;
103         in_buf.buffer.length = 0;
104
105         /* libnvdimm has already validated the input envelope */
106         for (i = 0; i < desc->in_num; i++)
107                 in_buf.buffer.length += nd_cmd_in_size(nvdimm, cmd, desc,
108                                 i, buf);
109
110         if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) {
111                 dev_dbg(dev, "%s:%s cmd: %s input length: %d\n", __func__,
112                                 dimm_name, cmd_name, in_buf.buffer.length);
113                 print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4,
114                                 4, in_buf.buffer.pointer, min_t(u32, 128,
115                                         in_buf.buffer.length), true);
116         }
117
118         out_obj = acpi_evaluate_dsm(handle, uuid, 1, cmd, &in_obj);
119         if (!out_obj) {
120                 dev_dbg(dev, "%s:%s _DSM failed cmd: %s\n", __func__, dimm_name,
121                                 cmd_name);
122                 return -EINVAL;
123         }
124
125         if (out_obj->package.type != ACPI_TYPE_BUFFER) {
126                 dev_dbg(dev, "%s:%s unexpected output object type cmd: %s type: %d\n",
127                                 __func__, dimm_name, cmd_name, out_obj->type);
128                 rc = -EINVAL;
129                 goto out;
130         }
131
132         if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) {
133                 dev_dbg(dev, "%s:%s cmd: %s output length: %d\n", __func__,
134                                 dimm_name, cmd_name, out_obj->buffer.length);
135                 print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4,
136                                 4, out_obj->buffer.pointer, min_t(u32, 128,
137                                         out_obj->buffer.length), true);
138         }
139
140         for (i = 0, offset = 0; i < desc->out_num; i++) {
141                 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
142                                 (u32 *) out_obj->buffer.pointer);
143
144                 if (offset + out_size > out_obj->buffer.length) {
145                         dev_dbg(dev, "%s:%s output object underflow cmd: %s field: %d\n",
146                                         __func__, dimm_name, cmd_name, i);
147                         break;
148                 }
149
150                 if (in_buf.buffer.length + offset + out_size > buf_len) {
151                         dev_dbg(dev, "%s:%s output overrun cmd: %s field: %d\n",
152                                         __func__, dimm_name, cmd_name, i);
153                         rc = -ENXIO;
154                         goto out;
155                 }
156                 memcpy(buf + in_buf.buffer.length + offset,
157                                 out_obj->buffer.pointer + offset, out_size);
158                 offset += out_size;
159         }
160         if (offset + in_buf.buffer.length < buf_len) {
161                 if (i >= 1) {
162                         /*
163                          * status valid, return the number of bytes left
164                          * unfilled in the output buffer
165                          */
166                         rc = buf_len - offset - in_buf.buffer.length;
167                 } else {
168                         dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
169                                         __func__, dimm_name, cmd_name, buf_len,
170                                         offset);
171                         rc = -ENXIO;
172                 }
173         } else
174                 rc = 0;
175
176  out:
177         ACPI_FREE(out_obj);
178
179         return rc;
180 }
181
182 static const char *spa_type_name(u16 type)
183 {
184         static const char *to_name[] = {
185                 [NFIT_SPA_VOLATILE] = "volatile",
186                 [NFIT_SPA_PM] = "pmem",
187                 [NFIT_SPA_DCR] = "dimm-control-region",
188                 [NFIT_SPA_BDW] = "block-data-window",
189                 [NFIT_SPA_VDISK] = "volatile-disk",
190                 [NFIT_SPA_VCD] = "volatile-cd",
191                 [NFIT_SPA_PDISK] = "persistent-disk",
192                 [NFIT_SPA_PCD] = "persistent-cd",
193
194         };
195
196         if (type > NFIT_SPA_PCD)
197                 return "unknown";
198
199         return to_name[type];
200 }
201
202 static int nfit_spa_type(struct acpi_nfit_system_address *spa)
203 {
204         int i;
205
206         for (i = 0; i < NFIT_UUID_MAX; i++)
207                 if (memcmp(to_nfit_uuid(i), spa->range_guid, 16) == 0)
208                         return i;
209         return -1;
210 }
211
212 static bool add_spa(struct acpi_nfit_desc *acpi_desc,
213                 struct acpi_nfit_system_address *spa)
214 {
215         struct device *dev = acpi_desc->dev;
216         struct nfit_spa *nfit_spa = devm_kzalloc(dev, sizeof(*nfit_spa),
217                         GFP_KERNEL);
218
219         if (!nfit_spa)
220                 return false;
221         INIT_LIST_HEAD(&nfit_spa->list);
222         nfit_spa->spa = spa;
223         list_add_tail(&nfit_spa->list, &acpi_desc->spas);
224         dev_dbg(dev, "%s: spa index: %d type: %s\n", __func__,
225                         spa->range_index,
226                         spa_type_name(nfit_spa_type(spa)));
227         return true;
228 }
229
230 static bool add_memdev(struct acpi_nfit_desc *acpi_desc,
231                 struct acpi_nfit_memory_map *memdev)
232 {
233         struct device *dev = acpi_desc->dev;
234         struct nfit_memdev *nfit_memdev = devm_kzalloc(dev,
235                         sizeof(*nfit_memdev), GFP_KERNEL);
236
237         if (!nfit_memdev)
238                 return false;
239         INIT_LIST_HEAD(&nfit_memdev->list);
240         nfit_memdev->memdev = memdev;
241         list_add_tail(&nfit_memdev->list, &acpi_desc->memdevs);
242         dev_dbg(dev, "%s: memdev handle: %#x spa: %d dcr: %d\n",
243                         __func__, memdev->device_handle, memdev->range_index,
244                         memdev->region_index);
245         return true;
246 }
247
248 static bool add_dcr(struct acpi_nfit_desc *acpi_desc,
249                 struct acpi_nfit_control_region *dcr)
250 {
251         struct device *dev = acpi_desc->dev;
252         struct nfit_dcr *nfit_dcr = devm_kzalloc(dev, sizeof(*nfit_dcr),
253                         GFP_KERNEL);
254
255         if (!nfit_dcr)
256                 return false;
257         INIT_LIST_HEAD(&nfit_dcr->list);
258         nfit_dcr->dcr = dcr;
259         list_add_tail(&nfit_dcr->list, &acpi_desc->dcrs);
260         dev_dbg(dev, "%s: dcr index: %d windows: %d\n", __func__,
261                         dcr->region_index, dcr->windows);
262         return true;
263 }
264
265 static bool add_bdw(struct acpi_nfit_desc *acpi_desc,
266                 struct acpi_nfit_data_region *bdw)
267 {
268         struct device *dev = acpi_desc->dev;
269         struct nfit_bdw *nfit_bdw = devm_kzalloc(dev, sizeof(*nfit_bdw),
270                         GFP_KERNEL);
271
272         if (!nfit_bdw)
273                 return false;
274         INIT_LIST_HEAD(&nfit_bdw->list);
275         nfit_bdw->bdw = bdw;
276         list_add_tail(&nfit_bdw->list, &acpi_desc->bdws);
277         dev_dbg(dev, "%s: bdw dcr: %d windows: %d\n", __func__,
278                         bdw->region_index, bdw->windows);
279         return true;
280 }
281
282 static void *add_table(struct acpi_nfit_desc *acpi_desc, void *table,
283                 const void *end)
284 {
285         struct device *dev = acpi_desc->dev;
286         struct acpi_nfit_header *hdr;
287         void *err = ERR_PTR(-ENOMEM);
288
289         if (table >= end)
290                 return NULL;
291
292         hdr = table;
293         switch (hdr->type) {
294         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
295                 if (!add_spa(acpi_desc, table))
296                         return err;
297                 break;
298         case ACPI_NFIT_TYPE_MEMORY_MAP:
299                 if (!add_memdev(acpi_desc, table))
300                         return err;
301                 break;
302         case ACPI_NFIT_TYPE_CONTROL_REGION:
303                 if (!add_dcr(acpi_desc, table))
304                         return err;
305                 break;
306         case ACPI_NFIT_TYPE_DATA_REGION:
307                 if (!add_bdw(acpi_desc, table))
308                         return err;
309                 break;
310         /* TODO */
311         case ACPI_NFIT_TYPE_INTERLEAVE:
312                 dev_dbg(dev, "%s: idt\n", __func__);
313                 break;
314         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
315                 dev_dbg(dev, "%s: flush\n", __func__);
316                 break;
317         case ACPI_NFIT_TYPE_SMBIOS:
318                 dev_dbg(dev, "%s: smbios\n", __func__);
319                 break;
320         default:
321                 dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type);
322                 break;
323         }
324
325         return table + hdr->length;
326 }
327
328 static void nfit_mem_find_spa_bdw(struct acpi_nfit_desc *acpi_desc,
329                 struct nfit_mem *nfit_mem)
330 {
331         u32 device_handle = __to_nfit_memdev(nfit_mem)->device_handle;
332         u16 dcr = nfit_mem->dcr->region_index;
333         struct nfit_spa *nfit_spa;
334
335         list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
336                 u16 range_index = nfit_spa->spa->range_index;
337                 int type = nfit_spa_type(nfit_spa->spa);
338                 struct nfit_memdev *nfit_memdev;
339
340                 if (type != NFIT_SPA_BDW)
341                         continue;
342
343                 list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
344                         if (nfit_memdev->memdev->range_index != range_index)
345                                 continue;
346                         if (nfit_memdev->memdev->device_handle != device_handle)
347                                 continue;
348                         if (nfit_memdev->memdev->region_index != dcr)
349                                 continue;
350
351                         nfit_mem->spa_bdw = nfit_spa->spa;
352                         return;
353                 }
354         }
355
356         dev_dbg(acpi_desc->dev, "SPA-BDW not found for SPA-DCR %d\n",
357                         nfit_mem->spa_dcr->range_index);
358         nfit_mem->bdw = NULL;
359 }
360
361 static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
362                 struct nfit_mem *nfit_mem, struct acpi_nfit_system_address *spa)
363 {
364         u16 dcr = __to_nfit_memdev(nfit_mem)->region_index;
365         struct nfit_dcr *nfit_dcr;
366         struct nfit_bdw *nfit_bdw;
367
368         list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
369                 if (nfit_dcr->dcr->region_index != dcr)
370                         continue;
371                 nfit_mem->dcr = nfit_dcr->dcr;
372                 break;
373         }
374
375         if (!nfit_mem->dcr) {
376                 dev_dbg(acpi_desc->dev, "SPA %d missing:%s%s\n",
377                                 spa->range_index, __to_nfit_memdev(nfit_mem)
378                                 ? "" : " MEMDEV", nfit_mem->dcr ? "" : " DCR");
379                 return -ENODEV;
380         }
381
382         /*
383          * We've found enough to create an nvdimm, optionally
384          * find an associated BDW
385          */
386         list_add(&nfit_mem->list, &acpi_desc->dimms);
387
388         list_for_each_entry(nfit_bdw, &acpi_desc->bdws, list) {
389                 if (nfit_bdw->bdw->region_index != dcr)
390                         continue;
391                 nfit_mem->bdw = nfit_bdw->bdw;
392                 break;
393         }
394
395         if (!nfit_mem->bdw)
396                 return 0;
397
398         nfit_mem_find_spa_bdw(acpi_desc, nfit_mem);
399         return 0;
400 }
401
402 static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
403                 struct acpi_nfit_system_address *spa)
404 {
405         struct nfit_mem *nfit_mem, *found;
406         struct nfit_memdev *nfit_memdev;
407         int type = nfit_spa_type(spa);
408         u16 dcr;
409
410         switch (type) {
411         case NFIT_SPA_DCR:
412         case NFIT_SPA_PM:
413                 break;
414         default:
415                 return 0;
416         }
417
418         list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
419                 int rc;
420
421                 if (nfit_memdev->memdev->range_index != spa->range_index)
422                         continue;
423                 found = NULL;
424                 dcr = nfit_memdev->memdev->region_index;
425                 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list)
426                         if (__to_nfit_memdev(nfit_mem)->region_index == dcr) {
427                                 found = nfit_mem;
428                                 break;
429                         }
430
431                 if (found)
432                         nfit_mem = found;
433                 else {
434                         nfit_mem = devm_kzalloc(acpi_desc->dev,
435                                         sizeof(*nfit_mem), GFP_KERNEL);
436                         if (!nfit_mem)
437                                 return -ENOMEM;
438                         INIT_LIST_HEAD(&nfit_mem->list);
439                 }
440
441                 if (type == NFIT_SPA_DCR) {
442                         /* multiple dimms may share a SPA when interleaved */
443                         nfit_mem->spa_dcr = spa;
444                         nfit_mem->memdev_dcr = nfit_memdev->memdev;
445                 } else {
446                         /*
447                          * A single dimm may belong to multiple SPA-PM
448                          * ranges, record at least one in addition to
449                          * any SPA-DCR range.
450                          */
451                         nfit_mem->memdev_pmem = nfit_memdev->memdev;
452                 }
453
454                 if (found)
455                         continue;
456
457                 rc = nfit_mem_add(acpi_desc, nfit_mem, spa);
458                 if (rc)
459                         return rc;
460         }
461
462         return 0;
463 }
464
465 static int nfit_mem_cmp(void *priv, struct list_head *_a, struct list_head *_b)
466 {
467         struct nfit_mem *a = container_of(_a, typeof(*a), list);
468         struct nfit_mem *b = container_of(_b, typeof(*b), list);
469         u32 handleA, handleB;
470
471         handleA = __to_nfit_memdev(a)->device_handle;
472         handleB = __to_nfit_memdev(b)->device_handle;
473         if (handleA < handleB)
474                 return -1;
475         else if (handleA > handleB)
476                 return 1;
477         return 0;
478 }
479
480 static int nfit_mem_init(struct acpi_nfit_desc *acpi_desc)
481 {
482         struct nfit_spa *nfit_spa;
483
484         /*
485          * For each SPA-DCR or SPA-PMEM address range find its
486          * corresponding MEMDEV(s).  From each MEMDEV find the
487          * corresponding DCR.  Then, if we're operating on a SPA-DCR,
488          * try to find a SPA-BDW and a corresponding BDW that references
489          * the DCR.  Throw it all into an nfit_mem object.  Note, that
490          * BDWs are optional.
491          */
492         list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
493                 int rc;
494
495                 rc = nfit_mem_dcr_init(acpi_desc, nfit_spa->spa);
496                 if (rc)
497                         return rc;
498         }
499
500         list_sort(NULL, &acpi_desc->dimms, nfit_mem_cmp);
501
502         return 0;
503 }
504
505 static ssize_t revision_show(struct device *dev,
506                 struct device_attribute *attr, char *buf)
507 {
508         struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
509         struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus);
510         struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
511
512         return sprintf(buf, "%d\n", acpi_desc->nfit->header.revision);
513 }
514 static DEVICE_ATTR_RO(revision);
515
516 static struct attribute *acpi_nfit_attributes[] = {
517         &dev_attr_revision.attr,
518         NULL,
519 };
520
521 static struct attribute_group acpi_nfit_attribute_group = {
522         .name = "nfit",
523         .attrs = acpi_nfit_attributes,
524 };
525
526 static const struct attribute_group *acpi_nfit_attribute_groups[] = {
527         &nvdimm_bus_attribute_group,
528         &acpi_nfit_attribute_group,
529         NULL,
530 };
531
532 static struct acpi_nfit_memory_map *to_nfit_memdev(struct device *dev)
533 {
534         struct nvdimm *nvdimm = to_nvdimm(dev);
535         struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
536
537         return __to_nfit_memdev(nfit_mem);
538 }
539
540 static struct acpi_nfit_control_region *to_nfit_dcr(struct device *dev)
541 {
542         struct nvdimm *nvdimm = to_nvdimm(dev);
543         struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
544
545         return nfit_mem->dcr;
546 }
547
548 static ssize_t handle_show(struct device *dev,
549                 struct device_attribute *attr, char *buf)
550 {
551         struct acpi_nfit_memory_map *memdev = to_nfit_memdev(dev);
552
553         return sprintf(buf, "%#x\n", memdev->device_handle);
554 }
555 static DEVICE_ATTR_RO(handle);
556
557 static ssize_t phys_id_show(struct device *dev,
558                 struct device_attribute *attr, char *buf)
559 {
560         struct acpi_nfit_memory_map *memdev = to_nfit_memdev(dev);
561
562         return sprintf(buf, "%#x\n", memdev->physical_id);
563 }
564 static DEVICE_ATTR_RO(phys_id);
565
566 static ssize_t vendor_show(struct device *dev,
567                 struct device_attribute *attr, char *buf)
568 {
569         struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
570
571         return sprintf(buf, "%#x\n", dcr->vendor_id);
572 }
573 static DEVICE_ATTR_RO(vendor);
574
575 static ssize_t rev_id_show(struct device *dev,
576                 struct device_attribute *attr, char *buf)
577 {
578         struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
579
580         return sprintf(buf, "%#x\n", dcr->revision_id);
581 }
582 static DEVICE_ATTR_RO(rev_id);
583
584 static ssize_t device_show(struct device *dev,
585                 struct device_attribute *attr, char *buf)
586 {
587         struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
588
589         return sprintf(buf, "%#x\n", dcr->device_id);
590 }
591 static DEVICE_ATTR_RO(device);
592
593 static ssize_t format_show(struct device *dev,
594                 struct device_attribute *attr, char *buf)
595 {
596         struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
597
598         return sprintf(buf, "%#x\n", dcr->code);
599 }
600 static DEVICE_ATTR_RO(format);
601
602 static ssize_t serial_show(struct device *dev,
603                 struct device_attribute *attr, char *buf)
604 {
605         struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
606
607         return sprintf(buf, "%#x\n", dcr->serial_number);
608 }
609 static DEVICE_ATTR_RO(serial);
610
611 static struct attribute *acpi_nfit_dimm_attributes[] = {
612         &dev_attr_handle.attr,
613         &dev_attr_phys_id.attr,
614         &dev_attr_vendor.attr,
615         &dev_attr_device.attr,
616         &dev_attr_format.attr,
617         &dev_attr_serial.attr,
618         &dev_attr_rev_id.attr,
619         NULL,
620 };
621
622 static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj,
623                 struct attribute *a, int n)
624 {
625         struct device *dev = container_of(kobj, struct device, kobj);
626
627         if (to_nfit_dcr(dev))
628                 return a->mode;
629         else
630                 return 0;
631 }
632
633 static struct attribute_group acpi_nfit_dimm_attribute_group = {
634         .name = "nfit",
635         .attrs = acpi_nfit_dimm_attributes,
636         .is_visible = acpi_nfit_dimm_attr_visible,
637 };
638
639 static const struct attribute_group *acpi_nfit_dimm_attribute_groups[] = {
640         &nvdimm_attribute_group,
641         &nd_device_attribute_group,
642         &acpi_nfit_dimm_attribute_group,
643         NULL,
644 };
645
646 static struct nvdimm *acpi_nfit_dimm_by_handle(struct acpi_nfit_desc *acpi_desc,
647                 u32 device_handle)
648 {
649         struct nfit_mem *nfit_mem;
650
651         list_for_each_entry(nfit_mem, &acpi_desc->dimms, list)
652                 if (__to_nfit_memdev(nfit_mem)->device_handle == device_handle)
653                         return nfit_mem->nvdimm;
654
655         return NULL;
656 }
657
658 static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
659                 struct nfit_mem *nfit_mem, u32 device_handle)
660 {
661         struct acpi_device *adev, *adev_dimm;
662         struct device *dev = acpi_desc->dev;
663         const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
664         unsigned long long sta;
665         int i, rc = -ENODEV;
666         acpi_status status;
667
668         nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
669         adev = to_acpi_dev(acpi_desc);
670         if (!adev)
671                 return 0;
672
673         adev_dimm = acpi_find_child_device(adev, device_handle, false);
674         nfit_mem->adev = adev_dimm;
675         if (!adev_dimm) {
676                 dev_err(dev, "no ACPI.NFIT device with _ADR %#x, disabling...\n",
677                                 device_handle);
678                 return force_enable_dimms ? 0 : -ENODEV;
679         }
680
681         status = acpi_evaluate_integer(adev_dimm->handle, "_STA", NULL, &sta);
682         if (status == AE_NOT_FOUND) {
683                 dev_dbg(dev, "%s missing _STA, assuming enabled...\n",
684                                 dev_name(&adev_dimm->dev));
685                 rc = 0;
686         } else if (ACPI_FAILURE(status))
687                 dev_err(dev, "%s failed to retrieve_STA, disabling...\n",
688                                 dev_name(&adev_dimm->dev));
689         else if ((sta & ACPI_STA_DEVICE_ENABLED) == 0)
690                 dev_info(dev, "%s disabled by firmware\n",
691                                 dev_name(&adev_dimm->dev));
692         else
693                 rc = 0;
694
695         for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
696                 if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
697                         set_bit(i, &nfit_mem->dsm_mask);
698
699         return force_enable_dimms ? 0 : rc;
700 }
701
702 static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
703 {
704         struct nfit_mem *nfit_mem;
705         int dimm_count = 0;
706
707         list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
708                 struct nvdimm *nvdimm;
709                 unsigned long flags = 0;
710                 u32 device_handle;
711                 int rc;
712
713                 device_handle = __to_nfit_memdev(nfit_mem)->device_handle;
714                 nvdimm = acpi_nfit_dimm_by_handle(acpi_desc, device_handle);
715                 if (nvdimm) {
716                         /*
717                          * If for some reason we find multiple DCRs the
718                          * first one wins
719                          */
720                         dev_err(acpi_desc->dev, "duplicate DCR detected: %s\n",
721                                         nvdimm_name(nvdimm));
722                         continue;
723                 }
724
725                 if (nfit_mem->bdw && nfit_mem->memdev_pmem)
726                         flags |= NDD_ALIASING;
727
728                 rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
729                 if (rc)
730                         continue;
731
732                 nvdimm = nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem,
733                                 acpi_nfit_dimm_attribute_groups,
734                                 flags, &nfit_mem->dsm_mask);
735                 if (!nvdimm)
736                         return -ENOMEM;
737
738                 nfit_mem->nvdimm = nvdimm;
739                 dimm_count++;
740         }
741
742         return nvdimm_bus_check_dimm_count(acpi_desc->nvdimm_bus, dimm_count);
743 }
744
745 static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
746 {
747         struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
748         const u8 *uuid = to_nfit_uuid(NFIT_DEV_BUS);
749         struct acpi_device *adev;
750         int i;
751
752         adev = to_acpi_dev(acpi_desc);
753         if (!adev)
754                 return;
755
756         for (i = ND_CMD_ARS_CAP; i <= ND_CMD_ARS_STATUS; i++)
757                 if (acpi_check_dsm(adev->handle, uuid, 1, 1ULL << i))
758                         set_bit(i, &nd_desc->dsm_mask);
759 }
760
761 static ssize_t range_index_show(struct device *dev,
762                 struct device_attribute *attr, char *buf)
763 {
764         struct nd_region *nd_region = to_nd_region(dev);
765         struct nfit_spa *nfit_spa = nd_region_provider_data(nd_region);
766
767         return sprintf(buf, "%d\n", nfit_spa->spa->range_index);
768 }
769 static DEVICE_ATTR_RO(range_index);
770
771 static struct attribute *acpi_nfit_region_attributes[] = {
772         &dev_attr_range_index.attr,
773         NULL,
774 };
775
776 static struct attribute_group acpi_nfit_region_attribute_group = {
777         .name = "nfit",
778         .attrs = acpi_nfit_region_attributes,
779 };
780
781 static const struct attribute_group *acpi_nfit_region_attribute_groups[] = {
782         &nd_region_attribute_group,
783         &nd_mapping_attribute_group,
784         &nd_device_attribute_group,
785         &acpi_nfit_region_attribute_group,
786         NULL,
787 };
788
789 /* enough info to uniquely specify an interleave set */
790 struct nfit_set_info {
791         struct nfit_set_info_map {
792                 u64 region_offset;
793                 u32 serial_number;
794                 u32 pad;
795         } mapping[0];
796 };
797
798 static size_t sizeof_nfit_set_info(int num_mappings)
799 {
800         return sizeof(struct nfit_set_info)
801                 + num_mappings * sizeof(struct nfit_set_info_map);
802 }
803
804 static int cmp_map(const void *m0, const void *m1)
805 {
806         const struct nfit_set_info_map *map0 = m0;
807         const struct nfit_set_info_map *map1 = m1;
808
809         return memcmp(&map0->region_offset, &map1->region_offset,
810                         sizeof(u64));
811 }
812
813 /* Retrieve the nth entry referencing this spa */
814 static struct acpi_nfit_memory_map *memdev_from_spa(
815                 struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
816 {
817         struct nfit_memdev *nfit_memdev;
818
819         list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list)
820                 if (nfit_memdev->memdev->range_index == range_index)
821                         if (n-- == 0)
822                                 return nfit_memdev->memdev;
823         return NULL;
824 }
825
826 static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
827                 struct nd_region_desc *ndr_desc,
828                 struct acpi_nfit_system_address *spa)
829 {
830         int i, spa_type = nfit_spa_type(spa);
831         struct device *dev = acpi_desc->dev;
832         struct nd_interleave_set *nd_set;
833         u16 nr = ndr_desc->num_mappings;
834         struct nfit_set_info *info;
835
836         if (spa_type == NFIT_SPA_PM || spa_type == NFIT_SPA_VOLATILE)
837                 /* pass */;
838         else
839                 return 0;
840
841         nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
842         if (!nd_set)
843                 return -ENOMEM;
844
845         info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
846         if (!info)
847                 return -ENOMEM;
848         for (i = 0; i < nr; i++) {
849                 struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i];
850                 struct nfit_set_info_map *map = &info->mapping[i];
851                 struct nvdimm *nvdimm = nd_mapping->nvdimm;
852                 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
853                 struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
854                                 spa->range_index, i);
855
856                 if (!memdev || !nfit_mem->dcr) {
857                         dev_err(dev, "%s: failed to find DCR\n", __func__);
858                         return -ENODEV;
859                 }
860
861                 map->region_offset = memdev->region_offset;
862                 map->serial_number = nfit_mem->dcr->serial_number;
863         }
864
865         sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
866                         cmp_map, NULL);
867         nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
868         ndr_desc->nd_set = nd_set;
869         devm_kfree(dev, info);
870
871         return 0;
872 }
873
874 static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
875                 struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc,
876                 struct acpi_nfit_memory_map *memdev,
877                 struct acpi_nfit_system_address *spa)
878 {
879         struct nvdimm *nvdimm = acpi_nfit_dimm_by_handle(acpi_desc,
880                         memdev->device_handle);
881         struct nfit_mem *nfit_mem;
882         int blk_valid = 0;
883
884         if (!nvdimm) {
885                 dev_err(acpi_desc->dev, "spa%d dimm: %#x not found\n",
886                                 spa->range_index, memdev->device_handle);
887                 return -ENODEV;
888         }
889
890         nd_mapping->nvdimm = nvdimm;
891         switch (nfit_spa_type(spa)) {
892         case NFIT_SPA_PM:
893         case NFIT_SPA_VOLATILE:
894                 nd_mapping->start = memdev->address;
895                 nd_mapping->size = memdev->region_size;
896                 break;
897         case NFIT_SPA_DCR:
898                 nfit_mem = nvdimm_provider_data(nvdimm);
899                 if (!nfit_mem || !nfit_mem->bdw) {
900                         dev_dbg(acpi_desc->dev, "spa%d %s missing bdw\n",
901                                         spa->range_index, nvdimm_name(nvdimm));
902                 } else {
903                         nd_mapping->size = nfit_mem->bdw->capacity;
904                         nd_mapping->start = nfit_mem->bdw->start_address;
905                         ndr_desc->num_lanes = nfit_mem->bdw->windows;
906                         blk_valid = 1;
907                 }
908
909                 ndr_desc->nd_mapping = nd_mapping;
910                 ndr_desc->num_mappings = blk_valid;
911                 if (!nvdimm_blk_region_create(acpi_desc->nvdimm_bus, ndr_desc))
912                         return -ENOMEM;
913                 break;
914         }
915
916         return 0;
917 }
918
919 static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
920                 struct nfit_spa *nfit_spa)
921 {
922         static struct nd_mapping nd_mappings[ND_MAX_MAPPINGS];
923         struct acpi_nfit_system_address *spa = nfit_spa->spa;
924         struct nfit_memdev *nfit_memdev;
925         struct nd_region_desc ndr_desc;
926         struct nvdimm_bus *nvdimm_bus;
927         struct resource res;
928         int count = 0, rc;
929
930         if (spa->range_index == 0) {
931                 dev_dbg(acpi_desc->dev, "%s: detected invalid spa index\n",
932                                 __func__);
933                 return 0;
934         }
935
936         memset(&res, 0, sizeof(res));
937         memset(&nd_mappings, 0, sizeof(nd_mappings));
938         memset(&ndr_desc, 0, sizeof(ndr_desc));
939         res.start = spa->address;
940         res.end = res.start + spa->length - 1;
941         ndr_desc.res = &res;
942         ndr_desc.provider_data = nfit_spa;
943         ndr_desc.attr_groups = acpi_nfit_region_attribute_groups;
944         list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
945                 struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
946                 struct nd_mapping *nd_mapping;
947
948                 if (memdev->range_index != spa->range_index)
949                         continue;
950                 if (count >= ND_MAX_MAPPINGS) {
951                         dev_err(acpi_desc->dev, "spa%d exceeds max mappings %d\n",
952                                         spa->range_index, ND_MAX_MAPPINGS);
953                         return -ENXIO;
954                 }
955                 nd_mapping = &nd_mappings[count++];
956                 rc = acpi_nfit_init_mapping(acpi_desc, nd_mapping, &ndr_desc,
957                                 memdev, spa);
958                 if (rc)
959                         return rc;
960         }
961
962         ndr_desc.nd_mapping = nd_mappings;
963         ndr_desc.num_mappings = count;
964         rc = acpi_nfit_init_interleave_set(acpi_desc, &ndr_desc, spa);
965         if (rc)
966                 return rc;
967
968         nvdimm_bus = acpi_desc->nvdimm_bus;
969         if (nfit_spa_type(spa) == NFIT_SPA_PM) {
970                 if (!nvdimm_pmem_region_create(nvdimm_bus, &ndr_desc))
971                         return -ENOMEM;
972         } else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE) {
973                 if (!nvdimm_volatile_region_create(nvdimm_bus, &ndr_desc))
974                         return -ENOMEM;
975         }
976         return 0;
977 }
978
979 static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
980 {
981         struct nfit_spa *nfit_spa;
982
983         list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
984                 int rc = acpi_nfit_register_region(acpi_desc, nfit_spa);
985
986                 if (rc)
987                         return rc;
988         }
989         return 0;
990 }
991
992 static int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz)
993 {
994         struct device *dev = acpi_desc->dev;
995         const void *end;
996         u8 *data;
997         int rc;
998
999         INIT_LIST_HEAD(&acpi_desc->spas);
1000         INIT_LIST_HEAD(&acpi_desc->dcrs);
1001         INIT_LIST_HEAD(&acpi_desc->bdws);
1002         INIT_LIST_HEAD(&acpi_desc->memdevs);
1003         INIT_LIST_HEAD(&acpi_desc->dimms);
1004
1005         data = (u8 *) acpi_desc->nfit;
1006         end = data + sz;
1007         data += sizeof(struct acpi_table_nfit);
1008         while (!IS_ERR_OR_NULL(data))
1009                 data = add_table(acpi_desc, data, end);
1010
1011         if (IS_ERR(data)) {
1012                 dev_dbg(dev, "%s: nfit table parsing error: %ld\n", __func__,
1013                                 PTR_ERR(data));
1014                 return PTR_ERR(data);
1015         }
1016
1017         if (nfit_mem_init(acpi_desc) != 0)
1018                 return -ENOMEM;
1019
1020         acpi_nfit_init_dsms(acpi_desc);
1021
1022         rc = acpi_nfit_register_dimms(acpi_desc);
1023         if (rc)
1024                 return rc;
1025
1026         return acpi_nfit_register_regions(acpi_desc);
1027 }
1028
1029 static int acpi_nfit_add(struct acpi_device *adev)
1030 {
1031         struct nvdimm_bus_descriptor *nd_desc;
1032         struct acpi_nfit_desc *acpi_desc;
1033         struct device *dev = &adev->dev;
1034         struct acpi_table_header *tbl;
1035         acpi_status status = AE_OK;
1036         acpi_size sz;
1037         int rc;
1038
1039         status = acpi_get_table_with_size("NFIT", 0, &tbl, &sz);
1040         if (ACPI_FAILURE(status)) {
1041                 dev_err(dev, "failed to find NFIT\n");
1042                 return -ENXIO;
1043         }
1044
1045         acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
1046         if (!acpi_desc)
1047                 return -ENOMEM;
1048
1049         dev_set_drvdata(dev, acpi_desc);
1050         acpi_desc->dev = dev;
1051         acpi_desc->nfit = (struct acpi_table_nfit *) tbl;
1052         nd_desc = &acpi_desc->nd_desc;
1053         nd_desc->provider_name = "ACPI.NFIT";
1054         nd_desc->ndctl = acpi_nfit_ctl;
1055         nd_desc->attr_groups = acpi_nfit_attribute_groups;
1056
1057         acpi_desc->nvdimm_bus = nvdimm_bus_register(dev, nd_desc);
1058         if (!acpi_desc->nvdimm_bus)
1059                 return -ENXIO;
1060
1061         rc = acpi_nfit_init(acpi_desc, sz);
1062         if (rc) {
1063                 nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1064                 return rc;
1065         }
1066         return 0;
1067 }
1068
1069 static int acpi_nfit_remove(struct acpi_device *adev)
1070 {
1071         struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev);
1072
1073         nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1074         return 0;
1075 }
1076
1077 static const struct acpi_device_id acpi_nfit_ids[] = {
1078         { "ACPI0012", 0 },
1079         { "", 0 },
1080 };
1081 MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
1082
1083 static struct acpi_driver acpi_nfit_driver = {
1084         .name = KBUILD_MODNAME,
1085         .ids = acpi_nfit_ids,
1086         .ops = {
1087                 .add = acpi_nfit_add,
1088                 .remove = acpi_nfit_remove,
1089         },
1090 };
1091
1092 static __init int nfit_init(void)
1093 {
1094         BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
1095         BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
1096         BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
1097         BUILD_BUG_ON(sizeof(struct acpi_nfit_interleave) != 20);
1098         BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9);
1099         BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80);
1100         BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40);
1101
1102         acpi_str_to_uuid(UUID_VOLATILE_MEMORY, nfit_uuid[NFIT_SPA_VOLATILE]);
1103         acpi_str_to_uuid(UUID_PERSISTENT_MEMORY, nfit_uuid[NFIT_SPA_PM]);
1104         acpi_str_to_uuid(UUID_CONTROL_REGION, nfit_uuid[NFIT_SPA_DCR]);
1105         acpi_str_to_uuid(UUID_DATA_REGION, nfit_uuid[NFIT_SPA_BDW]);
1106         acpi_str_to_uuid(UUID_VOLATILE_VIRTUAL_DISK, nfit_uuid[NFIT_SPA_VDISK]);
1107         acpi_str_to_uuid(UUID_VOLATILE_VIRTUAL_CD, nfit_uuid[NFIT_SPA_VCD]);
1108         acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_DISK, nfit_uuid[NFIT_SPA_PDISK]);
1109         acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_CD, nfit_uuid[NFIT_SPA_PCD]);
1110         acpi_str_to_uuid(UUID_NFIT_BUS, nfit_uuid[NFIT_DEV_BUS]);
1111         acpi_str_to_uuid(UUID_NFIT_DIMM, nfit_uuid[NFIT_DEV_DIMM]);
1112
1113         return acpi_bus_register_driver(&acpi_nfit_driver);
1114 }
1115
1116 static __exit void nfit_exit(void)
1117 {
1118         acpi_bus_unregister_driver(&acpi_nfit_driver);
1119 }
1120
1121 module_init(nfit_init);
1122 module_exit(nfit_exit);
1123 MODULE_LICENSE("GPL v2");
1124 MODULE_AUTHOR("Intel Corporation");