powerpc/powernv: Add interfaces for flash device access
authorCyril Bur <cyrilbur@gmail.com>
Wed, 1 Apr 2015 06:05:30 +0000 (14:05 +0800)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 11 Apr 2015 10:49:21 +0000 (20:49 +1000)
This change adds the OPAL interface definitions to allow Linux to read,
write and erase from system flash devices. We register platform devices
for the flash devices exported by firmware.

We clash with the existing opal_flash_init function, which is really for
the FSP flash update functionality, so we rename that initcall to
opal_flash_update_init().

A future change will add an mtd driver that uses this interface.

Changes from Joel Stanley and Jeremy Kerr.

Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Acked-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/opal-api.h
arch/powerpc/include/asm/opal.h
arch/powerpc/platforms/powernv/opal-flash.c
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/powerpc/platforms/powernv/opal.c

index e8a6baf55e8266e5bf6f4817e54ee86794d48fcc..0321a909e663bf1899e81154bfcff65b0febd7b1 100644 (file)
 #define OPAL_IPMI_SEND                         107
 #define OPAL_IPMI_RECV                         108
 #define OPAL_I2C_REQUEST                       109
-#define OPAL_LAST                              109
+#define OPAL_FLASH_READ                                110
+#define OPAL_FLASH_WRITE                       111
+#define OPAL_FLASH_ERASE                       112
+#define OPAL_LAST                              112
 
 /* Device tree flags */
 
index fde90bacc65ef09b27975dacb2554242ddf97177..042af1abfc4dd02a5f0902bd41b7e67237bfdfbd 100644 (file)
@@ -194,6 +194,13 @@ int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
                         struct opal_i2c_request *oreq);
 
+int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
+               uint64_t size, uint64_t token);
+int64_t opal_flash_write(uint64_t id, uint64_t offset, uint64_t buf,
+               uint64_t size, uint64_t token);
+int64_t opal_flash_erase(uint64_t id, uint64_t offset, uint64_t size,
+               uint64_t token);
+
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
                                   int depth, void *data);
@@ -226,7 +233,7 @@ extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
 struct rtc_time;
 extern unsigned long opal_get_boot_time(void);
 extern void opal_nvram_init(void);
-extern void opal_flash_init(void);
+extern void opal_flash_update_init(void);
 extern void opal_flash_term_callback(void);
 extern int opal_elog_init(void);
 extern void opal_platform_dump_init(void);
index 0ff07ff891f01991fccbed28a90185de5961af62..4ec6219287fc3a0caba84d9f07cbd978e4ffe825 100644 (file)
@@ -546,7 +546,7 @@ static struct attribute_group image_op_attr_group = {
        .attrs = image_op_attrs,
 };
 
-void __init opal_flash_init(void)
+void __init opal_flash_update_init(void)
 {
        int ret;
 
index b23fe7c4bf124347a014f39663f39f9191219e12..4e740375772c080d047b4eebb4da1e0a137dbed1 100644 (file)
@@ -292,3 +292,6 @@ OPAL_CALL(opal_tpo_read,                    OPAL_READ_TPO);
 OPAL_CALL(opal_ipmi_send,                      OPAL_IPMI_SEND);
 OPAL_CALL(opal_ipmi_recv,                      OPAL_IPMI_RECV);
 OPAL_CALL(opal_i2c_request,                    OPAL_I2C_REQUEST);
+OPAL_CALL(opal_flash_read,                     OPAL_FLASH_READ);
+OPAL_CALL(opal_flash_write,                    OPAL_FLASH_WRITE);
+OPAL_CALL(opal_flash_erase,                    OPAL_FLASH_ERASE);
index 3fb981c0ca8046757f47e9d40dfd8d594ce66790..2241565b0739ff3bc6dc84f9bc6c63c70edf8b8c 100644 (file)
@@ -693,6 +693,15 @@ static void __init opal_dump_region_init(void)
                        "rc = %d\n", rc);
 }
 
+static void opal_flash_init(struct device_node *opal_node)
+{
+       struct device_node *np;
+
+       for_each_child_of_node(opal_node, np)
+               if (of_device_is_compatible(np, "ibm,opal-flash"))
+                       of_platform_device_create(np, NULL, NULL);
+}
+
 static void opal_ipmi_init(struct device_node *opal_node)
 {
        struct device_node *np;
@@ -817,7 +826,7 @@ static int __init opal_init(void)
                /* Setup error log interface */
                rc = opal_elog_init();
                /* Setup code update interface */
-               opal_flash_init();
+               opal_flash_update_init();
                /* Setup platform dump extract interface */
                opal_platform_dump_init();
                /* Setup system parameters interface */
@@ -829,6 +838,8 @@ static int __init opal_init(void)
        /* Initialize OPAL IPMI backend */
        opal_ipmi_init(opal_node);
 
+       opal_flash_init(opal_node);
+
        return 0;
 }
 machine_subsys_initcall(powernv, opal_init);
@@ -867,6 +878,9 @@ void opal_shutdown(void)
 EXPORT_SYMBOL_GPL(opal_invalid_call);
 EXPORT_SYMBOL_GPL(opal_ipmi_send);
 EXPORT_SYMBOL_GPL(opal_ipmi_recv);
+EXPORT_SYMBOL_GPL(opal_flash_read);
+EXPORT_SYMBOL_GPL(opal_flash_write);
+EXPORT_SYMBOL_GPL(opal_flash_erase);
 
 /* Convert a region of vmalloc memory to an opal sg list */
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,