diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2012-11-29 08:35:47 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-11-30 11:47:25 -0500 |
commit | 7441b0627e2251370902305a204e1330a696ca04 (patch) | |
tree | d3a36466a8517f8b889b6f0037f15280e33302d4 /arch/s390 | |
parent | cbc0dd1f856b52b59c2c73a477b6cb210c8c66ad (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.h | 11 | ||||
-rw-r--r-- | arch/s390/include/asm/sclp.h | 2 | ||||
-rw-r--r-- | arch/s390/pci/pci.c | 9 |
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 | ||
98 | struct pci_hp_callback_ops { | ||
99 | int (*create_slot) (struct zpci_dev *zdev); | ||
100 | void (*remove_slot) (struct zpci_dev *zdev); | ||
101 | }; | ||
102 | |||
98 | static inline bool zdev_enabled(struct zpci_dev *zdev) | 103 | static 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); | |||
140 | int zpci_dma_init(void); | 145 | int zpci_dma_init(void); |
141 | void zpci_dma_exit(void); | 146 | void zpci_dma_exit(void); |
142 | 147 | ||
148 | /* Hotplug */ | ||
149 | extern struct mutex zpci_list_lock; | ||
150 | extern struct list_head zpci_list; | ||
151 | extern struct pci_hp_callback_ops hotplug_ops; | ||
152 | extern 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); | |||
55 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | 55 | void sclp_get_ipl_info(struct sclp_ipl_info *info); |
56 | bool sclp_has_linemode(void); | 56 | bool sclp_has_linemode(void); |
57 | bool sclp_has_vt220(void); | 57 | bool sclp_has_vt220(void); |
58 | int sclp_pci_configure(u32 fid); | ||
59 | int 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 */ |
49 | LIST_HEAD(zpci_list); | 49 | LIST_HEAD(zpci_list); |
50 | EXPORT_SYMBOL_GPL(zpci_list); | ||
50 | DEFINE_MUTEX(zpci_list_lock); | 51 | DEFINE_MUTEX(zpci_list_lock); |
52 | EXPORT_SYMBOL_GPL(zpci_list_lock); | ||
53 | |||
54 | struct pci_hp_callback_ops hotplug_ops; | ||
55 | EXPORT_SYMBOL_GPL(hotplug_ops); | ||
51 | 56 | ||
52 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); | 57 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); |
53 | static DEFINE_SPINLOCK(zpci_domain_lock); | 58 | static 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) | |||
948 | out_start: | 955 | out_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); |
952 | out_bus: | 961 | out_bus: |
953 | zpci_free_domain(zdev); | 962 | zpci_free_domain(zdev); |