diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-08-29 13:40:01 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-30 02:57:20 -0400 |
commit | 57b5918c33a0797930c3791fb602a8a9d46ef80c (patch) | |
tree | 47e3a5b503e8551f130fb722fbf1ae281e6ed292 /arch | |
parent | d03abe5882cc4815bf98c0e01a1deafa4a5d6730 (diff) |
s390/pci: update function handle after resume from hibernate
Function handles may change while the system was in hibernation
use list pci functions and update the function handles.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/pci.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/suspend.c | 2 | ||||
-rw-r--r-- | arch/s390/pci/pci.c | 15 | ||||
-rw-r--r-- | arch/s390/pci/pci_clp.c | 29 |
4 files changed, 45 insertions, 5 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 4b2bbc1fdbe0..c290f13d1c47 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h | |||
@@ -6,6 +6,7 @@ | |||
6 | /* must be set before including pci_clp.h */ | 6 | /* must be set before including pci_clp.h */ |
7 | #define PCI_BAR_COUNT 6 | 7 | #define PCI_BAR_COUNT 6 |
8 | 8 | ||
9 | #include <linux/pci.h> | ||
9 | #include <asm-generic/pci.h> | 10 | #include <asm-generic/pci.h> |
10 | #include <asm-generic/pci-dma-compat.h> | 11 | #include <asm-generic/pci-dma-compat.h> |
11 | #include <asm/pci_clp.h> | 12 | #include <asm/pci_clp.h> |
@@ -137,6 +138,7 @@ int zpci_unregister_ioat(struct zpci_dev *, u8); | |||
137 | /* CLP */ | 138 | /* CLP */ |
138 | int clp_scan_pci_devices(void); | 139 | int clp_scan_pci_devices(void); |
139 | int clp_rescan_pci_devices(void); | 140 | int clp_rescan_pci_devices(void); |
141 | int clp_rescan_pci_devices_simple(void); | ||
140 | int clp_add_pci_device(u32, u32, int); | 142 | int clp_add_pci_device(u32, u32, int); |
141 | int clp_enable_fh(struct zpci_dev *, u8); | 143 | int clp_enable_fh(struct zpci_dev *, u8); |
142 | int clp_disable_fh(struct zpci_dev *); | 144 | int clp_disable_fh(struct zpci_dev *); |
@@ -145,9 +147,11 @@ int clp_disable_fh(struct zpci_dev *); | |||
145 | /* Error handling and recovery */ | 147 | /* Error handling and recovery */ |
146 | void zpci_event_error(void *); | 148 | void zpci_event_error(void *); |
147 | void zpci_event_availability(void *); | 149 | void zpci_event_availability(void *); |
150 | void zpci_rescan(void); | ||
148 | #else /* CONFIG_PCI */ | 151 | #else /* CONFIG_PCI */ |
149 | static inline void zpci_event_error(void *e) {} | 152 | static inline void zpci_event_error(void *e) {} |
150 | static inline void zpci_event_availability(void *e) {} | 153 | static inline void zpci_event_availability(void *e) {} |
154 | static inline void zpci_rescan(void) {} | ||
151 | #endif /* CONFIG_PCI */ | 155 | #endif /* CONFIG_PCI */ |
152 | 156 | ||
153 | #ifdef CONFIG_HOTPLUG_PCI_S390 | 157 | #ifdef CONFIG_HOTPLUG_PCI_S390 |
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index eebab9f83f1d..737bff38e3ee 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/ctl_reg.h> | 12 | #include <asm/ctl_reg.h> |
13 | #include <asm/ipl.h> | 13 | #include <asm/ipl.h> |
14 | #include <asm/cio.h> | 14 | #include <asm/cio.h> |
15 | #include <asm/pci.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * References to section boundaries | 18 | * References to section boundaries |
@@ -219,4 +220,5 @@ void s390_early_resume(void) | |||
219 | { | 220 | { |
220 | lgr_info_log(); | 221 | lgr_info_log(); |
221 | channel_subsystem_reinit(); | 222 | channel_subsystem_reinit(); |
223 | zpci_rescan(); | ||
222 | } | 224 | } |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index a7ed6685e7fb..f17a8343e360 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* list of all detected zpci devices */ | 47 | /* list of all detected zpci devices */ |
48 | static LIST_HEAD(zpci_list); | 48 | static LIST_HEAD(zpci_list); |
49 | static DEFINE_MUTEX(zpci_list_lock); | 49 | static DEFINE_SPINLOCK(zpci_list_lock); |
50 | 50 | ||
51 | static void zpci_enable_irq(struct irq_data *data); | 51 | static void zpci_enable_irq(struct irq_data *data); |
52 | static void zpci_disable_irq(struct irq_data *data); | 52 | static void zpci_disable_irq(struct irq_data *data); |
@@ -88,14 +88,14 @@ struct zpci_dev *get_zdev_by_fid(u32 fid) | |||
88 | { | 88 | { |
89 | struct zpci_dev *tmp, *zdev = NULL; | 89 | struct zpci_dev *tmp, *zdev = NULL; |
90 | 90 | ||
91 | mutex_lock(&zpci_list_lock); | 91 | spin_lock(&zpci_list_lock); |
92 | list_for_each_entry(tmp, &zpci_list, entry) { | 92 | list_for_each_entry(tmp, &zpci_list, entry) { |
93 | if (tmp->fid == fid) { | 93 | if (tmp->fid == fid) { |
94 | zdev = tmp; | 94 | zdev = tmp; |
95 | break; | 95 | break; |
96 | } | 96 | } |
97 | } | 97 | } |
98 | mutex_unlock(&zpci_list_lock); | 98 | spin_unlock(&zpci_list_lock); |
99 | return zdev; | 99 | return zdev; |
100 | } | 100 | } |
101 | 101 | ||
@@ -821,9 +821,9 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
821 | if (rc) | 821 | if (rc) |
822 | goto out_disable; | 822 | goto out_disable; |
823 | 823 | ||
824 | mutex_lock(&zpci_list_lock); | 824 | spin_lock(&zpci_list_lock); |
825 | list_add_tail(&zdev->entry, &zpci_list); | 825 | list_add_tail(&zdev->entry, &zpci_list); |
826 | mutex_unlock(&zpci_list_lock); | 826 | spin_unlock(&zpci_list_lock); |
827 | 827 | ||
828 | zpci_init_slot(zdev); | 828 | zpci_init_slot(zdev); |
829 | 829 | ||
@@ -939,3 +939,8 @@ out: | |||
939 | return rc; | 939 | return rc; |
940 | } | 940 | } |
941 | subsys_initcall_sync(pci_base_init); | 941 | subsys_initcall_sync(pci_base_init); |
942 | |||
943 | void zpci_rescan(void) | ||
944 | { | ||
945 | clp_rescan_pci_devices_simple(); | ||
946 | } | ||
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 3eaf63a6ecac..475563c3d1e4 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c | |||
@@ -319,6 +319,20 @@ static void __clp_rescan(struct clp_fh_list_entry *entry) | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | static void __clp_update(struct clp_fh_list_entry *entry) | ||
323 | { | ||
324 | struct zpci_dev *zdev; | ||
325 | |||
326 | if (!entry->vendor_id) | ||
327 | return; | ||
328 | |||
329 | zdev = get_zdev_by_fid(entry->fid); | ||
330 | if (!zdev) | ||
331 | return; | ||
332 | |||
333 | zdev->fh = entry->fh; | ||
334 | } | ||
335 | |||
322 | int clp_scan_pci_devices(void) | 336 | int clp_scan_pci_devices(void) |
323 | { | 337 | { |
324 | struct clp_req_rsp_list_pci *rrb; | 338 | struct clp_req_rsp_list_pci *rrb; |
@@ -348,3 +362,18 @@ int clp_rescan_pci_devices(void) | |||
348 | clp_free_block(rrb); | 362 | clp_free_block(rrb); |
349 | return rc; | 363 | return rc; |
350 | } | 364 | } |
365 | |||
366 | int clp_rescan_pci_devices_simple(void) | ||
367 | { | ||
368 | struct clp_req_rsp_list_pci *rrb; | ||
369 | int rc; | ||
370 | |||
371 | rrb = clp_alloc_block(GFP_NOWAIT); | ||
372 | if (!rrb) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | rc = clp_list_pci(rrb, __clp_update); | ||
376 | |||
377 | clp_free_block(rrb); | ||
378 | return rc; | ||
379 | } | ||