Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * ipmi_si_platform.c
3 *
4 * Handling for platform devices in IPMI (ACPI, OF, and things
5 * coming from the platform.
6 */
7#include <linux/types.h>
8#include <linux/module.h>
9#include <linux/of_device.h>
10#include <linux/of_platform.h>
11#include <linux/of_address.h>
12#include <linux/of_irq.h>
13#include <linux/acpi.h>
14#include "ipmi_si.h"
15#include "ipmi_dmi.h"
16
17#define PFX "ipmi_platform: "
18
19static bool si_tryplatform = true;
20#ifdef CONFIG_ACPI
21static bool si_tryacpi = true;
22#endif
23#ifdef CONFIG_OF
24static bool si_tryopenfirmware = true;
25#endif
26#ifdef CONFIG_DMI
27static bool si_trydmi = true;
28#else
29static bool si_trydmi = false;
30#endif
31
32module_param_named(tryplatform, si_tryplatform, bool, 0);
33MODULE_PARM_DESC(tryplatform, "Setting this to zero will disable the"
34 " default scan of the interfaces identified via platform"
35 " interfaces besides ACPI, OpenFirmware, and DMI");
36#ifdef CONFIG_ACPI
37module_param_named(tryacpi, si_tryacpi, bool, 0);
38MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the"
39 " default scan of the interfaces identified via ACPI");
40#endif
41#ifdef CONFIG_OF
42module_param_named(tryopenfirmware, si_tryopenfirmware, bool, 0);
43MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the"
44 " default scan of the interfaces identified via OpenFirmware");
45#endif
46#ifdef CONFIG_DMI
47module_param_named(trydmi, si_trydmi, bool, 0);
48MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the"
49 " default scan of the interfaces identified via DMI");
50#endif
51
52#ifdef CONFIG_ACPI
53
54/*
55 * Once we get an ACPI failure, we don't try any more, because we go
56 * through the tables sequentially. Once we don't find a table, there
57 * are no more.
58 */
59static int acpi_failure;
60
61/* For GPE-type interrupts. */
62static u32 ipmi_acpi_gpe(acpi_handle gpe_device,
63 u32 gpe_number, void *context)
64{
65 struct si_sm_io *io = context;
66
67 ipmi_si_irq_handler(io->irq, io->irq_handler_data);
68 return ACPI_INTERRUPT_HANDLED;
69}
70
71static void acpi_gpe_irq_cleanup(struct si_sm_io *io)
72{
73 if (!io->irq)
74 return;
75
76 ipmi_irq_start_cleanup(io);
77 acpi_remove_gpe_handler(NULL, io->irq, &ipmi_acpi_gpe);
78}
79
80static int acpi_gpe_irq_setup(struct si_sm_io *io)
81{
82 acpi_status status;
83
84 if (!io->irq)
85 return 0;
86
87 status = acpi_install_gpe_handler(NULL,
88 io->irq,
89 ACPI_GPE_LEVEL_TRIGGERED,
90 &ipmi_acpi_gpe,
91 io);
92 if (status != AE_OK) {
93 dev_warn(io->dev,
94 "Unable to claim ACPI GPE %d, running polled\n",
95 io->irq);
96 io->irq = 0;
97 return -EINVAL;
98 } else {
99 io->irq_cleanup = acpi_gpe_irq_cleanup;
100 ipmi_irq_finish_setup(io);
101 dev_info(io->dev, "Using ACPI GPE %d\n", io->irq);
102 return 0;
103 }
104}
105
106/*
107 * Defined at
108 * http://h21007.www2.hp.com/portal/download/files/unprot/hpspmi.pdf
109 */
110struct SPMITable {
111 s8 Signature[4];
112 u32 Length;
113 u8 Revision;
114 u8 Checksum;
115 s8 OEMID[6];
116 s8 OEMTableID[8];
117 s8 OEMRevision[4];
118 s8 CreatorID[4];
119 s8 CreatorRevision[4];
120 u8 InterfaceType;
121 u8 IPMIlegacy;
122 s16 SpecificationRevision;
123
124 /*
125 * Bit 0 - SCI interrupt supported
126 * Bit 1 - I/O APIC/SAPIC
127 */
128 u8 InterruptType;
129
130 /*
131 * If bit 0 of InterruptType is set, then this is the SCI
132 * interrupt in the GPEx_STS register.
133 */
134 u8 GPE;
135
136 s16 Reserved;
137
138 /*
139 * If bit 1 of InterruptType is set, then this is the I/O
140 * APIC/SAPIC interrupt.
141 */
142 u32 GlobalSystemInterrupt;
143
144 /* The actual register address. */
145 struct acpi_generic_address addr;
146
147 u8 UID[4];
148
149 s8 spmi_id[1]; /* A '\0' terminated array starts here. */
150};
151
152static int try_init_spmi(struct SPMITable *spmi)
153{
154 struct si_sm_io io;
155
156 if (spmi->IPMIlegacy != 1) {
157 pr_info(PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
158 return -ENODEV;
159 }
160
161 memset(&io, 0, sizeof(io));
162 io.addr_source = SI_SPMI;
163 pr_info(PFX "probing via SPMI\n");
164
165 /* Figure out the interface type. */
166 switch (spmi->InterfaceType) {
167 case 1: /* KCS */
168 io.si_type = SI_KCS;
169 break;
170 case 2: /* SMIC */
171 io.si_type = SI_SMIC;
172 break;
173 case 3: /* BT */
174 io.si_type = SI_BT;
175 break;
176 case 4: /* SSIF, just ignore */
177 return -EIO;
178 default:
179 pr_info(PFX "Unknown ACPI/SPMI SI type %d\n",
180 spmi->InterfaceType);
181 return -EIO;
182 }
183
184 if (spmi->InterruptType & 1) {
185 /* We've got a GPE interrupt. */
186 io.irq = spmi->GPE;
187 io.irq_setup = acpi_gpe_irq_setup;
188 } else if (spmi->InterruptType & 2) {
189 /* We've got an APIC/SAPIC interrupt. */
190 io.irq = spmi->GlobalSystemInterrupt;
191 io.irq_setup = ipmi_std_irq_setup;
192 } else {
193 /* Use the default interrupt setting. */
194 io.irq = 0;
195 io.irq_setup = NULL;
196 }
197
198 if (spmi->addr.bit_width) {
199 /* A (hopefully) properly formed register bit width. */
200 io.regspacing = spmi->addr.bit_width / 8;
201 } else {
202 io.regspacing = DEFAULT_REGSPACING;
203 }
204 io.regsize = io.regspacing;
205 io.regshift = spmi->addr.bit_offset;
206
207 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
208 io.addr_type = IPMI_MEM_ADDR_SPACE;
209 } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
210 io.addr_type = IPMI_IO_ADDR_SPACE;
211 } else {
212 pr_warn(PFX "Unknown ACPI I/O Address type\n");
213 return -EIO;
214 }
215 io.addr_data = spmi->addr.address;
216
217 pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
218 (io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
219 io.addr_data, io.regsize, io.regspacing, io.irq);
220
221 return ipmi_si_add_smi(&io);
222}
223
224static void spmi_find_bmc(void)
225{
226 acpi_status status;
227 struct SPMITable *spmi;
228 int i;
229
230 if (acpi_disabled)
231 return;
232
233 if (acpi_failure)
234 return;
235
236 for (i = 0; ; i++) {
237 status = acpi_get_table(ACPI_SIG_SPMI, i+1,
238 (struct acpi_table_header **)&spmi);
239 if (status != AE_OK)
240 return;
241
242 try_init_spmi(spmi);
243 }
244}
245#endif
246
247static struct resource *
248ipmi_get_info_from_resources(struct platform_device *pdev,
249 struct si_sm_io *io)
250{
251 struct resource *res, *res_second;
252
253 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
254 if (res) {
255 io->addr_type = IPMI_IO_ADDR_SPACE;
256 } else {
257 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258 if (res)
259 io->addr_type = IPMI_MEM_ADDR_SPACE;
260 }
261 if (!res) {
262 dev_err(&pdev->dev, "no I/O or memory address\n");
263 return NULL;
264 }
265 io->addr_data = res->start;
266
267 io->regspacing = DEFAULT_REGSPACING;
268 res_second = platform_get_resource(pdev,
269 (io->addr_type == IPMI_IO_ADDR_SPACE) ?
270 IORESOURCE_IO : IORESOURCE_MEM,
271 1);
272 if (res_second) {
273 if (res_second->start > io->addr_data)
274 io->regspacing = res_second->start - io->addr_data;
275 }
276 io->regsize = DEFAULT_REGSIZE;
277 io->regshift = 0;
278
279 return res;
280}
281
282static int platform_ipmi_probe(struct platform_device *pdev)
283{
284 struct si_sm_io io;
285 u8 type, slave_addr, addr_source;
286 int rv;
287
288 rv = device_property_read_u8(&pdev->dev, "addr-source", &addr_source);
289 if (rv)
290 addr_source = SI_PLATFORM;
291 if (addr_source >= SI_LAST)
292 return -EINVAL;
293
294 if (addr_source == SI_SMBIOS) {
295 if (!si_trydmi)
296 return -ENODEV;
297 } else {
298 if (!si_tryplatform)
299 return -ENODEV;
300 }
301
302 rv = device_property_read_u8(&pdev->dev, "ipmi-type", &type);
303 if (rv)
304 return -ENODEV;
305
306 memset(&io, 0, sizeof(io));
307 io.addr_source = addr_source;
308 dev_info(&pdev->dev, PFX "probing via %s\n",
309 ipmi_addr_src_to_str(addr_source));
310
311 switch (type) {
312 case SI_KCS:
313 case SI_SMIC:
314 case SI_BT:
315 io.si_type = type;
316 break;
317 default:
318 dev_err(&pdev->dev, "ipmi-type property is invalid\n");
319 return -EINVAL;
320 }
321
322 if (!ipmi_get_info_from_resources(pdev, &io))
323 return -EINVAL;
324
325 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr);
326 if (rv) {
327 dev_warn(&pdev->dev, "device has no slave-addr property\n");
328 io.slave_addr = 0x20;
329 } else {
330 io.slave_addr = slave_addr;
331 }
332
333 io.irq = platform_get_irq(pdev, 0);
334 if (io.irq > 0)
335 io.irq_setup = ipmi_std_irq_setup;
336 else
337 io.irq = 0;
338
339 io.dev = &pdev->dev;
340
341 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
342 (io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
343 io.addr_data, io.regsize, io.regspacing, io.irq);
344
345 ipmi_si_add_smi(&io);
346
347 return 0;
348}
349
350#ifdef CONFIG_OF
351static const struct of_device_id of_ipmi_match[] = {
352 { .type = "ipmi", .compatible = "ipmi-kcs",
353 .data = (void *)(unsigned long) SI_KCS },
354 { .type = "ipmi", .compatible = "ipmi-smic",
355 .data = (void *)(unsigned long) SI_SMIC },
356 { .type = "ipmi", .compatible = "ipmi-bt",
357 .data = (void *)(unsigned long) SI_BT },
358 {},
359};
360MODULE_DEVICE_TABLE(of, of_ipmi_match);
361
362static int of_ipmi_probe(struct platform_device *pdev)
363{
364 const struct of_device_id *match;
365 struct si_sm_io io;
366 struct resource resource;
367 const __be32 *regsize, *regspacing, *regshift;
368 struct device_node *np = pdev->dev.of_node;
369 int ret;
370 int proplen;
371
372 if (!si_tryopenfirmware)
373 return -ENODEV;
374
375 dev_info(&pdev->dev, "probing via device tree\n");
376
377 match = of_match_device(of_ipmi_match, &pdev->dev);
378 if (!match)
379 return -ENODEV;
380
381 if (!of_device_is_available(np))
382 return -EINVAL;
383
384 ret = of_address_to_resource(np, 0, &resource);
385 if (ret) {
386 dev_warn(&pdev->dev, PFX "invalid address from OF\n");
387 return ret;
388 }
389
390 regsize = of_get_property(np, "reg-size", &proplen);
391 if (regsize && proplen != 4) {
392 dev_warn(&pdev->dev, PFX "invalid regsize from OF\n");
393 return -EINVAL;
394 }
395
396 regspacing = of_get_property(np, "reg-spacing", &proplen);
397 if (regspacing && proplen != 4) {
398 dev_warn(&pdev->dev, PFX "invalid regspacing from OF\n");
399 return -EINVAL;
400 }
401
402 regshift = of_get_property(np, "reg-shift", &proplen);
403 if (regshift && proplen != 4) {
404 dev_warn(&pdev->dev, PFX "invalid regshift from OF\n");
405 return -EINVAL;
406 }
407
408 memset(&io, 0, sizeof(io));
409 io.si_type = (enum si_type) match->data;
410 io.addr_source = SI_DEVICETREE;
411 io.irq_setup = ipmi_std_irq_setup;
412
413 if (resource.flags & IORESOURCE_IO)
414 io.addr_type = IPMI_IO_ADDR_SPACE;
415 else
416 io.addr_type = IPMI_MEM_ADDR_SPACE;
417
418 io.addr_data = resource.start;
419
420 io.regsize = regsize ? be32_to_cpup(regsize) : DEFAULT_REGSIZE;
421 io.regspacing = regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING;
422 io.regshift = regshift ? be32_to_cpup(regshift) : 0;
423
424 io.irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
425 io.dev = &pdev->dev;
426
427 dev_dbg(&pdev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n",
428 io.addr_data, io.regsize, io.regspacing, io.irq);
429
430 return ipmi_si_add_smi(&io);
431}
432#else
433#define of_ipmi_match NULL
434static int of_ipmi_probe(struct platform_device *dev)
435{
436 return -ENODEV;
437}
438#endif
439
440#ifdef CONFIG_ACPI
441static int find_slave_address(struct si_sm_io *io, int slave_addr)
442{
443#ifdef CONFIG_IPMI_DMI_DECODE
444 if (!slave_addr) {
445 u32 flags = IORESOURCE_IO;
446
447 if (io->addr_type == IPMI_MEM_ADDR_SPACE)
448 flags = IORESOURCE_MEM;
449
450 slave_addr = ipmi_dmi_get_slave_addr(io->si_type, flags,
451 io->addr_data);
452 }
453#endif
454
455 return slave_addr;
456}
457
458static int acpi_ipmi_probe(struct platform_device *pdev)
459{
460 struct si_sm_io io;
461 acpi_handle handle;
462 acpi_status status;
463 unsigned long long tmp;
464 struct resource *res;
465 int rv = -EINVAL;
466
467 if (!si_tryacpi)
468 return -ENODEV;
469
470 handle = ACPI_HANDLE(&pdev->dev);
471 if (!handle)
472 return -ENODEV;
473
474 memset(&io, 0, sizeof(io));
475 io.addr_source = SI_ACPI;
476 dev_info(&pdev->dev, PFX "probing via ACPI\n");
477
478 io.addr_info.acpi_info.acpi_handle = handle;
479
480 /* _IFT tells us the interface type: KCS, BT, etc */
481 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
482 if (ACPI_FAILURE(status)) {
483 dev_err(&pdev->dev,
484 "Could not find ACPI IPMI interface type\n");
485 goto err_free;
486 }
487
488 switch (tmp) {
489 case 1:
490 io.si_type = SI_KCS;
491 break;
492 case 2:
493 io.si_type = SI_SMIC;
494 break;
495 case 3:
496 io.si_type = SI_BT;
497 break;
498 case 4: /* SSIF, just ignore */
499 rv = -ENODEV;
500 goto err_free;
501 default:
502 dev_info(&pdev->dev, "unknown IPMI type %lld\n", tmp);
503 goto err_free;
504 }
505
506 res = ipmi_get_info_from_resources(pdev, &io);
507 if (!res) {
508 rv = -EINVAL;
509 goto err_free;
510 }
511
512 /* If _GPE exists, use it; otherwise use standard interrupts */
513 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
514 if (ACPI_SUCCESS(status)) {
515 io.irq = tmp;
516 io.irq_setup = acpi_gpe_irq_setup;
517 } else {
518 int irq = platform_get_irq(pdev, 0);
519
520 if (irq > 0) {
521 io.irq = irq;
522 io.irq_setup = ipmi_std_irq_setup;
523 }
524 }
525
526 io.slave_addr = find_slave_address(&io, io.slave_addr);
527
528 io.dev = &pdev->dev;
529
530 dev_info(io.dev, "%pR regsize %d spacing %d irq %d\n",
531 res, io.regsize, io.regspacing, io.irq);
532
533 return ipmi_si_add_smi(&io);
534
535err_free:
536 return rv;
537}
538
539static const struct acpi_device_id acpi_ipmi_match[] = {
540 { "IPI0001", 0 },
541 { },
542};
543MODULE_DEVICE_TABLE(acpi, acpi_ipmi_match);
544#else
545static int acpi_ipmi_probe(struct platform_device *dev)
546{
547 return -ENODEV;
548}
549#endif
550
551static int ipmi_probe(struct platform_device *pdev)
552{
553 if (pdev->dev.of_node && of_ipmi_probe(pdev) == 0)
554 return 0;
555
556 if (acpi_ipmi_probe(pdev) == 0)
557 return 0;
558
559 return platform_ipmi_probe(pdev);
560}
561
562static int ipmi_remove(struct platform_device *pdev)
563{
564 return ipmi_si_remove_by_dev(&pdev->dev);
565}
566
567struct platform_driver ipmi_platform_driver = {
568 .driver = {
569 .name = DEVICE_NAME,
570 .of_match_table = of_ipmi_match,
571 .acpi_match_table = ACPI_PTR(acpi_ipmi_match),
572 },
573 .probe = ipmi_probe,
574 .remove = ipmi_remove,
575};
576
577void ipmi_si_platform_init(void)
578{
579 int rv = platform_driver_register(&ipmi_platform_driver);
580 if (rv)
581 pr_err(PFX "Unable to register driver: %d\n", rv);
582
583#ifdef CONFIG_ACPI
584 if (si_tryacpi)
585 spmi_find_bmc();
586#endif
587
588}
589
590void ipmi_si_platform_shutdown(void)
591{
592 platform_driver_unregister(&ipmi_platform_driver);
593}