1 // SPDX-License-Identifier: GPL-2.0+
3 * A hack to create a platform device from a DMI entry. This will
4 * allow autoloading of the IPMI drive based on SMBIOS entries.
7 #define pr_fmt(fmt) "%s" fmt, "ipmi:dmi: "
10 #include <linux/ipmi.h>
11 #include <linux/init.h>
12 #include <linux/dmi.h>
13 #include <linux/platform_device.h>
14 #include <linux/property.h>
16 #include "ipmi_plat_data.h"
18 #define IPMI_DMI_TYPE_KCS 0x01
19 #define IPMI_DMI_TYPE_SMIC 0x02
20 #define IPMI_DMI_TYPE_BT 0x03
21 #define IPMI_DMI_TYPE_SSIF 0x04
23 struct ipmi_dmi_info
{
25 unsigned int space
; /* addr space for si, intf# for ssif */
28 struct ipmi_dmi_info
*next
;
31 static struct ipmi_dmi_info
*ipmi_dmi_infos
;
33 static int ipmi_dmi_nr __initdata
;
35 static void __init
dmi_add_platform_ipmi(unsigned long base_addr
,
43 struct ipmi_dmi_info
*info
;
44 struct ipmi_plat_data p
;
46 memset(&p
, 0, sizeof(p
));
49 p
.iftype
= IPMI_PLAT_IF_SI
;
51 case IPMI_DMI_TYPE_SSIF
:
52 name
= "dmi-ipmi-ssif";
53 p
.iftype
= IPMI_PLAT_IF_SSIF
;
54 p
.type
= SI_TYPE_INVALID
;
56 case IPMI_DMI_TYPE_BT
:
59 case IPMI_DMI_TYPE_KCS
:
62 case IPMI_DMI_TYPE_SMIC
:
66 pr_err("Invalid IPMI type: %d\n", type
);
72 p
.regspacing
= offset
;
74 p
.slave_addr
= slave_addr
;
75 p
.addr_source
= SI_SMBIOS
;
77 info
= kmalloc(sizeof(*info
), GFP_KERNEL
);
79 pr_warn("Could not allocate dmi info\n");
81 info
->si_type
= p
.type
;
83 info
->addr
= base_addr
;
84 info
->slave_addr
= slave_addr
;
85 info
->next
= ipmi_dmi_infos
;
86 ipmi_dmi_infos
= info
;
89 if (ipmi_platform_add(name
, ipmi_dmi_nr
, &p
))
94 * Look up the slave address for a given interface. This is here
95 * because ACPI doesn't have a slave address while SMBIOS does, but we
96 * prefer using ACPI so the ACPI code can use the IPMI namespace.
97 * This function allows an ACPI-specified IPMI device to look up the
98 * slave address from the DMI table.
100 int ipmi_dmi_get_slave_addr(enum si_type si_type
, unsigned int space
,
101 unsigned long base_addr
)
103 struct ipmi_dmi_info
*info
= ipmi_dmi_infos
;
106 if (info
->si_type
== si_type
&&
107 info
->space
== space
&&
108 info
->addr
== base_addr
)
109 return info
->slave_addr
;
115 EXPORT_SYMBOL(ipmi_dmi_get_slave_addr
);
117 #define DMI_IPMI_MIN_LENGTH 0x10
118 #define DMI_IPMI_VER2_LENGTH 0x12
119 #define DMI_IPMI_TYPE 4
120 #define DMI_IPMI_SLAVEADDR 6
121 #define DMI_IPMI_ADDR 8
122 #define DMI_IPMI_ACCESS 0x10
123 #define DMI_IPMI_IRQ 0x11
124 #define DMI_IPMI_IO_MASK 0xfffe
126 static void __init
dmi_decode_ipmi(const struct dmi_header
*dm
)
128 const u8
*data
= (const u8
*) dm
;
129 int space
= IPMI_IO_ADDR_SPACE
;
130 unsigned long base_addr
;
133 int irq
= 0, offset
= 0;
136 if (len
< DMI_IPMI_MIN_LENGTH
)
139 type
= data
[DMI_IPMI_TYPE
];
140 slave_addr
= data
[DMI_IPMI_SLAVEADDR
];
142 memcpy(&base_addr
, data
+ DMI_IPMI_ADDR
, sizeof(unsigned long));
144 pr_err("Base address is zero, assuming no IPMI interface\n");
147 if (len
>= DMI_IPMI_VER2_LENGTH
) {
148 if (type
== IPMI_DMI_TYPE_SSIF
) {
149 space
= 0; /* Match I2C interface 0. */
150 base_addr
= data
[DMI_IPMI_ADDR
] >> 1;
151 if (base_addr
== 0) {
153 * Some broken systems put the I2C address in
154 * the slave address field. We try to
155 * accommodate them here.
157 base_addr
= data
[DMI_IPMI_SLAVEADDR
] >> 1;
163 base_addr
&= DMI_IPMI_IO_MASK
;
166 space
= IPMI_MEM_ADDR_SPACE
;
170 * If bit 4 of byte 0x10 is set, then the lsb
171 * for the address is odd.
173 base_addr
|= (data
[DMI_IPMI_ACCESS
] >> 4) & 1;
175 irq
= data
[DMI_IPMI_IRQ
];
178 * The top two bits of byte 0x10 hold the
181 switch ((data
[DMI_IPMI_ACCESS
] >> 6) & 3) {
182 case 0: /* Byte boundaries */
185 case 1: /* 32-bit boundaries */
188 case 2: /* 16-byte boundaries */
192 pr_err("Invalid offset: 0\n");
199 * Note that technically, the lower bit of the base
200 * address should be 1 if the address is I/O and 0 if
201 * the address is in memory. So many systems get that
202 * wrong (and all that I have seen are I/O) so we just
203 * ignore that bit and assume I/O. Systems that use
204 * memory should use the newer spec, anyway.
206 base_addr
= base_addr
& DMI_IPMI_IO_MASK
;
210 dmi_add_platform_ipmi(base_addr
, space
, slave_addr
, irq
,
214 static int __init
scan_for_dmi_ipmi(void)
216 const struct dmi_device
*dev
= NULL
;
218 while ((dev
= dmi_find_device(DMI_DEV_TYPE_IPMI
, NULL
, dev
)))
219 dmi_decode_ipmi((const struct dmi_header
*) dev
->device_data
);
223 subsys_initcall(scan_for_dmi_ipmi
);