diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-03 12:25:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-03 12:25:44 -0700 |
commit | cc5ada7ca3618e25c1c2be29dad3c092573200d3 (patch) | |
tree | 3b9310236b7da5140f0d69726324321dad349308 /drivers/char | |
parent | 77624cd2a7783fccf2c518768a6fd7a7aeccd002 (diff) | |
parent | c6185e285c5c7cfeab739bae7f206ced695f09c7 (diff) |
Merge tag 'for-linus-4.17' of git://github.com/cminyard/linux-ipmi
Pull IPMI updates from Corey Minyard:
"Mostly small changes, as usual.
This does add an IPMI BMC server-side driver, to allow a Linux system
to act as an IPMI controller. That's the biggest change, but it is
just a new driver that is fairly narrow in use.
The other largish change is removing ACPI SPMI probe support, which
should have never really been there in the beginning"
* tag 'for-linus-4.17' of git://github.com/cminyard/linux-ipmi:
ipmi/parisc: Add IPMI chassis poweroff for certain HP PA-RISC and IA-64 servers
ipmi_ssif: Fix kernel panic at msg_done_handler
ipmi:pci: Blacklist a Realtek "IPMI" device
ipmi: Remove ACPI SPMI probing from the system interface driver
ipmi: Remove ACPI SPMI probing from the SSIF (I2C) driver
ipmi: missing error code in try_smi_init()
ipmi: use ARRAY_SIZE for poweroff_functions array sizing calculation
ipmi: Consolidate cleanup code
ipmi: Remove some unnecessary initializations
ipmi: Fix some error cleanup issues
ipmi: Add or fix SPDX-License-Identifier in all files
ipmi: Re-use existing macros for built-in properties
ipmi:pci: Make the PCI defines consistent with normal Linux ones
ipmi: kcs_bmc: coding-style fixes and use new poll type
char/ipmi: add documentation for sysfs interface
ipmi: kcs_bmc: mark expected switch fall-through in kcs_bmc_handle_data
ipmi: add an Aspeed KCS IPMI BMC driver
ipmi: add a KCS IPMI BMC driver
Diffstat (limited to 'drivers/char')
27 files changed, 1067 insertions, 593 deletions
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 3544abc0f9f9..3bda116c8aa0 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -96,6 +96,21 @@ config IPMI_POWEROFF endif # IPMI_HANDLER +config IPMI_KCS_BMC + tristate + +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + select IPMI_KCS_BMC + select REGMAP_MMIO + tristate "Aspeed KCS IPMI BMC driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). + + The driver implements the BMC side of the KCS contorller, it + provides the access of KCS IO space for BMC side. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 33b899fcf14a..21e9e872d973 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -21,4 +21,6 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o +obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c index c95b93b7598b..40b9927c072c 100644 --- a/drivers/char/ipmi/bt-bmc.c +++ b/drivers/char/ipmi/bt-bmc.c @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2015-2016, IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include <linux/atomic.h> diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index feafdab734ae..fd4ea8d87d4b 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_bt_sm.c * @@ -5,26 +6,7 @@ * of the driver architecture at http://sourceforge.net/projects/openipmi * * Author: Rocky Craig <first.last@hp.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ + */ #include <linux/kernel.h> /* For printk. */ #include <linux/string.h> diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 5f1bc9174735..8ecfd47806fa 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_devintf.c * @@ -8,27 +9,6 @@ * source@mvista.com * * Copyright 2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c index c5112b17d7ea..e2c143861b1e 100644 --- a/drivers/char/ipmi/ipmi_dmi.c +++ b/drivers/char/ipmi/ipmi_dmi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* * A hack to create a platform device from a DMI entry. This will * allow autoloading of the IPMI drive based on SMBIOS entries. @@ -29,15 +29,6 @@ static struct ipmi_dmi_info *ipmi_dmi_infos; static int ipmi_dmi_nr __initdata; -#define set_prop_entry(_p_, _name_, type, val) \ -do { \ - struct property_entry *_p = &_p_; \ - _p->name = _name_; \ - _p->length = sizeof(type); \ - _p->is_string = false; \ - _p->value.type##_data = val; \ -} while(0) - static void __init dmi_add_platform_ipmi(unsigned long base_addr, u32 flags, u8 slave_addr, @@ -85,9 +76,10 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr, } if (si_type != SI_TYPE_INVALID) - set_prop_entry(p[pidx++], "ipmi-type", u8, si_type); - set_prop_entry(p[pidx++], "slave-addr", u8, slave_addr); - set_prop_entry(p[pidx++], "addr-source", u8, SI_SMBIOS); + p[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", si_type); + + p[pidx++] = PROPERTY_ENTRY_U8("slave-addr", slave_addr); + p[pidx++] = PROPERTY_ENTRY_U8("addr-source", SI_SMBIOS); info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) { @@ -112,7 +104,7 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr, goto err; if (type == IPMI_DMI_TYPE_SSIF) { - set_prop_entry(p[pidx++], "i2c-addr", u16, base_addr); + p[pidx++] = PROPERTY_ENTRY_U16("i2c-addr", base_addr); goto add_properties; } diff --git a/drivers/char/ipmi/ipmi_dmi.h b/drivers/char/ipmi/ipmi_dmi.h index 6c21018e3668..8d2b094db8e6 100644 --- a/drivers/char/ipmi/ipmi_dmi.h +++ b/drivers/char/ipmi/ipmi_dmi.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * DMI defines for use by IPMI */ diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index 1da61af7f576..f4ea9f47230a 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_kcs_sm.c * @@ -8,27 +9,6 @@ * source@mvista.com * * Copyright 2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ /* diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e0b0d7e2d976..361148938801 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_msghandler.c * @@ -8,27 +9,6 @@ * source@mvista.com * * Copyright 2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c index bcf493d8e238..e96500372ce2 100644 --- a/drivers/char/ipmi/ipmi_powernv.c +++ b/drivers/char/ipmi/ipmi_powernv.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * PowerNV OPAL IPMI driver * * Copyright 2014 IBM Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. */ #define pr_fmt(fmt) "ipmi-powernv: " fmt diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 38e6af1c8e38..7996337852f2 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_poweroff.c * @@ -9,27 +10,6 @@ * source@mvista.com * * Copyright 2002,2004 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> #include <linux/moduleparam.h> @@ -457,6 +437,24 @@ static int ipmi_dell_chassis_detect(ipmi_user_t user) } /* + * ipmi_hp_chassis_detect() + * HP PA-RISC servers rp3410/rp3440, the C8000 workstation and the rx2600 and + * zx6000 machines support IPMI vers 1 and don't set the chassis capability bit + * but they can handle a chassis poweroff or powercycle command. + */ + +#define HP_IANA_MFR_ID 0x0b +#define HP_BMC_PROD_ID 0x8201 +static int ipmi_hp_chassis_detect(ipmi_user_t user) +{ + if (mfg_id == HP_IANA_MFR_ID + && prod_id == HP_BMC_PROD_ID + && ipmi_version == 1) + return 1; + return 0; +} + +/* * Standard chassis support */ @@ -533,14 +531,16 @@ static struct poweroff_function poweroff_functions[] = { { .platform_type = "chassis", .detect = ipmi_dell_chassis_detect, .poweroff_func = ipmi_poweroff_chassis }, + { .platform_type = "chassis", + .detect = ipmi_hp_chassis_detect, + .poweroff_func = ipmi_poweroff_chassis }, /* Chassis should generally be last, other things should override it. */ { .platform_type = "chassis", .detect = ipmi_chassis_detect, .poweroff_func = ipmi_poweroff_chassis }, }; -#define NUM_PO_FUNCS (sizeof(poweroff_functions) \ - / sizeof(struct poweroff_function)) +#define NUM_PO_FUNCS ARRAY_SIZE(poweroff_functions) /* Called on a powerdown request. */ diff --git a/drivers/char/ipmi/ipmi_si.h b/drivers/char/ipmi/ipmi_si.h index 17ce5f7b89ab..52f6152d1fcb 100644 --- a/drivers/char/ipmi/ipmi_si.h +++ b/drivers/char/ipmi/ipmi_si.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * ipmi_si.h * diff --git a/drivers/char/ipmi/ipmi_si_hardcode.c b/drivers/char/ipmi/ipmi_si_hardcode.c index fa9a4780de36..10219f24546b 100644 --- a/drivers/char/ipmi/ipmi_si_hardcode.c +++ b/drivers/char/ipmi/ipmi_si_hardcode.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/moduleparam.h> #include "ipmi_si.h" diff --git a/drivers/char/ipmi/ipmi_si_hotmod.c b/drivers/char/ipmi/ipmi_si_hotmod.c index fc03b9be2f3d..a98ca42a50b1 100644 --- a/drivers/char/ipmi/ipmi_si_hotmod.c +++ b/drivers/char/ipmi/ipmi_si_hotmod.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_si_hotmod.c * diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 6768cb2dd740..ff870aa91cfe 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_si.c * @@ -10,27 +11,6 @@ * * Copyright 2002 MontaVista Software Inc. * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -252,6 +232,12 @@ struct smi_info { /* Default driver model device. */ struct platform_device *pdev; + /* Have we added the device group to the device? */ + bool dev_group_added; + + /* Have we added the platform device? */ + bool pdev_registered; + /* Counters and things for the proc filesystem. */ atomic_t stats[SI_NUM_STATS]; @@ -275,7 +261,8 @@ static int num_max_busy_us; static bool unload_when_empty = true; static int try_smi_init(struct smi_info *smi); -static void cleanup_one_si(struct smi_info *to_clean); +static void shutdown_one_si(struct smi_info *smi_info); +static void cleanup_one_si(struct smi_info *smi_info); static void cleanup_ipmi_si(void); #ifdef DEBUG_TIMING @@ -2017,18 +2004,13 @@ int ipmi_si_add_smi(struct si_sm_io *io) ipmi_addr_src_to_str(new_smi->io.addr_source), si_to_str[new_smi->io.si_type]); - /* So we know not to free it unless we have allocated one. */ - new_smi->intf = NULL; - new_smi->si_sm = NULL; - new_smi->handlers = NULL; - list_add_tail(&new_smi->link, &smi_infos); if (initialized) { rv = try_smi_init(new_smi); if (rv) { - mutex_unlock(&smi_infos_lock); cleanup_one_si(new_smi); + mutex_unlock(&smi_infos_lock); return rv; } } @@ -2047,7 +2029,6 @@ static int try_smi_init(struct smi_info *new_smi) int rv = 0; int i; char *init_name = NULL; - bool platform_device_registered = false; pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", ipmi_addr_src_to_str(new_smi->io.addr_source), @@ -2090,6 +2071,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->intf_num); if (!new_smi->pdev) { pr_err(PFX "Unable to allocate platform device\n"); + rv = -ENOMEM; goto out_err; } new_smi->io.dev = &new_smi->pdev->dev; @@ -2168,7 +2150,7 @@ static int try_smi_init(struct smi_info *new_smi) atomic_set(&new_smi->req_events, 1); } - if (new_smi->pdev) { + if (new_smi->pdev && !new_smi->pdev_registered) { rv = platform_device_add(new_smi->pdev); if (rv) { dev_err(new_smi->io.dev, @@ -2176,7 +2158,7 @@ static int try_smi_init(struct smi_info *new_smi) rv); goto out_err; } - platform_device_registered = true; + new_smi->pdev_registered = true; } dev_set_drvdata(new_smi->io.dev, new_smi); @@ -2185,8 +2167,9 @@ static int try_smi_init(struct smi_info *new_smi) dev_err(new_smi->io.dev, "Unable to add device attributes: error %d\n", rv); - goto out_err_stop_timer; + goto out_err; } + new_smi->dev_group_added = true; rv = ipmi_register_smi(&handlers, new_smi, @@ -2196,7 +2179,7 @@ static int try_smi_init(struct smi_info *new_smi) dev_err(new_smi->io.dev, "Unable to register device: error %d\n", rv); - goto out_err_remove_attrs; + goto out_err; } #ifdef CONFIG_IPMI_PROC_INTERFACE @@ -2206,7 +2189,7 @@ static int try_smi_init(struct smi_info *new_smi) if (rv) { dev_err(new_smi->io.dev, "Unable to create proc entry: %d\n", rv); - goto out_err_stop_timer; + goto out_err; } rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", @@ -2215,7 +2198,7 @@ static int try_smi_init(struct smi_info *new_smi) if (rv) { dev_err(new_smi->io.dev, "Unable to create proc entry: %d\n", rv); - goto out_err_stop_timer; + goto out_err; } rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", @@ -2224,7 +2207,7 @@ static int try_smi_init(struct smi_info *new_smi) if (rv) { dev_err(new_smi->io.dev, "Unable to create proc entry: %d\n", rv); - goto out_err_stop_timer; + goto out_err; } #endif @@ -2239,56 +2222,8 @@ static int try_smi_init(struct smi_info *new_smi) return 0; -out_err_remove_attrs: - device_remove_group(new_smi->io.dev, &ipmi_si_dev_attr_group); - dev_set_drvdata(new_smi->io.dev, NULL); - -out_err_stop_timer: - stop_timer_and_thread(new_smi); - out_err: - new_smi->interrupt_disabled = true; - - if (new_smi->intf) { - ipmi_smi_t intf = new_smi->intf; - new_smi->intf = NULL; - ipmi_unregister_smi(intf); - } - - if (new_smi->io.irq_cleanup) { - new_smi->io.irq_cleanup(&new_smi->io); - new_smi->io.irq_cleanup = NULL; - } - - /* - * Wait until we know that we are out of any interrupt - * handlers might have been running before we freed the - * interrupt. - */ - synchronize_sched(); - - if (new_smi->si_sm) { - if (new_smi->handlers) - new_smi->handlers->cleanup(new_smi->si_sm); - kfree(new_smi->si_sm); - new_smi->si_sm = NULL; - } - if (new_smi->io.addr_source_cleanup) { - new_smi->io.addr_source_cleanup(&new_smi->io); - new_smi->io.addr_source_cleanup = NULL; - } - if (new_smi->io.io_cleanup) { - new_smi->io.io_cleanup(&new_smi->io); - new_smi->io.io_cleanup = NULL; - } - - if (new_smi->pdev) { - if (platform_device_registered) - platform_device_unregister(new_smi->pdev); - else - platform_device_put(new_smi->pdev); - new_smi->pdev = NULL; - } + shutdown_one_si(new_smi); kfree(init_name); @@ -2366,17 +2301,14 @@ skip_fallback_noirq: } module_init(init_ipmi_si); -static void cleanup_one_si(struct smi_info *to_clean) +static void shutdown_one_si(struct smi_info *smi_info) { int rv = 0; - if (!to_clean) - return; - - if (to_clean->intf) { - ipmi_smi_t intf = to_clean->intf; + if (smi_info->intf) { + ipmi_smi_t intf = smi_info->intf; - to_clean->intf = NULL; + smi_info->intf = NULL; rv = ipmi_unregister_smi(intf); if (rv) { pr_err(PFX "Unable to unregister device: errno=%d\n", @@ -2384,49 +2316,79 @@ static void cleanup_one_si(struct smi_info *to_clean) } } - device_remove_group(to_clean->io.dev, &ipmi_si_dev_attr_group); - dev_set_drvdata(to_clean->io.dev, NULL); - - list_del(&to_clean->link); + if (smi_info->dev_group_added) { + device_remove_group(smi_info->io.dev, &ipmi_si_dev_attr_group); + smi_info->dev_group_added = false; + } + if (smi_info->io.dev) + dev_set_drvdata(smi_info->io.dev, NULL); /* * Make sure that interrupts, the timer and the thread are * stopped and will not run again. */ - if (to_clean->io.irq_cleanup) - to_clean->io.irq_cleanup(&to_clean->io); - stop_timer_and_thread(to_clean); + smi_info->interrupt_disabled = true; + if (smi_info->io.irq_cleanup) { + smi_info->io.irq_cleanup(&smi_info->io); + smi_info->io.irq_cleanup = NULL; + } + stop_timer_and_thread(smi_info); + + /* + * Wait until we know that we are out of any interrupt + * handlers might have been running before we freed the + * interrupt. + */ + synchronize_sched(); /* * Timeouts are stopped, now make sure the interrupts are off * in the BMC. Note that timers and CPU interrupts are off, * so no need for locks. */ - while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { - poll(to_clean); + while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { + poll(smi_info); schedule_timeout_uninterruptible(1); } - if (to_clean->handlers) - disable_si_irq(to_clean); - while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { - poll(to_clean); + if (smi_info->handlers) + disable_si_irq(smi_info); + while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { + poll(smi_info); schedule_timeout_uninterruptible(1); } + if (smi_info->handlers) + smi_info->handlers->cleanup(smi_info->si_sm); + + if (smi_info->io.addr_source_cleanup) { + smi_info->io.addr_source_cleanup(&smi_info->io); + smi_info->io.addr_source_cleanup = NULL; + } + if (smi_info->io.io_cleanup) { + smi_info->io.io_cleanup(&smi_info->io); + smi_info->io.io_cleanup = NULL; + } - if (to_clean->handlers) - to_clean->handlers->cleanup(to_clean->si_sm); + kfree(smi_info->si_sm); + smi_info->si_sm = NULL; +} - kfree(to_clean->si_sm); +static void cleanup_one_si(struct smi_info *smi_info) +{ + if (!smi_info) + return; - if (to_clean->io.addr_source_cleanup) - to_clean->io.addr_source_cleanup(&to_clean->io); - if (to_clean->io.io_cleanup) - to_clean->io.io_cleanup(&to_clean->io); + list_del(&smi_info->link); - if (to_clean->pdev) - platform_device_unregister(to_clean->pdev); + shutdown_one_si(smi_info); + + if (smi_info->pdev) { + if (smi_info->pdev_registered) + platform_device_unregister(smi_info->pdev); + else + platform_device_put(smi_info->pdev); + } - kfree(to_clean); + kfree(smi_info); } int ipmi_si_remove_by_dev(struct device *dev) diff --git a/drivers/char/ipmi/ipmi_si_mem_io.c b/drivers/char/ipmi/ipmi_si_mem_io.c index 8796396ecd0f..1b869d530884 100644 --- a/drivers/char/ipmi/ipmi_si_mem_io.c +++ b/drivers/char/ipmi/ipmi_si_mem_io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/io.h> #include "ipmi_si.h" diff --git a/drivers/char/ipmi/ipmi_si_parisc.c b/drivers/char/ipmi/ipmi_si_parisc.c index 6b10f0e18a95..f3c99820f564 100644 --- a/drivers/char/ipmi/ipmi_si_parisc.c +++ b/drivers/char/ipmi/ipmi_si_parisc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/module.h> #include <asm/hardware.h> /* for register_parisc_driver() stuff */ diff --git a/drivers/char/ipmi/ipmi_si_pci.c b/drivers/char/ipmi/ipmi_si_pci.c index 27dd11c49d21..f54ca6869ed2 100644 --- a/drivers/char/ipmi/ipmi_si_pci.c +++ b/drivers/char/ipmi/ipmi_si_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ipmi_si_pci.c * @@ -17,16 +18,12 @@ module_param_named(trypci, si_trypci, bool, 0); MODULE_PARM_DESC(trypci, "Setting this to zero will disable the" " default scan of the interfaces identified via pci"); -#define PCI_ERMC_CLASSCODE 0x0C0700 -#define PCI_ERMC_CLASSCODE_MASK 0xffffff00 -#define PCI_ERMC_CLASSCODE_TYPE_MASK 0xff -#define PCI_ERMC_CLASSCODE_TYPE_SMIC 0x00 -#defin |