mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 10:32:35 +00:00
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: Corey Minyard <cminyard@mvista.com>
This commit is contained in:
parent
1a84df2df8
commit
bdb57b7bc1
@ -21,10 +21,11 @@ void ipmi_irq_start_cleanup(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);
|
||||
int ipmi_si_remove_by_dev(struct device *dev);
|
||||
void ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
|
||||
unsigned long addr);
|
||||
struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
|
||||
unsigned long addr);
|
||||
void ipmi_hardcode_init(void);
|
||||
void ipmi_si_hardcode_exit(void);
|
||||
void ipmi_si_hotmod_exit(void);
|
||||
int ipmi_si_hardcode_match(int addr_space, unsigned long addr);
|
||||
void ipmi_si_platform_init(void);
|
||||
void ipmi_si_platform_shutdown(void);
|
||||
|
@ -219,7 +219,18 @@ static int hotmod_handler(const char *val, const struct kernel_param *kp)
|
||||
atomic_inc_return(&hotmod_nr),
|
||||
&h);
|
||||
} 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;
|
||||
@ -227,3 +238,22 @@ out:
|
||||
kfree(str);
|
||||
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)
|
||||
return rv;
|
||||
}
|
||||
|
||||
void ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
|
||||
unsigned long addr)
|
||||
struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
|
||||
unsigned long addr)
|
||||
{
|
||||
/* remove */
|
||||
struct smi_info *e, *tmp_e;
|
||||
struct device *dev = NULL;
|
||||
|
||||
mutex_lock(&smi_infos_lock);
|
||||
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,
|
||||
continue;
|
||||
if (e->io.si_type != si_type)
|
||||
continue;
|
||||
if (e->io.addr_data == addr)
|
||||
if (e->io.addr_data == addr) {
|
||||
dev = get_device(e->io.dev);
|
||||
cleanup_one_si(e);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&smi_infos_lock);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void cleanup_ipmi_si(void)
|
||||
@ -2318,6 +2323,7 @@ static void cleanup_ipmi_si(void)
|
||||
mutex_unlock(&smi_infos_lock);
|
||||
|
||||
ipmi_si_hardcode_exit();
|
||||
ipmi_si_hotmod_exit();
|
||||
}
|
||||
module_exit(cleanup_ipmi_si);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user