kernel-ark/arch/x86/kernel/pmem.c
Christoph Hellwig ec776ef6bb x86/mm: Add support for the non-standard protected e820 type
Various recent BIOSes support NVDIMMs or ADR using a
non-standard e820 memory type, and Intel supplied reference
Linux code using this type to various vendors.

Wire this e820 table type up to export platform devices for the
pmem driver so that we can use it in Linux.

Based on earlier work from:

   Dave Jiang <dave.jiang@intel.com>
   Dan Williams <dan.j.williams@intel.com>

Includes fixes for NUMA regions from Boaz Harrosh.

Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Boaz Harrosh <boaz@plexistor.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Wilcox <willy@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-nvdimm@ml01.01.org
Link: http://lkml.kernel.org/r/1427872339-6688-2-git-send-email-hch@lst.de
[ Minor cleanups. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2015-04-01 17:02:43 +02:00

54 lines
1.0 KiB
C

/*
* Copyright (c) 2015, Christoph Hellwig.
*/
#include <linux/memblock.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/e820.h>
#include <asm/page_types.h>
#include <asm/setup.h>
static __init void register_pmem_device(struct resource *res)
{
struct platform_device *pdev;
int error;
pdev = platform_device_alloc("pmem", PLATFORM_DEVID_AUTO);
if (!pdev)
return;
error = platform_device_add_resources(pdev, res, 1);
if (error)
goto out_put_pdev;
error = platform_device_add(pdev);
if (error)
goto out_put_pdev;
return;
out_put_pdev:
dev_warn(&pdev->dev, "failed to add 'pmem' (persistent memory) device!\n");
platform_device_put(pdev);
}
static __init int register_pmem_devices(void)
{
int i;
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
if (ei->type == E820_PRAM) {
struct resource res = {
.flags = IORESOURCE_MEM,
.start = ei->addr,
.end = ei->addr + ei->size - 1,
};
register_pmem_device(&res);
}
}
return 0;
}
device_initcall(register_pmem_devices);