diff options
author | Tony Lindgren <tony@atomide.com> | 2011-11-07 12:27:23 -0800 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-11-07 12:27:23 -0800 |
commit | d30cc16c8e48368e0518f4975a78711e53e14a0f (patch) | |
tree | 26b57f7ab5a963cc3d6c57dff6951bd930875583 /arch/powerpc/platforms/powernv/opal-nvram.c | |
parent | 41eb2d813f558900884e240c2f723e36c7bd151f (diff) | |
parent | a1bcc1dcef8451b4291ea2a1b2677cb194102952 (diff) | |
download | op-kernel-dev-d30cc16c8e48368e0518f4975a78711e53e14a0f.zip op-kernel-dev-d30cc16c8e48368e0518f4975a78711e53e14a0f.tar.gz |
Merge branch 'fixes-modulesplit' into fixes
Diffstat (limited to 'arch/powerpc/platforms/powernv/opal-nvram.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-nvram.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c new file mode 100644 index 0000000..3f83e1a --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-nvram.c @@ -0,0 +1,88 @@ +/* + * PowerNV nvram code. + * + * Copyright 2011 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define DEBUG + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/of.h> + +#include <asm/opal.h> +#include <asm/machdep.h> + +static unsigned int nvram_size; + +static ssize_t opal_nvram_size(void) +{ + return nvram_size; +} + +static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index) +{ + s64 rc; + int off; + + if (*index >= nvram_size) + return 0; + off = *index; + if ((off + count) > nvram_size) + count = nvram_size - off; + rc = opal_read_nvram(__pa(buf), count, off); + if (rc != OPAL_SUCCESS) + return -EIO; + *index += count; + return count; +} + +static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) +{ + s64 rc = OPAL_BUSY; + int off; + + if (*index >= nvram_size) + return 0; + off = *index; + if ((off + count) > nvram_size) + count = nvram_size - off; + + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { + rc = opal_write_nvram(__pa(buf), count, off); + if (rc == OPAL_BUSY_EVENT) + opal_poll_events(NULL); + } + *index += count; + return count; +} + +void __init opal_nvram_init(void) +{ + struct device_node *np; + const u32 *nbytes_p; + + np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram"); + if (np == NULL) + return; + + nbytes_p = of_get_property(np, "#bytes", NULL); + if (!nbytes_p) { + of_node_put(np); + return; + } + nvram_size = *nbytes_p; + + printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size); + of_node_put(np); + + ppc_md.nvram_read = opal_nvram_read; + ppc_md.nvram_write = opal_nvram_write; + ppc_md.nvram_size = opal_nvram_size; +} + |