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

Commit 07bc9dc1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Ben Herrenschmidt:
 "Here is a series of powerpc fixes.  It's a bit big, mostly because of
  the series of 11 "EEH" patches from Gavin.  The EEH (Our IBM specific
  PCI/PCIe Enhanced Error Handling) code had been rotting for a while
  and this merge window saw a significant rework & fixing of it by Gavin
  Shan.

  However, that wasn't complete and left some open issues.  There were
  still a few corner cases that didn't work properly, for example in
  relation to hotplug and devices without explicit error handlers.  We
  had some patches but they weren't quite good enough yet so I left them
  off the 3.11 merge window.

  Gavin since then fixed it all up, we ran quite a few rounds of testing
  and it seems fairly solid (at least probably more than it has ever
  been).  This should probably have made -rc1 but both Gavin and I took
  some vacation so it had to wait for -rc2.

  The rest is more bug fixes, mostly to new features recently added, for
  example, we missed the cpu table entry for one of the two models of P8
  (we didn't realize they had different PVR [Processor Version Register]
  values), some module CRC issues, etc..."

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (23 commits)
  powerpc/perf: BHRB filter configuration should follow the task
  powerpc/perf: Ignore separate BHRB privilege state filter request
  powerpc/powernv: Mark pnv_pci_init_ioda2_phb() as __init
  powerpc/mm: Use the correct SLB(LLP) encoding in tlbie instruction
  powerpc/mm: Fix fallthrough bug in hpte_decode
  powerpc/pseries: Fix a typo in pSeries_lpar_hpte_insert()
  powerpc/eeh: Introdce flag to protect sysfs
  powerpc/eeh: Fix unbalanced enable for IRQ
  powerpc/eeh: Don't use pci_dev during BAR restore
  powerpc/eeh: Use partial hotplug for EEH unaware drivers
  powerpc/pci: Partial tree hotplug support
  powerpc/eeh: Use safe list traversal when walking EEH devices
  powerpc/eeh: Keep PE during hotplug
  powerpc/pci/hotplug: Don't need to remove from EEH cache twice
  powerpc/pci: Override pcibios_release_device()
  powerpc/eeh: Export functions for hotplug
  powerpc/eeh: Remove reference to PCI device
  powerpc: Fix the corrupt r3 error during MCE handling.
  powerpc/perf: Set PPC_FEATURE2_EBB when we register the power8 PMU
  powerpc/pseries: Drop "select HOTPLUG"
  ...
parents b48a97be ff3d79dc
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ struct device_node;
#define EEH_PE_RECOVERING	(1 << 1)	/* Recovering PE	*/
#define EEH_PE_PHB_DEAD		(1 << 2)	/* Dead PHB		*/

#define EEH_PE_KEEP		(1 << 8)	/* Keep PE on hotplug	*/

struct eeh_pe {
	int type;			/* PE type: PHB/Bus/Device	*/
	int state;			/* PE EEH dependent mode	*/
@@ -72,8 +74,8 @@ struct eeh_pe {
	struct list_head child;		/* Child PEs			*/
};

#define eeh_pe_for_each_dev(pe, edev) \
		list_for_each_entry(edev, &pe->edevs, list)
#define eeh_pe_for_each_dev(pe, edev, tmp) \
		list_for_each_entry_safe(edev, tmp, &pe->edevs, list)

/*
 * The struct is used to trace EEH state for the associated
@@ -82,7 +84,13 @@ struct eeh_pe {
 * another tree except the currently existing tree of PCI
 * buses and PCI devices
 */
#define EEH_DEV_IRQ_DISABLED	(1<<0)	/* Interrupt disabled		*/
#define EEH_DEV_BRIDGE		(1 << 0)	/* PCI bridge		*/
#define EEH_DEV_ROOT_PORT	(1 << 1)	/* PCIe root port	*/
#define EEH_DEV_DS_PORT		(1 << 2)	/* Downstream port	*/
#define EEH_DEV_IRQ_DISABLED	(1 << 3)	/* Interrupt disabled	*/
#define EEH_DEV_DISCONNECTED	(1 << 4)	/* Removing from PE	*/

#define EEH_DEV_SYSFS		(1 << 8)	/* Sysfs created        */

struct eeh_dev {
	int mode;			/* EEH mode			*/
@@ -90,11 +98,13 @@ struct eeh_dev {
	int config_addr;		/* Config address		*/
	int pe_config_addr;		/* PE config address		*/
	u32 config_space[16];		/* Saved PCI config space	*/
	u8 pcie_cap;			/* Saved PCIe capability	*/
	struct eeh_pe *pe;		/* Associated PE		*/
	struct list_head list;		/* Form link list in the PE	*/
	struct pci_controller *phb;	/* Associated PHB		*/
	struct device_node *dn;		/* Associated device node	*/
	struct pci_dev *pdev;		/* Associated PCI device	*/
	struct pci_bus *bus;		/* PCI bus for partial hotplug	*/
};

static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
@@ -193,8 +203,10 @@ int eeh_phb_pe_create(struct pci_controller *phb);
struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb);
struct eeh_pe *eeh_pe_get(struct eeh_dev *edev);
int eeh_add_to_parent_pe(struct eeh_dev *edev);
int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
void eeh_pe_update_time_stamp(struct eeh_pe *pe);
void *eeh_pe_traverse(struct eeh_pe *root,
		eeh_traverse_func fn, void *flag);
void *eeh_pe_dev_traverse(struct eeh_pe *root,
		eeh_traverse_func fn, void *flag);
void eeh_pe_restore_bars(struct eeh_pe *pe);
@@ -209,10 +221,12 @@ unsigned long eeh_check_failure(const volatile void __iomem *token,
				unsigned long val);
int eeh_dev_check_failure(struct eeh_dev *edev);
void eeh_addr_cache_build(void);
void eeh_add_device_early(struct device_node *);
void eeh_add_device_tree_early(struct device_node *);
void eeh_add_device_late(struct pci_dev *);
void eeh_add_device_tree_late(struct pci_bus *);
void eeh_add_sysfs_files(struct pci_bus *);
void eeh_remove_bus_device(struct pci_dev *, int);
void eeh_remove_device(struct pci_dev *);

/**
 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -252,13 +266,17 @@ static inline unsigned long eeh_check_failure(const volatile void __iomem *token

static inline void eeh_addr_cache_build(void) { }

static inline void eeh_add_device_early(struct device_node *dn) { }

static inline void eeh_add_device_tree_early(struct device_node *dn) { }

static inline void eeh_add_device_late(struct pci_dev *dev) { }

static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }

static inline void eeh_add_sysfs_files(struct pci_bus *bus) { }

static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { }
static inline void eeh_remove_device(struct pci_dev *dev) { }

#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
+4 −3
Original line number Diff line number Diff line
@@ -96,10 +96,11 @@ static inline bool arch_irqs_disabled(void)
#endif

#define hard_irq_disable()	do {			\
	u8 _was_enabled = get_paca()->soft_enabled;	\
	u8 _was_enabled;				\
	__hard_irq_disable();				\
	get_paca()->soft_enabled = 0;			\
	get_paca()->irq_happened |= PACA_IRQ_HARD_DIS;	\
	_was_enabled = local_paca->soft_enabled;	\
	local_paca->soft_enabled = 0;			\
	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;	\
	if (_was_enabled)				\
		trace_hardirqs_off();			\
} while(0)
+2 −3
Original line number Diff line number Diff line
@@ -82,10 +82,9 @@ struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
		   struct exception_table_entry *finish);

#ifdef CONFIG_MODVERSIONS
#if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64)
#define ARCH_RELOCATES_KCRCTAB

extern const unsigned long reloc_start[];
#define reloc_start PHYSICAL_START
#endif
#endif /* __KERNEL__ */
#endif	/* _ASM_POWERPC_MODULE_H */
+0 −1
Original line number Diff line number Diff line
@@ -209,7 +209,6 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);

/** Remove all of the PCI devices under this bus */
extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe);
extern void pcibios_remove_pci_devices(struct pci_bus *bus);

/** Discover new pci devices under this bus, and add them */
+2 −1
Original line number Diff line number Diff line
@@ -1088,7 +1088,8 @@
#define PVR_970MP	0x0044
#define PVR_970GX	0x0045
#define PVR_POWER7p	0x004A
#define PVR_POWER8	0x004B
#define PVR_POWER8E	0x004B
#define PVR_POWER8	0x004D
#define PVR_BE		0x0070
#define PVR_PA6T	0x0090

Loading