1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * ipmi_si_platform.c 4 * 5 * Handling for platform devices in IPMI (ACPI, OF, and things 6 * coming from the platform. 7 */ 8 9 #define pr_fmt(fmt) "ipmi_platform: " fmt 10 #define dev_fmt pr_fmt 11 12 #include <linux/types.h> 13 #include <linux/module.h> 14 #include <linux/of_device.h> 15 #include <linux/of_platform.h> 16 #include <linux/of_address.h> 17 #include <linux/of_irq.h> 18 #include <linux/acpi.h> 19 #include "ipmi_si.h" 20 #include "ipmi_dmi.h" 21 22 static bool si_tryplatform = true; 23 #ifdef CONFIG_ACPI 24 static bool si_tryacpi = true; 25 #endif 26 #ifdef CONFIG_OF 27 static bool si_tryopenfirmware = true; 28 #endif 29 #ifdef CONFIG_DMI 30 static bool si_trydmi = true; 31 #else 32 static bool si_trydmi = false; 33 #endif 34 35 module_param_named(tryplatform, si_tryplatform, bool, 0); 36 MODULE_PARM_DESC(tryplatform, "Setting this to zero will disable the" 37 " default scan of the interfaces identified via platform" 38 " interfaces besides ACPI, OpenFirmware, and DMI"); 39 #ifdef CONFIG_ACPI 40 module_param_named(tryacpi, si_tryacpi, bool, 0); 41 MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the" 42 " default scan of the interfaces identified via ACPI"); 43 #endif 44 #ifdef CONFIG_OF 45 module_param_named(tryopenfirmware, si_tryopenfirmware, bool, 0); 46 MODULE_PARM_DESC(tryopenfirmware, "Setting this to zero will disable the" 47 " default scan of the interfaces identified via OpenFirmware"); 48 #endif 49 #ifdef CONFIG_DMI 50 module_param_named(trydmi, si_trydmi, bool, 0); 51 MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the" 52 " default scan of the interfaces identified via DMI"); 53 #endif 54 55 #ifdef CONFIG_ACPI 56 /* For GPE-type interrupts. */ 57 static u32 ipmi_acpi_gpe(acpi_handle gpe_device, 58 u32 gpe_number, void *context) 59 { 60 struct si_sm_io *io = context; 61 62 ipmi_si_irq_handler(io->irq, io->irq_handler_data); 63 return ACPI_INTERRUPT_HANDLED; 64 } 65 66 static void acpi_gpe_irq_cleanup(struct si_sm_io *io) 67 { 68 if (!io->irq) 69 return; 70 71 ipmi_irq_start_cleanup(io); 72 acpi_remove_gpe_handler(NULL, io->irq, &ipmi_acpi_gpe); 73 } 74 75 static int acpi_gpe_irq_setup(struct si_sm_io *io) 76 { 77 acpi_status status; 78 79 if (!io->irq) 80 return 0; 81 82 status = acpi_install_gpe_handler(NULL, 83 io->irq, 84 ACPI_GPE_LEVEL_TRIGGERED, 85 &ipmi_acpi_gpe, 86 io); 87 if (status != AE_OK) { 88 dev_warn(io->dev, 89 "Unable to claim ACPI GPE %d, running polled\n", 90 io->irq); 91 io->irq = 0; 92 return -EINVAL; 93 } else { 94 io->irq_cleanup = acpi_gpe_irq_cleanup; 95 ipmi_irq_finish_setup(io); 96 dev_info(io->dev, "Using ACPI GPE %d\n", io->irq); 97 return 0; 98 } 99 } 100 #endif 101 102 static struct resource * 103 ipmi_get_info_from_resources(struct platform_device *pdev, 104 struct si_sm_io *io) 105 { 106 struct resource *res, *res_second; 107 108 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 109 if (res) { 110 io->addr_type = IPMI_IO_ADDR_SPACE; 111 } else { 112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 113 if (res) 114 io->addr_type = IPMI_MEM_ADDR_SPACE; 115 } 116 if (!res) { 117 dev_err(&pdev->dev, "no I/O or memory address\n"); 118 return NULL; 119 } 120 io->addr_data = res->start; 121 122 io->regspacing = DEFAULT_REGSPACING; 123 res_second = platform_get_resource(pdev, 124 (io->addr_type == IPMI_IO_ADDR_SPACE) ? 125 IORESOURCE_IO : IORESOURCE_MEM, 126 1); 127 if (res_second) { 128 if (res_second->start > io->addr_data) 129 io->regspacing = res_second->start - io->addr_data; 130 } 131 io->regsize = DEFAULT_REGSIZE; 132 io->regshift = 0; 133 134 return res; 135 } 136 137 static int platform_ipmi_probe(struct platform_device *pdev) 138 { 139 struct si_sm_io io; 140 u8 type, slave_addr, addr_source; 141 int rv; 142 143 rv = device_property_read_u8(&pdev->dev, "addr-source", &addr_source); 144 if (rv) 145 addr_source = SI_PLATFORM; 146 if (addr_source >= SI_LAST) 147 return -EINVAL; 148 149 if (addr_source == SI_SMBIOS) { 150 if (!si_trydmi) 151 return -ENODEV; 152 } else { 153 if (!si_tryplatform) 154 return -ENODEV; 155 } 156 157 rv = device_property_read_u8(&pdev->dev, "ipmi-type", &type); 158 if (rv) 159 return -ENODEV; 160 161 memset(&io, 0, sizeof(io)); 162 io.addr_source = addr_source; 163 dev_info(&pdev->dev, "probing via %s\n", 164 ipmi_addr_src_to_str(addr_source)); 165 166 switch (type) { 167 case SI_KCS: 168 case SI_SMIC: 169 case SI_BT: 170 io.si_type = type; 171 break; 172 default: 173 dev_err(&pdev->dev, "ipmi-type property is invalid\n"); 174 return -EINVAL; 175 } 176 177 if (!ipmi_get_info_from_resources(pdev, &io)) 178 return -EINVAL; 179 180 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr); 181 if (rv) { 182 dev_warn(&pdev->dev, "device has no slave-addr property\n"); 183 io.slave_addr = 0x20; 184 } else { 185 io.slave_addr = slave_addr; 186 } 187 188 io.irq = platform_get_irq(pdev, 0); 189 if (io.irq > 0) 190 io.irq_setup = ipmi_std_irq_setup; 191 else 192 io.irq = 0; 193 194 io.dev = &pdev->dev; 195 196 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", 197 (io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", 198 io.addr_data, io.regsize, io.regspacing, io.irq); 199 200 ipmi_si_add_smi(&io); 201 202 return 0; 203 } 204 205 #ifdef CONFIG_OF 206 static const struct of_device_id of_ipmi_match[] = { 207 { .type = "ipmi", .compatible = "ipmi-kcs", 208 .data = (void *)(unsigned long) SI_KCS }, 209 { .type = "ipmi", .compatible = "ipmi-smic", 210 .data = (void *)(unsigned long) SI_SMIC }, 211 { .type = "ipmi", .compatible = "ipmi-bt", 212 .data = (void *)(unsigned long) SI_BT }, 213 {}, 214 }; 215 MODULE_DEVICE_TABLE(of, of_ipmi_match); 216 217 static int of_ipmi_probe(struct platform_device *pdev) 218 { 219 const struct of_device_id *match; 220 struct si_sm_io io; 221 struct resource resource; 222 const __be32 *regsize, *regspacing, *regshift; 223 struct device_node *np = pdev->dev.of_node; 224 int ret; 225 int proplen; 226 227 if (!si_tryopenfirmware) 228 return -ENODEV; 229 230 dev_info(&pdev->dev, "probing via device tree\n"); 231 232 match = of_match_device(of_ipmi_match, &pdev->dev); 233 if (!match) 234 return -ENODEV; 235 236 if (!of_device_is_available(np)) 237 return -EINVAL; 238 239 ret = of_address_to_resource(np, 0, &resource); 240 if (ret) { 241 dev_warn(&pdev->dev, "invalid address from OF\n"); 242 return ret; 243 } 244 245 regsize = of_get_property(np, "reg-size", &proplen); 246 if (regsize && proplen != 4) { 247 dev_warn(&pdev->dev, "invalid regsize from OF\n"); 248 return -EINVAL; 249 } 250 251 regspacing = of_get_property(np, "reg-spacing", &proplen); 252 if (regspacing && proplen != 4) { 253 dev_warn(&pdev->dev, "invalid regspacing from OF\n"); 254 return -EINVAL; 255 } 256 257 regshift = of_get_property(np, "reg-shift", &proplen); 258 if (regshift && proplen != 4) { 259 dev_warn(&pdev->dev, "invalid regshift from OF\n"); 260 return -EINVAL; 261 } 262 263 memset(&io, 0, sizeof(io)); 264 io.si_type = (enum si_type) match->data; 265 io.addr_source = SI_DEVICETREE; 266 io.irq_setup = ipmi_std_irq_setup; 267 268 if (resource.flags & IORESOURCE_IO) 269 io.addr_type = IPMI_IO_ADDR_SPACE; 270 else 271 io.addr_type = IPMI_MEM_ADDR_SPACE; 272 273 io.addr_data = resource.start; 274 275 io.regsize = regsize ? be32_to_cpup(regsize) : DEFAULT_REGSIZE; 276 io.regspacing = regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING; 277 io.regshift = regshift ? be32_to_cpup(regshift) : 0; 278 279 io.irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 280 io.dev = &pdev->dev; 281 282 dev_dbg(&pdev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n", 283 io.addr_data, io.regsize, io.regspacing, io.irq); 284 285 return ipmi_si_add_smi(&io); 286 } 287 #else 288 #define of_ipmi_match NULL 289 static int of_ipmi_probe(struct platform_device *dev) 290 { 291 return -ENODEV; 292 } 293 #endif 294 295 #ifdef CONFIG_ACPI 296 static int find_slave_address(struct si_sm_io *io, int slave_addr) 297 { 298 #ifdef CONFIG_IPMI_DMI_DECODE 299 if (!slave_addr) { 300 u32 flags = IORESOURCE_IO; 301 302 if (io->addr_type == IPMI_MEM_ADDR_SPACE) 303 flags = IORESOURCE_MEM; 304 305 slave_addr = ipmi_dmi_get_slave_addr(io->si_type, flags, 306 io->addr_data); 307 } 308 #endif 309 310 return slave_addr; 311 } 312 313 static int acpi_ipmi_probe(struct platform_device *pdev) 314 { 315 struct si_sm_io io; 316 acpi_handle handle; 317 acpi_status status; 318 unsigned long long tmp; 319 struct resource *res; 320 int rv = -EINVAL; 321 322 if (!si_tryacpi) 323 return -ENODEV; 324 325 handle = ACPI_HANDLE(&pdev->dev); 326 if (!handle) 327 return -ENODEV; 328 329 memset(&io, 0, sizeof(io)); 330 io.addr_source = SI_ACPI; 331 dev_info(&pdev->dev, "probing via ACPI\n"); 332 333 io.addr_info.acpi_info.acpi_handle = handle; 334 335 /* _IFT tells us the interface type: KCS, BT, etc */ 336 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); 337 if (ACPI_FAILURE(status)) { 338 dev_err(&pdev->dev, 339 "Could not find ACPI IPMI interface type\n"); 340 goto err_free; 341 } 342 343 switch (tmp) { 344 case 1: 345 io.si_type = SI_KCS; 346 break; 347 case 2: 348 io.si_type = SI_SMIC; 349 break; 350 case 3: 351 io.si_type = SI_BT; 352 break; 353 case 4: /* SSIF, just ignore */ 354 rv = -ENODEV; 355 goto err_free; 356 default: 357 dev_info(&pdev->dev, "unknown IPMI type %lld\n", tmp); 358 goto err_free; 359 } 360 361 res = ipmi_get_info_from_resources(pdev, &io); 362 if (!res) { 363 rv = -EINVAL; 364 goto err_free; 365 } 366 367 /* If _GPE exists, use it; otherwise use standard interrupts */ 368 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); 369 if (ACPI_SUCCESS(status)) { 370 io.irq = tmp; 371 io.irq_setup = acpi_gpe_irq_setup; 372 } else { 373 int irq = platform_get_irq(pdev, 0); 374 375 if (irq > 0) { 376 io.irq = irq; 377 io.irq_setup = ipmi_std_irq_setup; 378 } 379 } 380 381 io.slave_addr = find_slave_address(&io, io.slave_addr); 382 383 io.dev = &pdev->dev; 384 385 dev_info(io.dev, "%pR regsize %d spacing %d irq %d\n", 386 res, io.regsize, io.regspacing, io.irq); 387 388 return ipmi_si_add_smi(&io); 389 390 err_free: 391 return rv; 392 } 393 394 static const struct acpi_device_id acpi_ipmi_match[] = { 395 { "IPI0001", 0 }, 396 { }, 397 }; 398 MODULE_DEVICE_TABLE(acpi, acpi_ipmi_match); 399 #else 400 static int acpi_ipmi_probe(struct platform_device *dev) 401 { 402 return -ENODEV; 403 } 404 #endif 405 406 static int ipmi_probe(struct platform_device *pdev) 407 { 408 if (pdev->dev.of_node && of_ipmi_probe(pdev) == 0) 409 return 0; 410 411 if (acpi_ipmi_probe(pdev) == 0) 412 return 0; 413 414 return platform_ipmi_probe(pdev); 415 } 416 417 static int ipmi_remove(struct platform_device *pdev) 418 { 419 return ipmi_si_remove_by_dev(&pdev->dev); 420 } 421 422 static const struct platform_device_id si_plat_ids[] = { 423 { "dmi-ipmi-si", 0 }, 424 { } 425 }; 426 427 struct platform_driver ipmi_platform_driver = { 428 .driver = { 429 .name = DEVICE_NAME, 430 .of_match_table = of_ipmi_match, 431 .acpi_match_table = ACPI_PTR(acpi_ipmi_match), 432 }, 433 .probe = ipmi_probe, 434 .remove = ipmi_remove, 435 .id_table = si_plat_ids 436 }; 437 438 void ipmi_si_platform_init(void) 439 { 440 int rv = platform_driver_register(&ipmi_platform_driver); 441 if (rv) 442 pr_err("Unable to register driver: %d\n", rv); 443 } 444 445 void ipmi_si_platform_shutdown(void) 446 { 447 platform_driver_unregister(&ipmi_platform_driver); 448 } 449