diff options
author | Jan-Bernd Themann <ossthema@de.ibm.com> | 2007-10-26 14:37:28 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-29 05:47:09 -0400 |
commit | 2a6f4e4983918b18fe5d3fb364afe33db7139870 (patch) | |
tree | 2887c2f847ca02caf87de3bf1d5445417091806e | |
parent | f920c186be09718542dfa77f6ebe1814be7d35cb (diff) | |
download | op-kernel-dev-2a6f4e4983918b18fe5d3fb364afe33db7139870.zip op-kernel-dev-2a6f4e4983918b18fe5d3fb364afe33db7139870.tar.gz |
ehea: add kexec support
eHEA resources that are allocated via H_CALLs have a unique identifier each.
These identifiers are necessary to free the resources. A reboot notifier
is used to free all eHEA resources before the indentifiers get lost, i.e
before kexec starts a new kernel.
Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/ehea/ehea.h | 2 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 21 |
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 4b4b74e..f78e5bf 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0079" +#define DRV_VERSION "EHEA_0080" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 0a7e789..f0319f1 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -33,6 +33,9 @@ #include <linux/if.h> #include <linux/list.h> #include <linux/if_ether.h> +#include <linux/notifier.h> +#include <linux/reboot.h> + #include <net/ip.h> #include "ehea.h" @@ -3295,6 +3298,20 @@ static int __devexit ehea_remove(struct of_device *dev) return 0; } +static int ehea_reboot_notifier(struct notifier_block *nb, + unsigned long action, void *unused) +{ + if (action == SYS_RESTART) { + ehea_info("Reboot: freeing all eHEA resources"); + ibmebus_unregister_driver(&ehea_driver); + } + return NOTIFY_DONE; +} + +static struct notifier_block ehea_reboot_nb = { + .notifier_call = ehea_reboot_notifier, +}; + static int check_module_parm(void) { int ret = 0; @@ -3351,6 +3368,8 @@ int __init ehea_module_init(void) if (ret) goto out; + register_reboot_notifier(&ehea_reboot_nb); + ret = ibmebus_register_driver(&ehea_driver); if (ret) { ehea_error("failed registering eHEA device driver on ebus"); @@ -3362,6 +3381,7 @@ int __init ehea_module_init(void) if (ret) { ehea_error("failed to register capabilities attribute, ret=%d", ret); + unregister_reboot_notifier(&ehea_reboot_nb); ibmebus_unregister_driver(&ehea_driver); goto out; } @@ -3375,6 +3395,7 @@ static void __exit ehea_module_exit(void) flush_scheduled_work(); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); + unregister_reboot_notifier(&ehea_reboot_nb); ehea_destroy_busmap(); } |