aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-11-29 08:35:47 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-30 11:47:25 -0500
commit7441b0627e2251370902305a204e1330a696ca04 (patch)
treed3a36466a8517f8b889b6f0037f15280e33302d4 /arch/s390
parentcbc0dd1f856b52b59c2c73a477b6cb210c8c66ad (diff)
s390/pci: PCI hotplug support via SCLP
Add SCLP PCI configure/deconfigure and implement a PCI hotplug controller (s390_pci_hpc). The hotplug controller creates a slot for every PCI function in stand-by or configured state. The PCI functions are named after the PCI function ID (fid). By writing to the power attribute in /sys/bus/pci/slots/<fid>/power the PCI function is moved to stand-by or configured state. If moved to the configured state the device is automatically scanned by the s390 PCI layer. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/pci.h11
-rw-r--r--arch/s390/include/asm/sclp.h2
-rw-r--r--arch/s390/pci/pci.c9
3 files changed, 22 insertions, 0 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index d3597dcfec33..48ce434d6fda 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -95,6 +95,11 @@ struct zpci_dev {
95 enum pci_bus_speed max_bus_speed; 95 enum pci_bus_speed max_bus_speed;
96}; 96};
97 97
98struct pci_hp_callback_ops {
99 int (*create_slot) (struct zpci_dev *zdev);
100 void (*remove_slot) (struct zpci_dev *zdev);
101};
102
98static inline bool zdev_enabled(struct zpci_dev *zdev) 103static inline bool zdev_enabled(struct zpci_dev *zdev)
99{ 104{
100 return (zdev->fh & (1UL << 31)) ? true : false; 105 return (zdev->fh & (1UL << 31)) ? true : false;
@@ -140,4 +145,10 @@ bool zpci_fid_present(u32);
140int zpci_dma_init(void); 145int zpci_dma_init(void);
141void zpci_dma_exit(void); 146void zpci_dma_exit(void);
142 147
148/* Hotplug */
149extern struct mutex zpci_list_lock;
150extern struct list_head zpci_list;
151extern struct pci_hp_callback_ops hotplug_ops;
152extern unsigned int pci_probe;
153
143#endif 154#endif
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index e62a555557ee..833788693f09 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -55,5 +55,7 @@ int sclp_chp_read_info(struct sclp_chp_info *info);
55void sclp_get_ipl_info(struct sclp_ipl_info *info); 55void sclp_get_ipl_info(struct sclp_ipl_info *info);
56bool sclp_has_linemode(void); 56bool sclp_has_linemode(void);
57bool sclp_has_vt220(void); 57bool sclp_has_vt220(void);
58int sclp_pci_configure(u32 fid);
59int sclp_pci_deconfigure(u32 fid);
58 60
59#endif /* _ASM_S390_SCLP_H */ 61#endif /* _ASM_S390_SCLP_H */
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 5a2ef9e75c97..c523594a6d45 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -47,7 +47,12 @@
47 47
48/* list of all detected zpci devices */ 48/* list of all detected zpci devices */
49LIST_HEAD(zpci_list); 49LIST_HEAD(zpci_list);
50EXPORT_SYMBOL_GPL(zpci_list);
50DEFINE_MUTEX(zpci_list_lock); 51DEFINE_MUTEX(zpci_list_lock);
52EXPORT_SYMBOL_GPL(zpci_list_lock);
53
54struct pci_hp_callback_ops hotplug_ops;
55EXPORT_SYMBOL_GPL(hotplug_ops);
51 56
52static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); 57static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
53static DEFINE_SPINLOCK(zpci_domain_lock); 58static DEFINE_SPINLOCK(zpci_domain_lock);
@@ -935,6 +940,8 @@ int zpci_create_device(struct zpci_dev *zdev)
935 940
936 mutex_lock(&zpci_list_lock); 941 mutex_lock(&zpci_list_lock);
937 list_add_tail(&zdev->entry, &zpci_list); 942 list_add_tail(&zdev->entry, &zpci_list);
943 if (hotplug_ops.create_slot)
944 hotplug_ops.create_slot(zdev);
938 mutex_unlock(&zpci_list_lock); 945 mutex_unlock(&zpci_list_lock);
939 946
940 if (zdev->state == ZPCI_FN_STATE_STANDBY) 947 if (zdev->state == ZPCI_FN_STATE_STANDBY)
@@ -948,6 +955,8 @@ int zpci_create_device(struct zpci_dev *zdev)
948out_start: 955out_start:
949 mutex_lock(&zpci_list_lock); 956 mutex_lock(&zpci_list_lock);
950 list_del(&zdev->entry); 957 list_del(&zdev->entry);
958 if (hotplug_ops.remove_slot)
959 hotplug_ops.remove_slot(zdev);
951 mutex_unlock(&zpci_list_lock); 960 mutex_unlock(&zpci_list_lock);
952out_bus: 961out_bus:
953 zpci_free_domain(zdev); 962 zpci_free_domain(zdev);