Commit bdb57b7b authored by Corey Minyard's avatar Corey Minyard

ipmi_si: Remove hotmod devices on removal and exit

When a hotmod-added device is removed or when the module is removed,
remove the platform devices that was created for it.
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent 1a84df2d
...@@ -21,10 +21,11 @@ void ipmi_irq_start_cleanup(struct si_sm_io *io); ...@@ -21,10 +21,11 @@ void ipmi_irq_start_cleanup(struct si_sm_io *io);
int ipmi_std_irq_setup(struct si_sm_io *io); int ipmi_std_irq_setup(struct si_sm_io *io);
void ipmi_irq_finish_setup(struct si_sm_io *io); void ipmi_irq_finish_setup(struct si_sm_io *io);
int ipmi_si_remove_by_dev(struct device *dev); int ipmi_si_remove_by_dev(struct device *dev);
void ipmi_si_remove_by_data(int addr_space, enum si_type si_type, struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
unsigned long addr); unsigned long addr);
void ipmi_hardcode_init(void); void ipmi_hardcode_init(void);
void ipmi_si_hardcode_exit(void); void ipmi_si_hardcode_exit(void);
void ipmi_si_hotmod_exit(void);
int ipmi_si_hardcode_match(int addr_space, unsigned long addr); int ipmi_si_hardcode_match(int addr_space, unsigned long addr);
void ipmi_si_platform_init(void); void ipmi_si_platform_init(void);
void ipmi_si_platform_shutdown(void); void ipmi_si_platform_shutdown(void);
......
...@@ -219,7 +219,18 @@ static int hotmod_handler(const char *val, const struct kernel_param *kp) ...@@ -219,7 +219,18 @@ static int hotmod_handler(const char *val, const struct kernel_param *kp)
atomic_inc_return(&hotmod_nr), atomic_inc_return(&hotmod_nr),
&h); &h);
} else { } else {
ipmi_si_remove_by_data(h.space, h.type, h.addr); struct device *dev;
dev = ipmi_si_remove_by_data(h.space, h.type, h.addr);
if (dev && dev_is_platform(dev)) {
struct platform_device *pdev;
pdev = to_platform_device(dev);
if (strcmp(pdev->name, "hotmod-ipmi-si") == 0)
platform_device_unregister(pdev);
}
if (dev)
put_device(dev);
} }
} }
rv = len; rv = len;
...@@ -227,3 +238,22 @@ static int hotmod_handler(const char *val, const struct kernel_param *kp) ...@@ -227,3 +238,22 @@ static int hotmod_handler(const char *val, const struct kernel_param *kp)
kfree(str); kfree(str);
return rv; return rv;
} }
static int pdev_match_name(struct device *dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
return strcmp(pdev->name, "hotmod-ipmi-si") == 0;
}
void ipmi_si_hotmod_exit(void)
{
struct device *dev;
while ((dev = bus_find_device(&platform_bus_type, NULL, NULL,
pdev_match_name))) {
struct platform_device *pdev = to_platform_device(dev);
platform_device_unregister(pdev);
}
}
...@@ -2281,11 +2281,12 @@ int ipmi_si_remove_by_dev(struct device *dev) ...@@ -2281,11 +2281,12 @@ int ipmi_si_remove_by_dev(struct device *dev)
return rv; return rv;
} }
void ipmi_si_remove_by_data(int addr_space, enum si_type si_type, struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
unsigned long addr) unsigned long addr)
{ {
/* remove */ /* remove */
struct smi_info *e, *tmp_e; struct smi_info *e, *tmp_e;
struct device *dev = NULL;
mutex_lock(&smi_infos_lock); mutex_lock(&smi_infos_lock);
list_for_each_entry_safe(e, tmp_e, &smi_infos, link) { list_for_each_entry_safe(e, tmp_e, &smi_infos, link) {
...@@ -2293,10 +2294,14 @@ void ipmi_si_remove_by_data(int addr_space, enum si_type si_type, ...@@ -2293,10 +2294,14 @@ void ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
continue; continue;
if (e->io.si_type != si_type) if (e->io.si_type != si_type)
continue; continue;
if (e->io.addr_data == addr) if (e->io.addr_data == addr) {
dev = get_device(e->io.dev);
cleanup_one_si(e); cleanup_one_si(e);
}
} }
mutex_unlock(&smi_infos_lock); mutex_unlock(&smi_infos_lock);
return dev;
} }
static void cleanup_ipmi_si(void) static void cleanup_ipmi_si(void)
...@@ -2318,6 +2323,7 @@ static void cleanup_ipmi_si(void) ...@@ -2318,6 +2323,7 @@ static void cleanup_ipmi_si(void)
mutex_unlock(&smi_infos_lock); mutex_unlock(&smi_infos_lock);
ipmi_si_hardcode_exit(); ipmi_si_hardcode_exit();
ipmi_si_hotmod_exit();
} }
module_exit(cleanup_ipmi_si); module_exit(cleanup_ipmi_si);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment