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