aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-10-07 19:46:24 -0400
committerDan Williams <dan.j.williams@intel.com>2016-10-07 19:46:24 -0400
commit178d6f4be8bf42b298bedf8ea2a00754100e0c4e (patch)
treea71865455adc31082a4ad21a942286520a7b5da1 /tools
parentdb58028ee4e360430de8e3b48f657dc798ee6591 (diff)
parent98a29c39dc689298d2f834f40102cba752eb49c0 (diff)
Merge branch 'for-4.9/libnvdimm' into libnvdimm-for-next
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/nvdimm/Kbuild1
-rw-r--r--tools/testing/nvdimm/test/iomap.c151
-rw-r--r--tools/testing/nvdimm/test/nfit.c160
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h12
4 files changed, 276 insertions, 48 deletions
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index ad6dd0543019..582db95127ed 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -13,6 +13,7 @@ ldflags-y += --wrap=__release_region
13ldflags-y += --wrap=devm_memremap_pages 13ldflags-y += --wrap=devm_memremap_pages
14ldflags-y += --wrap=insert_resource 14ldflags-y += --wrap=insert_resource
15ldflags-y += --wrap=remove_resource 15ldflags-y += --wrap=remove_resource
16ldflags-y += --wrap=acpi_evaluate_object
16 17
17DRIVERS := ../../../drivers 18DRIVERS := ../../../drivers
18NVDIMM_SRC := $(DRIVERS)/nvdimm 19NVDIMM_SRC := $(DRIVERS)/nvdimm
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index c29f8dca9e67..3ccef732fce9 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/pfn_t.h> 19#include <linux/pfn_t.h>
20#include <linux/acpi.h>
20#include <linux/io.h> 21#include <linux/io.h>
21#include <linux/mm.h> 22#include <linux/mm.h>
22#include "nfit_test.h" 23#include "nfit_test.h"
@@ -73,7 +74,7 @@ void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size,
73 74
74 if (nfit_res) 75 if (nfit_res)
75 return (void __iomem *) nfit_res->buf + offset 76 return (void __iomem *) nfit_res->buf + offset
76 - nfit_res->res->start; 77 - nfit_res->res.start;
77 return fallback_fn(offset, size); 78 return fallback_fn(offset, size);
78} 79}
79 80
@@ -84,7 +85,7 @@ void __iomem *__wrap_devm_ioremap_nocache(struct device *dev,
84 85
85 if (nfit_res) 86 if (nfit_res)
86 return (void __iomem *) nfit_res->buf + offset 87 return (void __iomem *) nfit_res->buf + offset
87 - nfit_res->res->start; 88 - nfit_res->res.start;
88 return devm_ioremap_nocache(dev, offset, size); 89 return devm_ioremap_nocache(dev, offset, size);
89} 90}
90EXPORT_SYMBOL(__wrap_devm_ioremap_nocache); 91EXPORT_SYMBOL(__wrap_devm_ioremap_nocache);
@@ -95,7 +96,7 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
95 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 96 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
96 97
97 if (nfit_res) 98 if (nfit_res)
98 return nfit_res->buf + offset - nfit_res->res->start; 99 return nfit_res->buf + offset - nfit_res->res.start;
99 return devm_memremap(dev, offset, size, flags); 100 return devm_memremap(dev, offset, size, flags);
100} 101}
101EXPORT_SYMBOL(__wrap_devm_memremap); 102EXPORT_SYMBOL(__wrap_devm_memremap);
@@ -107,7 +108,7 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
107 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 108 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
108 109
109 if (nfit_res) 110 if (nfit_res)
110 return nfit_res->buf + offset - nfit_res->res->start; 111 return nfit_res->buf + offset - nfit_res->res.start;
111 return devm_memremap_pages(dev, res, ref, altmap); 112 return devm_memremap_pages(dev, res, ref, altmap);
112} 113}
113EXPORT_SYMBOL(__wrap_devm_memremap_pages); 114EXPORT_SYMBOL(__wrap_devm_memremap_pages);
@@ -128,7 +129,7 @@ void *__wrap_memremap(resource_size_t offset, size_t size,
128 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 129 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
129 130
130 if (nfit_res) 131 if (nfit_res)
131 return nfit_res->buf + offset - nfit_res->res->start; 132 return nfit_res->buf + offset - nfit_res->res.start;
132 return memremap(offset, size, flags); 133 return memremap(offset, size, flags);
133} 134}
134EXPORT_SYMBOL(__wrap_memremap); 135EXPORT_SYMBOL(__wrap_memremap);
@@ -174,6 +175,63 @@ void __wrap_memunmap(void *addr)
174} 175}
175EXPORT_SYMBOL(__wrap_memunmap); 176EXPORT_SYMBOL(__wrap_memunmap);
176 177
178static bool nfit_test_release_region(struct device *dev,
179 struct resource *parent, resource_size_t start,
180 resource_size_t n);
181
182static void nfit_devres_release(struct device *dev, void *data)
183{
184 struct resource *res = *((struct resource **) data);
185
186 WARN_ON(!nfit_test_release_region(NULL, &iomem_resource, res->start,
187 resource_size(res)));
188}
189
190static int match(struct device *dev, void *__res, void *match_data)
191{
192 struct resource *res = *((struct resource **) __res);
193 resource_size_t start = *((resource_size_t *) match_data);
194
195 return res->start == start;
196}
197
198static bool nfit_test_release_region(struct device *dev,
199 struct resource *parent, resource_size_t start,
200 resource_size_t n)
201{
202 if (parent == &iomem_resource) {
203 struct nfit_test_resource *nfit_res = get_nfit_res(start);
204
205 if (nfit_res) {
206 struct nfit_test_request *req;
207 struct resource *res = NULL;
208
209 if (dev) {
210 devres_release(dev, nfit_devres_release, match,
211 &start);
212 return true;
213 }
214
215 spin_lock(&nfit_res->lock);
216 list_for_each_entry(req, &nfit_res->requests, list)
217 if (req->res.start == start) {
218 res = &req->res;
219 list_del(&req->list);
220 break;
221 }
222 spin_unlock(&nfit_res->lock);
223
224 WARN(!res || resource_size(res) != n,
225 "%s: start: %llx n: %llx mismatch: %pr\n",
226 __func__, start, n, res);
227 if (res)
228 kfree(req);
229 return true;
230 }
231 }
232 return false;
233}
234
177static struct resource *nfit_test_request_region(struct device *dev, 235static struct resource *nfit_test_request_region(struct device *dev,
178 struct resource *parent, resource_size_t start, 236 struct resource *parent, resource_size_t start,
179 resource_size_t n, const char *name, int flags) 237 resource_size_t n, const char *name, int flags)
@@ -183,21 +241,57 @@ static struct resource *nfit_test_request_region(struct device *dev,
183 if (parent == &iomem_resource) { 241 if (parent == &iomem_resource) {
184 nfit_res = get_nfit_res(start); 242 nfit_res = get_nfit_res(start);
185 if (nfit_res) { 243 if (nfit_res) {
186 struct resource *res = nfit_res->res + 1; 244 struct nfit_test_request *req;
245 struct resource *res = NULL;
187 246
188 if (start + n > nfit_res->res->start 247 if (start + n > nfit_res->res.start
189 + resource_size(nfit_res->res)) { 248 + resource_size(&nfit_res->res)) {
190 pr_debug("%s: start: %llx n: %llx overflow: %pr\n", 249 pr_debug("%s: start: %llx n: %llx overflow: %pr\n",
191 __func__, start, n, 250 __func__, start, n,
192 nfit_res->res); 251 &nfit_res->res);
193 return NULL; 252 return NULL;
194 } 253 }
195 254
255 spin_lock(&nfit_res->lock);
256 list_for_each_entry(req, &nfit_res->requests, list)
257 if (start == req->res.start) {
258 res = &req->res;
259 break;
260 }
261 spin_unlock(&nfit_res->lock);
262
263 if (res) {
264 WARN(1, "%pr already busy\n", res);
265 return NULL;
266 }
267
268 req = kzalloc(sizeof(*req), GFP_KERNEL);
269 if (!req)
270 return NULL;
271 INIT_LIST_HEAD(&req->list);
272 res = &req->res;
273
196 res->start = start; 274 res->start = start;
197 res->end = start + n - 1; 275 res->end = start + n - 1;
198 res->name = name; 276 res->name = name;
199 res->flags = resource_type(parent); 277 res->flags = resource_type(parent);
200 res->flags |= IORESOURCE_BUSY | flags; 278 res->flags |= IORESOURCE_BUSY | flags;
279 spin_lock(&nfit_res->lock);
280 list_add(&req->list, &nfit_res->requests);
281 spin_unlock(&nfit_res->lock);
282
283 if (dev) {
284 struct resource **d;
285
286 d = devres_alloc(nfit_devres_release,
287 sizeof(struct resource *),
288 GFP_KERNEL);
289 if (!d)
290 return NULL;
291 *d = res;
292 devres_add(dev, d);
293 }
294
201 pr_debug("%s: %pr\n", __func__, res); 295 pr_debug("%s: %pr\n", __func__, res);
202 return res; 296 return res;
203 } 297 }
@@ -241,29 +335,10 @@ struct resource *__wrap___devm_request_region(struct device *dev,
241} 335}
242EXPORT_SYMBOL(__wrap___devm_request_region); 336EXPORT_SYMBOL(__wrap___devm_request_region);
243 337
244static bool nfit_test_release_region(struct resource *parent,
245 resource_size_t start, resource_size_t n)
246{
247 if (parent == &iomem_resource) {
248 struct nfit_test_resource *nfit_res = get_nfit_res(start);
249 if (nfit_res) {
250 struct resource *res = nfit_res->res + 1;
251
252 if (start != res->start || resource_size(res) != n)
253 pr_info("%s: start: %llx n: %llx mismatch: %pr\n",
254 __func__, start, n, res);
255 else
256 memset(res, 0, sizeof(*res));
257 return true;
258 }
259 }
260 return false;
261}
262
263void __wrap___release_region(struct resource *parent, resource_size_t start, 338void __wrap___release_region(struct resource *parent, resource_size_t start,
264 resource_size_t n) 339 resource_size_t n)
265{ 340{
266 if (!nfit_test_release_region(parent, start, n)) 341 if (!nfit_test_release_region(NULL, parent, start, n))
267 __release_region(parent, start, n); 342 __release_region(parent, start, n);
268} 343}
269EXPORT_SYMBOL(__wrap___release_region); 344EXPORT_SYMBOL(__wrap___release_region);
@@ -271,9 +346,25 @@ EXPORT_SYMBOL(__wrap___release_region);
271void __wrap___devm_release_region(struct device *dev, struct resource *parent, 346void __wrap___devm_release_region(struct device *dev, struct resource *parent,
272 resource_size_t start, resource_size_t n) 347 resource_size_t start, resource_size_t n)
273{ 348{
274 if (!nfit_test_release_region(parent, start, n)) 349 if (!nfit_test_release_region(dev, parent, start, n))
275 __devm_release_region(dev, parent, start, n); 350 __devm_release_region(dev, parent, start, n);
276} 351}
277EXPORT_SYMBOL(__wrap___devm_release_region); 352EXPORT_SYMBOL(__wrap___devm_release_region);
278 353
354acpi_status __wrap_acpi_evaluate_object(acpi_handle handle, acpi_string path,
355 struct acpi_object_list *p, struct acpi_buffer *buf)
356{
357 struct nfit_test_resource *nfit_res = get_nfit_res((long) handle);
358 union acpi_object **obj;
359
360 if (!nfit_res || strcmp(path, "_FIT") || !buf)
361 return acpi_evaluate_object(handle, path, p, buf);
362
363 obj = nfit_res->buf;
364 buf->length = sizeof(union acpi_object);
365 buf->pointer = *obj;
366 return AE_OK;
367}
368EXPORT_SYMBOL(__wrap_acpi_evaluate_object);
369
279MODULE_LICENSE("GPL v2"); 370MODULE_LICENSE("GPL v2");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index f64c57bf1d4b..c9a6458cb63e 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -132,6 +132,8 @@ static u32 handle[NUM_DCR] = {
132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0), 132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
133}; 133};
134 134
135static unsigned long dimm_fail_cmd_flags[NUM_DCR];
136
135struct nfit_test { 137struct nfit_test {
136 struct acpi_nfit_desc acpi_desc; 138 struct acpi_nfit_desc acpi_desc;
137 struct platform_device pdev; 139 struct platform_device pdev;
@@ -154,11 +156,14 @@ struct nfit_test {
154 int (*alloc)(struct nfit_test *t); 156 int (*alloc)(struct nfit_test *t);
155 void (*setup)(struct nfit_test *t); 157 void (*setup)(struct nfit_test *t);
156 int setup_hotplug; 158 int setup_hotplug;
159 union acpi_object **_fit;
160 dma_addr_t _fit_dma;
157 struct ars_state { 161 struct ars_state {
158 struct nd_cmd_ars_status *ars_status; 162 struct nd_cmd_ars_status *ars_status;
159 unsigned long deadline; 163 unsigned long deadline;
160 spinlock_t lock; 164 spinlock_t lock;
161 } ars_state; 165 } ars_state;
166 struct device *dimm_dev[NUM_DCR];
162}; 167};
163 168
164static struct nfit_test *to_nfit_test(struct device *dev) 169static struct nfit_test *to_nfit_test(struct device *dev)
@@ -411,6 +416,9 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
411 if (i >= ARRAY_SIZE(handle)) 416 if (i >= ARRAY_SIZE(handle))
412 return -ENXIO; 417 return -ENXIO;
413 418
419 if ((1 << func) & dimm_fail_cmd_flags[i])
420 return -EIO;
421
414 switch (func) { 422 switch (func) {
415 case ND_CMD_GET_CONFIG_SIZE: 423 case ND_CMD_GET_CONFIG_SIZE:
416 rc = nfit_test_cmd_get_config_size(buf, buf_len); 424 rc = nfit_test_cmd_get_config_size(buf, buf_len);
@@ -428,6 +436,9 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
428 break; 436 break;
429 case ND_CMD_SMART_THRESHOLD: 437 case ND_CMD_SMART_THRESHOLD:
430 rc = nfit_test_cmd_smart_threshold(buf, buf_len); 438 rc = nfit_test_cmd_smart_threshold(buf, buf_len);
439 device_lock(&t->pdev.dev);
440 __acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
441 device_unlock(&t->pdev.dev);
431 break; 442 break;
432 default: 443 default:
433 return -ENOTTY; 444 return -ENOTTY;
@@ -467,14 +478,12 @@ static struct nfit_test *instances[NUM_NFITS];
467static void release_nfit_res(void *data) 478static void release_nfit_res(void *data)
468{ 479{
469 struct nfit_test_resource *nfit_res = data; 480 struct nfit_test_resource *nfit_res = data;
470 struct resource *res = nfit_res->res;
471 481
472 spin_lock(&nfit_test_lock); 482 spin_lock(&nfit_test_lock);
473 list_del(&nfit_res->list); 483 list_del(&nfit_res->list);
474 spin_unlock(&nfit_test_lock); 484 spin_unlock(&nfit_test_lock);
475 485
476 vfree(nfit_res->buf); 486 vfree(nfit_res->buf);
477 kfree(res);
478 kfree(nfit_res); 487 kfree(nfit_res);
479} 488}
480 489
@@ -482,12 +491,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
482 void *buf) 491 void *buf)
483{ 492{
484 struct device *dev = &t->pdev.dev; 493 struct device *dev = &t->pdev.dev;
485 struct resource *res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
486 struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res), 494 struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res),
487 GFP_KERNEL); 495 GFP_KERNEL);
488 int rc; 496 int rc;
489 497
490 if (!res || !buf || !nfit_res) 498 if (!buf || !nfit_res)
491 goto err; 499 goto err;
492 rc = devm_add_action(dev, release_nfit_res, nfit_res); 500 rc = devm_add_action(dev, release_nfit_res, nfit_res);
493 if (rc) 501 if (rc)
@@ -496,10 +504,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
496 memset(buf, 0, size); 504 memset(buf, 0, size);
497 nfit_res->dev = dev; 505 nfit_res->dev = dev;
498 nfit_res->buf = buf; 506 nfit_res->buf = buf;
499 nfit_res->res = res; 507 nfit_res->res.start = *dma;
500 res->start = *dma; 508 nfit_res->res.end = *dma + size - 1;
501 res->end = *dma + size - 1; 509 nfit_res->res.name = "NFIT";
502 res->name = "NFIT"; 510 spin_lock_init(&nfit_res->lock);
511 INIT_LIST_HEAD(&nfit_res->requests);
503 spin_lock(&nfit_test_lock); 512 spin_lock(&nfit_test_lock);
504 list_add(&nfit_res->list, &t->resources); 513 list_add(&nfit_res->list, &t->resources);
505 spin_unlock(&nfit_test_lock); 514 spin_unlock(&nfit_test_lock);
@@ -508,7 +517,6 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
508 err: 517 err:
509 if (buf) 518 if (buf)
510 vfree(buf); 519 vfree(buf);
511 kfree(res);
512 kfree(nfit_res); 520 kfree(nfit_res);
513 return NULL; 521 return NULL;
514} 522}
@@ -533,13 +541,13 @@ static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
533 continue; 541 continue;
534 spin_lock(&nfit_test_lock); 542 spin_lock(&nfit_test_lock);
535 list_for_each_entry(n, &t->resources, list) { 543 list_for_each_entry(n, &t->resources, list) {
536 if (addr >= n->res->start && (addr < n->res->start 544 if (addr >= n->res.start && (addr < n->res.start
537 + resource_size(n->res))) { 545 + resource_size(&n->res))) {
538 nfit_res = n; 546 nfit_res = n;
539 break; 547 break;
540 } else if (addr >= (unsigned long) n->buf 548 } else if (addr >= (unsigned long) n->buf
541 && (addr < (unsigned long) n->buf 549 && (addr < (unsigned long) n->buf
542 + resource_size(n->res))) { 550 + resource_size(&n->res))) {
543 nfit_res = n; 551 nfit_res = n;
544 break; 552 break;
545 } 553 }
@@ -564,6 +572,86 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state)
564 return 0; 572 return 0;
565} 573}
566 574
575static void put_dimms(void *data)
576{
577 struct device **dimm_dev = data;
578 int i;
579
580 for (i = 0; i < NUM_DCR; i++)
581 if (dimm_dev[i])
582 device_unregister(dimm_dev[i]);
583}
584
585static struct class *nfit_test_dimm;
586
587static int dimm_name_to_id(struct device *dev)
588{
589 int dimm;
590
591 if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
592 || dimm >= NUM_DCR || dimm < 0)
593 return -ENXIO;
594 return dimm;
595}
596
597
598static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
599 char *buf)
600{
601 int dimm = dimm_name_to_id(dev);
602
603 if (dimm < 0)
604 return dimm;
605
606 return sprintf(buf, "%#x", handle[dimm]);
607}
608DEVICE_ATTR_RO(handle);
609
610static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr,
611 char *buf)
612{
613 int dimm = dimm_name_to_id(dev);
614
615 if (dimm < 0)
616 return dimm;
617
618 return sprintf(buf, "%#lx\n", dimm_fail_cmd_flags[dimm]);
619}
620
621static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
622 const char *buf, size_t size)
623{
624 int dimm = dimm_name_to_id(dev);
625 unsigned long val;
626 ssize_t rc;
627
628 if (dimm < 0)
629 return dimm;
630
631 rc = kstrtol(buf, 0, &val);
632 if (rc)
633 return rc;
634
635 dimm_fail_cmd_flags[dimm] = val;
636 return size;
637}
638static DEVICE_ATTR_RW(fail_cmd);
639
640static struct attribute *nfit_test_dimm_attributes[] = {
641 &dev_attr_fail_cmd.attr,
642 &dev_attr_handle.attr,
643 NULL,
644};
645
646static struct attribute_group nfit_test_dimm_attribute_group = {
647 .attrs = nfit_test_dimm_attributes,
648};
649
650static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
651 &nfit_test_dimm_attribute_group,
652 NULL,
653};
654
567static int nfit_test0_alloc(struct nfit_test *t) 655static int nfit_test0_alloc(struct nfit_test *t)
568{ 656{
569 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA 657 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
@@ -616,6 +704,21 @@ static int nfit_test0_alloc(struct nfit_test *t)
616 return -ENOMEM; 704 return -ENOMEM;
617 } 705 }
618 706
707 t->_fit = test_alloc(t, sizeof(union acpi_object **), &t->_fit_dma);
708 if (!t->_fit)
709 return -ENOMEM;
710
711 if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
712 return -ENOMEM;
713 for (i = 0; i < NUM_DCR; i++) {
714 t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
715 &t->pdev.dev, 0, NULL,
716 nfit_test_dimm_attribute_groups,
717 "test_dimm%d", i);
718 if (!t->dimm_dev[i])
719 return -ENOMEM;
720 }
721
619 return ars_state_init(&t->pdev.dev, &t->ars_state); 722 return ars_state_init(&t->pdev.dev, &t->ars_state);
620} 723}
621 724
@@ -1409,6 +1512,8 @@ static int nfit_test_probe(struct platform_device *pdev)
1409 struct acpi_nfit_desc *acpi_desc; 1512 struct acpi_nfit_desc *acpi_desc;
1410 struct device *dev = &pdev->dev; 1513 struct device *dev = &pdev->dev;
1411 struct nfit_test *nfit_test; 1514 struct nfit_test *nfit_test;
1515 struct nfit_mem *nfit_mem;
1516 union acpi_object *obj;
1412 int rc; 1517 int rc;
1413 1518
1414 nfit_test = to_nfit_test(&pdev->dev); 1519 nfit_test = to_nfit_test(&pdev->dev);
@@ -1476,14 +1581,30 @@ static int nfit_test_probe(struct platform_device *pdev)
1476 if (nfit_test->setup != nfit_test0_setup) 1581 if (nfit_test->setup != nfit_test0_setup)
1477 return 0; 1582 return 0;
1478 1583
1479 flush_work(&acpi_desc->work);
1480 nfit_test->setup_hotplug = 1; 1584 nfit_test->setup_hotplug = 1;
1481 nfit_test->setup(nfit_test); 1585 nfit_test->setup(nfit_test);
1482 1586
1483 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf, 1587 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1484 nfit_test->nfit_size); 1588 if (!obj)
1485 if (rc) 1589 return -ENOMEM;
1486 return rc; 1590 obj->type = ACPI_TYPE_BUFFER;
1591 obj->buffer.length = nfit_test->nfit_size;
1592 obj->buffer.pointer = nfit_test->nfit_buf;
1593 *(nfit_test->_fit) = obj;
1594 __acpi_nfit_notify(&pdev->dev, nfit_test, 0x80);
1595
1596 /* associate dimm devices with nfit_mem data for notification testing */
1597 mutex_lock(&acpi_desc->init_mutex);
1598 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1599 u32 nfit_handle = __to_nfit_memdev(nfit_mem)->device_handle;
1600 int i;
1601
1602 for (i = 0; i < NUM_DCR; i++)
1603 if (nfit_handle == handle[i])
1604 dev_set_drvdata(nfit_test->dimm_dev[i],
1605 nfit_mem);
1606 }
1607 mutex_unlock(&acpi_desc->init_mutex);
1487 1608
1488 return 0; 1609 return 0;
1489} 1610}
@@ -1518,6 +1639,10 @@ static __init int nfit_test_init(void)
1518{ 1639{
1519 int rc, i; 1640 int rc, i;
1520 1641
1642 nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
1643 if (IS_ERR(nfit_test_dimm))
1644 return PTR_ERR(nfit_test_dimm);
1645
1521 nfit_test_setup(nfit_test_lookup); 1646 nfit_test_setup(nfit_test_lookup);
1522 1647
1523 for (i = 0; i < NUM_NFITS; i++) { 1648 for (i = 0; i < NUM_NFITS; i++) {
@@ -1584,6 +1709,7 @@ static __exit void nfit_test_exit(void)
1584 for (i = 0; i < NUM_NFITS; i++) 1709 for (i = 0; i < NUM_NFITS; i++)
1585 platform_device_unregister(&instances[i]->pdev); 1710 platform_device_unregister(&instances[i]->pdev);
1586 nfit_test_teardown(); 1711 nfit_test_teardown();
1712 class_destroy(nfit_test_dimm);
1587} 1713}
1588 1714
1589module_init(nfit_test_init); 1715module_init(nfit_test_init);
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 9f18e2a4a862..c281dd2e5e2d 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -13,11 +13,21 @@
13#ifndef __NFIT_TEST_H__ 13#ifndef __NFIT_TEST_H__
14#define __NFIT_TEST_H__ 14#define __NFIT_TEST_H__
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/ioport.h>
17#include <linux/spinlock_types.h>
18
19struct nfit_test_request {
20 struct list_head list;
21 struct resource res;
22};
16 23
17struct nfit_test_resource { 24struct nfit_test_resource {
25 struct list_head requests;
18 struct list_head list; 26 struct list_head list;
19 struct resource *res; 27 struct resource res;
20 struct device *dev; 28 struct device *dev;
29 spinlock_t lock;
30 int req_count;
21 void *buf; 31 void *buf;
22}; 32};
23 33