Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57b5918c authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d03abe58
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
/* must be set before including pci_clp.h */
#define PCI_BAR_COUNT	6

#include <linux/pci.h>
#include <asm-generic/pci.h>
#include <asm-generic/pci-dma-compat.h>
#include <asm/pci_clp.h>
@@ -137,6 +138,7 @@ int zpci_unregister_ioat(struct zpci_dev *, u8);
/* CLP */
int clp_scan_pci_devices(void);
int clp_rescan_pci_devices(void);
int clp_rescan_pci_devices_simple(void);
int clp_add_pci_device(u32, u32, int);
int clp_enable_fh(struct zpci_dev *, u8);
int clp_disable_fh(struct zpci_dev *);
@@ -145,9 +147,11 @@ int clp_disable_fh(struct zpci_dev *);
/* Error handling and recovery */
void zpci_event_error(void *);
void zpci_event_availability(void *);
void zpci_rescan(void);
#else /* CONFIG_PCI */
static inline void zpci_event_error(void *e) {}
static inline void zpci_event_availability(void *e) {}
static inline void zpci_rescan(void) {}
#endif /* CONFIG_PCI */

#ifdef CONFIG_HOTPLUG_PCI_S390
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <asm/ctl_reg.h>
#include <asm/ipl.h>
#include <asm/cio.h>
#include <asm/pci.h>

/*
 * References to section boundaries
@@ -219,4 +220,5 @@ void s390_early_resume(void)
{
	lgr_info_log();
	channel_subsystem_reinit();
	zpci_rescan();
}
+10 −5
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@

/* list of all detected zpci devices */
static LIST_HEAD(zpci_list);
static DEFINE_MUTEX(zpci_list_lock);
static DEFINE_SPINLOCK(zpci_list_lock);

static void zpci_enable_irq(struct irq_data *data);
static void zpci_disable_irq(struct irq_data *data);
@@ -88,14 +88,14 @@ struct zpci_dev *get_zdev_by_fid(u32 fid)
{
	struct zpci_dev *tmp, *zdev = NULL;

	mutex_lock(&zpci_list_lock);
	spin_lock(&zpci_list_lock);
	list_for_each_entry(tmp, &zpci_list, entry) {
		if (tmp->fid == fid) {
			zdev = tmp;
			break;
		}
	}
	mutex_unlock(&zpci_list_lock);
	spin_unlock(&zpci_list_lock);
	return zdev;
}

@@ -821,9 +821,9 @@ int zpci_create_device(struct zpci_dev *zdev)
	if (rc)
		goto out_disable;

	mutex_lock(&zpci_list_lock);
	spin_lock(&zpci_list_lock);
	list_add_tail(&zdev->entry, &zpci_list);
	mutex_unlock(&zpci_list_lock);
	spin_unlock(&zpci_list_lock);

	zpci_init_slot(zdev);

@@ -939,3 +939,8 @@ static int __init pci_base_init(void)
	return rc;
}
subsys_initcall_sync(pci_base_init);

void zpci_rescan(void)
{
	clp_rescan_pci_devices_simple();
}
+29 −0
Original line number Diff line number Diff line
@@ -319,6 +319,20 @@ static void __clp_rescan(struct clp_fh_list_entry *entry)
	}
}

static void __clp_update(struct clp_fh_list_entry *entry)
{
	struct zpci_dev *zdev;

	if (!entry->vendor_id)
		return;

	zdev = get_zdev_by_fid(entry->fid);
	if (!zdev)
		return;

	zdev->fh = entry->fh;
}

int clp_scan_pci_devices(void)
{
	struct clp_req_rsp_list_pci *rrb;
@@ -348,3 +362,18 @@ int clp_rescan_pci_devices(void)
	clp_free_block(rrb);
	return rc;
}

int clp_rescan_pci_devices_simple(void)
{
	struct clp_req_rsp_list_pci *rrb;
	int rc;

	rrb = clp_alloc_block(GFP_NOWAIT);
	if (!rrb)
		return -ENOMEM;

	rc = clp_list_pci(rrb, __clp_update);

	clp_free_block(rrb);
	return rc;
}