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>
15 #include "ipmi_si_sm.h"
17 #include "ipmi_plat_data.h"
19 #define IPMI_DMI_TYPE_KCS 0x01
20 #define IPMI_DMI_TYPE_SMIC 0x02
21 #define IPMI_DMI_TYPE_BT 0x03
22 #define IPMI_DMI_TYPE_SSIF 0x04
24 struct ipmi_dmi_info
{
26 unsigned int space
; /* addr space for si, intf# for ssif */
29 struct ipmi_dmi_info
*next
;
32 static struct ipmi_dmi_info
*ipmi_dmi_infos
;
34 static int ipmi_dmi_nr __initdata
;
36 static void __init
dmi_add_platform_ipmi(unsigned long base_addr
,
44 struct ipmi_dmi_info
*info
;
45 struct ipmi_plat_data p
;
47 memset(&p
, 0, sizeof(p
));
50 p
.iftype
= IPMI_PLAT_IF_SI
;
52 case IPMI_DMI_TYPE_SSIF
:
53 name
= "dmi-ipmi-ssif";
54 p
.iftype
= IPMI_PLAT_IF_SSIF
;
55 p
.type
= SI_TYPE_INVALID
;
57 case IPMI_DMI_TYPE_BT
:
60 case IPMI_DMI_TYPE_KCS
:
63 case IPMI_DMI_TYPE_SMIC
:
67 pr_err("Invalid IPMI type: %d\n", type
);
73 p
.regspacing
= offset
;
75 p
.slave_addr
= slave_addr
;
76 p
.addr_source
= SI_SMBIOS
;
78 info
= kmalloc(sizeof(*info
), GFP_KERNEL
);
80 pr_warn("Could not allocate dmi info\n");
82 info
->si_type
= p
.type
;
84 info
->addr
= base_addr
;
85 info
->slave_addr
= slave_addr
;
86 info
->next
= ipmi_dmi_infos
;
87 ipmi_dmi_infos
= info
;
90 if (ipmi_platform_add(name
, ipmi_dmi_nr
, &p
))
95 * Look up the slave address for a given interface. This is here
96 * because ACPI doesn't have a slave address while SMBIOS does, but we
97 * prefer using ACPI so the ACPI code can use the IPMI namespace.
98 * This function allows an ACPI-specified IPMI device to look up the
99 * slave address from the DMI table.
101 int ipmi_dmi_get_slave_addr(enum si_type si_type
, unsigned int space
,
102 unsigned long base_addr
)
104 struct ipmi_dmi_info
*info
= ipmi_dmi_infos
;
107 if (info
->si_type
== si_type
&&
108 info
->space
== space
&&
109 info
->addr
== base_addr
)
110 return info
->slave_addr
;
116 EXPORT_SYMBOL(ipmi_dmi_get_slave_addr
);
118 #define DMI_IPMI_MIN_LENGTH 0x10
119 #define DMI_IPMI_VER2_LENGTH 0x12
120 #define DMI_IPMI_TYPE 4
121 #define DMI_IPMI_SLAVEADDR 6
122 #define DMI_IPMI_ADDR 8
123 #define DMI_IPMI_ACCESS 0x10
124 #define DMI_IPMI_IRQ 0x11
125 #define DMI_IPMI_IO_MASK 0xfffe
127 static void __init
dmi_decode_ipmi(const struct dmi_header
*dm
)
129 const u8
*data
= (const u8
*) dm
;
130 int space
= IPMI_IO_ADDR_SPACE
;
131 unsigned long base_addr
;
134 int irq
= 0, offset
= 0;
137 if (len
< DMI_IPMI_MIN_LENGTH
)
140 type
= data
[DMI_IPMI_TYPE
];
141 slave_addr
= data
[DMI_IPMI_SLAVEADDR
];
143 memcpy(&base_addr
, data
+ DMI_IPMI_ADDR
, sizeof(unsigned long));
145 pr_err("Base address is zero, assuming no IPMI interface\n");
148 if (len
>= DMI_IPMI_VER2_LENGTH
) {
149 if (type
== IPMI_DMI_TYPE_SSIF
) {
150 space
= 0; /* Match I2C interface 0. */
151 base_addr
= data
[DMI_IPMI_ADDR
] >> 1;
152 if (base_addr
== 0) {
154 * Some broken systems put the I2C address in
155 * the slave address field. We try to
156 * accommodate them here.
158 base_addr
= data
[DMI_IPMI_SLAVEADDR
] >> 1;
164 base_addr
&= DMI_IPMI_IO_MASK
;
167 space
= IPMI_MEM_ADDR_SPACE
;
171 * If bit 4 of byte 0x10 is set, then the lsb
172 * for the address is odd.
174 base_addr
|= (data
[DMI_IPMI_ACCESS
] >> 4) & 1;
176 irq
= data
[DMI_IPMI_IRQ
];
179 * The top two bits of byte 0x10 hold the
182 switch ((data
[DMI_IPMI_ACCESS
] >> 6) & 3) {
183 case 0: /* Byte boundaries */
186 case 1: /* 32-bit boundaries */
189 case 2: /* 16-byte boundaries */
193 pr_err("Invalid offset: 0\n");
200 * Note that technically, the lower bit of the base
201 * address should be 1 if the address is I/O and 0 if
202 * the address is in memory. So many systems get that
203 * wrong (and all that I have seen are I/O) so we just
204 * ignore that bit and assume I/O. Systems that use
205 * memory should use the newer spec, anyway.
207 base_addr
= base_addr
& DMI_IPMI_IO_MASK
;
211 dmi_add_platform_ipmi(base_addr
, space
, slave_addr
, irq
,
215 static int __init
scan_for_dmi_ipmi(void)
217 const struct dmi_device
*dev
= NULL
;
219 while ((dev
= dmi_find_device(DMI_DEV_TYPE_IPMI
, NULL
, dev
)))
220 dmi_decode_ipmi((const struct dmi_header
*) dev
->device_data
);
224 subsys_initcall(scan_for_dmi_ipmi
);