summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerve Codina <Herve.CODINA@celad.com>2015-07-06 09:36:43 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-07-13 08:28:19 +0200
commita2136e6cbd732e627f9f33d9211ba0a67be52889 (patch)
treec1aff563dc89e01ed4a801ec7045b19e00041de5
parentd46b6785c4bcd3ceb7d90895e9f44a7bf7d6757d (diff)
downloadbarebox-a2136e6cbd732e627f9f33d9211ba0a67be52889.tar.gz
barebox-a2136e6cbd732e627f9f33d9211ba0a67be52889.tar.xz
exitcall: Add exitcall infrastructure
exitcall infrastructure is based on initcall infrastructure. It allows to have and use exit call hooks on barebox shutdown. Signed-off-by: Herve Codina <Herve.CODINA@celad.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/lib/barebox.lds.S4
-rw-r--r--arch/blackfin/boards/ipe337/barebox.lds.S4
-rw-r--r--arch/efi/lib/elf_ia32_efi.lds.S4
-rw-r--r--arch/efi/lib/elf_x86_64_efi.lds.S4
-rw-r--r--arch/mips/lib/barebox.lds.S4
-rw-r--r--arch/nios2/cpu/barebox.lds.S4
-rw-r--r--arch/openrisc/cpu/barebox.lds.S4
-rw-r--r--arch/ppc/boards/pcm030/barebox.lds.S5
-rw-r--r--arch/ppc/mach-mpc85xx/barebox.lds.S5
-rw-r--r--arch/sandbox/board/barebox.lds.S5
-rw-r--r--arch/x86/lib/barebox.lds.S9
-rw-r--r--common/startup.c11
-rw-r--r--include/asm-generic/barebox.lds.h9
-rw-r--r--include/init.h15
14 files changed, 86 insertions, 1 deletions
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index bb0354ae29..5344557860 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -90,6 +90,10 @@ SECTIONS
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
__usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
diff --git a/arch/blackfin/boards/ipe337/barebox.lds.S b/arch/blackfin/boards/ipe337/barebox.lds.S
index 9bb7cc4953..51a586af27 100644
--- a/arch/blackfin/boards/ipe337/barebox.lds.S
+++ b/arch/blackfin/boards/ipe337/barebox.lds.S
@@ -76,6 +76,10 @@ SECTIONS
.barebox_initcalls : { INITCALLS }
___barebox_initcalls_end = .;
+ ___barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ ___barebox_exitcalls_end = .;
+
___usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
___usymtab_end = .;
diff --git a/arch/efi/lib/elf_ia32_efi.lds.S b/arch/efi/lib/elf_ia32_efi.lds.S
index a5f6287500..69f43f5547 100644
--- a/arch/efi/lib/elf_ia32_efi.lds.S
+++ b/arch/efi/lib/elf_ia32_efi.lds.S
@@ -56,6 +56,10 @@ SECTIONS
__barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ __barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
. = ALIGN(64);
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
diff --git a/arch/efi/lib/elf_x86_64_efi.lds.S b/arch/efi/lib/elf_x86_64_efi.lds.S
index d48432d21b..9aa4e8d829 100644
--- a/arch/efi/lib/elf_x86_64_efi.lds.S
+++ b/arch/efi/lib/elf_x86_64_efi.lds.S
@@ -58,6 +58,10 @@ SECTIONS
__barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ __barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
. = ALIGN(64);
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index c690e71976..8057634ddb 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -67,6 +67,10 @@ SECTIONS
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
__usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
diff --git a/arch/nios2/cpu/barebox.lds.S b/arch/nios2/cpu/barebox.lds.S
index 943c507531..a2d7fa8cdf 100644
--- a/arch/nios2/cpu/barebox.lds.S
+++ b/arch/nios2/cpu/barebox.lds.S
@@ -63,6 +63,10 @@ SECTIONS
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
___usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
___usymtab_end = .;
diff --git a/arch/openrisc/cpu/barebox.lds.S b/arch/openrisc/cpu/barebox.lds.S
index 9c353f30f1..b819ca0996 100644
--- a/arch/openrisc/cpu/barebox.lds.S
+++ b/arch/openrisc/cpu/barebox.lds.S
@@ -65,6 +65,10 @@ SECTIONS
.barebox_initcalls : { INITCALLS } > ram
__barebox_initcalls_end = .;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS } > ram
+ __barebox_exitcalls_end = .;
+
___usymtab_start = .;
__usymtab : { BAREBOX_SYMS } > ram
___usymtab_end = .;
diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S
index 1332ad1cbd..0e08e053f7 100644
--- a/arch/ppc/boards/pcm030/barebox.lds.S
+++ b/arch/ppc/boards/pcm030/barebox.lds.S
@@ -112,6 +112,11 @@ SECTIONS
__barebox_initcalls_end = .;
__initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start) >> 2;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+ __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2;
+
__usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
diff --git a/arch/ppc/mach-mpc85xx/barebox.lds.S b/arch/ppc/mach-mpc85xx/barebox.lds.S
index 87ab7acfe2..1f7f52c39c 100644
--- a/arch/ppc/mach-mpc85xx/barebox.lds.S
+++ b/arch/ppc/mach-mpc85xx/barebox.lds.S
@@ -109,6 +109,11 @@ SECTIONS
__barebox_initcalls_end = .;
__initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start)>>2;
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+ __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2;
+
__usymtab_start = .;
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S
index db5b7deb23..0d67ab6607 100644
--- a/arch/sandbox/board/barebox.lds.S
+++ b/arch/sandbox/board/barebox.lds.S
@@ -8,6 +8,11 @@ SECTIONS
__barebox_initcalls_end = .;
. = ALIGN(64);
+ __barebox_exitcalls_start = .;
+ __barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
+ . = ALIGN(64);
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S
index 6cf6b10d1b..23d7546532 100644
--- a/arch/x86/lib/barebox.lds.S
+++ b/arch/x86/lib/barebox.lds.S
@@ -185,7 +185,14 @@ SECTIONS
. = ALIGN(4);
} > barebox
- .__usymtab : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) {
+ .barebox_exitcalls : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) {
+ __barebox_exitcalls_start = .;
+ EXITCALLS
+ __barebox_exitcalls_end = .;
+ . = ALIGN(4);
+ } > barebox
+
+ .__usymtab : AT ( LOADADDR(.barebox_exitcalls) + SIZEOF (.barebox_exitcalls) ) {
__usymtab_start = .;
BAREBOX_SYMS
__usymtab_end = .;
diff --git a/common/startup.c b/common/startup.c
index 6178fc5353..45d8d86aee 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -45,6 +45,9 @@
extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
__barebox_initcalls_end[];
+extern exitcall_t __barebox_exitcalls_start[], __barebox_exitcalls_end[];
+
+
#if defined CONFIG_FS_RAMFS && defined CONFIG_FS_DEVFS
static int mount_root(void)
{
@@ -140,6 +143,14 @@ void (*board_shutdown)(void);
*/
void shutdown_barebox(void)
{
+ exitcall_t *exitcall;
+
+ for (exitcall = __barebox_exitcalls_start;
+ exitcall < __barebox_exitcalls_end; exitcall++) {
+ pr_debug("exitcall-> %pS\n", *exitcall);
+ (*exitcall)();
+ }
+
devices_shutdown();
#ifdef ARCH_SHUTDOWN
arch_shutdown();
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 00d6ecaf54..772058e77d 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -38,6 +38,15 @@
KEEP(*(.initcall.13)) \
KEEP(*(.initcall.14))
+#define EXITCALLS \
+ KEEP(*(.exitcall.0)) \
+ KEEP(*(.exitcall.1)) \
+ KEEP(*(.exitcall.2)) \
+ KEEP(*(.exitcall.3)) \
+ KEEP(*(.exitcall.4)) \
+ KEEP(*(.exitcall.5)) \
+ KEEP(*(.exitcall.6))
+
#define BAREBOX_CMDS KEEP(*(SORT_BY_NAME(.barebox_cmd*)))
#define BAREBOX_SYMS KEEP(*(__usymtab))
diff --git a/include/init.h b/include/init.h
index f619c951d3..527d49afec 100644
--- a/include/init.h
+++ b/include/init.h
@@ -7,17 +7,24 @@
#define __init
#define __initdata
#define __initconst
+#define __exit
+#define __exitdata
/* For assembly routines */
#define __BARE_INIT .section ".text_bare_init.text","ax"
#ifndef __ASSEMBLY__
typedef int (*initcall_t)(void);
+typedef void (*exitcall_t)(void);
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute__((__used__)) \
__attribute__((__section__(".initcall." level))) = fn
+#define __define_exitcall(level,fn,id) \
+ static exitcall_t __exitcall_##fn##id __attribute__((__used__)) \
+ __attribute__((__section__(".exitcall." level))) = fn
+
/*
* A "pure" initcall has no dependencies on anything else, and purely
@@ -42,6 +49,14 @@ typedef int (*initcall_t)(void);
#define environment_initcall(fn) __define_initcall("13",fn,13)
#define postenvironment_initcall(fn) __define_initcall("14",fn,14)
+#define early_exitcall(fn) __define_exitcall("0",fn,0)
+#define predevshutdown_exitcall(fn) __define_exitcall("1",fn,1)
+#define devshutdown_exitcall(fn) __define_exitcall("2",fn,2)
+#define postdevshutdown_exitcall(fn) __define_exitcall("3",fn,3)
+#define prearchshutdown_exitcall(fn) __define_exitcall("4",fn,4)
+#define archshutdown_exitcall(fn) __define_exitcall("5",fn,5)
+#define postarchshutdown_exitcall(fn) __define_exitcall("6",fn,6)
+
/* section for code used very early when
* - we're not running from where we linked at
* - bss not cleared