Skip to content

Commit

Permalink
ipmi_si: Remove hotmod devices on removal and exit
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
cminyard committed Feb 22, 2019
1 parent 1a84df2 commit bdb57b7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
5 changes: 3 additions & 2 deletions drivers/char/ipmi/ipmi_si.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
32 changes: 31 additions & 1 deletion drivers/char/ipmi/ipmi_si_hotmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,41 @@ 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;
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);
}
}
12 changes: 9 additions & 3 deletions drivers/char/ipmi/ipmi_si_intf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2281,22 +2281,27 @@ 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) {
if (e->io.addr_space != addr_space)
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)
Expand All @@ -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);

Expand Down

0 comments on commit bdb57b7

Please sign in to comment.