Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ioapic.c
Go to the documentation of this file.
1 /*
2  * IOAPIC/IOxAPIC/IOSAPIC driver
3  *
4  * Copyright (C) 2009 Fujitsu Limited.
5  * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
6  *
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.
10  */
11 
12 /*
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
16  * them.
17  */
18 
19 #include <linux/pci.h>
20 #include <linux/module.h>
21 #include <linux/acpi.h>
22 #include <linux/slab.h>
23 #include <acpi/acpi_bus.h>
24 
25 struct ioapic {
27  u32 gsi_base;
28 };
29 
30 static int __devinit ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
31 {
34  unsigned long long gsb;
35  struct ioapic *ioapic;
36  int ret;
37  char *type;
38  struct resource *res;
39 
40  handle = DEVICE_ACPI_HANDLE(&dev->dev);
41  if (!handle)
42  return -EINVAL;
43 
44  status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
45  if (ACPI_FAILURE(status))
46  return -EINVAL;
47 
48  /*
49  * The previous code in acpiphp evaluated _MAT if _GSB failed, but
50  * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs.
51  */
52 
53  ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL);
54  if (!ioapic)
55  return -ENOMEM;
56 
57  ioapic->handle = handle;
58  ioapic->gsi_base = (u32) gsb;
59 
61  type = "IOAPIC";
62  else
63  type = "IOxAPIC";
64 
65  ret = pci_enable_device(dev);
66  if (ret < 0)
67  goto exit_free;
68 
69  pci_set_master(dev);
70 
71  if (pci_request_region(dev, 0, type))
72  goto exit_disable;
73 
74  res = &dev->resource[0];
75  if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base))
76  goto exit_release;
77 
78  pci_set_drvdata(dev, ioapic);
79  dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base);
80  return 0;
81 
82 exit_release:
83  pci_release_region(dev, 0);
84 exit_disable:
85  pci_disable_device(dev);
86 exit_free:
87  kfree(ioapic);
88  return -ENODEV;
89 }
90 
91 static void __devexit ioapic_remove(struct pci_dev *dev)
92 {
93  struct ioapic *ioapic = pci_get_drvdata(dev);
94 
95  acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base);
96  pci_release_region(dev, 0);
97  pci_disable_device(dev);
98  kfree(ioapic);
99 }
100 
101 
102 static DEFINE_PCI_DEVICE_TABLE(ioapic_devices) = {
105  { }
106 };
107 MODULE_DEVICE_TABLE(pci, ioapic_devices);
108 
109 static struct pci_driver ioapic_driver = {
110  .name = "ioapic",
111  .id_table = ioapic_devices,
112  .probe = ioapic_probe,
113  .remove = __devexit_p(ioapic_remove),
114 };
115 
116 static int __init ioapic_init(void)
117 {
118  return pci_register_driver(&ioapic_driver);
119 }
120 
121 static void __exit ioapic_exit(void)
122 {
123  pci_unregister_driver(&ioapic_driver);
124 }
125 
126 module_init(ioapic_init);
127 module_exit(ioapic_exit);