Linux Audio

Check our new training course

Loading...
v3.5.6
  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
 25struct ioapic {
 26	acpi_handle	handle;
 27	u32		gsi_base;
 28};
 29
 30static int __devinit ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 31{
 32	acpi_handle handle;
 33	acpi_status status;
 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
 60	if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC)
 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
 82exit_release:
 83	pci_release_region(dev, 0);
 84exit_disable:
 85	pci_disable_device(dev);
 86exit_free:
 87	kfree(ioapic);
 88	return -ENODEV;
 89}
 90
 91static 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
102static DEFINE_PCI_DEVICE_TABLE(ioapic_devices) = {
103	{ PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOAPIC, ~0) },
104	{ PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOXAPIC, ~0) },
 
 
105	{ }
106};
107MODULE_DEVICE_TABLE(pci, ioapic_devices);
108
109static 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
116static int __init ioapic_init(void)
117{
118	return pci_register_driver(&ioapic_driver);
119}
120
121static void __exit ioapic_exit(void)
122{
123	pci_unregister_driver(&ioapic_driver);
124}
125
126module_init(ioapic_init);
127module_exit(ioapic_exit);
v3.1
  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/acpi.h>
 21#include <linux/slab.h>
 22#include <acpi/acpi_bus.h>
 23
 24struct ioapic {
 25	acpi_handle	handle;
 26	u32		gsi_base;
 27};
 28
 29static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 30{
 31	acpi_handle handle;
 32	acpi_status status;
 33	unsigned long long gsb;
 34	struct ioapic *ioapic;
 35	int ret;
 36	char *type;
 37	struct resource *res;
 38
 39	handle = DEVICE_ACPI_HANDLE(&dev->dev);
 40	if (!handle)
 41		return -EINVAL;
 42
 43	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
 44	if (ACPI_FAILURE(status))
 45		return -EINVAL;
 46
 47	/*
 48	 * The previous code in acpiphp evaluated _MAT if _GSB failed, but
 49	 * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs.
 50	 */
 51
 52	ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL);
 53	if (!ioapic)
 54		return -ENOMEM;
 55
 56	ioapic->handle = handle;
 57	ioapic->gsi_base = (u32) gsb;
 58
 59	if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC)
 60		type = "IOAPIC";
 61	else
 62		type = "IOxAPIC";
 63
 64	ret = pci_enable_device(dev);
 65	if (ret < 0)
 66		goto exit_free;
 67
 68	pci_set_master(dev);
 69
 70	if (pci_request_region(dev, 0, type))
 71		goto exit_disable;
 72
 73	res = &dev->resource[0];
 74	if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base))
 75		goto exit_release;
 76
 77	pci_set_drvdata(dev, ioapic);
 78	dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base);
 79	return 0;
 80
 81exit_release:
 82	pci_release_region(dev, 0);
 83exit_disable:
 84	pci_disable_device(dev);
 85exit_free:
 86	kfree(ioapic);
 87	return -ENODEV;
 88}
 89
 90static void ioapic_remove(struct pci_dev *dev)
 91{
 92	struct ioapic *ioapic = pci_get_drvdata(dev);
 93
 94	acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base);
 95	pci_release_region(dev, 0);
 96	pci_disable_device(dev);
 97	kfree(ioapic);
 98}
 99
100
101static struct pci_device_id ioapic_devices[] = {
102	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
103	  PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, },
104	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
105	  PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, },
106	{ }
107};
 
108
109static 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
116static int __init ioapic_init(void)
117{
118	return pci_register_driver(&ioapic_driver);
119}
120
121static void __exit ioapic_exit(void)
122{
123	pci_unregister_driver(&ioapic_driver);
124}
125
126module_init(ioapic_init);
127module_exit(ioapic_exit);