mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-04-01 11:54:10 +00:00
Merge branch 'pci/yinghai-root-bus-hotplug' into next
* pci/yinghai-root-bus-hotplug: PCI: Put pci_dev in device tree as early as possible PCI: Skip attaching driver in device_add() PCI: acpiphp: Keep driver loaded even if no slots found PCI/ACPI: Print info if host bridge notify handler installation fails PCI: acpiphp: Move host bridge hotplug to pci_root.c PCI/ACPI: acpiphp: Rename alloc_acpiphp_hp_work() to alloc_acpi_hp_work() PCI: Make device create/destroy logic symmetric PCI: Fix reference count leak in pci_dev_present() PCI: Set pci_dev dev_node early so IOAPIC irq_descs are allocated locally PCI: Add root bus children dev's res to fail list PCI: acpiphp: Add is_hotplug_bridge detection Conflicts: drivers/pci/pci.h
This commit is contained in:
commit
939de1d69c
18 changed files with 274 additions and 219 deletions
|
@ -68,6 +68,7 @@ struct acpi_ec {
|
||||||
extern struct acpi_ec *first_ec;
|
extern struct acpi_ec *first_ec;
|
||||||
|
|
||||||
int acpi_pci_root_init(void);
|
int acpi_pci_root_init(void);
|
||||||
|
void acpi_pci_root_hp_init(void);
|
||||||
int acpi_ec_init(void);
|
int acpi_ec_init(void);
|
||||||
int acpi_ec_ecdt_probe(void);
|
int acpi_ec_ecdt_probe(void);
|
||||||
int acpi_boot_ec_enable(void);
|
int acpi_boot_ec_enable(void);
|
||||||
|
|
|
@ -84,8 +84,7 @@ static acpi_osd_handler acpi_irq_handler;
|
||||||
static void *acpi_irq_context;
|
static void *acpi_irq_context;
|
||||||
static struct workqueue_struct *kacpid_wq;
|
static struct workqueue_struct *kacpid_wq;
|
||||||
static struct workqueue_struct *kacpi_notify_wq;
|
static struct workqueue_struct *kacpi_notify_wq;
|
||||||
struct workqueue_struct *kacpi_hotplug_wq;
|
static struct workqueue_struct *kacpi_hotplug_wq;
|
||||||
EXPORT_SYMBOL(kacpi_hotplug_wq);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This list of permanent mappings is for memory that may be accessed from
|
* This list of permanent mappings is for memory that may be accessed from
|
||||||
|
@ -1778,3 +1777,24 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
|
||||||
{
|
{
|
||||||
__acpi_os_prepare_sleep = func;
|
__acpi_os_prepare_sleep = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
|
||||||
|
void (*func)(struct work_struct *work))
|
||||||
|
{
|
||||||
|
struct acpi_hp_work *hp_work;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
|
||||||
|
if (!hp_work)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hp_work->handle = handle;
|
||||||
|
hp_work->type = type;
|
||||||
|
hp_work->context = context;
|
||||||
|
|
||||||
|
INIT_WORK(&hp_work->work, func);
|
||||||
|
ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
|
||||||
|
if (!ret)
|
||||||
|
kfree(hp_work);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(alloc_acpi_hp_work);
|
||||||
|
|
|
@ -655,3 +655,133 @@ int __init acpi_pci_root_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* Support root bridge hotplug */
|
||||||
|
|
||||||
|
static void handle_root_bridge_insertion(acpi_handle handle)
|
||||||
|
{
|
||||||
|
struct acpi_device *device;
|
||||||
|
|
||||||
|
if (!acpi_bus_get_device(handle, &device)) {
|
||||||
|
printk(KERN_DEBUG "acpi device exists...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acpi_bus_scan(handle))
|
||||||
|
printk(KERN_ERR "cannot add bridge to acpi list\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_root_bridge_removal(struct acpi_device *device)
|
||||||
|
{
|
||||||
|
struct acpi_eject_event *ej_event;
|
||||||
|
|
||||||
|
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
|
||||||
|
if (!ej_event) {
|
||||||
|
/* Inform firmware the hot-remove operation has error */
|
||||||
|
(void) acpi_evaluate_hotplug_ost(device->handle,
|
||||||
|
ACPI_NOTIFY_EJECT_REQUEST,
|
||||||
|
ACPI_OST_SC_NON_SPECIFIC_FAILURE,
|
||||||
|
NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ej_event->device = device;
|
||||||
|
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
|
||||||
|
|
||||||
|
acpi_bus_hot_remove_device(ej_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _handle_hotplug_event_root(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct acpi_pci_root *root;
|
||||||
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
|
||||||
|
struct acpi_hp_work *hp_work;
|
||||||
|
acpi_handle handle;
|
||||||
|
u32 type;
|
||||||
|
|
||||||
|
hp_work = container_of(work, struct acpi_hp_work, work);
|
||||||
|
handle = hp_work->handle;
|
||||||
|
type = hp_work->type;
|
||||||
|
|
||||||
|
root = acpi_pci_find_root(handle);
|
||||||
|
|
||||||
|
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ACPI_NOTIFY_BUS_CHECK:
|
||||||
|
/* bus enumerate */
|
||||||
|
printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
|
||||||
|
(char *)buffer.pointer);
|
||||||
|
if (!root)
|
||||||
|
handle_root_bridge_insertion(handle);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||||
|
/* device check */
|
||||||
|
printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
|
||||||
|
(char *)buffer.pointer);
|
||||||
|
if (!root)
|
||||||
|
handle_root_bridge_insertion(handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||||
|
/* request device eject */
|
||||||
|
printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
|
||||||
|
(char *)buffer.pointer);
|
||||||
|
if (root)
|
||||||
|
handle_root_bridge_removal(root->device);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
|
||||||
|
type, (char *)buffer.pointer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
|
||||||
|
kfree(buffer.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_hotplug_event_root(acpi_handle handle, u32 type,
|
||||||
|
void *context)
|
||||||
|
{
|
||||||
|
alloc_acpi_hp_work(handle, type, context,
|
||||||
|
_handle_hotplug_event_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
static acpi_status __init
|
||||||
|
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
char objname[64];
|
||||||
|
struct acpi_buffer buffer = { .length = sizeof(objname),
|
||||||
|
.pointer = objname };
|
||||||
|
int *count = (int *)context;
|
||||||
|
|
||||||
|
if (!acpi_is_root_bridge(handle))
|
||||||
|
return AE_OK;
|
||||||
|
|
||||||
|
(*count)++;
|
||||||
|
|
||||||
|
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
|
||||||
|
|
||||||
|
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||||
|
handle_hotplug_event_root, NULL);
|
||||||
|
if (ACPI_FAILURE(status))
|
||||||
|
printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
|
||||||
|
objname, (unsigned int)status);
|
||||||
|
else
|
||||||
|
printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
|
||||||
|
objname);
|
||||||
|
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init acpi_pci_root_hp_init(void)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||||
|
ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
|
||||||
|
|
||||||
|
printk(KERN_DEBUG "Found %d acpi root devices\n", num);
|
||||||
|
}
|
||||||
|
|
|
@ -1706,5 +1706,8 @@ int __init acpi_scan_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_update_all_gpes();
|
acpi_update_all_gpes();
|
||||||
|
|
||||||
|
acpi_pci_root_hp_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,68 +161,35 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
|
||||||
void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
|
void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_bus_add_device - add a single device
|
* pci_bus_add_device - start driver for a single device
|
||||||
* @dev: device to add
|
* @dev: device to add
|
||||||
*
|
*
|
||||||
* This adds a single pci device to the global
|
* This adds add sysfs entries and start device drivers
|
||||||
* device list and adds sysfs and procfs entries
|
|
||||||
*/
|
*/
|
||||||
int pci_bus_add_device(struct pci_dev *dev)
|
int pci_bus_add_device(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
pci_fixup_device(pci_fixup_final, dev);
|
/*
|
||||||
|
* Can not put in pci_device_add yet because resources
|
||||||
|
* are not assigned yet for some devices.
|
||||||
|
*/
|
||||||
|
pci_create_sysfs_dev_files(dev);
|
||||||
|
|
||||||
retval = pcibios_add_device(dev);
|
dev->match_driver = true;
|
||||||
if (retval)
|
retval = device_attach(&dev->dev);
|
||||||
return retval;
|
WARN_ON(retval < 0);
|
||||||
|
|
||||||
retval = device_add(&dev->dev);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
dev->is_added = 1;
|
dev->is_added = 1;
|
||||||
pci_proc_attach_device(dev);
|
|
||||||
pci_create_sysfs_dev_files(dev);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_bus_add_child - add a child bus
|
* pci_bus_add_devices - start driver for PCI devices
|
||||||
* @bus: bus to add
|
|
||||||
*
|
|
||||||
* This adds sysfs entries for a single bus
|
|
||||||
*/
|
|
||||||
int pci_bus_add_child(struct pci_bus *bus)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
if (bus->bridge)
|
|
||||||
bus->dev.parent = bus->bridge;
|
|
||||||
|
|
||||||
retval = device_register(&bus->dev);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
bus->is_added = 1;
|
|
||||||
|
|
||||||
/* Create legacy_io and legacy_mem files for this bus */
|
|
||||||
pci_create_legacy_files(bus);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pci_bus_add_devices - insert newly discovered PCI devices
|
|
||||||
* @bus: bus to check for new devices
|
* @bus: bus to check for new devices
|
||||||
*
|
*
|
||||||
* Add newly discovered PCI devices (which are on the bus->devices
|
* Start driver for PCI devices and add some sysfs entries.
|
||||||
* list) to the global PCI device list, add the sysfs and procfs
|
|
||||||
* entries. Where a bridge is found, add the discovered bus to
|
|
||||||
* the parents list of child buses, and recurse (breadth-first
|
|
||||||
* to be compatible with 2.4)
|
|
||||||
*
|
|
||||||
* Call hotplug for each new devices.
|
|
||||||
*/
|
*/
|
||||||
void pci_bus_add_devices(const struct pci_bus *bus)
|
void pci_bus_add_devices(const struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
|
@ -235,36 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus)
|
||||||
if (dev->is_added)
|
if (dev->is_added)
|
||||||
continue;
|
continue;
|
||||||
retval = pci_bus_add_device(dev);
|
retval = pci_bus_add_device(dev);
|
||||||
if (retval)
|
|
||||||
dev_err(&dev->dev, "Error adding device, continuing\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||||
BUG_ON(!dev->is_added);
|
BUG_ON(!dev->is_added);
|
||||||
|
|
||||||
child = dev->subordinate;
|
child = dev->subordinate;
|
||||||
/*
|
|
||||||
* If there is an unattached subordinate bus, attach
|
|
||||||
* it and then scan for unattached PCI devices.
|
|
||||||
*/
|
|
||||||
if (!child)
|
if (!child)
|
||||||
continue;
|
continue;
|
||||||
if (list_empty(&child->node)) {
|
|
||||||
down_write(&pci_bus_sem);
|
|
||||||
list_add_tail(&child->node, &dev->bus->children);
|
|
||||||
up_write(&pci_bus_sem);
|
|
||||||
}
|
|
||||||
pci_bus_add_devices(child);
|
pci_bus_add_devices(child);
|
||||||
|
|
||||||
/*
|
|
||||||
* register the bus with sysfs as the parent is now
|
|
||||||
* properly registered.
|
|
||||||
*/
|
|
||||||
if (child->is_added)
|
if (child->is_added)
|
||||||
continue;
|
continue;
|
||||||
retval = pci_bus_add_child(child);
|
child->is_added = 1;
|
||||||
if (retval)
|
|
||||||
dev_err(&dev->dev, "Error adding bus, continuing\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
|
||||||
/* acpiphp_glue.c */
|
/* acpiphp_glue.c */
|
||||||
extern int acpiphp_glue_init (void);
|
extern int acpiphp_glue_init (void);
|
||||||
extern void acpiphp_glue_exit (void);
|
extern void acpiphp_glue_exit (void);
|
||||||
extern int acpiphp_get_num_slots (void);
|
|
||||||
typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
|
typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
|
||||||
|
|
||||||
extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
|
extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
bool acpiphp_debug;
|
bool acpiphp_debug;
|
||||||
|
|
||||||
/* local variables */
|
/* local variables */
|
||||||
static int num_slots;
|
|
||||||
static struct acpiphp_attention_info *attention_info;
|
static struct acpiphp_attention_info *attention_info;
|
||||||
|
|
||||||
#define DRIVER_VERSION "0.5"
|
#define DRIVER_VERSION "0.5"
|
||||||
|
@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init init_acpi(void)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
/* initialize internal data structure etc. */
|
|
||||||
retval = acpiphp_glue_init();
|
|
||||||
|
|
||||||
/* read initial number of slots */
|
|
||||||
if (!retval) {
|
|
||||||
num_slots = acpiphp_get_num_slots();
|
|
||||||
if (num_slots == 0) {
|
|
||||||
acpiphp_glue_exit();
|
|
||||||
retval = -ENODEV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* release_slot - free up the memory used by a slot
|
* release_slot - free up the memory used by a slot
|
||||||
* @hotplug_slot: slot to free
|
* @hotplug_slot: slot to free
|
||||||
|
@ -379,7 +359,8 @@ static int __init acpiphp_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* read all the ACPI info from the system */
|
/* read all the ACPI info from the system */
|
||||||
return init_acpi();
|
/* initialize internal data structure etc. */
|
||||||
|
return acpiphp_glue_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -543,10 +543,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
acpi_handle handle = bridge->handle;
|
acpi_handle handle = bridge->handle;
|
||||||
|
|
||||||
status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
if (bridge->type != BRIDGE_TYPE_HOST) {
|
||||||
|
status = acpi_remove_notify_handler(handle,
|
||||||
|
ACPI_SYSTEM_NOTIFY,
|
||||||
handle_hotplug_event_bridge);
|
handle_hotplug_event_bridge);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
err("failed to remove notify handler\n");
|
err("failed to remove notify handler\n");
|
||||||
|
}
|
||||||
|
|
||||||
if ((bridge->type != BRIDGE_TYPE_HOST) &&
|
if ((bridge->type != BRIDGE_TYPE_HOST) &&
|
||||||
((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
|
((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
|
||||||
|
@ -630,9 +633,6 @@ static void remove_bridge(struct acpi_pci_root *root)
|
||||||
bridge = acpiphp_handle_to_bridge(handle);
|
bridge = acpiphp_handle_to_bridge(handle);
|
||||||
if (bridge)
|
if (bridge)
|
||||||
cleanup_bridge(bridge);
|
cleanup_bridge(bridge);
|
||||||
else
|
|
||||||
acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
|
||||||
handle_hotplug_event_bridge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int power_on_slot(struct acpiphp_slot *slot)
|
static int power_on_slot(struct acpiphp_slot *slot)
|
||||||
|
@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
struct acpiphp_func *func;
|
||||||
|
|
||||||
|
if (!dev->subordinate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* quirk, or pcie could set it already */
|
||||||
|
if (dev->is_hotplug_bridge)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PCI_SLOT(dev->devfn) != slot->device)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_for_each_entry(func, &slot->funcs, sibling) {
|
||||||
|
if (PCI_FUNC(dev->devfn) == func->function) {
|
||||||
|
/* check if this bridge has ejectable slots */
|
||||||
|
if ((detect_ejectable_slots(func->handle) > 0))
|
||||||
|
dev->is_hotplug_bridge = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* enable_device - enable, configure a slot
|
* enable_device - enable, configure a slot
|
||||||
* @slot: slot to be enabled
|
* @slot: slot to be enabled
|
||||||
|
@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
||||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
|
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
|
||||||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
|
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
|
||||||
max = pci_scan_bridge(bus, dev, max, pass);
|
max = pci_scan_bridge(bus, dev, max, pass);
|
||||||
if (pass && dev->subordinate)
|
if (pass && dev->subordinate) {
|
||||||
|
check_hotplug_bridge(slot, dev);
|
||||||
pci_bus_size_bridges(dev->subordinate);
|
pci_bus_size_bridges(dev->subordinate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1098,18 +1123,12 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program resources in newly inserted bridge */
|
/* Program resources in newly inserted bridge */
|
||||||
static int acpiphp_configure_bridge (acpi_handle handle)
|
static int acpiphp_configure_p2p_bridge(acpi_handle handle)
|
||||||
{
|
{
|
||||||
struct pci_bus *bus;
|
struct pci_dev *pdev = acpi_get_pci_dev(handle);
|
||||||
|
struct pci_bus *bus = pdev->subordinate;
|
||||||
|
|
||||||
if (acpi_is_root_bridge(handle)) {
|
pci_dev_put(pdev);
|
||||||
struct acpi_pci_root *root = acpi_pci_find_root(handle);
|
|
||||||
bus = root->bus;
|
|
||||||
} else {
|
|
||||||
struct pci_dev *pdev = acpi_get_pci_dev(handle);
|
|
||||||
bus = pdev->subordinate;
|
|
||||||
pci_dev_put(pdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_bus_size_bridges(bus);
|
pci_bus_size_bridges(bus);
|
||||||
pci_bus_assign_resources(bus);
|
pci_bus_assign_resources(bus);
|
||||||
|
@ -1119,7 +1138,7 @@ static int acpiphp_configure_bridge (acpi_handle handle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_bridge_insertion(acpi_handle handle, u32 type)
|
static void handle_p2p_bridge_insertion(acpi_handle handle, u32 type)
|
||||||
{
|
{
|
||||||
struct acpi_device *device;
|
struct acpi_device *device;
|
||||||
|
|
||||||
|
@ -1137,8 +1156,8 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
|
||||||
err("ACPI device object missing\n");
|
err("ACPI device object missing\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!acpiphp_configure_bridge(handle))
|
if (!acpiphp_configure_p2p_bridge(handle))
|
||||||
add_bridge(handle);
|
add_p2p_bridge(handle);
|
||||||
else
|
else
|
||||||
err("cannot configure and start bridge\n");
|
err("cannot configure and start bridge\n");
|
||||||
|
|
||||||
|
@ -1178,34 +1197,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||||
return AE_OK ;
|
return AE_OK ;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct acpiphp_hp_work {
|
|
||||||
struct work_struct work;
|
|
||||||
acpi_handle handle;
|
|
||||||
u32 type;
|
|
||||||
void *context;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type,
|
|
||||||
void *context,
|
|
||||||
void (*func)(struct work_struct *work))
|
|
||||||
{
|
|
||||||
struct acpiphp_hp_work *hp_work;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
|
|
||||||
if (!hp_work)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hp_work->handle = handle;
|
|
||||||
hp_work->type = type;
|
|
||||||
hp_work->context = context;
|
|
||||||
|
|
||||||
INIT_WORK(&hp_work->work, func);
|
|
||||||
ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
|
|
||||||
if (!ret)
|
|
||||||
kfree(hp_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _handle_hotplug_event_bridge(struct work_struct *work)
|
static void _handle_hotplug_event_bridge(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct acpiphp_bridge *bridge;
|
struct acpiphp_bridge *bridge;
|
||||||
|
@ -1214,17 +1205,17 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
|
||||||
.pointer = objname };
|
.pointer = objname };
|
||||||
struct acpi_device *device;
|
struct acpi_device *device;
|
||||||
int num_sub_bridges = 0;
|
int num_sub_bridges = 0;
|
||||||
struct acpiphp_hp_work *hp_work;
|
struct acpi_hp_work *hp_work;
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
u32 type;
|
u32 type;
|
||||||
|
|
||||||
hp_work = container_of(work, struct acpiphp_hp_work, work);
|
hp_work = container_of(work, struct acpi_hp_work, work);
|
||||||
handle = hp_work->handle;
|
handle = hp_work->handle;
|
||||||
type = hp_work->type;
|
type = hp_work->type;
|
||||||
|
|
||||||
if (acpi_bus_get_device(handle, &device)) {
|
if (acpi_bus_get_device(handle, &device)) {
|
||||||
/* This bridge must have just been physically inserted */
|
/* This bridge must have just been physically inserted */
|
||||||
handle_bridge_insertion(handle, type);
|
handle_p2p_bridge_insertion(handle, type);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1321,8 +1312,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
|
||||||
* For now just re-add this work to the kacpi_hotplug_wq so we
|
* For now just re-add this work to the kacpi_hotplug_wq so we
|
||||||
* don't deadlock on hotplug actions.
|
* don't deadlock on hotplug actions.
|
||||||
*/
|
*/
|
||||||
alloc_acpiphp_hp_work(handle, type, context,
|
alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
|
||||||
_handle_hotplug_event_bridge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _handle_hotplug_event_func(struct work_struct *work)
|
static void _handle_hotplug_event_func(struct work_struct *work)
|
||||||
|
@ -1331,12 +1321,12 @@ static void _handle_hotplug_event_func(struct work_struct *work)
|
||||||
char objname[64];
|
char objname[64];
|
||||||
struct acpi_buffer buffer = { .length = sizeof(objname),
|
struct acpi_buffer buffer = { .length = sizeof(objname),
|
||||||
.pointer = objname };
|
.pointer = objname };
|
||||||
struct acpiphp_hp_work *hp_work;
|
struct acpi_hp_work *hp_work;
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
u32 type;
|
u32 type;
|
||||||
void *context;
|
void *context;
|
||||||
|
|
||||||
hp_work = container_of(work, struct acpiphp_hp_work, work);
|
hp_work = container_of(work, struct acpi_hp_work, work);
|
||||||
handle = hp_work->handle;
|
handle = hp_work->handle;
|
||||||
type = hp_work->type;
|
type = hp_work->type;
|
||||||
context = hp_work->context;
|
context = hp_work->context;
|
||||||
|
@ -1397,23 +1387,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
|
||||||
* For now just re-add this work to the kacpi_hotplug_wq so we
|
* For now just re-add this work to the kacpi_hotplug_wq so we
|
||||||
* don't deadlock on hotplug actions.
|
* don't deadlock on hotplug actions.
|
||||||
*/
|
*/
|
||||||
alloc_acpiphp_hp_work(handle, type, context,
|
alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func);
|
||||||
_handle_hotplug_event_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
|
|
||||||
{
|
|
||||||
int *count = (int *)context;
|
|
||||||
|
|
||||||
if (!acpi_is_root_bridge(handle))
|
|
||||||
return AE_OK;
|
|
||||||
|
|
||||||
(*count)++;
|
|
||||||
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
|
||||||
handle_hotplug_event_bridge, NULL);
|
|
||||||
|
|
||||||
return AE_OK ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct acpi_pci_driver acpi_pci_hp_driver = {
|
static struct acpi_pci_driver acpi_pci_hp_driver = {
|
||||||
|
@ -1426,15 +1400,7 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
|
||||||
*/
|
*/
|
||||||
int __init acpiphp_glue_init(void)
|
int __init acpiphp_glue_init(void)
|
||||||
{
|
{
|
||||||
int num = 0;
|
acpi_pci_register_driver(&acpi_pci_hp_driver);
|
||||||
|
|
||||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
|
||||||
ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
|
|
||||||
|
|
||||||
if (num <= 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
acpi_pci_register_driver(&acpi_pci_hp_driver);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1450,28 +1416,6 @@ void acpiphp_glue_exit(void)
|
||||||
acpi_pci_unregister_driver(&acpi_pci_hp_driver);
|
acpi_pci_unregister_driver(&acpi_pci_hp_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* acpiphp_get_num_slots - count number of slots in a system
|
|
||||||
*/
|
|
||||||
int __init acpiphp_get_num_slots(void)
|
|
||||||
{
|
|
||||||
struct acpiphp_bridge *bridge;
|
|
||||||
int num_slots = 0;
|
|
||||||
|
|
||||||
list_for_each_entry(bridge, &bridge_list, list) {
|
|
||||||
dbg("Bus %04x:%02x has %d slot%s\n",
|
|
||||||
pci_domain_nr(bridge->pci_bus),
|
|
||||||
bridge->pci_bus->number, bridge->nr_slots,
|
|
||||||
bridge->nr_slots == 1 ? "" : "s");
|
|
||||||
num_slots += bridge->nr_slots;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("Total %d slots\n", num_slots);
|
|
||||||
return num_slots;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpiphp_enable_slot - power on slot
|
* acpiphp_enable_slot - power on slot
|
||||||
* @slot: ACPI PHP slot
|
* @slot: ACPI PHP slot
|
||||||
|
|
|
@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pci_bus_insert_busn_res(child, busnr, busnr);
|
pci_bus_insert_busn_res(child, busnr, busnr);
|
||||||
child->dev.parent = bus->bridge;
|
bus->is_added = 1;
|
||||||
rc = pci_bus_add_child(child);
|
|
||||||
if (rc) {
|
|
||||||
pci_remove_bus(child);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
||||||
virtfn->is_virtfn = 1;
|
virtfn->is_virtfn = 1;
|
||||||
|
|
||||||
rc = pci_bus_add_device(virtfn);
|
rc = pci_bus_add_device(virtfn);
|
||||||
if (rc)
|
|
||||||
goto failed1;
|
|
||||||
sprintf(buf, "virtfn%u", id);
|
sprintf(buf, "virtfn%u", id);
|
||||||
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
|
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
|
@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev)
|
||||||
static int pci_bus_match(struct device *dev, struct device_driver *drv)
|
static int pci_bus_match(struct device *dev, struct device_driver *drv)
|
||||||
{
|
{
|
||||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||||
struct pci_driver *pci_drv = to_pci_driver(drv);
|
struct pci_driver *pci_drv;
|
||||||
const struct pci_device_id *found_id;
|
const struct pci_device_id *found_id;
|
||||||
|
|
||||||
|
if (!pci_dev->match_driver)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pci_drv = to_pci_driver(drv);
|
||||||
found_id = pci_match_device(pci_drv, pci_dev);
|
found_id = pci_match_device(pci_drv, pci_dev);
|
||||||
if (found_id)
|
if (found_id)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -203,8 +203,8 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||||
struct resource *res, unsigned int reg);
|
struct resource *res, unsigned int reg);
|
||||||
extern int pci_resource_bar(struct pci_dev *dev, int resno,
|
extern int pci_resource_bar(struct pci_dev *dev, int resno,
|
||||||
enum pci_bar_type *type);
|
enum pci_bar_type *type);
|
||||||
extern int pci_bus_add_child(struct pci_bus *bus);
|
|
||||||
extern void pci_configure_ari(struct pci_dev *dev);
|
extern void pci_configure_ari(struct pci_dev *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_ari_enabled - query ARI forwarding status
|
* pci_ari_enabled - query ARI forwarding status
|
||||||
* @bus: the PCI bus
|
* @bus: the PCI bus
|
||||||
|
|
|
@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||||
{
|
{
|
||||||
struct pci_bus *child;
|
struct pci_bus *child;
|
||||||
int i;
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new bus, and inherit stuff from the parent..
|
* Allocate a new bus, and inherit stuff from the parent..
|
||||||
|
@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||||
child->bus_flags = parent->bus_flags;
|
child->bus_flags = parent->bus_flags;
|
||||||
|
|
||||||
/* initialize some portions of the bus device, but don't register it
|
/* initialize some portions of the bus device, but don't register it
|
||||||
* now as the parent is not properly set up yet. This device will get
|
* now as the parent is not properly set up yet.
|
||||||
* registered later in pci_bus_add_devices()
|
|
||||||
*/
|
*/
|
||||||
child->dev.class = &pcibus_class;
|
child->dev.class = &pcibus_class;
|
||||||
dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
|
dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
|
||||||
|
@ -651,11 +651,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||||
child->primary = parent->busn_res.start;
|
child->primary = parent->busn_res.start;
|
||||||
child->busn_res.end = 0xff;
|
child->busn_res.end = 0xff;
|
||||||
|
|
||||||
if (!bridge)
|
if (!bridge) {
|
||||||
return child;
|
child->dev.parent = parent->bridge;
|
||||||
|
goto add_dev;
|
||||||
|
}
|
||||||
|
|
||||||
child->self = bridge;
|
child->self = bridge;
|
||||||
child->bridge = get_device(&bridge->dev);
|
child->bridge = get_device(&bridge->dev);
|
||||||
|
child->dev.parent = child->bridge;
|
||||||
pci_set_bus_of_node(child);
|
pci_set_bus_of_node(child);
|
||||||
pci_set_bus_speed(child);
|
pci_set_bus_speed(child);
|
||||||
|
|
||||||
|
@ -666,6 +669,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||||
}
|
}
|
||||||
bridge->subordinate = child;
|
bridge->subordinate = child;
|
||||||
|
|
||||||
|
add_dev:
|
||||||
|
ret = device_register(&child->dev);
|
||||||
|
WARN_ON(ret < 0);
|
||||||
|
|
||||||
|
/* Create legacy_io and legacy_mem files for this bus */
|
||||||
|
pci_create_legacy_files(child);
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1296,10 +1306,12 @@ static void pci_init_capabilities(struct pci_dev *dev)
|
||||||
|
|
||||||
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
|
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
device_initialize(&dev->dev);
|
device_initialize(&dev->dev);
|
||||||
dev->dev.release = pci_release_dev;
|
dev->dev.release = pci_release_dev;
|
||||||
pci_dev_get(dev);
|
|
||||||
|
|
||||||
|
set_dev_node(&dev->dev, pcibus_to_node(bus));
|
||||||
dev->dev.dma_mask = &dev->dma_mask;
|
dev->dev.dma_mask = &dev->dma_mask;
|
||||||
dev->dev.dma_parms = &dev->dma_parms;
|
dev->dev.dma_parms = &dev->dma_parms;
|
||||||
dev->dev.coherent_dma_mask = 0xffffffffull;
|
dev->dev.coherent_dma_mask = 0xffffffffull;
|
||||||
|
@ -1326,6 +1338,17 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
|
||||||
down_write(&pci_bus_sem);
|
down_write(&pci_bus_sem);
|
||||||
list_add_tail(&dev->bus_list, &bus->devices);
|
list_add_tail(&dev->bus_list, &bus->devices);
|
||||||
up_write(&pci_bus_sem);
|
up_write(&pci_bus_sem);
|
||||||
|
|
||||||
|
pci_fixup_device(pci_fixup_final, dev);
|
||||||
|
ret = pcibios_add_device(dev);
|
||||||
|
WARN_ON(ret < 0);
|
||||||
|
|
||||||
|
/* Notifier could use PCI capabilities */
|
||||||
|
dev->match_driver = false;
|
||||||
|
ret = device_add(&dev->dev);
|
||||||
|
WARN_ON(ret < 0);
|
||||||
|
|
||||||
|
pci_proc_attach_device(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
|
struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
|
||||||
|
@ -1650,13 +1673,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||||
char bus_addr[64];
|
char bus_addr[64];
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
|
||||||
|
|
||||||
b = pci_alloc_bus();
|
b = pci_alloc_bus();
|
||||||
if (!b)
|
if (!b)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
b->sysdata = sysdata;
|
b->sysdata = sysdata;
|
||||||
b->ops = ops;
|
b->ops = ops;
|
||||||
|
b->number = b->busn_res.start = bus;
|
||||||
b2 = pci_find_bus(pci_domain_nr(b), bus);
|
b2 = pci_find_bus(pci_domain_nr(b), bus);
|
||||||
if (b2) {
|
if (b2) {
|
||||||
/* If we already got to this bus through a different bridge, ignore it */
|
/* If we already got to this bus through a different bridge, ignore it */
|
||||||
|
@ -1695,8 +1718,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||||
/* Create legacy_io and legacy_mem files for this bus */
|
/* Create legacy_io and legacy_mem files for this bus */
|
||||||
pci_create_legacy_files(b);
|
pci_create_legacy_files(b);
|
||||||
|
|
||||||
b->number = b->busn_res.start = bus;
|
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
|
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
|
||||||
else
|
else
|
||||||
|
|
|
@ -22,7 +22,7 @@ static void pci_stop_dev(struct pci_dev *dev)
|
||||||
if (dev->is_added) {
|
if (dev->is_added) {
|
||||||
pci_proc_detach_device(dev);
|
pci_proc_detach_device(dev);
|
||||||
pci_remove_sysfs_dev_files(dev);
|
pci_remove_sysfs_dev_files(dev);
|
||||||
device_unregister(&dev->dev);
|
device_del(&dev->dev);
|
||||||
dev->is_added = 0;
|
dev->is_added = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
|
||||||
up_write(&pci_bus_sem);
|
up_write(&pci_bus_sem);
|
||||||
|
|
||||||
pci_free_resources(dev);
|
pci_free_resources(dev);
|
||||||
pci_dev_put(dev);
|
put_device(&dev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pci_remove_bus(struct pci_bus *bus)
|
void pci_remove_bus(struct pci_bus *bus)
|
||||||
|
|
|
@ -319,13 +319,13 @@ int pci_dev_present(const struct pci_device_id *ids)
|
||||||
WARN_ON(in_interrupt());
|
WARN_ON(in_interrupt());
|
||||||
while (ids->vendor || ids->subvendor || ids->class_mask) {
|
while (ids->vendor || ids->subvendor || ids->class_mask) {
|
||||||
found = pci_get_dev_by_id(ids, NULL);
|
found = pci_get_dev_by_id(ids, NULL);
|
||||||
if (found)
|
if (found) {
|
||||||
goto exit;
|
pci_dev_put(found);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
ids++;
|
ids++;
|
||||||
}
|
}
|
||||||
exit:
|
|
||||||
if (found)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_dev_present);
|
EXPORT_SYMBOL(pci_dev_present);
|
||||||
|
|
|
@ -283,7 +283,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
|
||||||
idx = res - &dev_res->dev->resource[0];
|
idx = res - &dev_res->dev->resource[0];
|
||||||
if (resource_size(res) &&
|
if (resource_size(res) &&
|
||||||
pci_assign_resource(dev_res->dev, idx)) {
|
pci_assign_resource(dev_res->dev, idx)) {
|
||||||
if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) {
|
if (fail_head) {
|
||||||
/*
|
/*
|
||||||
* if the failed res is for ROM BAR, and it will
|
* if the failed res is for ROM BAR, and it will
|
||||||
* be enabled later, don't add it to the list
|
* be enabled later, don't add it to the list
|
||||||
|
|
|
@ -310,6 +310,15 @@ struct acpi_eject_event {
|
||||||
u32 event;
|
u32 event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acpi_hp_work {
|
||||||
|
struct work_struct work;
|
||||||
|
acpi_handle handle;
|
||||||
|
u32 type;
|
||||||
|
void *context;
|
||||||
|
};
|
||||||
|
void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
|
||||||
|
void (*func)(struct work_struct *work));
|
||||||
|
|
||||||
extern struct kobject *acpi_kobj;
|
extern struct kobject *acpi_kobj;
|
||||||
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
|
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
|
||||||
void acpi_bus_private_data_handler(acpi_handle, void *);
|
void acpi_bus_private_data_handler(acpi_handle, void *);
|
||||||
|
|
|
@ -193,8 +193,6 @@ void acpi_os_fixed_event_count(u32 fixed_event_number);
|
||||||
/*
|
/*
|
||||||
* Threads and Scheduling
|
* Threads and Scheduling
|
||||||
*/
|
*/
|
||||||
extern struct workqueue_struct *kacpi_hotplug_wq;
|
|
||||||
|
|
||||||
acpi_thread_id acpi_os_get_thread_id(void);
|
acpi_thread_id acpi_os_get_thread_id(void);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
|
|
|
@ -286,6 +286,7 @@ struct pci_dev {
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
|
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
|
||||||
|
|
||||||
|
bool match_driver; /* Skip attaching driver */
|
||||||
/* These fields are used by common fixups */
|
/* These fields are used by common fixups */
|
||||||
unsigned int transparent:1; /* Transparent PCI bridge */
|
unsigned int transparent:1; /* Transparent PCI bridge */
|
||||||
unsigned int multifunction:1;/* Part of multi-function device */
|
unsigned int multifunction:1;/* Part of multi-function device */
|
||||||
|
|
Loading…
Add table
Reference in a new issue