aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-02-07 12:15:10 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-02-07 12:15:10 -0800
commit6270aa63b3ee5dcf78aa915719a0425bbee176ee (patch)
treea1dc773f8ec9fd1bc7954f46337c5c6c8f2a8f6e /pci
parent641e80f1e8bdbcc54e037795ab9bbfc072551500 (diff)
downloadpatches-6270aa63b3ee5dcf78aa915719a0425bbee176ee.tar.gz
pci patches
Diffstat (limited to 'pci')
-rw-r--r--pci/acpiphp-handle-dock-stations.patch650
-rw-r--r--pci/pci-hotplug-acpiphp-handle-dock-bridges.patch330
-rw-r--r--pci/pci-hotplug-convert-semaphores-to-mutex.patch32
3 files changed, 657 insertions, 355 deletions
diff --git a/pci/acpiphp-handle-dock-stations.patch b/pci/acpiphp-handle-dock-stations.patch
new file mode 100644
index 0000000000000..3d1d9819190b2
--- /dev/null
+++ b/pci/acpiphp-handle-dock-stations.patch
@@ -0,0 +1,650 @@
+From kristenc@cs.pdx.edu Wed Feb 1 15:30:56 2006
+Date: Wed, 1 Feb 2006 15:30:05 -0800
+From: Kristen Carlson Accardi <kristenc@cs.pdx.edu>
+Cc: <greg@kroah.com>, <len.brown@intel.com>, <pavel@ucw.cz>, <muneda.takahiro@jp.fujitsu.com>
+Subject: [patch] acpiphp: handle dock stations
+Message-ID: <20060201233005.GA4999@nerpa>
+Content-Disposition: inline
+
+
+From: Kristen Carlson Accardi kristen.c.accardi@intel.com
+
+This patch will add hot add/remove of docking stations to acpiphp. Because
+some docking stations will have a _DCK method that is not associated with
+a dock bridge, we use the _EJD method to determine which devices are
+dependent on the dock device, then try to find which of these dependent
+devices are pci devices. We register a separate event handler with acpi
+to handle dock notifications, but if we have discovered any pci devices
+dependent on the dock station, we notify the acpiphp driver to rescan
+the correct bus. If no pci devices are found, but there is still a _DCK method
+present, the driver will stay loaded to deal with the dock notifications.
+
+This patch does not implement full _EJD support yet - it just uses it
+to find the dock bridge (if it exists) for rescanning pci. It also does
+not attempt to add devices that are not enumerable via pci. It will
+stay loaded even if we find a dock station with no p2p dock bridge
+to handle the dock notifications. I will likely move all the dependent
+device stuff out of acpiphp and into acpi in the future because some
+of that code can be used by any device that has _EJD, not just pci
+hotplug - but for now we'll leave it here.
+
+You cannot use this patch and the ibm_acpi driver at same time due to
+the fact that both drivers attempt to register for dock notifications.
+
+Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/Makefile | 3
+ drivers/pci/hotplug/acpiphp.h | 36 +++
+ drivers/pci/hotplug/acpiphp_core.c | 7
+ drivers/pci/hotplug/acpiphp_dock.c | 368 +++++++++++++++++++++++++++++++++++++
+ drivers/pci/hotplug/acpiphp_glue.c | 53 ++++-
+ 5 files changed, 452 insertions(+), 15 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/Makefile
++++ gregkh-2.6/drivers/pci/hotplug/Makefile
+@@ -37,7 +37,8 @@ ibmphp-objs := ibmphp_core.o \
+ ibmphp_hpc.o
+
+ acpiphp-objs := acpiphp_core.o \
+- acpiphp_glue.o
++ acpiphp_glue.o \
++ acpiphp_dock.o
+
+ rpaphp-objs := rpaphp_core.o \
+ rpaphp_pci.o \
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h
+@@ -160,6 +160,25 @@ struct acpiphp_attention_info
+ struct module *owner;
+ };
+
++
++struct dependent_device {
++ struct list_head device_list;
++ struct list_head pci_list;
++ acpi_handle handle;
++ struct acpiphp_func *func;
++};
++
++
++struct acpiphp_dock_station {
++ acpi_handle handle;
++ u32 last_dock_time;
++ u32 flags;
++ struct acpiphp_func *dock_bridge;
++ struct list_head dependent_devices;
++ struct list_head pci_dependent_devices;
++};
++
++
+ /* PCI bus bridge HID */
+ #define ACPI_PCI_HOST_HID "PNP0A03"
+
+@@ -197,6 +216,12 @@ struct acpiphp_attention_info
+ #define FUNC_HAS_PS1 (0x00000020)
+ #define FUNC_HAS_PS2 (0x00000040)
+ #define FUNC_HAS_PS3 (0x00000080)
++#define FUNC_HAS_DCK (0x00000100)
++#define FUNC_IS_DD (0x00000200)
++
++/* dock station flags */
++#define DOCK_DOCKING (0x00000001)
++#define DOCK_HAS_BRIDGE (0x00000002)
+
+ /* function prototypes */
+
+@@ -210,6 +235,7 @@ extern void acpiphp_glue_exit (void);
+ extern int acpiphp_get_num_slots (void);
+ extern struct acpiphp_slot *get_slot_from_id (int id);
+ typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
++void handle_hotplug_event_func(acpi_handle, u32, void*);
+
+ extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
+ extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
+@@ -219,6 +245,16 @@ extern u8 acpiphp_get_latch_status (stru
+ extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
+ extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
+
++/* acpiphp_dock.c */
++extern int find_dock_station(void);
++extern void remove_dock_station(void);
++extern void add_dependent_device(struct dependent_device *new_dd);
++extern void add_pci_dependent_device(struct dependent_device *new_dd);
++extern struct dependent_device *get_dependent_device(acpi_handle handle);
++extern int is_dependent_device(acpi_handle handle);
++extern int detect_dependent_devices(acpi_handle *bridge_handle);
++extern struct dependent_device *alloc_dependent_device(acpi_handle handle);
++
+ /* variables */
+ extern int acpiphp_debug;
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_core.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_core.c
+@@ -429,14 +429,17 @@ static void __exit cleanup_slots (void)
+ static int __init acpiphp_init(void)
+ {
+ int retval;
++ int docking_station;
+
+ info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+
+ acpiphp_debug = debug;
+
++ docking_station = find_dock_station();
++
+ /* read all the ACPI info from the system */
+ retval = init_acpi();
+- if (retval)
++ if (retval && !(docking_station))
+ return retval;
+
+ return init_slots();
+@@ -448,6 +451,8 @@ static void __exit acpiphp_exit(void)
+ cleanup_slots();
+ /* deallocate internal data structures etc. */
+ acpiphp_glue_exit();
++
++ remove_dock_station();
+ }
+
+ module_init(acpiphp_init);
+--- /dev/null
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_dock.c
+@@ -0,0 +1,368 @@
++/*
++ * ACPI PCI HotPlug dock functions to ACPI CA subsystem
++ *
++ * Copyright (C) 2006 Kristen Carlson Accardi (kristen.c.accardi@intel.com)
++ * Copyright (C) 2006 Intel Corporation
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
++ * NON INFRINGEMENT. See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Send feedback to <kristen.c.accardi@intel.com>
++ *
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/smp_lock.h>
++#include <linux/mutex.h>
++
++#include "../pci.h"
++#include "pci_hotplug.h"
++#include "acpiphp.h"
++
++static struct acpiphp_dock_station *ds;
++#define MY_NAME "acpiphp_dock"
++
++
++int is_dependent_device(acpi_handle handle)
++{
++ struct dependent_device *dd;
++
++ if (!ds)
++ return 0;
++
++ list_for_each_entry(dd, &ds->dependent_devices, device_list) {
++ if (handle == dd->handle)
++ return 1;
++ }
++ return 0;
++}
++
++
++static acpi_status
++find_dependent_device(acpi_handle handle, u32 lvl, void *context, void **rv)
++{
++ int *count = (int *)context;
++
++ if (is_dependent_device(handle)) {
++ (*count)++;
++ return AE_CTRL_TERMINATE;
++ } else {
++ return AE_OK;
++ }
++}
++
++
++
++
++void add_dependent_device(struct dependent_device *new_dd)
++{
++ list_add_tail(&new_dd->device_list, &ds->dependent_devices);
++}
++
++
++void add_pci_dependent_device(struct dependent_device *new_dd)
++{
++ list_add_tail(&new_dd->pci_list, &ds->pci_dependent_devices);
++}
++
++
++
++struct dependent_device * get_dependent_device(acpi_handle handle)
++{
++ struct dependent_device *dd;
++
++ list_for_each_entry(dd, &ds->dependent_devices, device_list) {
++ if (handle == dd->handle)
++ return dd;
++ }
++ return NULL;
++}
++
++
++
++struct dependent_device *alloc_dependent_device(acpi_handle handle)
++{
++ struct dependent_device *dd;
++
++ dd = kzalloc(sizeof(*dd), GFP_KERNEL);
++ if (dd) {
++ INIT_LIST_HEAD(&dd->pci_list);
++ INIT_LIST_HEAD(&dd->device_list);
++ dd->handle = handle;
++ }
++ return dd;
++}
++
++
++
++static int is_dock(acpi_handle handle)
++{
++ acpi_status status;
++ acpi_handle tmp;
++
++ status = acpi_get_handle(handle, "_DCK", &tmp);
++ if (ACPI_FAILURE(status)) {
++ return 0;
++ }
++ return 1;
++}
++
++
++
++static acpi_status handle_dock(acpi_handle handle, int dock)
++{
++ acpi_status status;
++ struct acpi_object_list arg_list;
++ union acpi_object arg;
++ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
++
++ /* _DCK method has one argument */
++ arg_list.count = 1;
++ arg_list.pointer = &arg;
++ arg.type = ACPI_TYPE_INTEGER;
++ arg.integer.value = dock;
++ status = acpi_evaluate_object(handle, "_DCK",
++ &arg_list, &buffer);
++ if (ACPI_FAILURE(status))
++ err("%s: failed to dock!!\n", __FUNCTION__);
++ acpi_os_free(buffer.pointer);
++
++ return status;
++}
++
++
++
++/*
++ * the _DCK method can do funny things... and sometimes not
++ * hah-hah funny.
++ */
++static void post_dock_fixups(struct acpiphp_slot *slot)
++{
++ struct pci_bus *bus = slot->bridge->pci_bus;
++ u32 buses;
++
++ /* fixup bad _DCK function that rewrites
++ * secondary bridge on slot
++ */
++ pci_read_config_dword(bus->self,
++ PCI_PRIMARY_BUS,
++ &buses);
++
++ if (((buses >> 8) & 0xff) != bus->secondary) {
++ buses = (buses & 0xff000000)
++ | ((unsigned int)(bus->primary) << 0)
++ | ((unsigned int)(bus->secondary) << 8)
++ | ((unsigned int)(bus->subordinate) << 16);
++ pci_write_config_dword(bus->self,
++ PCI_PRIMARY_BUS,
++ buses);
++ }
++}
++
++
++
++
++static void
++handle_hotplug_event_dock(acpi_handle handle, u32 type, void *context)
++{
++ struct acpiphp_dock_station *station =
++ (struct acpiphp_dock_station *) context;
++ struct dependent_device *dd;
++
++ switch (type) {
++ case ACPI_NOTIFY_BUS_CHECK:
++ station->flags |= DOCK_DOCKING;
++ handle_dock(station->handle, 1);
++ /* TBD - this should be done probably similar
++ * to pci quirks, because only certain laptops
++ * will need certain fixups done.
++ */
++ list_for_each_entry(dd, &ds->pci_dependent_devices,
++ pci_list)
++ post_dock_fixups(dd->func->slot);
++
++ list_for_each_entry(dd, &ds->pci_dependent_devices,
++ pci_list)
++ handle_hotplug_event_func(dd->handle,
++ type, dd->func);
++ station->flags &= ~(DOCK_DOCKING);
++ station->last_dock_time = jiffies;
++ break;
++ case ACPI_NOTIFY_EJECT_REQUEST:
++ if (station->flags & DOCK_DOCKING ||
++ station->last_dock_time == jiffies) {
++ } else {
++ handle_dock(station->handle, 0);
++ list_for_each_entry(dd,
++ &ds->pci_dependent_devices, pci_list)
++
++ handle_hotplug_event_func(dd->handle,
++ type, dd->func);
++ }
++ break;
++ }
++}
++
++
++
++
++static acpi_status
++find_dock_ejd(acpi_handle handle, u32 lvl, void *context, void **rv)
++{
++ acpi_status status;
++ acpi_handle tmp;
++ acpi_handle dck_handle = (acpi_handle) context;
++ char objname[64];
++ char ejd_objname[64];
++ struct acpi_buffer buffer = { .length = sizeof(objname),
++ .pointer = objname };
++ struct acpi_buffer ejd_buffer = {ACPI_ALLOCATE_BUFFER, NULL};
++ struct acpi_buffer ejd_name_buffer = { .length = sizeof(objname),
++ .pointer = ejd_objname };
++ union acpi_object *ejd_obj;
++ union acpi_object *dck_obj;
++
++ status = acpi_get_handle(handle, "_EJD", &tmp);
++ if (ACPI_FAILURE(status))
++ return AE_OK;
++
++ /* make sure we are dependent on the dock device */
++ acpi_get_name(dck_handle, ACPI_FULL_PATHNAME, &buffer);
++ status = acpi_evaluate_object(handle, "_EJD", NULL, &ejd_buffer);
++ if (ACPI_FAILURE(status)) {
++ err("Unable to execute _EJD!\n");
++ goto find_ejd_out;
++ }
++
++ /* because acpi_get_name will pad the names if they are less
++ * than 4 characters, we can't compare the strings returned
++ * from _EJD with those returned from acpi_get_name. So,
++ * we have to get a handle to the object referenced by _EJD
++ * and then call get name on that.
++ */
++ ejd_obj = ejd_buffer.pointer;
++ status = acpi_get_handle(NULL, ejd_obj->string.pointer, &tmp);
++ if (ACPI_FAILURE(status))
++ goto find_ejd_out;
++ acpi_get_name(tmp, ACPI_FULL_PATHNAME, &ejd_name_buffer);
++
++ dck_obj = buffer.pointer;
++ if (!strncmp(ejd_objname, objname, strlen(ejd_objname))) {
++ struct dependent_device *dd;
++ dbg("%s: found device dependent on dock\n", __FUNCTION__);
++ dd = alloc_dependent_device(handle);
++ if (!dd) {
++ err("Can't allocate memory for dependent device!\n");
++ goto find_ejd_out;
++ }
++ add_dependent_device(dd);
++ }
++
++find_ejd_out:
++ acpi_os_free(ejd_buffer.pointer);
++ return AE_OK;
++}
++
++
++
++int detect_dependent_devices(acpi_handle *bridge_handle)
++{
++ acpi_status status;
++ int count;
++
++ count = 0;
++
++ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
++ (u32)1, find_dependent_device,
++ (void *)&count, NULL);
++
++ return count;
++}
++
++
++
++
++
++static acpi_status
++find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
++{
++ int *count = (int *)context;
++
++ if (is_dock(handle)) {
++ dbg("%s: found dock\n", __FUNCTION__);
++ ds = kzalloc(sizeof(*ds), GFP_KERNEL);
++ ds->handle = handle;
++ INIT_LIST_HEAD(&ds->dependent_devices);
++ INIT_LIST_HEAD(&ds->pci_dependent_devices);
++
++ /* look for devices dependent on dock station */
++ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
++ ACPI_UINT32_MAX, find_dock_ejd, handle, NULL);
++
++ acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
++ handle_hotplug_event_dock, ds);
++ (*count)++;
++ }
++
++ return AE_OK;
++}
++
++
++
++
++int find_dock_station(void)
++{
++ int num = 0;
++
++ ds = NULL;
++
++ /* start from the root object, because some laptops define
++ * _DCK methods outside the scope of PCI (IBM x-series laptop)
++ */
++ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
++ ACPI_UINT32_MAX, find_dock, &num, NULL);
++
++ return num;
++}
++
++
++
++void remove_dock_station(void)
++{
++ struct dependent_device *dd;
++ if (ds) {
++ if (ACPI_FAILURE(acpi_remove_notify_handler(ds->handle,
++ ACPI_SYSTEM_NOTIFY, handle_hotplug_event_dock)))
++ err("failed to remove dock notify handler\n");
++
++ /* free all dependent devices */
++ list_for_each_entry(dd, &ds->dependent_devices, device_list) {
++ list_del(&dd->device_list);
++ kfree(dd);
++ }
++
++ /* no need to touch the pci_dependent_device list,
++ * cause all memory was freed above
++ */
++ kfree(ds);
++ }
++}
++
++
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
+@@ -57,7 +57,6 @@ static LIST_HEAD(bridge_list);
+ #define MY_NAME "acpiphp_glue"
+
+ static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
+-static void handle_hotplug_event_func (acpi_handle, u32, void *);
+ static void acpiphp_sanitize_bus(struct pci_bus *bus);
+ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
+
+@@ -125,6 +124,7 @@ register_slot(acpi_handle handle, u32 lv
+ struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
+ struct acpiphp_slot *slot;
+ struct acpiphp_func *newfunc;
++ struct dependent_device *dd;
+ acpi_handle tmp;
+ acpi_status status = AE_OK;
+ unsigned long adr, sun;
+@@ -138,7 +138,7 @@ register_slot(acpi_handle handle, u32 lv
+
+ status = acpi_get_handle(handle, "_EJ0", &tmp);
+
+- if (ACPI_FAILURE(status))
++ if (ACPI_FAILURE(status) && !(is_dependent_device(handle)))
+ return AE_OK;
+
+ device = (adr >> 16) & 0xffff;
+@@ -152,7 +152,8 @@ register_slot(acpi_handle handle, u32 lv
+ INIT_LIST_HEAD(&newfunc->sibling);
+ newfunc->handle = handle;
+ newfunc->function = function;
+- newfunc->flags = FUNC_HAS_EJ0;
++ if (ACPI_SUCCESS(status))
++ newfunc->flags = FUNC_HAS_EJ0;
+
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
+ newfunc->flags |= FUNC_HAS_STA;
+@@ -163,6 +164,19 @@ register_slot(acpi_handle handle, u32 lv
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
+ newfunc->flags |= FUNC_HAS_PS3;
+
++ if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) {
++ newfunc->flags |= FUNC_HAS_DCK;
++ /* add to devices dependent on dock station,
++ * because this may actually be the dock bridge
++ */
++ dd = alloc_dependent_device(handle);
++ if (!dd)
++ err("Can't allocate memory for "
++ "new dependent device!\n");
++ else
++ add_dependent_device(dd);
++ }
++
+ status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
+ if (ACPI_FAILURE(status))
+ sun = -1;
+@@ -210,18 +224,28 @@ register_slot(acpi_handle handle, u32 lv
+ slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
+ }
+
++ /* if this is a device dependent on a dock station,
++ * associate the acpiphp_func to the dependent_device
++ * struct.
++ */
++ if ((dd = get_dependent_device(handle))) {
++ newfunc->flags |= FUNC_IS_DD;
++ dd->func = newfunc;
++ add_pci_dependent_device(dd);
++ }
++
+ /* install notify handler */
+- status = acpi_install_notify_handler(handle,
++ if (!(newfunc->flags & FUNC_HAS_DCK)) {
++ status = acpi_install_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_func,
+ newfunc);
+
+- if (ACPI_FAILURE(status)) {
+- err("failed to register interrupt notify handler\n");
+- return status;
++ if (ACPI_FAILURE(status))
++ err("failed to register interrupt notify handler\n");
+ }
+
+- return AE_OK;
++ return status;
+ }
+
+
+@@ -410,7 +434,8 @@ find_p2p_bridge(acpi_handle handle, u32
+ goto out;
+
+ /* check if this bridge has ejectable slots */
+- if (detect_ejectable_slots(handle) > 0) {
++ if ((detect_ejectable_slots(handle) > 0) ||
++ (detect_dependent_devices(handle) > 0)) {
+ dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
+ add_p2p_bridge(handle, dev);
+ }
+@@ -512,11 +537,13 @@ static void cleanup_bridge(struct acpiph
+ list_for_each_safe (list, tmp, &slot->funcs) {
+ struct acpiphp_func *func;
+ func = list_entry(list, struct acpiphp_func, sibling);
+- status = acpi_remove_notify_handler(func->handle,
++ if (!(func->flags & FUNC_HAS_DCK)) {
++ status = acpi_remove_notify_handler(func->handle,
+ ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_func);
+- if (ACPI_FAILURE(status))
+- err("failed to remove notify handler\n");
++ if (ACPI_FAILURE(status))
++ err("failed to remove notify handler\n");
++ }
+ pci_dev_put(func->pci_dev);
+ list_del(list);
+ kfree(func);
+@@ -1200,7 +1227,7 @@ static void handle_hotplug_event_bridge(
+ * handles ACPI event notification on slots
+ *
+ */
+-static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
++void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
+ {
+ struct acpiphp_func *func;
+ char objname[64];
diff --git a/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch b/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch
deleted file mode 100644
index 6e828b9da83ec..0000000000000
--- a/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From kristen.c.accardi@intel.com Tue Jan 17 16:54:09 2006
-From: Kristen Accardi <kristen.c.accardi@intel.com>
-Subject: PCI Hotplug: acpiphp: handle dock bridges
-Cc: <len.brown@intel.com>, <pavel@ucw.cz>
-Date: Tue, 17 Jan 2006 16:56:59 -0800
-Message-Id: <1137545819.19858.47.camel@whizzy>
-
-This patch will modify the acpiphp driver to handle docking and undocking
-events and hot adding of the PCI devices on the dock station. It currently
-has a workaround for a problem with acpi where the
-acpi threads will deadlock and never return from executing the _DCK method.
-As a workaround, I spawn a separate thread to do the dock. In addition,
-I've found that some _DCK methods do some bad things, so have implemented
-a fixups section for after docking that will no doubt grow as more laptops
-get tested. This patch CONFLICTS with some acpi plugins that try to do
-their own docking support (such as ibm_acpi), so you cannot use this driver
-and the conflicting driver simultaneously.
-
-
-Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- drivers/pci/hotplug/acpiphp.h | 2
- drivers/pci/hotplug/acpiphp_glue.c | 207 ++++++++++++++++++++++++++++++++++++-
- 2 files changed, 204 insertions(+), 5 deletions(-)
-
---- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h
-+++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h
-@@ -188,6 +188,7 @@ struct acpiphp_attention_info
- #define SLOT_POWEREDON (0x00000001)
- #define SLOT_ENABLED (0x00000002)
- #define SLOT_MULTIFUNCTION (0x00000004)
-+#define SLOT_DOCKING (0x00000008)
-
- /* function flags */
-
-@@ -197,6 +198,7 @@ struct acpiphp_attention_info
- #define FUNC_HAS_PS1 (0x00000020)
- #define FUNC_HAS_PS2 (0x00000040)
- #define FUNC_HAS_PS3 (0x00000080)
-+#define FUNC_HAS_DCK (0x00000100)
-
- /* function prototypes */
-
---- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
-+++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
-@@ -55,12 +55,14 @@
- static LIST_HEAD(bridge_list);
-
- #define MY_NAME "acpiphp_glue"
--
-+static struct work_struct dock_task;
-+static int enable_device(struct acpiphp_slot *slot);
- static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
- static void handle_hotplug_event_func (acpi_handle, u32, void *);
- static void acpiphp_sanitize_bus(struct pci_bus *bus);
- static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
--
-+static void dock(void *data);
-+static unsigned int get_slot_status(struct acpiphp_slot *slot);
-
- /*
- * initialization & terminatation routines
-@@ -118,6 +120,30 @@ is_ejectable_slot(acpi_handle handle, u3
- }
-
-
-+static acpi_status handle_dock(struct acpiphp_func *func, int dock)
-+{
-+ acpi_status status;
-+ struct acpi_object_list arg_list;
-+ union acpi_object arg;
-+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-+
-+ dbg("%s: enter\n", __FUNCTION__);
-+
-+ /* _DCK method has one argument */
-+ arg_list.count = 1;
-+ arg_list.pointer = &arg;
-+ arg.type = ACPI_TYPE_INTEGER;
-+ arg.integer.value = dock;
-+ status = acpi_evaluate_object(func->handle, "_DCK",
-+ &arg_list, &buffer);
-+ if (ACPI_FAILURE(status))
-+ err("%s: failed to dock!!\n", MY_NAME);
-+
-+ return status;
-+}
-+
-+
-+
- /* callback routine to register each ACPI PCI slot object */
- static acpi_status
- register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
-@@ -210,6 +236,12 @@ register_slot(acpi_handle handle, u32 lv
- slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
- }
-
-+ /* install dock notify handler */
-+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) {
-+ newfunc->flags |= FUNC_HAS_DCK;
-+ INIT_WORK(&dock_task, dock, slot);
-+ }
-+
- /* install notify handler */
- status = acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
-@@ -681,6 +713,88 @@ static int acpiphp_configure_ioapics(acp
- return 0;
- }
-
-+/*
-+ * the _DCK method can do funny things... and sometimes not
-+ * hah-hah funny.
-+ */
-+static void post_dock_fixups(struct acpiphp_slot *slot,
-+ struct acpiphp_func *func)
-+{
-+ struct pci_bus *bus = slot->bridge->pci_bus;
-+ u32 buses;
-+
-+ /* fixup bad _DCK function that rewrites
-+ * secondary bridge on slot
-+ */
-+ pci_read_config_dword(bus->self,
-+ PCI_PRIMARY_BUS,
-+ &buses);
-+
-+ if (((buses >> 8) & 0xff) != bus->secondary) {
-+ buses = (buses & 0xff000000)
-+ | ((unsigned int)(bus->primary) << 0)
-+ | ((unsigned int)(bus->secondary) << 8)
-+ | ((unsigned int)(bus->subordinate) << 16);
-+ pci_write_config_dword(bus->self,
-+ PCI_PRIMARY_BUS,
-+ buses);
-+ }
-+}
-+
-+
-+static int acpiphp_bus_add(struct acpiphp_func *func)
-+{
-+ acpi_handle phandle;
-+ struct acpi_device *device, *pdevice;
-+ int ret_val;
-+
-+ acpi_get_parent(func->handle, &phandle);
-+ if (acpi_bus_get_device(phandle, &pdevice)) {
-+ dbg("no parent device, assuming NULL\n");
-+ pdevice = NULL;
-+ }
-+ ret_val = acpi_bus_add(&device, pdevice, func->handle,
-+ ACPI_BUS_TYPE_DEVICE);
-+ if (ret_val)
-+ dbg("cannot add bridge to acpi list\n");
-+
-+ /*
-+ * try to start anyway. We could have failed to add
-+ * simply because this bus had previously been added
-+ * on another dock. Don't bother with the return value
-+ * we just keep going.
-+ */
-+ ret_val = acpi_bus_start(device);
-+
-+ return ret_val;
-+}
-+
-+
-+
-+static void dock(void *data)
-+{
-+ struct list_head *l;
-+ struct acpiphp_func *func;
-+ struct acpiphp_slot *slot = data;
-+
-+ down(&slot->crit_sect);
-+ list_for_each(l, &slot->funcs) {
-+ func = list_entry(l, struct acpiphp_func, sibling);
-+ if (func->flags & FUNC_HAS_DCK) {
-+ handle_dock(func, 1);
-+ post_dock_fixups(slot, func);
-+ slot->flags |= SLOT_POWEREDON;
-+ if (get_slot_status(slot) == ACPI_STA_ALL) {
-+ enable_device(slot);
-+ }
-+ }
-+ }
-+ slot->flags &= (~SLOT_DOCKING);
-+ up(&slot->crit_sect);
-+}
-+
-+
-+
- static int power_on_slot(struct acpiphp_slot *slot)
- {
- acpi_status status;
-@@ -705,6 +819,19 @@ static int power_on_slot(struct acpiphp_
- } else
- break;
- }
-+
-+ if (func->flags & FUNC_HAS_DCK) {
-+ dbg("%s: executing _DCK\n", __FUNCTION__);
-+ slot->flags |= SLOT_DOCKING;
-+ /*
-+ * FIXME - work around for acpi. Right
-+ * now if we call _DCK from this thread,
-+ * we block forever.
-+ */
-+ schedule_work(&dock_task);
-+ retval = -1;
-+ goto err_exit;
-+ }
- }
-
- /* TBD: evaluate _STA to check if the slot is enabled */
-@@ -730,7 +857,11 @@ static int power_off_slot(struct acpiphp
-
- list_for_each (l, &slot->funcs) {
- func = list_entry(l, struct acpiphp_func, sibling);
--
-+ if (func->flags & FUNC_HAS_DCK) {
-+ dbg("%s: undock commencing\n", __FUNCTION__);
-+ handle_dock(func, 0);
-+ dbg("%s: undock complete\n", __FUNCTION__);
-+ }
- if (func->flags & FUNC_HAS_PS3) {
- status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
- if (ACPI_FAILURE(status)) {
-@@ -752,6 +883,63 @@ static int power_off_slot(struct acpiphp
-
-
- /**
-+ * get_func - given pci_dev & slot, get the matching acpiphp_func
-+ * @slot: slot to be scanned.
-+ * @dev: pci_dev to match
-+ *
-+ * This function will check the list of acpiphp functions for
-+ * this slot and return the one that represents the given
-+ * pci_dev structure.
-+ */
-+static struct acpiphp_func * get_func(struct acpiphp_slot *slot,
-+ struct pci_dev *dev)
-+{
-+ struct list_head *l;
-+ struct acpiphp_func *func;
-+ struct pci_bus *bus = slot->bridge->pci_bus;
-+
-+ list_for_each (l, &slot->funcs) {
-+ func = list_entry(l, struct acpiphp_func, sibling);
-+ if (pci_get_slot(bus, PCI_DEVFN(slot->device,
-+ func->function)) == dev)
-+ return func;
-+ }
-+ return NULL;
-+}
-+
-+
-+
-+/** acpiphp_max_busnr - find the max reserved busnr for this bus
-+ * @bus: the bus to scan
-+ */
-+static unsigned char
-+acpiphp_max_busnr(struct pci_bus *bus)
-+{
-+ struct list_head *tmp;
-+ unsigned char max, n;
-+
-+ /*
-+ * pci_bus_max_busnr will return the highest
-+ * reserved busnr for all these children.
-+ * that is equivalent to the bus->subordinate
-+ * value. We don't want to use the parent's
-+ * bus->subordinate value because it could have
-+ * padding in it.
-+ */
-+ max = bus->secondary;
-+
-+ list_for_each(tmp, &bus->children) {
-+ n = pci_bus_max_busnr(pci_bus_b(tmp));
-+ if (n > max)
-+ max = n;
-+ }
-+ return max;
-+}
-+
-+
-+
-+
-+/**
- * enable_device - enable, configure a slot
- * @slot: slot to be enabled
- *
-@@ -788,7 +976,7 @@ static int enable_device(struct acpiphp_
- goto err_exit;
- }
-
-- max = bus->secondary;
-+ max = acpiphp_max_busnr(bus);
- for (pass = 0; pass < 2; pass++) {
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (PCI_SLOT(dev->devfn) != slot->device)
-@@ -796,8 +984,12 @@ static int enable_device(struct acpiphp_
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
- dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
- max = pci_scan_bridge(bus, dev, max, pass);
-- if (pass && dev->subordinate)
-+ if (pass && dev->subordinate) {
- pci_bus_size_bridges(dev->subordinate);
-+ func = get_func(slot, dev);
-+ if (func)
-+ acpiphp_bus_add(func);
-+ }
- }
- }
- }
-@@ -1231,6 +1423,11 @@ static void handle_hotplug_event_func(ac
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- /* request device eject */
-+ if (func->slot->flags & SLOT_DOCKING) {
-+ /* ignore if we are in the middle of docking */
-+ dbg("eject request in the middle of a dock\n");
-+ break;
-+ }
- dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
- if (!(acpiphp_disable_slot(func->slot)))
- acpiphp_eject_slot(func->slot);
diff --git a/pci/pci-hotplug-convert-semaphores-to-mutex.patch b/pci/pci-hotplug-convert-semaphores-to-mutex.patch
index a40cbb1b8fa9e..2cbbc23a6d7fd 100644
--- a/pci/pci-hotplug-convert-semaphores-to-mutex.patch
+++ b/pci/pci-hotplug-convert-semaphores-to-mutex.patch
@@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/pci/hotplug/acpiphp.h | 3 -
- drivers/pci/hotplug/acpiphp_glue.c | 16 +++---
+ drivers/pci/hotplug/acpiphp_glue.c | 12 ++--
drivers/pci/hotplug/cpqphp.h | 3 -
drivers/pci/hotplug/cpqphp_core.c | 14 ++---
drivers/pci/hotplug/cpqphp_ctrl.c | 56 ++++++++++-----------
@@ -34,7 +34,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/shpchp.h | 3 -
drivers/pci/hotplug/shpchp_ctrl.c | 98 ++++++++++++++++++-------------------
drivers/pci/hotplug/shpchp_hpc.c | 2
- 13 files changed, 145 insertions(+), 139 deletions(-)
+ 13 files changed, 143 insertions(+), 137 deletions(-)
--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h
+++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h
@@ -66,7 +66,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#include "../pci.h"
#include "pci_hotplug.h"
-@@ -214,7 +214,7 @@ register_slot(acpi_handle handle, u32 lv
+@@ -202,7 +202,7 @@ register_slot(acpi_handle handle, u32 lv
slot->device = device;
slot->sun = sun;
INIT_LIST_HEAD(&slot->funcs);
@@ -75,25 +75,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
slot->next = bridge->slots;
bridge->slots = slot;
-@@ -777,7 +777,7 @@ static void dock(void *data)
- struct acpiphp_func *func;
- struct acpiphp_slot *slot = data;
-
-- down(&slot->crit_sect);
-+ mutex_lock(&slot->crit_sect);
- list_for_each(l, &slot->funcs) {
- func = list_entry(l, struct acpiphp_func, sibling);
- if (func->flags & FUNC_HAS_DCK) {
-@@ -790,7 +790,7 @@ static void dock(void *data)
- }
- }
- slot->flags &= (~SLOT_DOCKING);
-- up(&slot->crit_sect);
-+ mutex_unlock(&slot->crit_sect);
- }
-
-
-@@ -1598,7 +1598,7 @@ int acpiphp_enable_slot(struct acpiphp_s
+@@ -1428,7 +1428,7 @@ int acpiphp_enable_slot(struct acpiphp_s
{
int retval;
@@ -102,7 +84,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* wake up all functions */
retval = power_on_slot(slot);
-@@ -1610,7 +1610,7 @@ int acpiphp_enable_slot(struct acpiphp_s
+@@ -1440,7 +1440,7 @@ int acpiphp_enable_slot(struct acpiphp_s
retval = enable_device(slot);
err_exit:
@@ -111,7 +93,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return retval;
}
-@@ -1621,7 +1621,7 @@ int acpiphp_disable_slot(struct acpiphp_
+@@ -1451,7 +1451,7 @@ int acpiphp_disable_slot(struct acpiphp_
{
int retval = 0;
@@ -120,7 +102,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
/* unconfigure all functions */
retval = disable_device(slot);
-@@ -1634,7 +1634,7 @@ int acpiphp_disable_slot(struct acpiphp_
+@@ -1464,7 +1464,7 @@ int acpiphp_disable_slot(struct acpiphp_
goto err_exit;
err_exit: