Commit 9cba938a authored by Corey Minyard's avatar Corey Minyard
Browse files

ipmi:si: Move SI type information into an info structure



Andy reported:

Debian clang version 19.1.7 is not happy when compiled with
`make W=1` (note, CONFIG_WERROR=y is the default):

ipmi_si_platform.c:268:15: error: cast to smaller integer type 'enum si_type' from 'const void *' [-Werror,-Wvoid-pointer-to-enum-cast]
  268 |         io.si_type      = (enum si_type)device_get_match_data(&pdev->dev);

The IPMI SI type is an enum that was cast into a pointer that was
then cast into an enum again.  That's not the greatest style, so
instead create an info structure to hold the data and use that.

Reported-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Closes: https://lore.kernel.org/lkml/20250415085156.446430-1-andriy.shevchenko@linux.intel.com/


Suggested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarCorey Minyard <corey@minyard.net>
parent 4f79eaa2
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -26,6 +26,14 @@ enum si_type {
/* Array is defined in the ipmi_si_intf.c */
extern const char *const si_to_str[];

struct ipmi_match_info {
	enum si_type type;
};

extern const struct ipmi_match_info ipmi_kcs_si_info;
extern const struct ipmi_match_info ipmi_smic_si_info;
extern const struct ipmi_match_info ipmi_bt_si_info;

enum ipmi_addr_space {
	IPMI_IO_ADDR_SPACE, IPMI_MEM_ADDR_SPACE
};
@@ -64,7 +72,7 @@ struct si_sm_io {
	void (*irq_cleanup)(struct si_sm_io *io);

	u8 slave_addr;
	enum si_type si_type;
	const struct ipmi_match_info *si_info;
	struct device *dev;
};

+19 −15
Original line number Diff line number Diff line
@@ -73,6 +73,10 @@ enum si_intf_state {
/* 'invalid' to allow a firmware-specified interface to be disabled */
const char *const si_to_str[] = { "invalid", "kcs", "smic", "bt", NULL };

const struct ipmi_match_info ipmi_kcs_si_info = { .type = SI_KCS };
const struct ipmi_match_info ipmi_smic_si_info = { .type = SI_SMIC };
const struct ipmi_match_info ipmi_bt_si_info = { .type = SI_BT };

static bool initialized;

/*
@@ -692,7 +696,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
			break;
		}
		enables = current_global_enables(smi_info, 0, &irq_on);
		if (smi_info->io.si_type == SI_BT)
		if (smi_info->io.si_info->type == SI_BT)
			/* BT has its own interrupt enable bit. */
			check_bt_irq(smi_info, irq_on);
		if (enables != (msg[3] & GLOBAL_ENABLES_MASK)) {
@@ -1119,7 +1123,7 @@ irqreturn_t ipmi_si_irq_handler(int irq, void *data)
	struct smi_info *smi_info = data;
	unsigned long   flags;

	if (smi_info->io.si_type == SI_BT)
	if (smi_info->io.si_info->type == SI_BT)
		/* We need to clear the IRQ flag for the BT interface. */
		smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
				     IPMI_BT_INTMASK_CLEAR_IRQ_BIT
@@ -1164,7 +1168,7 @@ static int smi_start_processing(void *send_info,
	 * The BT interface is efficient enough to not need a thread,
	 * and there is no need for a thread if we have interrupts.
	 */
	else if ((new_smi->io.si_type != SI_BT) && (!new_smi->io.irq))
	else if (new_smi->io.si_info->type != SI_BT && !new_smi->io.irq)
		enable = 1;

	if (enable) {
@@ -1235,7 +1239,7 @@ MODULE_PARM_DESC(kipmid_max_busy_us,

void ipmi_irq_finish_setup(struct si_sm_io *io)
{
	if (io->si_type == SI_BT)
	if (io->si_info->type == SI_BT)
		/* Enable the interrupt in the BT interface. */
		io->outputb(io, IPMI_BT_INTMASK_REG,
			    IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
@@ -1243,7 +1247,7 @@ void ipmi_irq_finish_setup(struct si_sm_io *io)

void ipmi_irq_start_cleanup(struct si_sm_io *io)
{
	if (io->si_type == SI_BT)
	if (io->si_info->type == SI_BT)
		/* Disable the interrupt in the BT interface. */
		io->outputb(io, IPMI_BT_INTMASK_REG, 0);
}
@@ -1614,7 +1618,7 @@ static ssize_t type_show(struct device *dev,
{
	struct smi_info *smi_info = dev_get_drvdata(dev);

	return sysfs_emit(buf, "%s\n", si_to_str[smi_info->io.si_type]);
	return sysfs_emit(buf, "%s\n", si_to_str[smi_info->io.si_info->type]);
}
static DEVICE_ATTR_RO(type);

@@ -1649,7 +1653,7 @@ static ssize_t params_show(struct device *dev,

	return sysfs_emit(buf,
			"%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
			si_to_str[smi_info->io.si_type],
			si_to_str[smi_info->io.si_info->type],
			addr_space_to_str[smi_info->io.addr_space],
			smi_info->io.addr_data,
			smi_info->io.regspacing,
@@ -1803,7 +1807,7 @@ setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
{
	struct ipmi_device_id *id = &smi_info->device_id;
	if (id->manufacturer_id == DELL_IANA_MFR_ID &&
	    smi_info->io.si_type == SI_BT)
	    smi_info->io.si_info->type == SI_BT)
		register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
}

@@ -1907,13 +1911,13 @@ int ipmi_si_add_smi(struct si_sm_io *io)
			/* We prefer ACPI over SMBIOS. */
			dev_info(dup->io.dev,
				 "Removing SMBIOS-specified %s state machine in favor of ACPI\n",
				 si_to_str[new_smi->io.si_type]);
				 si_to_str[new_smi->io.si_info->type]);
			cleanup_one_si(dup);
		} else {
			dev_info(new_smi->io.dev,
				 "%s-specified %s state machine: duplicate\n",
				 ipmi_addr_src_to_str(new_smi->io.addr_source),
				 si_to_str[new_smi->io.si_type]);
				 si_to_str[new_smi->io.si_info->type]);
			rv = -EBUSY;
			kfree(new_smi);
			goto out_err;
@@ -1922,7 +1926,7 @@ int ipmi_si_add_smi(struct si_sm_io *io)

	pr_info("Adding %s-specified %s state machine\n",
		ipmi_addr_src_to_str(new_smi->io.addr_source),
		si_to_str[new_smi->io.si_type]);
		si_to_str[new_smi->io.si_info->type]);

	list_add_tail(&new_smi->link, &smi_infos);

@@ -1945,12 +1949,12 @@ static int try_smi_init(struct smi_info *new_smi)

	pr_info("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),
		si_to_str[new_smi->io.si_type],
		si_to_str[new_smi->io.si_info->type],
		addr_space_to_str[new_smi->io.addr_space],
		new_smi->io.addr_data,
		new_smi->io.slave_addr, new_smi->io.irq);

	switch (new_smi->io.si_type) {
	switch (new_smi->io.si_info->type) {
	case SI_KCS:
		new_smi->handlers = &kcs_smi_handlers;
		break;
@@ -2073,7 +2077,7 @@ static int try_smi_init(struct smi_info *new_smi)
	smi_num++;

	dev_info(new_smi->io.dev, "IPMI %s interface initialized\n",
		 si_to_str[new_smi->io.si_type]);
		 si_to_str[new_smi->io.si_info->type]);

	WARN_ON(new_smi->io.dev->init_name != NULL);

@@ -2267,7 +2271,7 @@ struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
	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)
		if (e->io.si_info->type != si_type)
			continue;
		if (e->io.addr_data == addr) {
			dev = get_device(e->io.dev);
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev)

	memset(&io, 0, sizeof(io));

	io.si_type	= SI_KCS;
	io.si_info	= &ipmi_kcs_si_info;
	io.addr_source	= SI_DEVICETREE;
	io.addr_space	= IPMI_MEM_ADDR_SPACE;
	io.addr_data	= dev->hpa.start;
+27 −25
Original line number Diff line number Diff line
@@ -23,10 +23,12 @@ MODULE_PARM_DESC(trypci,

static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
{
	if (io->si_type == SI_KCS) {
	unsigned char status;
	int regspacing;

	if (io->si_info->type != SI_KCS)
		return DEFAULT_REGSPACING;

	io->regsize = DEFAULT_REGSIZE;
	io->regshift = 0;

@@ -46,7 +48,7 @@ static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
			return regspacing;
		regspacing *= 4;
	}
	}

	return DEFAULT_REGSPACING;
}

@@ -74,15 +76,15 @@ static int ipmi_pci_probe(struct pci_dev *pdev,

	switch (pdev->class) {
	case PCI_CLASS_SERIAL_IPMI_SMIC:
		io.si_type = SI_SMIC;
		io.si_info = &ipmi_smic_si_info;
		break;

	case PCI_CLASS_SERIAL_IPMI_KCS:
		io.si_type = SI_KCS;
		io.si_info = &ipmi_kcs_si_info;
		break;

	case PCI_CLASS_SERIAL_IPMI_BT:
		io.si_type = SI_BT;
		io.si_info = &ipmi_bt_si_info;
		break;

	default:
+14 −13
Original line number Diff line number Diff line
@@ -163,9 +163,13 @@ static int platform_ipmi_probe(struct platform_device *pdev)

	switch (type) {
	case SI_KCS:
		io.si_info = &ipmi_kcs_si_info;
		break;
	case SI_SMIC:
		io.si_info = &ipmi_smic_si_info;
		break;
	case SI_BT:
		io.si_type = type;
		io.si_info = &ipmi_bt_si_info;
		break;
	case SI_TYPE_INVALID: /* User disabled this in hardcode. */
		return -ENODEV;
@@ -213,13 +217,10 @@ static int platform_ipmi_probe(struct platform_device *pdev)

#ifdef CONFIG_OF
static const struct of_device_id of_ipmi_match[] = {
	{ .type = "ipmi", .compatible = "ipmi-kcs",
	  .data = (void *)(unsigned long) SI_KCS },
	{ .type = "ipmi", .compatible = "ipmi-smic",
	  .data = (void *)(unsigned long) SI_SMIC },
	{ .type = "ipmi", .compatible = "ipmi-bt",
	  .data = (void *)(unsigned long) SI_BT },
	{},
	{ .type = "ipmi", .compatible = "ipmi-kcs", .data = &ipmi_kcs_si_info },
	{ .type = "ipmi", .compatible = "ipmi-smic", .data = &ipmi_smic_si_info },
	{ .type = "ipmi", .compatible = "ipmi-bt", .data = &ipmi_bt_si_info },
	{}
};
MODULE_DEVICE_TABLE(of, of_ipmi_match);

@@ -265,7 +266,7 @@ static int of_ipmi_probe(struct platform_device *pdev)
	}

	memset(&io, 0, sizeof(io));
	io.si_type	= (enum si_type)device_get_match_data(&pdev->dev);
	io.si_info	= device_get_match_data(&pdev->dev);
	io.addr_source	= SI_DEVICETREE;
	io.irq_setup	= ipmi_std_irq_setup;

@@ -296,7 +297,7 @@ static int find_slave_address(struct si_sm_io *io, int slave_addr)
{
#ifdef CONFIG_IPMI_DMI_DECODE
	if (!slave_addr)
		slave_addr = ipmi_dmi_get_slave_addr(io->si_type,
		slave_addr = ipmi_dmi_get_slave_addr(io->si_info->type,
						     io->addr_space,
						     io->addr_data);
#endif
@@ -335,13 +336,13 @@ static int acpi_ipmi_probe(struct platform_device *pdev)

	switch (tmp) {
	case 1:
		io.si_type = SI_KCS;
		io.si_info = &ipmi_kcs_si_info;
		break;
	case 2:
		io.si_type = SI_SMIC;
		io.si_info = &ipmi_smic_si_info;
		break;
	case 3:
		io.si_type = SI_BT;
		io.si_info = &ipmi_bt_si_info;
		break;
	case 4: /* SSIF, just ignore */
		return -ENODEV;