Skip to content

Commit 0fbcf4a

Browse files
committed
ipmi: Convert the IPMI SI ACPI handling to a platform device
The IPMI SI driver was using direct PNP, but that was not really ideal because the IPMI device is a platform device. There was some special handling in the acpi_pnp.c code for making this work, but that was breaking ACPI handling for the IPMI SSIF driver. So without this patch there were significant issues getting the SSIF driver to work with ACPI. So use a platform device for ACPI detection and remove the entry from acpi_pnp.c. Signed-off-by: Corey Minyard <[email protected]>
1 parent 92e8472 commit 0fbcf4a

File tree

2 files changed

+157
-165
lines changed

2 files changed

+157
-165
lines changed

drivers/acpi/acpi_pnp.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
1919
{"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */
2020
/* floppy */
2121
{"PNP0700"},
22-
/* ipmi_si */
23-
{"IPI0001"},
2422
/* tpm_inf_pnp */
2523
{"IFX0101"}, /* Infineon TPMs */
2624
{"IFX0102"}, /* Infineon TPMs */

drivers/char/ipmi/ipmi_si_intf.c

Lines changed: 157 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
#include <linux/dmi.h>
6565
#include <linux/string.h>
6666
#include <linux/ctype.h>
67-
#include <linux/pnp.h>
6867
#include <linux/of_device.h>
6968
#include <linux/of_platform.h>
7069
#include <linux/of_address.h>
@@ -309,9 +308,6 @@ static int num_force_kipmid;
309308
#ifdef CONFIG_PCI
310309
static bool pci_registered;
311310
#endif
312-
#ifdef CONFIG_ACPI
313-
static bool pnp_registered;
314-
#endif
315311
#ifdef CONFIG_PARISC
316312
static bool parisc_registered;
317313
#endif
@@ -2233,134 +2229,6 @@ static void spmi_find_bmc(void)
22332229
try_init_spmi(spmi);
22342230
}
22352231
}
2236-
2237-
static int ipmi_pnp_probe(struct pnp_dev *dev,
2238-
const struct pnp_device_id *dev_id)
2239-
{
2240-
struct acpi_device *acpi_dev;
2241-
struct smi_info *info;
2242-
struct resource *res, *res_second;
2243-
acpi_handle handle;
2244-
acpi_status status;
2245-
unsigned long long tmp;
2246-
int rv = -EINVAL;
2247-
2248-
acpi_dev = pnp_acpi_device(dev);
2249-
if (!acpi_dev)
2250-
return -ENODEV;
2251-
2252-
info = smi_info_alloc();
2253-
if (!info)
2254-
return -ENOMEM;
2255-
2256-
info->addr_source = SI_ACPI;
2257-
printk(KERN_INFO PFX "probing via ACPI\n");
2258-
2259-
handle = acpi_dev->handle;
2260-
info->addr_info.acpi_info.acpi_handle = handle;
2261-
2262-
/* _IFT tells us the interface type: KCS, BT, etc */
2263-
status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
2264-
if (ACPI_FAILURE(status)) {
2265-
dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n");
2266-
goto err_free;
2267-
}
2268-
2269-
switch (tmp) {
2270-
case 1:
2271-
info->si_type = SI_KCS;
2272-
break;
2273-
case 2:
2274-
info->si_type = SI_SMIC;
2275-
break;
2276-
case 3:
2277-
info->si_type = SI_BT;
2278-
break;
2279-
case 4: /* SSIF, just ignore */
2280-
rv = -ENODEV;
2281-
goto err_free;
2282-
default:
2283-
dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp);
2284-
goto err_free;
2285-
}
2286-
2287-
res = pnp_get_resource(dev, IORESOURCE_IO, 0);
2288-
if (res) {
2289-
info->io_setup = port_setup;
2290-
info->io.addr_type = IPMI_IO_ADDR_SPACE;
2291-
} else {
2292-
res = pnp_get_resource(dev, IORESOURCE_MEM, 0);
2293-
if (res) {
2294-
info->io_setup = mem_setup;
2295-
info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2296-
}
2297-
}
2298-
if (!res) {
2299-
dev_err(&dev->dev, "no I/O or memory address\n");
2300-
goto err_free;
2301-
}
2302-
info->io.addr_data = res->start;
2303-
2304-
info->io.regspacing = DEFAULT_REGSPACING;
2305-
res_second = pnp_get_resource(dev,
2306-
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
2307-
IORESOURCE_IO : IORESOURCE_MEM,
2308-
1);
2309-
if (res_second) {
2310-
if (res_second->start > info->io.addr_data)
2311-
info->io.regspacing = res_second->start - info->io.addr_data;
2312-
}
2313-
info->io.regsize = DEFAULT_REGSPACING;
2314-
info->io.regshift = 0;
2315-
2316-
/* If _GPE exists, use it; otherwise use standard interrupts */
2317-
status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
2318-
if (ACPI_SUCCESS(status)) {
2319-
info->irq = tmp;
2320-
info->irq_setup = acpi_gpe_irq_setup;
2321-
} else if (pnp_irq_valid(dev, 0)) {
2322-
info->irq = pnp_irq(dev, 0);
2323-
info->irq_setup = std_irq_setup;
2324-
}
2325-
2326-
info->dev = &dev->dev;
2327-
pnp_set_drvdata(dev, info);
2328-
2329-
dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n",
2330-
res, info->io.regsize, info->io.regspacing,
2331-
info->irq);
2332-
2333-
rv = add_smi(info);
2334-
if (rv)
2335-
kfree(info);
2336-
2337-
return rv;
2338-
2339-
err_free:
2340-
kfree(info);
2341-
return rv;
2342-
}
2343-
2344-
static void ipmi_pnp_remove(struct pnp_dev *dev)
2345-
{
2346-
struct smi_info *info = pnp_get_drvdata(dev);
2347-
2348-
cleanup_one_si(info);
2349-
}
2350-
2351-
static const struct pnp_device_id pnp_dev_table[] = {
2352-
{"IPI0001", 0},
2353-
{"", 0},
2354-
};
2355-
2356-
static struct pnp_driver ipmi_pnp_driver = {
2357-
.name = DEVICE_NAME,
2358-
.probe = ipmi_pnp_probe,
2359-
.remove = ipmi_pnp_remove,
2360-
.id_table = pnp_dev_table,
2361-
};
2362-
2363-
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
23642232
#endif
23652233

23662234
#ifdef CONFIG_DMI
@@ -2669,10 +2537,19 @@ static struct pci_driver ipmi_pci_driver = {
26692537
};
26702538
#endif /* CONFIG_PCI */
26712539

2672-
static const struct of_device_id ipmi_match[];
2673-
static int ipmi_probe(struct platform_device *dev)
2674-
{
26752540
#ifdef CONFIG_OF
2541+
static const struct of_device_id of_ipmi_match[] = {
2542+
{ .type = "ipmi", .compatible = "ipmi-kcs",
2543+
.data = (void *)(unsigned long) SI_KCS },
2544+
{ .type = "ipmi", .compatible = "ipmi-smic",
2545+
.data = (void *)(unsigned long) SI_SMIC },
2546+
{ .type = "ipmi", .compatible = "ipmi-bt",
2547+
.data = (void *)(unsigned long) SI_BT },
2548+
{},
2549+
};
2550+
2551+
static int of_ipmi_probe(struct platform_device *dev)
2552+
{
26762553
const struct of_device_id *match;
26772554
struct smi_info *info;
26782555
struct resource resource;
@@ -2683,9 +2560,9 @@ static int ipmi_probe(struct platform_device *dev)
26832560

26842561
dev_info(&dev->dev, "probing via device tree\n");
26852562

2686-
match = of_match_device(ipmi_match, &dev->dev);
2563+
match = of_match_device(of_ipmi_match, &dev->dev);
26872564
if (!match)
2688-
return -EINVAL;
2565+
return -ENODEV;
26892566

26902567
if (!of_device_is_available(np))
26912568
return -EINVAL;
@@ -2754,33 +2631,161 @@ static int ipmi_probe(struct platform_device *dev)
27542631
kfree(info);
27552632
return ret;
27562633
}
2757-
#endif
27582634
return 0;
27592635
}
2636+
#else
2637+
#define of_ipmi_match NULL
2638+
static int of_ipmi_probe(struct platform_device *dev)
2639+
{
2640+
return -ENODEV;
2641+
}
2642+
#endif
27602643

2761-
static int ipmi_remove(struct platform_device *dev)
2644+
#ifdef CONFIG_ACPI
2645+
static int acpi_ipmi_probe(struct platform_device *dev)
27622646
{
2763-
#ifdef CONFIG_OF
2764-
cleanup_one_si(dev_get_drvdata(&dev->dev));
2647+
struct smi_info *info;
2648+
struct resource *res, *res_second;
2649+
acpi_handle handle;
2650+
acpi_status status;
2651+
unsigned long long tmp;
2652+
int rv = -EINVAL;
2653+
2654+
handle = ACPI_HANDLE(&dev->dev);
2655+
if (!handle)
2656+
return -ENODEV;
2657+
2658+
info = smi_info_alloc();
2659+
if (!info)
2660+
return -ENOMEM;
2661+
2662+
info->addr_source = SI_ACPI;
2663+
dev_info(&dev->dev, PFX "probing via ACPI\n");
2664+
2665+
info->addr_info.acpi_info.acpi_handle = handle;
2666+
2667+
/* _IFT tells us the interface type: KCS, BT, etc */
2668+
status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
2669+
if (ACPI_FAILURE(status)) {
2670+
dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n");
2671+
goto err_free;
2672+
}
2673+
2674+
switch (tmp) {
2675+
case 1:
2676+
info->si_type = SI_KCS;
2677+
break;
2678+
case 2:
2679+
info->si_type = SI_SMIC;
2680+
break;
2681+
case 3:
2682+
info->si_type = SI_BT;
2683+
break;
2684+
case 4: /* SSIF, just ignore */
2685+
rv = -ENODEV;
2686+
goto err_free;
2687+
default:
2688+
dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp);
2689+
goto err_free;
2690+
}
2691+
2692+
res = platform_get_resource(dev, IORESOURCE_IO, 0);
2693+
if (res) {
2694+
info->io_setup = port_setup;
2695+
info->io.addr_type = IPMI_IO_ADDR_SPACE;
2696+
} else {
2697+
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
2698+
if (res) {
2699+
info->io_setup = mem_setup;
2700+
info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2701+
}
2702+
}
2703+
if (!res) {
2704+
dev_err(&dev->dev, "no I/O or memory address\n");
2705+
goto err_free;
2706+
}
2707+
info->io.addr_data = res->start;
2708+
2709+
info->io.regspacing = DEFAULT_REGSPACING;
2710+
res_second = platform_get_resource(dev,
2711+
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
2712+
IORESOURCE_IO : IORESOURCE_MEM,
2713+
1);
2714+
if (res_second) {
2715+
if (res_second->start > info->io.addr_data)
2716+
info->io.regspacing =
2717+
res_second->start - info->io.addr_data;
2718+
}
2719+
info->io.regsize = DEFAULT_REGSPACING;
2720+
info->io.regshift = 0;
2721+
2722+
/* If _GPE exists, use it; otherwise use standard interrupts */
2723+
status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
2724+
if (ACPI_SUCCESS(status)) {
2725+
info->irq = tmp;
2726+
info->irq_setup = acpi_gpe_irq_setup;
2727+
} else {
2728+
int irq = platform_get_irq(dev, 0);
2729+
2730+
if (irq > 0) {
2731+
info->irq = irq;
2732+
info->irq_setup = std_irq_setup;
2733+
}
2734+
}
2735+
2736+
info->dev = &dev->dev;
2737+
platform_set_drvdata(dev, info);
2738+
2739+
dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n",
2740+
res, info->io.regsize, info->io.regspacing,
2741+
info->irq);
2742+
2743+
rv = add_smi(info);
2744+
if (rv)
2745+
kfree(info);
2746+
2747+
return rv;
2748+
2749+
err_free:
2750+
kfree(info);
2751+
return rv;
2752+
}
2753+
2754+
static struct acpi_device_id acpi_ipmi_match[] = {
2755+
{ "IPI0001", 0 },
2756+
{ },
2757+
};
2758+
MODULE_DEVICE_TABLE(acpi, acpi_ipmi_match);
2759+
#else
2760+
static int acpi_ipmi_probe(struct platform_device *dev)
2761+
{
2762+
return -ENODEV;
2763+
}
27652764
#endif
2766-
return 0;
2765+
2766+
static int ipmi_probe(struct platform_device *dev)
2767+
{
2768+
if (of_ipmi_probe(dev) == 0)
2769+
return 0;
2770+
2771+
return acpi_ipmi_probe(dev);
27672772
}
27682773

2769-
static const struct of_device_id ipmi_match[] =
2774+
static int ipmi_remove(struct platform_device *dev)
27702775
{
2771-
{ .type = "ipmi", .compatible = "ipmi-kcs",
2772-
.data = (void *)(unsigned long) SI_KCS },
2773-
{ .type = "ipmi", .compatible = "ipmi-smic",
2774-
.data = (void *)(unsigned long) SI_SMIC },
2775-
{ .type = "ipmi", .compatible = "ipmi-bt",
2776-
.data = (void *)(unsigned long) SI_BT },
2777-
{},
2778-
};
2776+
struct smi_info *info = dev_get_drvdata(&dev->dev);
2777+
2778+
if (info)
2779+
cleanup_one_si(info);
2780+
2781+
return 0;
2782+
}
27792783

27802784
static struct platform_driver ipmi_driver = {
27812785
.driver = {
27822786
.name = DEVICE_NAME,
2783-
.of_match_table = ipmi_match,
2787+
.of_match_table = of_ipmi_match,
2788+
.acpi_match_table = ACPI_PTR(acpi_ipmi_match),
27842789
},
27852790
.probe = ipmi_probe,
27862791
.remove = ipmi_remove,
@@ -3692,13 +3697,6 @@ static int init_ipmi_si(void)
36923697
}
36933698
#endif
36943699

3695-
#ifdef CONFIG_ACPI
3696-
if (si_tryacpi) {
3697-
pnp_register_driver(&ipmi_pnp_driver);
3698-
pnp_registered = true;
3699-
}
3700-
#endif
3701-
37023700
#ifdef CONFIG_DMI
37033701
if (si_trydmi)
37043702
dmi_find_bmc();
@@ -3850,10 +3848,6 @@ static void cleanup_ipmi_si(void)
38503848
if (pci_registered)
38513849
pci_unregister_driver(&ipmi_pci_driver);
38523850
#endif
3853-
#ifdef CONFIG_ACPI
3854-
if (pnp_registered)
3855-
pnp_unregister_driver(&ipmi_pnp_driver);
3856-
#endif
38573851
#ifdef CONFIG_PARISC
38583852
if (parisc_registered)
38593853
unregister_parisc_driver(&ipmi_parisc_driver);

0 commit comments

Comments
 (0)