Skip to content

Commit 9cba938

Browse files
committed
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: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Closes: https://lore.kernel.org/lkml/20250415085156.446430-1-andriy.shevchenko@linux.intel.com/ Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Corey Minyard <corey@minyard.net>
1 parent 4f79eaa commit 9cba938

5 files changed

Lines changed: 70 additions & 55 deletions

File tree

drivers/char/ipmi/ipmi_si.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ enum si_type {
2626
/* Array is defined in the ipmi_si_intf.c */
2727
extern const char *const si_to_str[];
2828

29+
struct ipmi_match_info {
30+
enum si_type type;
31+
};
32+
33+
extern const struct ipmi_match_info ipmi_kcs_si_info;
34+
extern const struct ipmi_match_info ipmi_smic_si_info;
35+
extern const struct ipmi_match_info ipmi_bt_si_info;
36+
2937
enum ipmi_addr_space {
3038
IPMI_IO_ADDR_SPACE, IPMI_MEM_ADDR_SPACE
3139
};
@@ -64,7 +72,7 @@ struct si_sm_io {
6472
void (*irq_cleanup)(struct si_sm_io *io);
6573

6674
u8 slave_addr;
67-
enum si_type si_type;
75+
const struct ipmi_match_info *si_info;
6876
struct device *dev;
6977
};
7078

drivers/char/ipmi/ipmi_si_intf.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ enum si_intf_state {
7373
/* 'invalid' to allow a firmware-specified interface to be disabled */
7474
const char *const si_to_str[] = { "invalid", "kcs", "smic", "bt", NULL };
7575

76+
const struct ipmi_match_info ipmi_kcs_si_info = { .type = SI_KCS };
77+
const struct ipmi_match_info ipmi_smic_si_info = { .type = SI_SMIC };
78+
const struct ipmi_match_info ipmi_bt_si_info = { .type = SI_BT };
79+
7680
static bool initialized;
7781

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

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

11701174
if (enable) {
@@ -1235,15 +1239,15 @@ MODULE_PARM_DESC(kipmid_max_busy_us,
12351239

12361240
void ipmi_irq_finish_setup(struct si_sm_io *io)
12371241
{
1238-
if (io->si_type == SI_BT)
1242+
if (io->si_info->type == SI_BT)
12391243
/* Enable the interrupt in the BT interface. */
12401244
io->outputb(io, IPMI_BT_INTMASK_REG,
12411245
IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
12421246
}
12431247

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

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

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

16501654
return sysfs_emit(buf,
16511655
"%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
1652-
si_to_str[smi_info->io.si_type],
1656+
si_to_str[smi_info->io.si_info->type],
16531657
addr_space_to_str[smi_info->io.addr_space],
16541658
smi_info->io.addr_data,
16551659
smi_info->io.regspacing,
@@ -1803,7 +1807,7 @@ setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
18031807
{
18041808
struct ipmi_device_id *id = &smi_info->device_id;
18051809
if (id->manufacturer_id == DELL_IANA_MFR_ID &&
1806-
smi_info->io.si_type == SI_BT)
1810+
smi_info->io.si_info->type == SI_BT)
18071811
register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
18081812
}
18091813

@@ -1907,13 +1911,13 @@ int ipmi_si_add_smi(struct si_sm_io *io)
19071911
/* We prefer ACPI over SMBIOS. */
19081912
dev_info(dup->io.dev,
19091913
"Removing SMBIOS-specified %s state machine in favor of ACPI\n",
1910-
si_to_str[new_smi->io.si_type]);
1914+
si_to_str[new_smi->io.si_info->type]);
19111915
cleanup_one_si(dup);
19121916
} else {
19131917
dev_info(new_smi->io.dev,
19141918
"%s-specified %s state machine: duplicate\n",
19151919
ipmi_addr_src_to_str(new_smi->io.addr_source),
1916-
si_to_str[new_smi->io.si_type]);
1920+
si_to_str[new_smi->io.si_info->type]);
19171921
rv = -EBUSY;
19181922
kfree(new_smi);
19191923
goto out_err;
@@ -1922,7 +1926,7 @@ int ipmi_si_add_smi(struct si_sm_io *io)
19221926

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

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

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

19461950
pr_info("Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n",
19471951
ipmi_addr_src_to_str(new_smi->io.addr_source),
1948-
si_to_str[new_smi->io.si_type],
1952+
si_to_str[new_smi->io.si_info->type],
19491953
addr_space_to_str[new_smi->io.addr_space],
19501954
new_smi->io.addr_data,
19511955
new_smi->io.slave_addr, new_smi->io.irq);
19521956

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

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

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

@@ -2267,7 +2271,7 @@ struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type,
22672271
list_for_each_entry_safe(e, tmp_e, &smi_infos, link) {
22682272
if (e->io.addr_space != addr_space)
22692273
continue;
2270-
if (e->io.si_type != si_type)
2274+
if (e->io.si_info->type != si_type)
22712275
continue;
22722276
if (e->io.addr_data == addr) {
22732277
dev = get_device(e->io.dev);

drivers/char/ipmi/ipmi_si_parisc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev)
1313

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

16-
io.si_type = SI_KCS;
16+
io.si_info = &ipmi_kcs_si_info;
1717
io.addr_source = SI_DEVICETREE;
1818
io.addr_space = IPMI_MEM_ADDR_SPACE;
1919
io.addr_data = dev->hpa.start;

drivers/char/ipmi/ipmi_si_pci.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,32 @@ MODULE_PARM_DESC(trypci,
2323

2424
static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
2525
{
26-
if (io->si_type == SI_KCS) {
27-
unsigned char status;
28-
int regspacing;
29-
30-
io->regsize = DEFAULT_REGSIZE;
31-
io->regshift = 0;
32-
33-
/* detect 1, 4, 16byte spacing */
34-
for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
35-
io->regspacing = regspacing;
36-
if (io->io_setup(io)) {
37-
dev_err(io->dev, "Could not setup I/O space\n");
38-
return DEFAULT_REGSPACING;
39-
}
40-
/* write invalid cmd */
41-
io->outputb(io, 1, 0x10);
42-
/* read status back */
43-
status = io->inputb(io, 1);
44-
io->io_cleanup(io);
45-
if (status)
46-
return regspacing;
47-
regspacing *= 4;
26+
unsigned char status;
27+
int regspacing;
28+
29+
if (io->si_info->type != SI_KCS)
30+
return DEFAULT_REGSPACING;
31+
32+
io->regsize = DEFAULT_REGSIZE;
33+
io->regshift = 0;
34+
35+
/* detect 1, 4, 16byte spacing */
36+
for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
37+
io->regspacing = regspacing;
38+
if (io->io_setup(io)) {
39+
dev_err(io->dev, "Could not setup I/O space\n");
40+
return DEFAULT_REGSPACING;
4841
}
42+
/* write invalid cmd */
43+
io->outputb(io, 1, 0x10);
44+
/* read status back */
45+
status = io->inputb(io, 1);
46+
io->io_cleanup(io);
47+
if (status)
48+
return regspacing;
49+
regspacing *= 4;
4950
}
51+
5052
return DEFAULT_REGSPACING;
5153
}
5254

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

7577
switch (pdev->class) {
7678
case PCI_CLASS_SERIAL_IPMI_SMIC:
77-
io.si_type = SI_SMIC;
79+
io.si_info = &ipmi_smic_si_info;
7880
break;
7981

8082
case PCI_CLASS_SERIAL_IPMI_KCS:
81-
io.si_type = SI_KCS;
83+
io.si_info = &ipmi_kcs_si_info;
8284
break;
8385

8486
case PCI_CLASS_SERIAL_IPMI_BT:
85-
io.si_type = SI_BT;
87+
io.si_info = &ipmi_bt_si_info;
8688
break;
8789

8890
default:

drivers/char/ipmi/ipmi_si_platform.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,13 @@ static int platform_ipmi_probe(struct platform_device *pdev)
163163

164164
switch (type) {
165165
case SI_KCS:
166+
io.si_info = &ipmi_kcs_si_info;
167+
break;
166168
case SI_SMIC:
169+
io.si_info = &ipmi_smic_si_info;
170+
break;
167171
case SI_BT:
168-
io.si_type = type;
172+
io.si_info = &ipmi_bt_si_info;
169173
break;
170174
case SI_TYPE_INVALID: /* User disabled this in hardcode. */
171175
return -ENODEV;
@@ -213,13 +217,10 @@ static int platform_ipmi_probe(struct platform_device *pdev)
213217

214218
#ifdef CONFIG_OF
215219
static const struct of_device_id of_ipmi_match[] = {
216-
{ .type = "ipmi", .compatible = "ipmi-kcs",
217-
.data = (void *)(unsigned long) SI_KCS },
218-
{ .type = "ipmi", .compatible = "ipmi-smic",
219-
.data = (void *)(unsigned long) SI_SMIC },
220-
{ .type = "ipmi", .compatible = "ipmi-bt",
221-
.data = (void *)(unsigned long) SI_BT },
222-
{},
220+
{ .type = "ipmi", .compatible = "ipmi-kcs", .data = &ipmi_kcs_si_info },
221+
{ .type = "ipmi", .compatible = "ipmi-smic", .data = &ipmi_smic_si_info },
222+
{ .type = "ipmi", .compatible = "ipmi-bt", .data = &ipmi_bt_si_info },
223+
{}
223224
};
224225
MODULE_DEVICE_TABLE(of, of_ipmi_match);
225226

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

267268
memset(&io, 0, sizeof(io));
268-
io.si_type = (enum si_type)device_get_match_data(&pdev->dev);
269+
io.si_info = device_get_match_data(&pdev->dev);
269270
io.addr_source = SI_DEVICETREE;
270271
io.irq_setup = ipmi_std_irq_setup;
271272

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

336337
switch (tmp) {
337338
case 1:
338-
io.si_type = SI_KCS;
339+
io.si_info = &ipmi_kcs_si_info;
339340
break;
340341
case 2:
341-
io.si_type = SI_SMIC;
342+
io.si_info = &ipmi_smic_si_info;
342343
break;
343344
case 3:
344-
io.si_type = SI_BT;
345+
io.si_info = &ipmi_bt_si_info;
345346
break;
346347
case 4: /* SSIF, just ignore */
347348
return -ENODEV;

0 commit comments

Comments
 (0)