summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-11-29 17:35:47 +0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-30 20:47:25 +0400
commit7441b0627e2251370902305a204e1330a696ca04 (patch)
treed3a36466a8517f8b889b6f0037f15280e33302d4 /arch
parentcbc0dd1f856b52b59c2c73a477b6cb210c8c66ad (diff)
downloadlinux-7441b0627e2251370902305a204e1330a696ca04.tar.xz
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')
-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 {
enum pci_bus_speed max_bus_speed;
};
+struct pci_hp_callback_ops {
+ int (*create_slot) (struct zpci_dev *zdev);
+ void (*remove_slot) (struct zpci_dev *zdev);
+};
+
static inline bool zdev_enabled(struct zpci_dev *zdev)
{
return (zdev->fh & (1UL << 31)) ? true : false;
@@ -140,4 +145,10 @@ bool zpci_fid_present(u32);
int zpci_dma_init(void);
void zpci_dma_exit(void);
+/* Hotplug */
+extern struct mutex zpci_list_lock;
+extern struct list_head zpci_list;
+extern struct pci_hp_callback_ops hotplug_ops;
+extern unsigned int pci_probe;
+
#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);
void sclp_get_ipl_info(struct sclp_ipl_info *info);
bool sclp_has_linemode(void);
bool sclp_has_vt220(void);
+int sclp_pci_configure(u32 fid);
+int sclp_pci_deconfigure(u32 fid);
#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 @@
/* list of all detected zpci devices */
LIST_HEAD(zpci_list);
+EXPORT_SYMBOL_GPL(zpci_list);
DEFINE_MUTEX(zpci_list_lock);
+EXPORT_SYMBOL_GPL(zpci_list_lock);
+
+struct pci_hp_callback_ops hotplug_ops;
+EXPORT_SYMBOL_GPL(hotplug_ops);
static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
static DEFINE_SPINLOCK(zpci_domain_lock);
@@ -935,6 +940,8 @@ int zpci_create_device(struct zpci_dev *zdev)
mutex_lock(&zpci_list_lock);
list_add_tail(&zdev->entry, &zpci_list);
+ if (hotplug_ops.create_slot)
+ hotplug_ops.create_slot(zdev);
mutex_unlock(&zpci_list_lock);
if (zdev->state == ZPCI_FN_STATE_STANDBY)
@@ -948,6 +955,8 @@ int zpci_create_device(struct zpci_dev *zdev)
out_start:
mutex_lock(&zpci_list_lock);
list_del(&zdev->entry);
+ if (hotplug_ops.remove_slot)
+ hotplug_ops.remove_slot(zdev);
mutex_unlock(&zpci_list_lock);
out_bus:
zpci_free_domain(zdev);