summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--flash.h2
-rw-r--r--flashrom.c33
2 files changed, 35 insertions, 0 deletions
diff --git a/flash.h b/flash.h
index 9238c2a..1474a38 100644
--- a/flash.h
+++ b/flash.h
@@ -99,6 +99,8 @@ struct programmer_entry {
extern const struct programmer_entry programmer_table[];
+int register_shutdown(void (*function) (void *data), void *data);
+
int programmer_init(void);
int programmer_shutdown(void);
void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
diff --git a/flashrom.c b/flashrom.c
index 3710606..b8de3c1 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -308,6 +308,35 @@ const struct programmer_entry programmer_table[] = {
{}, /* This entry corresponds to PROGRAMMER_INVALID. */
};
+#define SHUTDOWN_MAXFN 4
+static int shutdown_fn_count = 0;
+struct shutdown_func_data {
+ void (*func) (void *data);
+ void *data;
+} shutdown_fn[SHUTDOWN_MAXFN];
+
+/* Register a function to be executed on programmer shutdown.
+ * The advantage over atexit() is that you can supply a void pointer which will
+ * be used as parameter to the registered function upon programmer shutdown.
+ * This pointer can point to arbitrary data used by said function, e.g. undo
+ * information for GPIO settings etc. If unneeded, set data=NULL.
+ * Please note that the first (void *data) belongs to the function signature of
+ * the function passed as first parameter.
+ */
+int register_shutdown(void (*function) (void *data), void *data)
+{
+ if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
+ msg_perr("Tried to register more than %n shutdown functions.\n",
+ SHUTDOWN_MAXFN);
+ return 1;
+ }
+ shutdown_fn[shutdown_fn_count].func = function;
+ shutdown_fn[shutdown_fn_count].data = data;
+ shutdown_fn_count++;
+
+ return 0;
+}
+
int programmer_init(void)
{
return programmer_table[programmer].init();
@@ -315,6 +344,10 @@ int programmer_init(void)
int programmer_shutdown(void)
{
+ int i;
+
+ for (i = shutdown_fn_count - 1; i >= 0; i--)
+ shutdown_fn[i].func(shutdown_fn[i].data);
return programmer_table[programmer].shutdown();
}
OpenPOWER on IntegriCloud