aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-03-13 10:27:32 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-13 10:27:32 +0000
commit7371b8e3bf96f28003582afb5f76182b7a9c4062 (patch)
treef2780b6029998e080850e96e6e67ca4fe60fd51c /pci
parent1b558141db8b06c61edebaaf5e3394ed98540ac7 (diff)
downloadpatches-7371b8e3bf96f28003582afb5f76182b7a9c4062.tar.gz
refresh for 2.6.16-rc6
Diffstat (limited to 'pci')
-rw-r--r--pci/acpiphp-add-dock-event-handling.patch24
-rw-r--r--pci/altix-msi-support.patch386
-rw-r--r--pci/msi-vector-targeting-abstractions.patch520
-rw-r--r--pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch72
-rw-r--r--pci/pci-msi-save-restore-for-suspend-resume.patch200
-rw-r--r--pci/per-platform-ia64_-first-last-_device_vector-definitions.patch46
-rw-r--r--pci/shpchp-cleanup-check-command-status.patch142
-rw-r--r--pci/shpchp-event-handling-rework.patch414
8 files changed, 902 insertions, 902 deletions
diff --git a/pci/acpiphp-add-dock-event-handling.patch b/pci/acpiphp-add-dock-event-handling.patch
index 064b4d117ab57..1cbbeccd6ead0 100644
--- a/pci/acpiphp-add-dock-event-handling.patch
+++ b/pci/acpiphp-add-dock-event-handling.patch
@@ -33,6 +33,18 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/acpiphp_glue.c | 85 +++++--
5 files changed, 545 insertions(+), 24 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
@@ -161,6 +161,25 @@ struct acpiphp_attention_info
@@ -735,15 +747,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
{
struct acpiphp_func *func;
char objname[64];
---- 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 \
diff --git a/pci/altix-msi-support.patch b/pci/altix-msi-support.patch
index 59f99f217b937..fd92f3340f3ee 100644
--- a/pci/altix-msi-support.patch
+++ b/pci/altix-msi-support.patch
@@ -25,6 +25,199 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/asm-ia64/sn/tiocp.h | 3
11 files changed, 405 insertions(+), 118 deletions(-)
+--- gregkh-2.6.orig/arch/ia64/sn/kernel/io_init.c
++++ gregkh-2.6/arch/ia64/sn/kernel/io_init.c
+@@ -56,7 +56,7 @@ static int max_pcibus_number = 255; /* D
+ */
+
+ static dma_addr_t
+-sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size)
++sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
+ {
+ return 0;
+ }
+--- gregkh-2.6.orig/arch/ia64/sn/kernel/irq.c
++++ gregkh-2.6/arch/ia64/sn/kernel/irq.c
+@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct s
+
+ int sn_force_interrupt_flag = 1;
+ extern int sn_ioif_inited;
+-static struct list_head **sn_irq_lh;
++struct list_head **sn_irq_lh;
+ static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
+
+-static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
+- u64 sn_irq_info,
++u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
++ struct sn_irq_info *sn_irq_info,
+ int req_irq, nasid_t req_nasid,
+ int req_slice)
+ {
+@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t
+
+ SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
+ (u64) SAL_INTR_ALLOC, (u64) local_nasid,
+- (u64) local_widget, (u64) sn_irq_info, (u64) req_irq,
++ (u64) local_widget, __pa(sn_irq_info), (u64) req_irq,
+ (u64) req_nasid, (u64) req_slice);
++
+ return ret_stuff.status;
+ }
+
+-static inline void sn_intr_free(nasid_t local_nasid, int local_widget,
++void sn_intr_free(nasid_t local_nasid, int local_widget,
+ struct sn_irq_info *sn_irq_info)
+ {
+ struct ia64_sal_retval ret_stuff;
+@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq)
+
+ static void sn_irq_info_free(struct rcu_head *head);
+
+-static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
++struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info,
++ nasid_t nasid, int slice)
+ {
+- struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
+- int cpuid, cpuphys;
++ int vector;
++ int cpuphys;
++ int64_t bridge;
++ int local_widget, status;
++ nasid_t local_nasid;
++ struct sn_irq_info *new_irq_info;
++ struct sn_pcibus_provider *pci_provider;
+
+- cpuid = first_cpu(mask);
+- cpuphys = cpu_physical_id(cpuid);
++ new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
++ if (new_irq_info == NULL)
++ return NULL;
+
+- list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
+- sn_irq_lh[irq], list) {
+- u64 bridge;
+- int local_widget, status;
+- nasid_t local_nasid;
+- struct sn_irq_info *new_irq_info;
+- struct sn_pcibus_provider *pci_provider;
+-
+- new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
+- if (new_irq_info == NULL)
+- break;
+- memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
+-
+- bridge = (u64) new_irq_info->irq_bridge;
+- if (!bridge) {
+- kfree(new_irq_info);
+- break; /* irq is not a device interrupt */
+- }
++ memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
+
+- local_nasid = NASID_GET(bridge);
++ bridge = (u64) new_irq_info->irq_bridge;
++ if (!bridge) {
++ kfree(new_irq_info);
++ return NULL; /* irq is not a device interrupt */
++ }
+
+- if (local_nasid & 1)
+- local_widget = TIO_SWIN_WIDGETNUM(bridge);
+- else
+- local_widget = SWIN_WIDGETNUM(bridge);
+-
+- /* Free the old PROM new_irq_info structure */
+- sn_intr_free(local_nasid, local_widget, new_irq_info);
+- /* Update kernels new_irq_info with new target info */
+- unregister_intr_pda(new_irq_info);
+-
+- /* allocate a new PROM new_irq_info struct */
+- status = sn_intr_alloc(local_nasid, local_widget,
+- __pa(new_irq_info), irq,
+- cpuid_to_nasid(cpuid),
+- cpuid_to_slice(cpuid));
+-
+- /* SAL call failed */
+- if (status) {
+- kfree(new_irq_info);
+- break;
+- }
++ local_nasid = NASID_GET(bridge);
++
++ if (local_nasid & 1)
++ local_widget = TIO_SWIN_WIDGETNUM(bridge);
++ else
++ local_widget = SWIN_WIDGETNUM(bridge);
++
++ vector = sn_irq_info->irq_irq;
++ /* Free the old PROM new_irq_info structure */
++ sn_intr_free(local_nasid, local_widget, new_irq_info);
++ /* Update kernels new_irq_info with new target info */
++ unregister_intr_pda(new_irq_info);
++
++ /* allocate a new PROM new_irq_info struct */
++ status = sn_intr_alloc(local_nasid, local_widget,
++ new_irq_info, vector,
++ nasid, slice);
++
++ /* SAL call failed */
++ if (status) {
++ kfree(new_irq_info);
++ return NULL;
++ }
++
++ cpuphys = nasid_slice_to_cpuid(nasid, slice);
++ new_irq_info->irq_cpuid = cpuphys;
++ register_intr_pda(new_irq_info);
++
++ pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
+
+- new_irq_info->irq_cpuid = cpuid;
+- register_intr_pda(new_irq_info);
++ /*
++ * If this represents a line interrupt, target it. If it's
++ * an msi (irq_int_bit < 0), it's already targeted.
++ */
++ if (new_irq_info->irq_int_bit >= 0 &&
++ pci_provider && pci_provider->target_interrupt)
++ (pci_provider->target_interrupt)(new_irq_info);
+
+- pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
+- if (pci_provider && pci_provider->target_interrupt)
+- (pci_provider->target_interrupt)(new_irq_info);
+-
+- spin_lock(&sn_irq_info_lock);
+- list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
+- spin_unlock(&sn_irq_info_lock);
+- call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
++ spin_lock(&sn_irq_info_lock);
++ list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
++ spin_unlock(&sn_irq_info_lock);
++ call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
+
+ #ifdef CONFIG_SMP
+- set_irq_affinity_info((irq & 0xff), cpuphys, 0);
++ set_irq_affinity_info((vector & 0xff), cpuphys, 0);
+ #endif
+- }
++
++ return new_irq_info;
++}
++
++static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
++{
++ struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
++ nasid_t nasid;
++ int slice;
++
++ nasid = cpuid_to_nasid(first_cpu(mask));
++ slice = cpuid_to_slice(first_cpu(mask));
++
++ list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
++ sn_irq_lh[irq], list)
++ (void)sn_retarget_vector(sn_irq_info, nasid, slice);
+ }
+
+ struct hw_interrupt_type irq_type_sn = {
--- gregkh-2.6.orig/arch/ia64/sn/pci/msi.c
+++ gregkh-2.6/arch/ia64/sn/pci/msi.c
@@ -6,13 +6,205 @@
@@ -237,199 +430,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ msi_register(&sn_msi_ops);
+ return 0;
}
---- gregkh-2.6.orig/arch/ia64/sn/kernel/io_init.c
-+++ gregkh-2.6/arch/ia64/sn/kernel/io_init.c
-@@ -56,7 +56,7 @@ static int max_pcibus_number = 255; /* D
- */
-
- static dma_addr_t
--sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size)
-+sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
- {
- return 0;
- }
---- gregkh-2.6.orig/arch/ia64/sn/kernel/irq.c
-+++ gregkh-2.6/arch/ia64/sn/kernel/irq.c
-@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct s
-
- int sn_force_interrupt_flag = 1;
- extern int sn_ioif_inited;
--static struct list_head **sn_irq_lh;
-+struct list_head **sn_irq_lh;
- static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
-
--static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
-- u64 sn_irq_info,
-+u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
-+ struct sn_irq_info *sn_irq_info,
- int req_irq, nasid_t req_nasid,
- int req_slice)
- {
-@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t
-
- SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
- (u64) SAL_INTR_ALLOC, (u64) local_nasid,
-- (u64) local_widget, (u64) sn_irq_info, (u64) req_irq,
-+ (u64) local_widget, __pa(sn_irq_info), (u64) req_irq,
- (u64) req_nasid, (u64) req_slice);
-+
- return ret_stuff.status;
- }
-
--static inline void sn_intr_free(nasid_t local_nasid, int local_widget,
-+void sn_intr_free(nasid_t local_nasid, int local_widget,
- struct sn_irq_info *sn_irq_info)
- {
- struct ia64_sal_retval ret_stuff;
-@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq)
-
- static void sn_irq_info_free(struct rcu_head *head);
-
--static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
-+struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info,
-+ nasid_t nasid, int slice)
- {
-- struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
-- int cpuid, cpuphys;
-+ int vector;
-+ int cpuphys;
-+ int64_t bridge;
-+ int local_widget, status;
-+ nasid_t local_nasid;
-+ struct sn_irq_info *new_irq_info;
-+ struct sn_pcibus_provider *pci_provider;
-
-- cpuid = first_cpu(mask);
-- cpuphys = cpu_physical_id(cpuid);
-+ new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
-+ if (new_irq_info == NULL)
-+ return NULL;
-
-- list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
-- sn_irq_lh[irq], list) {
-- u64 bridge;
-- int local_widget, status;
-- nasid_t local_nasid;
-- struct sn_irq_info *new_irq_info;
-- struct sn_pcibus_provider *pci_provider;
--
-- new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
-- if (new_irq_info == NULL)
-- break;
-- memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
--
-- bridge = (u64) new_irq_info->irq_bridge;
-- if (!bridge) {
-- kfree(new_irq_info);
-- break; /* irq is not a device interrupt */
-- }
-+ memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
-
-- local_nasid = NASID_GET(bridge);
-+ bridge = (u64) new_irq_info->irq_bridge;
-+ if (!bridge) {
-+ kfree(new_irq_info);
-+ return NULL; /* irq is not a device interrupt */
-+ }
-
-- if (local_nasid & 1)
-- local_widget = TIO_SWIN_WIDGETNUM(bridge);
-- else
-- local_widget = SWIN_WIDGETNUM(bridge);
--
-- /* Free the old PROM new_irq_info structure */
-- sn_intr_free(local_nasid, local_widget, new_irq_info);
-- /* Update kernels new_irq_info with new target info */
-- unregister_intr_pda(new_irq_info);
--
-- /* allocate a new PROM new_irq_info struct */
-- status = sn_intr_alloc(local_nasid, local_widget,
-- __pa(new_irq_info), irq,
-- cpuid_to_nasid(cpuid),
-- cpuid_to_slice(cpuid));
--
-- /* SAL call failed */
-- if (status) {
-- kfree(new_irq_info);
-- break;
-- }
-+ local_nasid = NASID_GET(bridge);
-+
-+ if (local_nasid & 1)
-+ local_widget = TIO_SWIN_WIDGETNUM(bridge);
-+ else
-+ local_widget = SWIN_WIDGETNUM(bridge);
-+
-+ vector = sn_irq_info->irq_irq;
-+ /* Free the old PROM new_irq_info structure */
-+ sn_intr_free(local_nasid, local_widget, new_irq_info);
-+ /* Update kernels new_irq_info with new target info */
-+ unregister_intr_pda(new_irq_info);
-+
-+ /* allocate a new PROM new_irq_info struct */
-+ status = sn_intr_alloc(local_nasid, local_widget,
-+ new_irq_info, vector,
-+ nasid, slice);
-+
-+ /* SAL call failed */
-+ if (status) {
-+ kfree(new_irq_info);
-+ return NULL;
-+ }
-+
-+ cpuphys = nasid_slice_to_cpuid(nasid, slice);
-+ new_irq_info->irq_cpuid = cpuphys;
-+ register_intr_pda(new_irq_info);
-+
-+ pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
-
-- new_irq_info->irq_cpuid = cpuid;
-- register_intr_pda(new_irq_info);
-+ /*
-+ * If this represents a line interrupt, target it. If it's
-+ * an msi (irq_int_bit < 0), it's already targeted.
-+ */
-+ if (new_irq_info->irq_int_bit >= 0 &&
-+ pci_provider && pci_provider->target_interrupt)
-+ (pci_provider->target_interrupt)(new_irq_info);
-
-- pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
-- if (pci_provider && pci_provider->target_interrupt)
-- (pci_provider->target_interrupt)(new_irq_info);
--
-- spin_lock(&sn_irq_info_lock);
-- list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
-- spin_unlock(&sn_irq_info_lock);
-- call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
-+ spin_lock(&sn_irq_info_lock);
-+ list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
-+ spin_unlock(&sn_irq_info_lock);
-+ call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
-
- #ifdef CONFIG_SMP
-- set_irq_affinity_info((irq & 0xff), cpuphys, 0);
-+ set_irq_affinity_info((vector & 0xff), cpuphys, 0);
- #endif
-- }
-+
-+ return new_irq_info;
-+}
-+
-+static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
-+{
-+ struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
-+ nasid_t nasid;
-+ int slice;
-+
-+ nasid = cpuid_to_nasid(first_cpu(mask));
-+ slice = cpuid_to_slice(first_cpu(mask));
-+
-+ list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
-+ sn_irq_lh[irq], list)
-+ (void)sn_retarget_vector(sn_irq_info, nasid, slice);
- }
-
- struct hw_interrupt_type irq_type_sn = {
--- gregkh-2.6.orig/arch/ia64/sn/pci/pci_dma.c
+++ gregkh-2.6/arch/ia64/sn/pci/pci_dma.c
@@ -11,7 +11,7 @@
diff --git a/pci/msi-vector-targeting-abstractions.patch b/pci/msi-vector-targeting-abstractions.patch
index 9dba47ff61eb7..158129efa562e 100644
--- a/pci/msi-vector-targeting-abstractions.patch
+++ b/pci/msi-vector-targeting-abstractions.patch
@@ -28,6 +28,148 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/asm-x86_64/msi.h | 8 ++
12 files changed, 300 insertions(+), 129 deletions(-)
+--- gregkh-2.6.orig/arch/ia64/sn/pci/Makefile
++++ gregkh-2.6/arch/ia64/sn/pci/Makefile
+@@ -3,10 +3,11 @@
+ # License. See the file "COPYING" in the main directory of this archive
+ # for more details.
+ #
+-# Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
++# Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ #
+ # Makefile for the sn pci general routines.
+
+ CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
+ obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
++obj-$(CONFIG_PCI_MSI) += msi.o
+--- /dev/null
++++ gregkh-2.6/arch/ia64/sn/pci/msi.c
+@@ -0,0 +1,18 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
++ */
++
++#include <asm/errno.h>
++
++int
++sn_msi_init(void)
++{
++ /*
++ * return error until MSI is supported on altix platforms
++ */
++ return -EINVAL;
++}
+--- gregkh-2.6.orig/drivers/pci/Makefile
++++ gregkh-2.6/drivers/pci/Makefile
+@@ -26,7 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o
+ obj-$(CONFIG_PPC64) += setup-bus.o
+ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
+ obj-$(CONFIG_X86_VISWS) += setup-irq.o
+-obj-$(CONFIG_PCI_MSI) += msi.o
++obj-$(CONFIG_PCI_MSI) += msi.o msi-apic.o
+
+ #
+ # ACPI Related PCI FW Functions
+--- /dev/null
++++ gregkh-2.6/drivers/pci/msi-apic.c
+@@ -0,0 +1,92 @@
++/*
++ * MSI hooks for standard x86 apic
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
++ */
++
++#include <linux/pci.h>
++#include <linux/irq.h>
++
++#include "pci.h"
++#include "msi.h"
++
++/* Shifts for APIC-based data */
++#define MSI_DATA_VECTOR_SHIFT 0
++#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
++
++#define MSI_DATA_DELIVERY_SHIFT 8
++#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
++#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
++
++#define MSI_DATA_LEVEL_SHIFT 14
++#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
++#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
++
++#define MSI_DATA_TRIGGER_SHIFT 15
++#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
++#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
++
++/* Shift/mask fields for APIC-based bus address */
++#define MSI_ADDR_HEADER 0xfee00000
++
++#define MSI_ADDR_DESTID_MASK 0xfff0000f
++#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
++
++#define MSI_ADDR_DESTMODE_SHIFT 2
++#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
++#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
++
++#define MSI_ADDR_REDIRECTION_SHIFT 3
++#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
++#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
++
++
++static void msi_target_apic(unsigned int vector, unsigned int dest_cpu,
++ u32 *address_hi, u32 *address_lo)
++{
++ u32 addr = *address_lo;
++
++ addr &= MSI_ADDR_DESTID_MASK;
++ addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
++
++ *address_lo = addr;
++}
++
++static int msi_setup_apic(struct pci_dev *pdev, unsigned int vector,
++ u32 *address_hi, u32 *address_lo, u32 *data)
++{
++ unsigned long dest_phys_id;
++
++ dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
++
++ *address_hi = 0;
++ *address_lo = MSI_ADDR_HEADER |
++ MSI_ADDR_DESTMODE_PHYS |
++ MSI_ADDR_REDIRECTION_CPU |
++ MSI_ADDR_DESTID_CPU(dest_phys_id);
++
++ *data = MSI_DATA_TRIGGER_EDGE |
++ MSI_DATA_LEVEL_ASSERT |
++ MSI_DATA_DELIVERY_FIXED |
++ MSI_DATA_VECTOR(vector);
++
++ return 0;
++}
++
++static void msi_teardown_apic(unsigned int vector)
++{
++ return;
++}
++
++/*
++ * Generic ops used on most IA archs/platforms. Set with msi_register()
++ */
++struct msi_ops msi_apic_ops = {
++ .setup = msi_setup_apic,
++ .teardown = msi_teardown_apic,
++ .target = msi_target_apic,
++};
--- gregkh-2.6.orig/drivers/pci/msi.c
+++ gregkh-2.6/drivers/pci/msi.c
@@ -23,8 +23,6 @@
@@ -276,266 +418,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
spin_lock_irqsave(&msi_lock, flags);
entry = msi_desc[vector];
if (!entry || entry->dev != dev) {
---- gregkh-2.6.orig/include/asm-i386/msi.h
-+++ gregkh-2.6/include/asm-i386/msi.h
-@@ -12,4 +12,12 @@
- #define LAST_DEVICE_VECTOR 232
- #define MSI_TARGET_CPU_SHIFT 12
-
-+extern struct msi_ops msi_apic_ops;
-+
-+static inline int msi_arch_init(void)
-+{
-+ msi_register(&msi_apic_ops);
-+ return 0;
-+}
-+
- #endif /* ASM_MSI_H */
---- gregkh-2.6.orig/include/asm-x86_64/msi.h
-+++ gregkh-2.6/include/asm-x86_64/msi.h
-@@ -13,4 +13,12 @@
- #define LAST_DEVICE_VECTOR 232
- #define MSI_TARGET_CPU_SHIFT 12
-
-+extern struct msi_ops msi_apic_ops;
-+
-+static inline int msi_arch_init(void)
-+{
-+ msi_register(&msi_apic_ops);
-+ return 0;
-+}
-+
- #endif /* ASM_MSI_H */
---- gregkh-2.6.orig/include/asm-ia64/machvec.h
-+++ gregkh-2.6/include/asm-ia64/machvec.h
-@@ -74,6 +74,7 @@ typedef unsigned char ia64_mv_readb_rela
- typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
- typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
- typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
-+typedef int ia64_mv_msi_init_t (void);
-
- static inline void
- machvec_noop (void)
-@@ -146,6 +147,7 @@ extern void machvec_tlb_migrate_finish (
- # define platform_readw_relaxed ia64_mv.readw_relaxed
- # define platform_readl_relaxed ia64_mv.readl_relaxed
- # define platform_readq_relaxed ia64_mv.readq_relaxed
-+# define platform_msi_init ia64_mv.msi_init
- # endif
-
- /* __attribute__((__aligned__(16))) is required to make size of the
-@@ -194,6 +196,7 @@ struct ia64_machine_vector {
- ia64_mv_readw_relaxed_t *readw_relaxed;
- ia64_mv_readl_relaxed_t *readl_relaxed;
- ia64_mv_readq_relaxed_t *readq_relaxed;
-+ ia64_mv_msi_init_t *msi_init;
- } __attribute__((__aligned__(16))); /* align attrib? see above comment */
-
- #define MACHVEC_INIT(name) \
-@@ -238,6 +241,7 @@ struct ia64_machine_vector {
- platform_readw_relaxed, \
- platform_readl_relaxed, \
- platform_readq_relaxed, \
-+ platform_msi_init, \
- }
-
- extern struct ia64_machine_vector ia64_mv;
-@@ -386,5 +390,13 @@ extern ia64_mv_dma_supported swiotlb_dm
- #ifndef platform_readq_relaxed
- # define platform_readq_relaxed __ia64_readq_relaxed
- #endif
-+#ifndef platform_msi_init
-+#ifdef CONFIG_PCI_MSI
-+#include <asm/msi.h> /* pull in ia64_msi_init() */
-+# define platform_msi_init ia64_msi_init
-+#else
-+# define platform_msi_init NULL
-+#endif /* CONFIG_PCI_MSI */
-+#endif
-
- #endif /* _ASM_IA64_MACHVEC_H */
---- gregkh-2.6.orig/include/asm-ia64/machvec_sn2.h
-+++ gregkh-2.6/include/asm-ia64/machvec_sn2.h
-@@ -66,6 +66,7 @@ extern ia64_mv_dma_sync_single_for_devic
- extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
- extern ia64_mv_dma_mapping_error sn_dma_mapping_error;
- extern ia64_mv_dma_supported sn_dma_supported;
-+extern ia64_mv_msi_init_t sn_msi_init;
-
- /*
- * This stuff has dual use!
-@@ -115,6 +116,11 @@ extern ia64_mv_dma_supported sn_dma_sup
- #define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device
- #define platform_dma_mapping_error sn_dma_mapping_error
- #define platform_dma_supported sn_dma_supported
-+#ifdef CONFIG_PCI_MSI
-+#define platform_msi_init sn_msi_init
-+#else
-+#define platform_msi_init NULL
-+#endif
-
- #include <asm/sn/io.h>
-
---- gregkh-2.6.orig/include/asm-ia64/msi.h
-+++ gregkh-2.6/include/asm-ia64/msi.h
-@@ -14,4 +14,15 @@ static inline void set_intr_gate (int nr
- #define ack_APIC_irq ia64_eoi
- #define MSI_TARGET_CPU_SHIFT 4
-
-+extern struct msi_ops msi_apic_ops;
-+
-+/* default ia64 msi init routine */
-+static inline int ia64_msi_init(void)
-+{
-+ msi_register(&msi_apic_ops);
-+ return 0;
-+}
-+
-+#define msi_arch_init platform_msi_init /* in asm/machvec.h */
-+
- #endif /* ASM_MSI_H */
---- gregkh-2.6.orig/arch/ia64/sn/pci/Makefile
-+++ gregkh-2.6/arch/ia64/sn/pci/Makefile
-@@ -3,10 +3,11 @@
- # License. See the file "COPYING" in the main directory of this archive
- # for more details.
- #
--# Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
-+# Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
- #
- # Makefile for the sn pci general routines.
-
- CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
-
- obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
-+obj-$(CONFIG_PCI_MSI) += msi.o
---- /dev/null
-+++ gregkh-2.6/arch/ia64/sn/pci/msi.c
-@@ -0,0 +1,18 @@
-+/*
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
-+ */
-+
-+#include <asm/errno.h>
-+
-+int
-+sn_msi_init(void)
-+{
-+ /*
-+ * return error until MSI is supported on altix platforms
-+ */
-+ return -EINVAL;
-+}
---- gregkh-2.6.orig/drivers/pci/Makefile
-+++ gregkh-2.6/drivers/pci/Makefile
-@@ -26,7 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o
- obj-$(CONFIG_PPC64) += setup-bus.o
- obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
- obj-$(CONFIG_X86_VISWS) += setup-irq.o
--obj-$(CONFIG_PCI_MSI) += msi.o
-+obj-$(CONFIG_PCI_MSI) += msi.o msi-apic.o
-
- #
- # ACPI Related PCI FW Functions
---- /dev/null
-+++ gregkh-2.6/drivers/pci/msi-apic.c
-@@ -0,0 +1,92 @@
-+/*
-+ * MSI hooks for standard x86 apic
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
-+ */
-+
-+#include <linux/pci.h>
-+#include <linux/irq.h>
-+
-+#include "pci.h"
-+#include "msi.h"
-+
-+/* Shifts for APIC-based data */
-+#define MSI_DATA_VECTOR_SHIFT 0
-+#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
-+
-+#define MSI_DATA_DELIVERY_SHIFT 8
-+#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
-+#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
-+
-+#define MSI_DATA_LEVEL_SHIFT 14
-+#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
-+#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
-+
-+#define MSI_DATA_TRIGGER_SHIFT 15
-+#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
-+#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
-+
-+/* Shift/mask fields for APIC-based bus address */
-+#define MSI_ADDR_HEADER 0xfee00000
-+
-+#define MSI_ADDR_DESTID_MASK 0xfff0000f
-+#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
-+
-+#define MSI_ADDR_DESTMODE_SHIFT 2
-+#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
-+#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
-+
-+#define MSI_ADDR_REDIRECTION_SHIFT 3
-+#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
-+#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
-+
-+
-+static void msi_target_apic(unsigned int vector, unsigned int dest_cpu,
-+ u32 *address_hi, u32 *address_lo)
-+{
-+ u32 addr = *address_lo;
-+
-+ addr &= MSI_ADDR_DESTID_MASK;
-+ addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
-+
-+ *address_lo = addr;
-+}
-+
-+static int msi_setup_apic(struct pci_dev *pdev, unsigned int vector,
-+ u32 *address_hi, u32 *address_lo, u32 *data)
-+{
-+ unsigned long dest_phys_id;
-+
-+ dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
-+
-+ *address_hi = 0;
-+ *address_lo = MSI_ADDR_HEADER |
-+ MSI_ADDR_DESTMODE_PHYS |
-+ MSI_ADDR_REDIRECTION_CPU |
-+ MSI_ADDR_DESTID_CPU(dest_phys_id);
-+
-+ *data = MSI_DATA_TRIGGER_EDGE |
-+ MSI_DATA_LEVEL_ASSERT |
-+ MSI_DATA_DELIVERY_FIXED |
-+ MSI_DATA_VECTOR(vector);
-+
-+ return 0;
-+}
-+
-+static void msi_teardown_apic(unsigned int vector)
-+{
-+ return;
-+}
-+
-+/*
-+ * Generic ops used on most IA archs/platforms. Set with msi_register()
-+ */
-+struct msi_ops msi_apic_ops = {
-+ .setup = msi_setup_apic,
-+ .teardown = msi_teardown_apic,
-+ .target = msi_target_apic,
-+};
--- gregkh-2.6.orig/drivers/pci/msi.h
+++ gregkh-2.6/drivers/pci/msi.h
@@ -63,67 +63,6 @@ extern int pci_vector_resources(int last
@@ -693,3 +575,121 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#endif
extern int pcie_mch_quirk;
+--- gregkh-2.6.orig/include/asm-i386/msi.h
++++ gregkh-2.6/include/asm-i386/msi.h
+@@ -12,4 +12,12 @@
+ #define LAST_DEVICE_VECTOR 232
+ #define MSI_TARGET_CPU_SHIFT 12
+
++extern struct msi_ops msi_apic_ops;
++
++static inline int msi_arch_init(void)
++{
++ msi_register(&msi_apic_ops);
++ return 0;
++}
++
+ #endif /* ASM_MSI_H */
+--- gregkh-2.6.orig/include/asm-ia64/machvec.h
++++ gregkh-2.6/include/asm-ia64/machvec.h
+@@ -74,6 +74,7 @@ typedef unsigned char ia64_mv_readb_rela
+ typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
+ typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
+ typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
++typedef int ia64_mv_msi_init_t (void);
+
+ static inline void
+ machvec_noop (void)
+@@ -146,6 +147,7 @@ extern void machvec_tlb_migrate_finish (
+ # define platform_readw_relaxed ia64_mv.readw_relaxed
+ # define platform_readl_relaxed ia64_mv.readl_relaxed
+ # define platform_readq_relaxed ia64_mv.readq_relaxed
++# define platform_msi_init ia64_mv.msi_init
+ # endif
+
+ /* __attribute__((__aligned__(16))) is required to make size of the
+@@ -194,6 +196,7 @@ struct ia64_machine_vector {
+ ia64_mv_readw_relaxed_t *readw_relaxed;
+ ia64_mv_readl_relaxed_t *readl_relaxed;
+ ia64_mv_readq_relaxed_t *readq_relaxed;
++ ia64_mv_msi_init_t *msi_init;
+ } __attribute__((__aligned__(16))); /* align attrib? see above comment */
+
+ #define MACHVEC_INIT(name) \
+@@ -238,6 +241,7 @@ struct ia64_machine_vector {
+ platform_readw_relaxed, \
+ platform_readl_relaxed, \
+ platform_readq_relaxed, \
++ platform_msi_init, \
+ }
+
+ extern struct ia64_machine_vector ia64_mv;
+@@ -386,5 +390,13 @@ extern ia64_mv_dma_supported swiotlb_dm
+ #ifndef platform_readq_relaxed
+ # define platform_readq_relaxed __ia64_readq_relaxed
+ #endif
++#ifndef platform_msi_init
++#ifdef CONFIG_PCI_MSI
++#include <asm/msi.h> /* pull in ia64_msi_init() */
++# define platform_msi_init ia64_msi_init
++#else
++# define platform_msi_init NULL
++#endif /* CONFIG_PCI_MSI */
++#endif
+
+ #endif /* _ASM_IA64_MACHVEC_H */
+--- gregkh-2.6.orig/include/asm-ia64/machvec_sn2.h
++++ gregkh-2.6/include/asm-ia64/machvec_sn2.h
+@@ -66,6 +66,7 @@ extern ia64_mv_dma_sync_single_for_devic
+ extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
+ extern ia64_mv_dma_mapping_error sn_dma_mapping_error;
+ extern ia64_mv_dma_supported sn_dma_supported;
++extern ia64_mv_msi_init_t sn_msi_init;
+
+ /*
+ * This stuff has dual use!
+@@ -115,6 +116,11 @@ extern ia64_mv_dma_supported sn_dma_sup
+ #define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device
+ #define platform_dma_mapping_error sn_dma_mapping_error
+ #define platform_dma_supported sn_dma_supported
++#ifdef CONFIG_PCI_MSI
++#define platform_msi_init sn_msi_init
++#else
++#define platform_msi_init NULL
++#endif
+
+ #include <asm/sn/io.h>
+
+--- gregkh-2.6.orig/include/asm-ia64/msi.h
++++ gregkh-2.6/include/asm-ia64/msi.h
+@@ -14,4 +14,15 @@ static inline void set_intr_gate (int nr
+ #define ack_APIC_irq ia64_eoi
+ #define MSI_TARGET_CPU_SHIFT 4
+
++extern struct msi_ops msi_apic_ops;
++
++/* default ia64 msi init routine */
++static inline int ia64_msi_init(void)
++{
++ msi_register(&msi_apic_ops);
++ return 0;
++}
++
++#define msi_arch_init platform_msi_init /* in asm/machvec.h */
++
+ #endif /* ASM_MSI_H */
+--- gregkh-2.6.orig/include/asm-x86_64/msi.h
++++ gregkh-2.6/include/asm-x86_64/msi.h
+@@ -13,4 +13,12 @@
+ #define LAST_DEVICE_VECTOR 232
+ #define MSI_TARGET_CPU_SHIFT 12
+
++extern struct msi_ops msi_apic_ops;
++
++static inline int msi_arch_init(void)
++{
++ msi_register(&msi_apic_ops);
++ return 0;
++}
++
+ #endif /* ASM_MSI_H */
diff --git a/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch b/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch
index 6598904477ebb..28586405592ee 100644
--- a/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch
+++ b/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch
@@ -29,6 +29,14 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86_64/pci/Makefile | 3 ++-
7 files changed, 40 insertions(+), 23 deletions(-)
+--- gregkh-2.6.orig/arch/i386/pci/Makefile
++++ gregkh-2.6/arch/i386/pci/Makefile
+@@ -1,4 +1,4 @@
+-obj-y := i386.o
++obj-y := i386.o init.o
+
+ obj-$(CONFIG_PCI_BIOS) += pcbios.o
+ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
--- gregkh-2.6.orig/arch/i386/pci/direct.c
+++ gregkh-2.6/arch/i386/pci/direct.c
@@ -245,7 +245,7 @@ static int __init pci_check_type2(void)
@@ -77,6 +85,34 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
-
-arch_initcall(pci_direct_init);
+--- /dev/null
++++ gregkh-2.6/arch/i386/pci/init.c
+@@ -0,0 +1,25 @@
++#include <linux/config.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include "pci.h"
++
++/* arch_initcall has too random ordering, so call the initializers
++ in the right sequence from here. */
++static __init int pci_access_init(void)
++{
++#ifdef CONFIG_PCI_MMCONFIG
++ pci_mmcfg_init();
++#endif
++ if (raw_pci_ops)
++ return 0;
++#ifdef CONFIG_PCI_DIRECT
++ pci_direct_init();
++#endif
++ if (raw_pci_ops)
++ return 0;
++#ifdef CONFIG_PCI_BIOS
++ pci_pcbios_init();
++#endif
++ return 0;
++}
++arch_initcall(pci_access_init);
--- gregkh-2.6.orig/arch/i386/pci/mmconfig.c
+++ gregkh-2.6/arch/i386/pci/mmconfig.c
@@ -172,25 +172,20 @@ static __init void unreachable_devices(v
@@ -152,39 +188,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fixup-y += ../../i386/pci/fixup.o
i386-y += ../../i386/pci/i386.o
+init-y += ../../i386/pci/init.o
---- /dev/null
-+++ gregkh-2.6/arch/i386/pci/init.c
-@@ -0,0 +1,25 @@
-+#include <linux/config.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include "pci.h"
-+
-+/* arch_initcall has too random ordering, so call the initializers
-+ in the right sequence from here. */
-+static __init int pci_access_init(void)
-+{
-+#ifdef CONFIG_PCI_MMCONFIG
-+ pci_mmcfg_init();
-+#endif
-+ if (raw_pci_ops)
-+ return 0;
-+#ifdef CONFIG_PCI_DIRECT
-+ pci_direct_init();
-+#endif
-+ if (raw_pci_ops)
-+ return 0;
-+#ifdef CONFIG_PCI_BIOS
-+ pci_pcbios_init();
-+#endif
-+ return 0;
-+}
-+arch_initcall(pci_access_init);
---- gregkh-2.6.orig/arch/i386/pci/Makefile
-+++ gregkh-2.6/arch/i386/pci/Makefile
-@@ -1,4 +1,4 @@
--obj-y := i386.o
-+obj-y := i386.o init.o
-
- obj-$(CONFIG_PCI_BIOS) += pcbios.o
- obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
diff --git a/pci/pci-msi-save-restore-for-suspend-resume.patch b/pci/pci-msi-save-restore-for-suspend-resume.patch
index acf089517e216..0bb2d18c0ba47 100644
--- a/pci/pci-msi-save-restore-for-suspend-resume.patch
+++ b/pci/pci-msi-save-restore-for-suspend-resume.patch
@@ -17,106 +17,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/linux/pci.h | 31 ++++++
4 files changed, 282 insertions(+), 31 deletions(-)
---- gregkh-2.6.orig/include/linux/pci.h
-+++ gregkh-2.6/include/linux/pci.h
-@@ -100,6 +100,12 @@ enum pci_bus_flags {
- PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1,
- };
-
-+struct pci_cap_saved_state {
-+ struct hlist_node next;
-+ char cap_nr;
-+ u32 data[0];
-+};
-+
- /*
- * The pci_dev structure is used to describe PCI devices.
- */
-@@ -159,6 +165,7 @@ struct pci_dev {
- unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
-
- u32 saved_config_space[16]; /* config space saved at suspend time */
-+ struct hlist_head saved_cap_space;
- struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
- int rom_attr_enabled; /* has display of the rom attribute been enabled? */
- struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
-@@ -169,6 +176,30 @@ struct pci_dev {
- #define to_pci_dev(n) container_of(n, struct pci_dev, dev)
- #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
-
-+static inline struct pci_cap_saved_state *pci_find_saved_cap(
-+ struct pci_dev *pci_dev,char cap)
-+{
-+ struct pci_cap_saved_state *tmp;
-+ struct hlist_node *pos;
-+
-+ hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) {
-+ if (tmp->cap_nr == cap)
-+ return tmp;
-+ }
-+ return NULL;
-+}
-+
-+static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
-+ struct pci_cap_saved_state *new_cap)
-+{
-+ hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
-+}
-+
-+static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap)
-+{
-+ hlist_del(&cap->next);
-+}
-+
- /*
- * For PCI devices, the region numbers are assigned this way:
- *
---- gregkh-2.6.orig/drivers/pci/pci.h
-+++ gregkh-2.6/drivers/pci/pci.h
-@@ -57,6 +57,18 @@ static inline void disable_msi_mode(stru
- static inline int msi_register(struct msi_ops *ops) { return 0; }
- #endif
-
-+#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
-+int pci_save_msi_state(struct pci_dev *dev);
-+int pci_save_msix_state(struct pci_dev *dev);
-+int pci_restore_msi_state(struct pci_dev *dev);
-+int pci_restore_msix_state(struct pci_dev *dev);
-+#else
-+static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
-+static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
-+static inline int pci_restore_msi_state(struct pci_dev *dev) { return 0; }
-+static inline int pci_restore_msix_state(struct pci_dev *dev) { return 0; }
-+#endif
-+
- extern int pcie_mch_quirk;
- extern struct device_attribute pci_dev_attrs[];
- extern struct class_device_attribute class_device_attr_cpuaffinity;
---- gregkh-2.6.orig/drivers/pci/pci.c
-+++ gregkh-2.6/drivers/pci/pci.c
-@@ -444,6 +444,11 @@ pci_save_state(struct pci_dev *dev)
- /* XXX: 100% dword access ok here? */
- for (i = 0; i < 16; i++)
- pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
-+ if ((i = pci_save_msi_state(dev)) != 0)
-+ return i;
-+ if ((i = pci_save_msix_state(dev)) != 0)
-+ return i;
-+
- return 0;
- }
-
-@@ -458,6 +463,10 @@ pci_restore_state(struct pci_dev *dev)
-
- for (i = 0; i < 16; i++)
- pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
-+ if ((i = pci_restore_msi_state(dev)) != 0)
-+ return i;
-+ if ((i = pci_restore_msix_state(dev)) != 0)
-+ return i;
- return 0;
- }
-
--- gregkh-2.6.orig/drivers/pci/msi.c
+++ gregkh-2.6/drivers/pci/msi.c
@@ -514,6 +514,221 @@ void pci_scan_msi_device(struct pci_dev
@@ -415,3 +315,103 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
spin_unlock_irqrestore(&msi_lock, flags);
dev->irq = temp;
+--- gregkh-2.6.orig/drivers/pci/pci.c
++++ gregkh-2.6/drivers/pci/pci.c
+@@ -444,6 +444,11 @@ pci_save_state(struct pci_dev *dev)
+ /* XXX: 100% dword access ok here? */
+ for (i = 0; i < 16; i++)
+ pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
++ if ((i = pci_save_msi_state(dev)) != 0)
++ return i;
++ if ((i = pci_save_msix_state(dev)) != 0)
++ return i;
++
+ return 0;
+ }
+
+@@ -458,6 +463,10 @@ pci_restore_state(struct pci_dev *dev)
+
+ for (i = 0; i < 16; i++)
+ pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
++ if ((i = pci_restore_msi_state(dev)) != 0)
++ return i;
++ if ((i = pci_restore_msix_state(dev)) != 0)
++ return i;
+ return 0;
+ }
+
+--- gregkh-2.6.orig/drivers/pci/pci.h
++++ gregkh-2.6/drivers/pci/pci.h
+@@ -57,6 +57,18 @@ static inline void disable_msi_mode(stru
+ static inline int msi_register(struct msi_ops *ops) { return 0; }
+ #endif
+
++#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
++int pci_save_msi_state(struct pci_dev *dev);
++int pci_save_msix_state(struct pci_dev *dev);
++int pci_restore_msi_state(struct pci_dev *dev);
++int pci_restore_msix_state(struct pci_dev *dev);
++#else
++static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
++static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
++static inline int pci_restore_msi_state(struct pci_dev *dev) { return 0; }
++static inline int pci_restore_msix_state(struct pci_dev *dev) { return 0; }
++#endif
++
+ extern int pcie_mch_quirk;
+ extern struct device_attribute pci_dev_attrs[];
+ extern struct class_device_attribute class_device_attr_cpuaffinity;
+--- gregkh-2.6.orig/include/linux/pci.h
++++ gregkh-2.6/include/linux/pci.h
+@@ -100,6 +100,12 @@ enum pci_bus_flags {
+ PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1,
+ };
+
++struct pci_cap_saved_state {
++ struct hlist_node next;
++ char cap_nr;
++ u32 data[0];
++};
++
+ /*
+ * The pci_dev structure is used to describe PCI devices.
+ */
+@@ -159,6 +165,7 @@ struct pci_dev {
+ unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
+
+ u32 saved_config_space[16]; /* config space saved at suspend time */
++ struct hlist_head saved_cap_space;
+ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
+ int rom_attr_enabled; /* has display of the rom attribute been enabled? */
+ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
+@@ -169,6 +176,30 @@ struct pci_dev {
+ #define to_pci_dev(n) container_of(n, struct pci_dev, dev)
+ #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
+
++static inline struct pci_cap_saved_state *pci_find_saved_cap(
++ struct pci_dev *pci_dev,char cap)
++{
++ struct pci_cap_saved_state *tmp;
++ struct hlist_node *pos;
++
++ hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) {
++ if (tmp->cap_nr == cap)
++ return tmp;
++ }
++ return NULL;
++}
++
++static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
++ struct pci_cap_saved_state *new_cap)
++{
++ hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
++}
++
++static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap)
++{
++ hlist_del(&cap->next);
++}
++
+ /*
+ * For PCI devices, the region numbers are assigned this way:
+ *
diff --git a/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch b/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch
index 740294d42f32f..291d35ba08a51 100644
--- a/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch
+++ b/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch
@@ -96,6 +96,29 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
static inline void
+--- gregkh-2.6.orig/drivers/pci/msi.c
++++ gregkh-2.6/drivers/pci/msi.c
+@@ -35,7 +35,7 @@ static int nr_msix_devices;
+
+ #ifndef CONFIG_X86_IO_APIC
+ int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
+-u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
++u8 irq_vector[NR_IRQ_VECTORS];
+ #endif
+
+ static struct msi_ops *msi_ops;
+@@ -378,6 +378,11 @@ static int msi_init(void)
+ printk(KERN_WARNING "PCI: MSI cache init failed\n");
+ return status;
+ }
++
++#ifndef CONFIG_X86_IO_APIC
++ irq_vector[0] = FIRST_DEVICE_VECTOR;
++#endif
++
+ last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
+ if (last_alloc_vector < 0) {
+ pci_msi_enable = 0;
--- gregkh-2.6.orig/include/asm-ia64/hw_irq.h
+++ gregkh-2.6/include/asm-ia64/hw_irq.h
@@ -47,9 +47,19 @@ typedef u8 ia64_vector;
@@ -128,26 +151,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
---- gregkh-2.6.orig/drivers/pci/msi.c
-+++ gregkh-2.6/drivers/pci/msi.c
-@@ -35,7 +35,7 @@ static int nr_msix_devices;
-
- #ifndef CONFIG_X86_IO_APIC
- int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
--u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
-+u8 irq_vector[NR_IRQ_VECTORS];
- #endif
-
- static struct msi_ops *msi_ops;
-@@ -378,6 +378,11 @@ static int msi_init(void)
- printk(KERN_WARNING "PCI: MSI cache init failed\n");
- return status;
- }
-+
-+#ifndef CONFIG_X86_IO_APIC
-+ irq_vector[0] = FIRST_DEVICE_VECTOR;
-+#endif
-+
- last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
- if (last_alloc_vector < 0) {
- pci_msi_enable = 0;
diff --git a/pci/shpchp-cleanup-check-command-status.patch b/pci/shpchp-cleanup-check-command-status.patch
index d8a7a4e22b574..d54b3a7b52350 100644
--- a/pci/shpchp-cleanup-check-command-status.patch
+++ b/pci/shpchp-cleanup-check-command-status.patch
@@ -28,77 +28,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
-+++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
-@@ -231,6 +231,7 @@ static spinlock_t list_lock;
- static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
-
- static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
-+static int hpc_check_cmd_status(struct controller *ctrl);
-
- /* This is the interrupt polling timeout function. */
- static void int_poll_timeout(unsigned long lphp_ctlr)
-@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *s
- int i;
-
- DBG_ENTER_ROUTINE
--
-+
-+ mutex_lock(&slot->ctrl->cmd_lock);
-+
- if (!php_ctlr) {
- err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-- return -1;
-+ retval = -EINVAL;
-+ goto out;
- }
-
- for (i = 0; i < 10; i++) {
-@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *s
- if (cmd_status & 0x1) {
- /* After 1 sec and and the controller is still busy */
- err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
-- return -1;
-+ retval = -EBUSY;
-+ goto out;
- }
-
- ++t_slot;
-@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *s
- * Wait for command completion.
- */
- retval = shpc_wait_cmd(slot->ctrl);
-+ if (retval)
-+ goto out;
-+
-+ cmd_status = hpc_check_cmd_status(slot->ctrl);
-+ if (cmd_status) {
-+ err("%s: Failed to issued command 0x%x (error code = %d)\n",
-+ __FUNCTION__, cmd, cmd_status);
-+ retval = -EIO;
-+ }
-+ out:
-+ mutex_unlock(&slot->ctrl->cmd_lock);
-
- DBG_LEAVE_ROUTINE
- return retval;
-@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
- .green_led_blink = hpc_set_green_led_blink,
-
- .release_ctlr = hpc_release_ctlr,
-- .check_cmd_status = hpc_check_cmd_status,
- };
-
- inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
-@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl,
- dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
-
- mutex_init(&ctrl->crit_sect);
-+ mutex_init(&ctrl->cmd_lock);
-+
- /* Setup wait queue */
- init_waitqueue_head(&ctrl->queue);
-
--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c
+++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c
@@ -242,21 +242,10 @@ static int change_bus_speed(struct contr
@@ -346,3 +275,74 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
} else {
/* refresh notification */
if (p_slot)
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -231,6 +231,7 @@ static spinlock_t list_lock;
+ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
+
+ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
++static int hpc_check_cmd_status(struct controller *ctrl);
+
+ /* This is the interrupt polling timeout function. */
+ static void int_poll_timeout(unsigned long lphp_ctlr)
+@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *s
+ int i;
+
+ DBG_ENTER_ROUTINE
+-
++
++ mutex_lock(&slot->ctrl->cmd_lock);
++
+ if (!php_ctlr) {
+ err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
+- return -1;
++ retval = -EINVAL;
++ goto out;
+ }
+
+ for (i = 0; i < 10; i++) {
+@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *s
+ if (cmd_status & 0x1) {
+ /* After 1 sec and and the controller is still busy */
+ err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
+- return -1;
++ retval = -EBUSY;
++ goto out;
+ }
+
+ ++t_slot;
+@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *s
+ * Wait for command completion.
+ */
+ retval = shpc_wait_cmd(slot->ctrl);
++ if (retval)
++ goto out;
++
++ cmd_status = hpc_check_cmd_status(slot->ctrl);
++ if (cmd_status) {
++ err("%s: Failed to issued command 0x%x (error code = %d)\n",
++ __FUNCTION__, cmd, cmd_status);
++ retval = -EIO;
++ }
++ out:
++ mutex_unlock(&slot->ctrl->cmd_lock);
+
+ DBG_LEAVE_ROUTINE
+ return retval;
+@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
+ .green_led_blink = hpc_set_green_led_blink,
+
+ .release_ctlr = hpc_release_ctlr,
+- .check_cmd_status = hpc_check_cmd_status,
+ };
+
+ inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
+@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl,
+ dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+
+ mutex_init(&ctrl->crit_sect);
++ mutex_init(&ctrl->cmd_lock);
++
+ /* Setup wait queue */
+ init_waitqueue_head(&ctrl->queue);
+
diff --git a/pci/shpchp-event-handling-rework.patch b/pci/shpchp-event-handling-rework.patch
index c0668a6de18ed..670e496a23ff3 100644
--- a/pci/shpchp-event-handling-rework.patch
+++ b/pci/shpchp-event-handling-rework.patch
@@ -27,6 +27,213 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/shpchp_hpc.c | 10 +
4 files changed, 120 insertions(+), 267 deletions(-)
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h
++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h
+@@ -46,6 +46,7 @@
+ extern int shpchp_poll_mode;
+ extern int shpchp_poll_time;
+ extern int shpchp_debug;
++extern struct workqueue_struct *shpchp_wq;
+
+ /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
+ #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
+@@ -70,11 +71,13 @@ struct slot {
+ struct hotplug_slot *hotplug_slot;
+ struct list_head slot_list;
+ char name[SLOT_NAME_SIZE];
++ struct work_struct work; /* work for button event */
+ };
+
+ struct event_info {
+ u32 event_type;
+- u8 hp_slot;
++ struct slot *p_slot;
++ struct work_struct work;
+ };
+
+ struct controller {
+@@ -85,11 +88,9 @@ struct controller {
+ int num_slots; /* Number of slots on ctlr */
+ int slot_num_inc; /* 1 or -1 */
+ struct pci_dev *pci_dev;
+- struct event_info event_queue[10];
+ struct list_head slot_list;
+ struct hpc_ops *hpc_ops;
+ wait_queue_head_t queue; /* sleep & wake process */
+- u8 next_event;
+ u8 bus;
+ u8 device;
+ u8 function;
+@@ -180,9 +181,6 @@ struct hotplug_params {
+ /* sysfs functions for the hotplug controller info */
+ extern void shpchp_create_ctrl_files (struct controller *ctrl);
+
+-/* controller functions */
+-extern int shpchp_event_start_thread(void);
+-extern void shpchp_event_stop_thread(void);
+ extern int shpchp_enable_slot(struct slot *slot);
+ extern int shpchp_disable_slot(struct slot *slot);
+
+@@ -201,7 +199,8 @@ extern void get_hp_params_from_firmware(
+ extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
+ u32 *sun, u8 busnum, u8 devnum);
+ extern void shpchp_remove_ctrl_files(struct controller *ctrl);
+-
++extern void cleanup_slots(struct controller *ctrl);
++extern void shpchp_pushbutton_thread(void *data);
+
+ /* Global variables */
+ extern struct list_head shpchp_ctrl_list;
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c
+@@ -32,6 +32,7 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
++#include <linux/workqueue.h>
+ #include "shpchp.h"
+
+ /* Global variables */
+@@ -39,6 +40,7 @@ int shpchp_debug;
+ int shpchp_poll_mode;
+ int shpchp_poll_time;
+ LIST_HEAD(shpchp_ctrl_list);
++struct workqueue_struct *shpchp_wq;
+
+ #define DRIVER_VERSION "0.4"
+ #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
+@@ -57,7 +59,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Poll
+
+ #define SHPC_MODULE_NAME "shpchp"
+
+-static int shpc_start_thread (void);
+ static int set_attention_status (struct hotplug_slot *slot, u8 value);
+ static int enable_slot (struct hotplug_slot *slot);
+ static int disable_slot (struct hotplug_slot *slot);
+@@ -141,6 +142,7 @@ static int init_slots(struct controller
+ goto error_info;
+
+ slot->number = sun;
++ INIT_WORK(&slot->work, shpchp_pushbutton_thread, slot);
+
+ /* register this slot with the hotplug pci core */
+ hotplug_slot->private = slot;
+@@ -176,7 +178,7 @@ error:
+ return retval;
+ }
+
+-static void cleanup_slots(struct controller *ctrl)
++void cleanup_slots(struct controller *ctrl)
+ {
+ struct list_head *tmp;
+ struct list_head *next;
+@@ -185,6 +187,8 @@ static void cleanup_slots(struct control
+ list_for_each_safe(tmp, next, &ctrl->slot_list) {
+ slot = list_entry(tmp, struct slot, slot_list);
+ list_del(&slot->slot_list);
++ cancel_delayed_work(&slot->work);
++ flush_workqueue(shpchp_wq);
+ pci_hp_deregister(slot->hotplug_slot);
+ }
+ }
+@@ -400,7 +404,7 @@ static int shpc_probe(struct pci_dev *pd
+ rc = get_ctlr_slot_config(ctrl);
+ if (rc) {
+ err(msg_initialization_err, rc);
+- goto err_out_unmap_mmio_region;
++ goto err_out_release_ctlr;
+ }
+ first_device_num = ctrl->slot_device_offset;
+ num_ctlr_slots = ctrl->num_slots;
+@@ -411,7 +415,7 @@ static int shpc_probe(struct pci_dev *pd
+ rc = init_slots(ctrl);
+ if (rc) {
+ err(msg_initialization_err, 6);
+- goto err_out_free_ctrl_slot;
++ goto err_out_release_ctlr;
+ }
+
+ /* Now hpc_functions (slot->hpc_ops->functions) are ready */
+@@ -427,18 +431,13 @@ static int shpc_probe(struct pci_dev *pd
+ ctrl->speed = PCI_SPEED_33MHz;
+ }
+
+- /* Finish setting up the hot plug ctrl device */
+- ctrl->next_event = 0;
+-
+ list_add(&ctrl->ctrl_list, &shpchp_ctrl_list);
+
+ shpchp_create_ctrl_files(ctrl);
+
+ return 0;
+
+-err_out_free_ctrl_slot:
+- cleanup_slots(ctrl);
+-err_out_unmap_mmio_region:
++err_out_release_ctlr:
+ ctrl->hpc_ops->release_ctlr(ctrl);
+ err_out_free_ctrl:
+ kfree(ctrl);
+@@ -446,21 +445,6 @@ err_out_none:
+ return -ENODEV;
+ }
+
+-static int shpc_start_thread(void)
+-{
+- int retval = 0;
+-
+- dbg("Initialize + Start the notification/polling mechanism \n");
+-
+- retval = shpchp_event_start_thread();
+- if (retval) {
+- dbg("shpchp_event_start_thread() failed\n");
+- return retval;
+- }
+-
+- return retval;
+-}
+-
+ static void __exit unload_shpchpd(void)
+ {
+ struct list_head *tmp;
+@@ -470,14 +454,11 @@ static void __exit unload_shpchpd(void)
+ list_for_each_safe(tmp, next, &shpchp_ctrl_list) {
+ ctrl = list_entry(tmp, struct controller, ctrl_list);
+ shpchp_remove_ctrl_files(ctrl);
+- cleanup_slots(ctrl);
+ ctrl->hpc_ops->release_ctlr(ctrl);
+ kfree(ctrl);
+ }
+
+- /* Stop the notification mechanism */
+- shpchp_event_stop_thread();
+-
++ destroy_workqueue(shpchp_wq);
+ }
+
+ static struct pci_device_id shpcd_pci_tbl[] = {
+@@ -501,17 +482,15 @@ static int __init shpcd_init(void)
+ shpchp_poll_mode = 1;
+ #endif
+
+- retval = shpc_start_thread();
+- if (retval)
+- goto error_hpc_init;
++ shpchp_wq = create_singlethread_workqueue("shpchpd");
++ if (!shpchp_wq)
++ return -ENOMEM;
+
+ retval = pci_register_driver(&shpc_driver);
+ dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
+ info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+-
+-error_hpc_init:
+ if (retval) {
+- shpchp_event_stop_thread();
++ destroy_workqueue(shpchp_wq);
+ }
+ return retval;
+ }
--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c
+++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c
@@ -32,44 +32,46 @@
@@ -512,213 +719,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h
-+++ gregkh-2.6/drivers/pci/hotplug/shpchp.h
-@@ -46,6 +46,7 @@
- extern int shpchp_poll_mode;
- extern int shpchp_poll_time;
- extern int shpchp_debug;
-+extern struct workqueue_struct *shpchp_wq;
-
- /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
- #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
-@@ -70,11 +71,13 @@ struct slot {
- struct hotplug_slot *hotplug_slot;
- struct list_head slot_list;
- char name[SLOT_NAME_SIZE];
-+ struct work_struct work; /* work for button event */
- };
-
- struct event_info {
- u32 event_type;
-- u8 hp_slot;
-+ struct slot *p_slot;
-+ struct work_struct work;
- };
-
- struct controller {
-@@ -85,11 +88,9 @@ struct controller {
- int num_slots; /* Number of slots on ctlr */
- int slot_num_inc; /* 1 or -1 */
- struct pci_dev *pci_dev;
-- struct event_info event_queue[10];
- struct list_head slot_list;
- struct hpc_ops *hpc_ops;
- wait_queue_head_t queue; /* sleep & wake process */
-- u8 next_event;
- u8 bus;
- u8 device;
- u8 function;
-@@ -180,9 +181,6 @@ struct hotplug_params {
- /* sysfs functions for the hotplug controller info */
- extern void shpchp_create_ctrl_files (struct controller *ctrl);
-
--/* controller functions */
--extern int shpchp_event_start_thread(void);
--extern void shpchp_event_stop_thread(void);
- extern int shpchp_enable_slot(struct slot *slot);
- extern int shpchp_disable_slot(struct slot *slot);
-
-@@ -201,7 +199,8 @@ extern void get_hp_params_from_firmware(
- extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
- u32 *sun, u8 busnum, u8 devnum);
- extern void shpchp_remove_ctrl_files(struct controller *ctrl);
--
-+extern void cleanup_slots(struct controller *ctrl);
-+extern void shpchp_pushbutton_thread(void *data);
-
- /* Global variables */
- extern struct list_head shpchp_ctrl_list;
---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c
-+++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c
-@@ -32,6 +32,7 @@
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/pci.h>
-+#include <linux/workqueue.h>
- #include "shpchp.h"
-
- /* Global variables */
-@@ -39,6 +40,7 @@ int shpchp_debug;
- int shpchp_poll_mode;
- int shpchp_poll_time;
- LIST_HEAD(shpchp_ctrl_list);
-+struct workqueue_struct *shpchp_wq;
-
- #define DRIVER_VERSION "0.4"
- #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
-@@ -57,7 +59,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Poll
-
- #define SHPC_MODULE_NAME "shpchp"
-
--static int shpc_start_thread (void);
- static int set_attention_status (struct hotplug_slot *slot, u8 value);
- static int enable_slot (struct hotplug_slot *slot);
- static int disable_slot (struct hotplug_slot *slot);
-@@ -141,6 +142,7 @@ static int init_slots(struct controller
- goto error_info;
-
- slot->number = sun;
-+ INIT_WORK(&slot->work, shpchp_pushbutton_thread, slot);
-
- /* register this slot with the hotplug pci core */
- hotplug_slot->private = slot;
-@@ -176,7 +178,7 @@ error:
- return retval;
- }
-
--static void cleanup_slots(struct controller *ctrl)
-+void cleanup_slots(struct controller *ctrl)
- {
- struct list_head *tmp;
- struct list_head *next;
-@@ -185,6 +187,8 @@ static void cleanup_slots(struct control
- list_for_each_safe(tmp, next, &ctrl->slot_list) {
- slot = list_entry(tmp, struct slot, slot_list);
- list_del(&slot->slot_list);
-+ cancel_delayed_work(&slot->work);
-+ flush_workqueue(shpchp_wq);
- pci_hp_deregister(slot->hotplug_slot);
- }
- }
-@@ -400,7 +404,7 @@ static int shpc_probe(struct pci_dev *pd
- rc = get_ctlr_slot_config(ctrl);
- if (rc) {
- err(msg_initialization_err, rc);
-- goto err_out_unmap_mmio_region;
-+ goto err_out_release_ctlr;
- }
- first_device_num = ctrl->slot_device_offset;
- num_ctlr_slots = ctrl->num_slots;
-@@ -411,7 +415,7 @@ static int shpc_probe(struct pci_dev *pd
- rc = init_slots(ctrl);
- if (rc) {
- err(msg_initialization_err, 6);
-- goto err_out_free_ctrl_slot;
-+ goto err_out_release_ctlr;
- }
-
- /* Now hpc_functions (slot->hpc_ops->functions) are ready */
-@@ -427,18 +431,13 @@ static int shpc_probe(struct pci_dev *pd
- ctrl->speed = PCI_SPEED_33MHz;
- }
-
-- /* Finish setting up the hot plug ctrl device */
-- ctrl->next_event = 0;
--
- list_add(&ctrl->ctrl_list, &shpchp_ctrl_list);
-
- shpchp_create_ctrl_files(ctrl);
-
- return 0;
-
--err_out_free_ctrl_slot:
-- cleanup_slots(ctrl);
--err_out_unmap_mmio_region:
-+err_out_release_ctlr:
- ctrl->hpc_ops->release_ctlr(ctrl);
- err_out_free_ctrl:
- kfree(ctrl);
-@@ -446,21 +445,6 @@ err_out_none:
- return -ENODEV;
- }
-
--static int shpc_start_thread(void)
--{
-- int retval = 0;
--
-- dbg("Initialize + Start the notification/polling mechanism \n");
--
-- retval = shpchp_event_start_thread();
-- if (retval) {
-- dbg("shpchp_event_start_thread() failed\n");
-- return retval;
-- }
--
-- return retval;
--}
--
- static void __exit unload_shpchpd(void)
- {
- struct list_head *tmp;
-@@ -470,14 +454,11 @@ static void __exit unload_shpchpd(void)
- list_for_each_safe(tmp, next, &shpchp_ctrl_list) {
- ctrl = list_entry(tmp, struct controller, ctrl_list);
- shpchp_remove_ctrl_files(ctrl);
-- cleanup_slots(ctrl);
- ctrl->hpc_ops->release_ctlr(ctrl);
- kfree(ctrl);
- }
-
-- /* Stop the notification mechanism */
-- shpchp_event_stop_thread();
--
-+ destroy_workqueue(shpchp_wq);
- }
-
- static struct pci_device_id shpcd_pci_tbl[] = {
-@@ -501,17 +482,15 @@ static int __init shpcd_init(void)
- shpchp_poll_mode = 1;
- #endif
-
-- retval = shpc_start_thread();
-- if (retval)
-- goto error_hpc_init;
-+ shpchp_wq = create_singlethread_workqueue("shpchpd");
-+ if (!shpchp_wq)
-+ return -ENOMEM;
-
- retval = pci_register_driver(&shpc_driver);
- dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
--
--error_hpc_init:
- if (retval) {
-- shpchp_event_stop_thread();
-+ destroy_workqueue(shpchp_wq);
- }
- return retval;
- }
--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
+++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
@@ -813,6 +813,7 @@ static void hpc_release_ctlr(struct cont