xref: /openbmc/linux/drivers/char/ipmi/ipmi_dmi.c (revision 68198dca)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
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.
5  */
6 
7 #include <linux/ipmi.h>
8 #include <linux/init.h>
9 #include <linux/dmi.h>
10 #include <linux/platform_device.h>
11 #include <linux/property.h>
12 #include "ipmi_si_sm.h"
13 #include "ipmi_dmi.h"
14 
15 #define IPMI_DMI_TYPE_KCS	0x01
16 #define IPMI_DMI_TYPE_SMIC	0x02
17 #define IPMI_DMI_TYPE_BT	0x03
18 #define IPMI_DMI_TYPE_SSIF	0x04
19 
20 struct ipmi_dmi_info {
21 	enum si_type si_type;
22 	u32 flags;
23 	unsigned long addr;
24 	u8 slave_addr;
25 	struct ipmi_dmi_info *next;
26 };
27 
28 static struct ipmi_dmi_info *ipmi_dmi_infos;
29 
30 static int ipmi_dmi_nr __initdata;
31 
32 #define set_prop_entry(_p_, _name_, type, val)	\
33 do {					\
34 	struct property_entry *_p = &_p_;	\
35 	_p->name = _name_;			\
36 	_p->length = sizeof(type);		\
37 	_p->is_string = false;			\
38 	_p->value.type##_data = val;		\
39 } while(0)
40 
41 static void __init dmi_add_platform_ipmi(unsigned long base_addr,
42 					 u32 flags,
43 					 u8 slave_addr,
44 					 int irq,
45 					 int offset,
46 					 int type)
47 {
48 	struct platform_device *pdev;
49 	struct resource r[4];
50 	unsigned int num_r = 1, size;
51 	struct property_entry p[5];
52 	unsigned int pidx = 0;
53 	char *name, *override;
54 	int rv;
55 	enum si_type si_type;
56 	struct ipmi_dmi_info *info;
57 
58 	memset(p, 0, sizeof(p));
59 
60 	name = "dmi-ipmi-si";
61 	override = "ipmi_si";
62 	switch (type) {
63 	case IPMI_DMI_TYPE_SSIF:
64 		name = "dmi-ipmi-ssif";
65 		override = "ipmi_ssif";
66 		offset = 1;
67 		size = 1;
68 		si_type = SI_TYPE_INVALID;
69 		break;
70 	case IPMI_DMI_TYPE_BT:
71 		size = 3;
72 		si_type = SI_BT;
73 		break;
74 	case IPMI_DMI_TYPE_KCS:
75 		size = 2;
76 		si_type = SI_KCS;
77 		break;
78 	case IPMI_DMI_TYPE_SMIC:
79 		size = 2;
80 		si_type = SI_SMIC;
81 		break;
82 	default:
83 		pr_err("ipmi:dmi: Invalid IPMI type: %d\n", type);
84 		return;
85 	}
86 
87 	if (si_type != SI_TYPE_INVALID)
88 		set_prop_entry(p[pidx++], "ipmi-type", u8, si_type);
89 	set_prop_entry(p[pidx++], "slave-addr", u8, slave_addr);
90 	set_prop_entry(p[pidx++], "addr-source", u8, SI_SMBIOS);
91 
92 	info = kmalloc(sizeof(*info), GFP_KERNEL);
93 	if (!info) {
94 		pr_warn("ipmi:dmi: Could not allocate dmi info\n");
95 	} else {
96 		info->si_type = si_type;
97 		info->flags = flags;
98 		info->addr = base_addr;
99 		info->slave_addr = slave_addr;
100 		info->next = ipmi_dmi_infos;
101 		ipmi_dmi_infos = info;
102 	}
103 
104 	pdev = platform_device_alloc(name, ipmi_dmi_nr);
105 	if (!pdev) {
106 		pr_err("ipmi:dmi: Error allocation IPMI platform device\n");
107 		return;
108 	}
109 	pdev->driver_override = override;
110 
111 	if (type == IPMI_DMI_TYPE_SSIF) {
112 		set_prop_entry(p[pidx++], "i2c-addr", u16, base_addr);
113 		goto add_properties;
114 	}
115 
116 	memset(r, 0, sizeof(r));
117 
118 	r[0].start = base_addr;
119 	r[0].end = r[0].start + offset - 1;
120 	r[0].name = "IPMI Address 1";
121 	r[0].flags = flags;
122 
123 	if (size > 1) {
124 		r[1].start = r[0].start + offset;
125 		r[1].end = r[1].start + offset - 1;
126 		r[1].name = "IPMI Address 2";
127 		r[1].flags = flags;
128 		num_r++;
129 	}
130 
131 	if (size > 2) {
132 		r[2].start = r[1].start + offset;
133 		r[2].end = r[2].start + offset - 1;
134 		r[2].name = "IPMI Address 3";
135 		r[2].flags = flags;
136 		num_r++;
137 	}
138 
139 	if (irq) {
140 		r[num_r].start = irq;
141 		r[num_r].end = irq;
142 		r[num_r].name = "IPMI IRQ";
143 		r[num_r].flags = IORESOURCE_IRQ;
144 		num_r++;
145 	}
146 
147 	rv = platform_device_add_resources(pdev, r, num_r);
148 	if (rv) {
149 		dev_err(&pdev->dev,
150 			"ipmi:dmi: Unable to add resources: %d\n", rv);
151 		goto err;
152 	}
153 
154 add_properties:
155 	rv = platform_device_add_properties(pdev, p);
156 	if (rv) {
157 		dev_err(&pdev->dev,
158 			"ipmi:dmi: Unable to add properties: %d\n", rv);
159 		goto err;
160 	}
161 
162 	rv = platform_device_add(pdev);
163 	if (rv) {
164 		dev_err(&pdev->dev, "ipmi:dmi: Unable to add device: %d\n", rv);
165 		goto err;
166 	}
167 
168 	ipmi_dmi_nr++;
169 	return;
170 
171 err:
172 	platform_device_put(pdev);
173 }
174 
175 /*
176  * Look up the slave address for a given interface.  This is here
177  * because ACPI doesn't have a slave address while SMBIOS does, but we
178  * prefer using ACPI so the ACPI code can use the IPMI namespace.
179  * This function allows an ACPI-specified IPMI device to look up the
180  * slave address from the DMI table.
181  */
182 int ipmi_dmi_get_slave_addr(enum si_type si_type, u32 flags,
183 			    unsigned long base_addr)
184 {
185 	struct ipmi_dmi_info *info = ipmi_dmi_infos;
186 
187 	while (info) {
188 		if (info->si_type == si_type &&
189 		    info->flags == flags &&
190 		    info->addr == base_addr)
191 			return info->slave_addr;
192 		info = info->next;
193 	}
194 
195 	return 0;
196 }
197 EXPORT_SYMBOL(ipmi_dmi_get_slave_addr);
198 
199 #define DMI_IPMI_MIN_LENGTH	0x10
200 #define DMI_IPMI_VER2_LENGTH	0x12
201 #define DMI_IPMI_TYPE		4
202 #define DMI_IPMI_SLAVEADDR	6
203 #define DMI_IPMI_ADDR		8
204 #define DMI_IPMI_ACCESS		0x10
205 #define DMI_IPMI_IRQ		0x11
206 #define DMI_IPMI_IO_MASK	0xfffe
207 
208 static void __init dmi_decode_ipmi(const struct dmi_header *dm)
209 {
210 	const u8	*data = (const u8 *) dm;
211 	u32             flags = IORESOURCE_IO;
212 	unsigned long	base_addr;
213 	u8              len = dm->length;
214 	u8              slave_addr;
215 	int             irq = 0, offset;
216 	int             type;
217 
218 	if (len < DMI_IPMI_MIN_LENGTH)
219 		return;
220 
221 	type = data[DMI_IPMI_TYPE];
222 	slave_addr = data[DMI_IPMI_SLAVEADDR];
223 
224 	memcpy(&base_addr, data + DMI_IPMI_ADDR, sizeof(unsigned long));
225 	if (len >= DMI_IPMI_VER2_LENGTH) {
226 		if (type == IPMI_DMI_TYPE_SSIF) {
227 			offset = 0;
228 			flags = 0;
229 			base_addr = data[DMI_IPMI_ADDR] >> 1;
230 			if (base_addr == 0) {
231 				/*
232 				 * Some broken systems put the I2C address in
233 				 * the slave address field.  We try to
234 				 * accommodate them here.
235 				 */
236 				base_addr = data[DMI_IPMI_SLAVEADDR] >> 1;
237 				slave_addr = 0;
238 			}
239 		} else {
240 			if (base_addr & 1) {
241 				/* I/O */
242 				base_addr &= DMI_IPMI_IO_MASK;
243 			} else {
244 				/* Memory */
245 				flags = IORESOURCE_MEM;
246 			}
247 
248 			/*
249 			 * If bit 4 of byte 0x10 is set, then the lsb
250 			 * for the address is odd.
251 			 */
252 			base_addr |= (data[DMI_IPMI_ACCESS] >> 4) & 1;
253 
254 			irq = data[DMI_IPMI_IRQ];
255 
256 			/*
257 			 * The top two bits of byte 0x10 hold the
258 			 * register spacing.
259 			 */
260 			switch ((data[DMI_IPMI_ACCESS] >> 6) & 3) {
261 			case 0: /* Byte boundaries */
262 				offset = 1;
263 				break;
264 			case 1: /* 32-bit boundaries */
265 				offset = 4;
266 				break;
267 			case 2: /* 16-byte boundaries */
268 				offset = 16;
269 				break;
270 			default:
271 				pr_err("ipmi:dmi: Invalid offset: 0\n");
272 				return;
273 			}
274 		}
275 	} else {
276 		/* Old DMI spec. */
277 		/*
278 		 * Note that technically, the lower bit of the base
279 		 * address should be 1 if the address is I/O and 0 if
280 		 * the address is in memory.  So many systems get that
281 		 * wrong (and all that I have seen are I/O) so we just
282 		 * ignore that bit and assume I/O.  Systems that use
283 		 * memory should use the newer spec, anyway.
284 		 */
285 		base_addr = base_addr & DMI_IPMI_IO_MASK;
286 		offset = 1;
287 	}
288 
289 	dmi_add_platform_ipmi(base_addr, flags, slave_addr, irq,
290 			      offset, type);
291 }
292 
293 static int __init scan_for_dmi_ipmi(void)
294 {
295 	const struct dmi_device *dev = NULL;
296 
297 	while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
298 		dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
299 
300 	return 0;
301 }
302 subsys_initcall(scan_for_dmi_ipmi);
303