2 * IOAPIC/IOxAPIC/IOSAPIC driver
4 * Copyright (C) 2009 Fujitsu Limited.
5 * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
13 * This driver manages PCI I/O APICs added by hotplug after boot. We try to
14 * claim all I/O APIC PCI devices, but those present at boot were registered
15 * when we parsed the ACPI MADT, so we'll fail when we try to re-register
19 #include <linux/pci.h>
20 #include <linux/acpi.h>
21 #include <acpi/acpi_bus.h>
28 static int ioapic_probe(struct pci_dev
*dev
, const struct pci_device_id
*ent
)
32 unsigned long long gsb
;
33 struct ioapic
*ioapic
;
38 handle
= DEVICE_ACPI_HANDLE(&dev
->dev
);
42 status
= acpi_evaluate_integer(handle
, "_GSB", NULL
, &gsb
);
43 if (ACPI_FAILURE(status
))
47 * The previous code in acpiphp evaluated _MAT if _GSB failed, but
48 * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs.
51 ioapic
= kzalloc(sizeof(*ioapic
), GFP_KERNEL
);
55 ioapic
->handle
= handle
;
56 ioapic
->gsi_base
= (u32
) gsb
;
58 if (dev
->class == PCI_CLASS_SYSTEM_PIC_IOAPIC
)
63 ret
= pci_enable_device(dev
);
69 if (pci_request_region(dev
, 0, type
))
72 res
= &dev
->resource
[0];
73 if (acpi_register_ioapic(ioapic
->handle
, res
->start
, ioapic
->gsi_base
))
76 pci_set_drvdata(dev
, ioapic
);
77 dev_info(&dev
->dev
, "%s at %pR, GSI %u\n", type
, res
, ioapic
->gsi_base
);
81 pci_release_region(dev
, 0);
83 pci_disable_device(dev
);
89 static void ioapic_remove(struct pci_dev
*dev
)
91 struct ioapic
*ioapic
= pci_get_drvdata(dev
);
93 acpi_unregister_ioapic(ioapic
->handle
, ioapic
->gsi_base
);
94 pci_release_region(dev
, 0);
95 pci_disable_device(dev
);
100 static struct pci_device_id ioapic_devices
[] = {
101 { PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
102 PCI_CLASS_SYSTEM_PIC_IOAPIC
<< 8, 0xffff00, },
103 { PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
104 PCI_CLASS_SYSTEM_PIC_IOXAPIC
<< 8, 0xffff00, },
108 static struct pci_driver ioapic_driver
= {
110 .id_table
= ioapic_devices
,
111 .probe
= ioapic_probe
,
112 .remove
= __devexit_p(ioapic_remove
),
115 static int __init
ioapic_init(void)
117 return pci_register_driver(&ioapic_driver
);
120 static void __exit
ioapic_exit(void)
122 pci_unregister_driver(&ioapic_driver
);
125 module_init(ioapic_init
);
126 module_exit(ioapic_exit
);