LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 06/11] powerpc/eeh: Tranverse EEH devices with safe mode
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

Currently, we're transversing EEH devices by list_for_each_entry().
That's not safe enough because the EEH devices might be removed from
its parent PE while doing iteration. The patch replaces that with
list_for_each_entry_safe().

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h |    4 ++--
 arch/powerpc/kernel/eeh.c      |    4 ++--
 arch/powerpc/kernel/eeh_pe.c   |   10 +++++-----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 2ce22d7..e8c411b 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -74,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
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index ce81477..56bd458 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -231,7 +231,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
 void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
 {
 	size_t loglen = 0;
-	struct eeh_dev *edev;
+	struct eeh_dev *edev, *tmp;
 	bool valid_cfg_log = true;
 
 	/*
@@ -251,7 +251,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
 		eeh_pe_restore_bars(pe);
 
 		pci_regs_buf[0] = 0;
-		eeh_pe_for_each_dev(pe, edev) {
+		eeh_pe_for_each_dev(pe, edev, tmp) {
 			loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen,
 						      EEH_PCI_REGS_LOG_LEN - loglen);
 		}
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 32ef409..c8b815e 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -176,7 +176,7 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,
 		eeh_traverse_func fn, void *flag)
 {
 	struct eeh_pe *pe;
-	struct eeh_dev *edev;
+	struct eeh_dev *edev, *tmp;
 	void *ret;
 
 	if (!root) {
@@ -186,7 +186,7 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,
 
 	/* Traverse root PE */
 	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
-		eeh_pe_for_each_dev(pe, edev) {
+		eeh_pe_for_each_dev(pe, edev, tmp) {
 			ret = fn(edev, flag);
 			if (ret)
 				return ret;
@@ -501,7 +501,7 @@ static void *__eeh_pe_state_mark(void *data, void *flag)
 {
 	struct eeh_pe *pe = (struct eeh_pe *)data;
 	int state = *((int *)flag);
-	struct eeh_dev *tmp;
+	struct eeh_dev *edev, *tmp;
 	struct pci_dev *pdev;
 
 	/*
@@ -511,8 +511,8 @@ static void *__eeh_pe_state_mark(void *data, void *flag)
 	 * the PCI device driver.
 	 */
 	pe->state |= state;
-	eeh_pe_for_each_dev(pe, tmp) {
-		pdev = eeh_dev_to_pci_dev(tmp);
+	eeh_pe_for_each_dev(pe, edev, tmp) {
+		pdev = eeh_dev_to_pci_dev(edev);
 		if (pdev)
 			pdev->error_state = pci_channel_io_frozen;
 	}
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 07/11] powerpc/pci: Partial hotplug support
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

When EEH error happens to one specific PE, the device drivers
of its attached EEH devices (PCI devices) are checked to see
the further action: reset with complete hotplug, or reset without
hotplug. However, that's not enough for those PCI devices whose
drivers can't support EEH, or those PCI devices without driver.
So we need do so-called "partial hotplug" on basis of PCI devices.
In the situation, part of PCI devices of the specific PE are
unplugged and plugged again after PE reset.

The patch changes pcibios_add_pci_devices() so that it can support
full hotplug and so-called "partial" hotplug based on device-tree
or real hardware. It's notable that pci_of_scan.c has been changed
for a bit in order to support the "partial" hotplug based on dev-tree.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/pci-common.c  |    2 +
 arch/powerpc/kernel/pci-hotplug.c |   14 ++++++---
 arch/powerpc/kernel/pci_of_scan.c |   56 ++++++++++++++++++++++++++----------
 3 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index f46914a..7d22a67 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1462,6 +1462,8 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
 	/* Allocate bus and devices resources */
 	pcibios_allocate_bus_resources(bus);
 	pcibios_claim_one_bus(bus);
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_assign_unassigned_bus_resources(bus);
 
 	/* Fixup EEH */
 	eeh_add_device_tree_late(bus);
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index fc0831d..62388a6 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
  */
 void pcibios_add_pci_devices(struct pci_bus * bus)
 {
-	int slotno, num, mode, pass, max;
+	int slotno, mode, pass, max;
 	struct pci_dev *dev;
 	struct device_node *dn = pci_bus_to_OF_node(bus);
 
@@ -85,11 +85,15 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
 		/* use ofdt-based probe */
 		of_rescan_bus(dn, bus);
 	} else if (mode == PCI_PROBE_NORMAL) {
-		/* use legacy probe */
+		/*
+		 * Use legacy probe. In the partial hotplug case, we
+		 * probably have indirect child devices unplugged. So
+		 * we don't check return value from pci_scan_slot() in
+		 * order for full-scan to pick up those indirect child
+		 * devices, which were removed during partial hotplug.
+		 */
 		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
-		num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-		if (!num)
-			return;
+		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
 		pcibios_setup_bus_devices(bus);
 		max = bus->busn_res.start;
 		for (pass = 0; pass < 2; pass++) {
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 6b0ba58..15d9105 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -230,11 +230,14 @@ void of_scan_pci_bridge(struct pci_dev *dev)
 		return;
 	}
 
-	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+	bus = pci_find_bus(pci_domain_nr(dev->bus), busrange[0]);
 	if (!bus) {
-		printk(KERN_ERR "Failed to create pci bus for %s\n",
-		       node->full_name);
-		return;
+		bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+		if (!bus) {
+			printk(KERN_ERR "Failed to create pci bus for %s\n",
+			       node->full_name);
+			return;
+		}
 	}
 
 	bus->primary = dev->bus->number;
@@ -292,6 +295,38 @@ void of_scan_pci_bridge(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(of_scan_pci_bridge);
 
+static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
+			    struct device_node *dn)
+{
+	struct pci_dev *dev = NULL;
+	const u32 *reg;
+	int reglen, devfn;
+
+	pr_debug("  * %s\n", dn->full_name);
+	if (!of_device_is_available(dn))
+		return NULL;
+
+	reg = of_get_property(dn, "reg", &reglen);
+	if (reg == NULL || reglen < 20)
+		return NULL;
+	devfn = (reg[0] >> 8) & 0xff;
+
+	/* Check if the PCI device is already there */
+	dev = pci_get_slot(bus, devfn);
+	if (dev) {
+		pci_dev_put(dev);
+		return dev;
+	}
+
+	/* create a new pci_dev for this device */
+	dev = of_create_pci_dev(dn, bus, devfn);
+	if (!dev)
+		return NULL;
+
+	pr_debug("  dev header type: %x\n", dev->hdr_type);
+	return dev;
+}
+
 /**
  * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices
  * @node: device tree node for the PCI bus
@@ -302,8 +337,6 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus,
 			  int rescan_existing)
 {
 	struct device_node *child;
-	const u32 *reg;
-	int reglen, devfn;
 	struct pci_dev *dev;
 
 	pr_debug("of_scan_bus(%s) bus no %d...\n",
@@ -311,16 +344,7 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus,
 
 	/* Scan direct children */
 	for_each_child_of_node(node, child) {
-		pr_debug("  * %s\n", child->full_name);
-		if (!of_device_is_available(child))
-			continue;
-		reg = of_get_property(child, "reg", &reglen);
-		if (reg == NULL || reglen < 20)
-			continue;
-		devfn = (reg[0] >> 8) & 0xff;
-
-		/* create a new pci_dev for this device */
-		dev = of_create_pci_dev(child, bus, devfn);
+		dev = of_scan_pci_dev(bus, child);
 		if (!dev)
 			continue;
 		pr_debug("    dev header type: %x\n", dev->hdr_type);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 01/11] powerpc/eeh: Remove reference to PCI device
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

We will rely on pcibios_release_device() to remove the EEH cache
and unbind EEH device for the specific PCI device. So we shouldn't
hold the reference to the PCI device from EEH cache and EEH device.
Otherwise, pcibios_release_device() won't be called as we expected.
The patch removes the reference to the PCI device in EEH core.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/eeh.c       |    4 ----
 arch/powerpc/kernel/eeh_cache.c |   18 +++++-------------
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 39954fe..b5c425e 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -499,8 +499,6 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
 	}
 
 	eeh_dev_check_failure(edev);
-
-	pci_dev_put(eeh_dev_to_pci_dev(edev));
 	return val;
 }
 
@@ -904,7 +902,6 @@ static void eeh_add_device_late(struct pci_dev *dev)
 	}
 	WARN_ON(edev->pdev);
 
-	pci_dev_get(dev);
 	edev->pdev = dev;
 	dev->dev.archdata.edev = edev;
 
@@ -992,7 +989,6 @@ static void eeh_remove_device(struct pci_dev *dev, int purge_pe)
 	}
 	edev->pdev = NULL;
 	dev->dev.archdata.edev = NULL;
-	pci_dev_put(dev);
 
 	eeh_rmv_from_parent_pe(edev, purge_pe);
 	eeh_addr_cache_rmv_dev(dev);
diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
index f9ac123..e8c9fd5 100644
--- a/arch/powerpc/kernel/eeh_cache.c
+++ b/arch/powerpc/kernel/eeh_cache.c
@@ -68,16 +68,12 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr)
 		struct pci_io_addr_range *piar;
 		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
 
-		if (addr < piar->addr_lo) {
+		if (addr < piar->addr_lo)
 			n = n->rb_left;
-		} else {
-			if (addr > piar->addr_hi) {
-				n = n->rb_right;
-			} else {
-				pci_dev_get(piar->pcidev);
-				return piar->edev;
-			}
-		}
+		else if (addr > piar->addr_hi)
+			n = n->rb_right;
+		else
+			return piar->edev;
 	}
 
 	return NULL;
@@ -156,7 +152,6 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
 	if (!piar)
 		return NULL;
 
-	pci_dev_get(dev);
 	piar->addr_lo = alo;
 	piar->addr_hi = ahi;
 	piar->edev = pci_dev_to_eeh_dev(dev);
@@ -250,7 +245,6 @@ restart:
 
 		if (piar->pcidev == dev) {
 			rb_erase(n, &pci_io_addr_cache_root.rb_root);
-			pci_dev_put(piar->pcidev);
 			kfree(piar);
 			goto restart;
 		}
@@ -302,12 +296,10 @@ void eeh_addr_cache_build(void)
 		if (!edev)
 			continue;
 
-		pci_dev_get(dev);  /* matching put is in eeh_remove_device() */
 		dev->dev.archdata.edev = edev;
 		edev->pdev = dev;
 
 		eeh_addr_cache_insert_dev(dev);
-
 		eeh_sysfs_add_device(dev);
 	}
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 02/11] powerpc/eeh: Export functions for hotplug
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

Make some functions public in order to support hotplug on either specific
PCI bus or PCI device in future.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h |    9 +++++++++
 arch/powerpc/kernel/eeh.c      |    6 +++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 09a8743..d9d35c2 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -209,9 +209,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_device(struct pci_dev *, int);
 void eeh_remove_bus_device(struct pci_dev *, int);
 
 /**
@@ -252,12 +255,18 @@ 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_device(struct pci_dev *dev, int purge_pe) { }
+
 static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { }
 
 #define EEH_POSSIBLE_ERROR(val, type) (0)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index b5c425e..582ad1e 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -836,7 +836,7 @@ core_initcall_sync(eeh_init);
  * on the CEC architecture, type of the device, on earlier boot
  * command-line arguments & etc.
  */
-static void eeh_add_device_early(struct device_node *dn)
+void eeh_add_device_early(struct device_node *dn)
 {
 	struct pci_controller *phb;
 
@@ -884,7 +884,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
  * This routine must be used to complete EEH initialization for PCI
  * devices that were added after system boot (e.g. hotplug, dlpar).
  */
-static void eeh_add_device_late(struct pci_dev *dev)
+void eeh_add_device_late(struct pci_dev *dev)
 {
 	struct device_node *dn;
 	struct eeh_dev *edev;
@@ -972,7 +972,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
  * this device will no longer be detected after this call; thus,
  * i/o errors affecting this slot may leave this device unusable.
  */
-static void eeh_remove_device(struct pci_dev *dev, int purge_pe)
+void eeh_remove_device(struct pci_dev *dev, int purge_pe)
 {
 	struct eeh_dev *edev;
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 05/11] powerpc/eeh: Keep PE during hotplug
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

When we do normal hotplug, the PE shouldn't be kept. However, we
need the PE if the hotplug caused by EEH errors. Since we remove
EEH device through the PCI hook pcibios_stop_dev(), the flag
"purge_pe" passed to various functions is meaningless. So the patch
removes the meaningless flag and introduce new flag "EEH_PE_KEEP"
to save the PE while doing hotplug during EEH error recovery.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h        |   11 +++++------
 arch/powerpc/include/asm/pci-bridge.h |    1 -
 arch/powerpc/kernel/eeh.c             |   28 ++--------------------------
 arch/powerpc/kernel/eeh_driver.c      |    7 +++++--
 arch/powerpc/kernel/eeh_pe.c          |    7 +++----
 arch/powerpc/kernel/pci-hotplug.c     |   26 +++++---------------------
 6 files changed, 20 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index d9d35c2..2ce22d7 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -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	*/
@@ -193,7 +195,7 @@ 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_dev_traverse(struct eeh_pe *root,
 		eeh_traverse_func fn, void *flag);
@@ -214,8 +216,7 @@ 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_device(struct pci_dev *, int);
-void eeh_remove_bus_device(struct pci_dev *, int);
+void eeh_remove_device(struct pci_dev *);
 
 /**
  * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -265,9 +266,7 @@ 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_device(struct pci_dev *dev, int purge_pe) { }
-
-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)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 2c1d8cb..32d0d20 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -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 */
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 582ad1e..ce81477 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -964,7 +964,6 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
 /**
  * eeh_remove_device - Undo EEH setup for the indicated pci device
  * @dev: pci device to be removed
- * @purge_pe: remove the PE or not
  *
  * This routine should be called when a device is removed from
  * a running system (e.g. by hotplug or dlpar).  It unregisters
@@ -972,7 +971,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
  * this device will no longer be detected after this call; thus,
  * i/o errors affecting this slot may leave this device unusable.
  */
-void eeh_remove_device(struct pci_dev *dev, int purge_pe)
+void eeh_remove_device(struct pci_dev *dev)
 {
 	struct eeh_dev *edev;
 
@@ -990,34 +989,11 @@ void eeh_remove_device(struct pci_dev *dev, int purge_pe)
 	edev->pdev = NULL;
 	dev->dev.archdata.edev = NULL;
 
-	eeh_rmv_from_parent_pe(edev, purge_pe);
+	eeh_rmv_from_parent_pe(edev);
 	eeh_addr_cache_rmv_dev(dev);
 	eeh_sysfs_remove_device(dev);
 }
 
-/**
- * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device
- * @dev: PCI device
- * @purge_pe: remove the corresponding PE or not
- *
- * This routine must be called when a device is removed from the
- * running system through hotplug or dlpar. The corresponding
- * PCI address cache will be removed.
- */
-void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe)
-{
-	struct pci_bus *bus = dev->subordinate;
-	struct pci_dev *child, *tmp;
-
-	eeh_remove_device(dev, purge_pe);
-
-	if (bus && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		list_for_each_entry_safe(child, tmp, &bus->devices, bus_list)
-			 eeh_remove_bus_device(child, purge_pe);
-	}
-}
-EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
-
 static int proc_eeh_show(struct seq_file *m, void *v)
 {
 	if (0 == eeh_subsystem_enabled) {
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 2b1ce17..9ef3bbb 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -362,8 +362,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
 	 * devices are expected to be attached soon when calling
 	 * into pcibios_add_pci_devices().
 	 */
-	if (bus)
-		__pcibios_remove_pci_devices(bus, 0);
+	if (bus) {
+		eeh_pe_state_mark(pe, EEH_PE_KEEP);
+		pcibios_remove_pci_devices(bus);
+	}
 
 	/* Reset the pci controller. (Asserts RST#; resets config space).
 	 * Reconfigure bridges and devices. Don't try to bring the system
@@ -386,6 +388,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
 	if (bus) {
 		ssleep(5);
 		pcibios_add_pci_devices(bus);
+		eeh_pe_state_clear(pe, EEH_PE_KEEP);
 	}
 
 	pe->tstamp = tstamp;
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 016588a..32ef409 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -333,7 +333,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 		while (parent) {
 			if (!(parent->type & EEH_PE_INVALID))
 				break;
-			parent->type &= ~EEH_PE_INVALID;
+			parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
 			parent = parent->parent;
 		}
 		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
@@ -397,14 +397,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 /**
  * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
  * @edev: EEH device
- * @purge_pe: remove PE or not
  *
  * The PE hierarchy tree might be changed when doing PCI hotplug.
  * Also, the PCI devices or buses could be removed from the system
  * during EEH recovery. So we have to call the function remove the
  * corresponding PE accordingly if necessary.
  */
-int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
 {
 	struct eeh_pe *pe, *parent, *child;
 	int cnt;
@@ -431,7 +430,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
 		if (pe->type & EEH_PE_PHB)
 			break;
 
-		if (purge_pe) {
+		if (!(pe->state & EEH_PE_KEEP)) {
 			if (list_empty(&pe->edevs) &&
 			    list_empty(&pe->child_list)) {
 				list_del(&pe->child);
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 3dab2f2..fc0831d 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -29,49 +29,33 @@
  */
 void pcibios_release_device(struct pci_dev *dev)
 {
-	eeh_remove_device(dev, 1);
+	eeh_remove_device(dev);
 }
 
 /**
- * __pcibios_remove_pci_devices - remove all devices under this bus
+ * pcibios_remove_pci_devices - remove all devices under this bus
  * @bus: the indicated PCI bus
- * @purge_pe: destroy the PE on removal of PCI devices
  *
  * Remove all of the PCI devices under this bus both from the
  * linux pci device tree, and from the powerpc EEH address cache.
- * By default, the corresponding PE will be destroied during the
- * normal PCI hotplug path. For PCI hotplug during EEH recovery,
- * the corresponding PE won't be destroied and deallocated.
  */
-void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe)
+void pcibios_remove_pci_devices(struct pci_bus *bus)
 {
 	struct pci_dev *dev, *tmp;
 	struct pci_bus *child_bus;
 
 	/* First go down child busses */
 	list_for_each_entry(child_bus, &bus->children, node)
-		__pcibios_remove_pci_devices(child_bus, purge_pe);
+		pcibios_remove_pci_devices(child_bus);
 
 	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
 		 pci_domain_nr(bus),  bus->number);
 	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
-		pr_debug("     * Removing %s...\n", pci_name(dev));
-		eeh_remove_bus_device(dev, purge_pe);
+		pr_debug("   Removing %s...\n", pci_name(dev));
 		pci_stop_and_remove_bus_device(dev);
 	}
 }
 
-/**
- * pcibios_remove_pci_devices - remove all devices under this bus
- * @bus: the indicated PCI bus
- *
- * Remove all of the PCI devices under this bus both from the
- * linux pci device tree, and from the powerpc EEH address cache.
- */
-void pcibios_remove_pci_devices(struct pci_bus *bus)
-{
-	__pcibios_remove_pci_devices(bus, 1);
-}
 EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
 
 /**
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 04/11] PCI/hotplug: Needn't remove EEH cache again
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Bjorn Helgaas, Gavin Shan
In-Reply-To: <1374632701-20972-1-git-send-email-shangw@linux.vnet.ibm.com>

Since pcibios_release_device() called by pci_stop_and_remove_bus_device()
has removed the EEH cache, we needn't do that again.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 drivers/pci/hotplug/rpadlpar_core.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index b29e20b..bb7af78 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -388,7 +388,6 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
 	/* Remove the EADS bridge device itself */
 	BUG_ON(!bus->self);
 	pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
-	eeh_remove_bus_device(bus->self, true);
 	pci_stop_and_remove_bus_device(bus->self);
 
 	return 0;
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH v4 0/11] EEH Followup Fixes (II)
From: Gavin Shan @ 2013-07-24  2:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

The series of patches bases on linux-poerpc-next initially and intends to resolve
the following problems:
 
	- On pSeries platform, the EEH doesn't work after PHB hotplug
	  with "drmgr". The root cause is that the EEH resources (
	  EEH devices, EEH caches) aren't released correctly. For the
	  problem, we add one hook (pcibios_stop_dev), which is called
	  on pci_stop_and_remove_device(). In pcibios_stop_dev(), we
	  release the EEH resources.
	- Another issue is that we need put the domain (PE or PHB) into
	  quite state while doing reset on that domain. However, some
	  deivces in the domain might not have EEH sensitive drivers, or
	  even don't have driver. Those deivces can't be put into quite
	  state and possibly keep issuing PCI-CFG or MMIO request during
	  resetting the domain. That possibly causes the failure of reset
	  and eventually failure of EEH recovery. For the issue, we introduces
	  so-called "partial hotplug". That means, those devices without driver or
	  without EEH sensitive driver are removed before doing reset, and
	  plugged (probed) into the system after reset.
	- We need traverse EEH devices of one specific PE with safe variant
	  of list tranverse function. The EEH device might be removed while
	  doing iteration.
	- When doing plug for PCI bus, we need check if we need reassign the
	  resources for subordinate devices (PCI_REASSIGN_ALL_RSRC) and do that
	  accordingly.

The patchset is verified on pSeires and PowerNV platforms:

pSeries Platform:

drmgr -c phb -r -s "PHB 513"
drmgr -c phb -a -s "PHB 513"
errinjct eeh -f 1 -s net/eth2

PowerNV Platform:

cd /sys/devices/pci0005:00/0005:00:00.0/0005:01:00.0/0005:02:08.0/0005:80:00.0/0005:90:01.0
while true; do od -x config > /dev/null; sleep 1; done
echo 1 > /sys/kernel/debug/powerpc/PCI0005/err_injct

---

v3 -> v4:
	* Add some comments to explain why we needn't check the return
	  value of pci_scan_slot() in pcibios_add_pci_devices().
	* Check PCI_PROBE_ONLY while assigning those unassigned resources
	  in pcibios_finish_adding_to_bus().
v2 -> v3:
	* Make pcibios_add_pci_devices() to support "partial" hotplug
	  according to Ben's comments. arch/powerpc/kernel/pci_of_scan.c
	  has been adjusted for that.
	* Use pcibios_add_pci_devices() to do "partial" hotplug inside
	  eeh_reset_device().
	* Introduce flag EEH_DEV_SYSFS to trace the state of sysfs entries
	  of the EEH device (then PCI device) to avoid race condition during
	  "partial" hotplug.
v1 -> v2:
	* Rebase to 3.11.rc1 in order to use pcibios_release_device().
	* Use pcibios_release_device() to release EEH cache and detach
	  EEH device from PCI device.
	* Remove reference to PCI device in EEH cache since we're relying
	  on pcibios_release_device().
	* PCI device instance (struct pci_dev) isn't available during BAR
	  restore and avoid use the instance that time.
	* Fix unbalanced enable for IRQ in eeh_driver.c
	* Retest the series of patches on Firebird-L/VPL3/VPL4

---

arch/powerpc/include/asm/eeh.h               |   30 ++++++++--
arch/powerpc/include/asm/pci-bridge.h        |    1 -
arch/powerpc/kernel/eeh.c                    |   70 +++++++++++------------
arch/powerpc/kernel/eeh_cache.c              |   18 ++----
arch/powerpc/kernel/eeh_driver.c             |   77 +++++++++++++++++++++++++-
arch/powerpc/kernel/eeh_pe.c                 |   58 ++++++++-----------
arch/powerpc/kernel/eeh_sysfs.c              |   21 +++++++
arch/powerpc/kernel/pci-common.c             |    2 +
arch/powerpc/kernel/pci-hotplug.c            |   49 ++++++++--------
arch/powerpc/kernel/pci_of_scan.c            |   56 +++++++++++++-----
arch/powerpc/platforms/powernv/eeh-powernv.c |   17 +++++-
arch/powerpc/platforms/pseries/eeh_pseries.c |   67 +++++++++++++++++++++-
drivers/pci/hotplug/rpadlpar_core.c          |    1 -
13 files changed, 327 insertions(+), 140 deletions(-)

Thanks,
Gavin

^ permalink raw reply

* RE: [PATCH 2/2] cpuidle: export cpuidle_idle_call symbol
From: Wang Dongsheng-B40534 @ 2013-07-24  2:17 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: daniel.lezcano@linaro.org, linuxppc-dev@lists.ozlabs.org,
	linux-pm@vger.kernel.org
In-Reply-To: <16375354.KJ7QhjYo9F@vostro.rjw.lan>

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogUmFmYWVsIEouIFd5c29j
a2kgW21haWx0bzpyandAc2lzay5wbF0NCj4gU2VudDogV2VkbmVzZGF5LCBKdWx5IDI0LCAyMDEz
IDU6MzMgQU0NCj4gVG86IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiBDYzogZGFuaWVsLmxlemNh
bm9AbGluYXJvLm9yZzsgbGludXgtcG1Admdlci5rZXJuZWwub3JnOyBsaW51eHBwYy0NCj4gZGV2
QGxpc3RzLm96bGFicy5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRDSCAyLzJdIGNwdWlkbGU6IGV4
cG9ydCBjcHVpZGxlX2lkbGVfY2FsbCBzeW1ib2wNCj4gDQo+IE9uIFR1ZXNkYXksIEp1bHkgMjMs
IDIwMTMgMDU6Mjg6MDEgUE0gRG9uZ3NoZW5nIFdhbmcgd3JvdGU6DQo+ID4gRnJvbTogV2FuZyBE
b25nc2hlbmcgPGRvbmdzaGVuZy53YW5nQGZyZWVzY2FsZS5jb20+DQo+ID4NCj4gPiBFeHBvcnQg
Y3B1aWRsZV9pZGxlX2NhbGwgc3ltYm9sLCBtYWtlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGludm9r
ZWQgaW4NCj4gPiB0aGUgbW9kdWxlLg0KPiANCj4gV2h5Pw0KPiANCk9uIHBvd2VycGMgcGxhdGZv
cm0sIHRoZXJlIGlzIGFscmVhZHkgaGF2ZSBjcHUgaWRsZSBpbXBsZW1lbnRhdGlvbi4NCg0KSSB3
YW50IHVzZSBjcHVpZGxlIGZyYW1ld29yayB0byBjb250cm9sIHZhcmlvdXMgbG93IHBvd2VyIG1v
ZGVzLiBCdXQgbmVlZCB0bw0KYmUgY29tcGF0aWJsZSB3aXRoIHRoZSBjdXJyZW50IGltcGxlbWVu
dGF0aW9uLiBBbmQgZHJpdmVyIHNob3VsZCBiZSBhcyBhIG1vZHVsZSwNClRoZSB1c2VyIGNhbiB1
c2luZyB0aGlzIG1vZHVsZSBhdCBhbnkgdGltZS4NCg0KV2UgbmVlZCBjcHVpZGxlX2lkbGVfY2Fs
bCB0byBkcml2ZSB0aGUgbmV3IGltcGxlbWVudGF0aW9uIGluIG1vZHVsZXMuDQoNClRoYW5rcy4N
Ci0gZG9uZ3NoZW5nDQoNCj4gUmFmYWVsDQoNCg0K

^ permalink raw reply

* Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
From: Chen Gang @ 2013-07-24  2:09 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linuxppc-dev@lists.ozlabs.org, Thomas Gleixner, paulus@samba.org,
	chenhui.zhao, Srivatsa S. Bhat
In-Reply-To: <20130724011640.GA6042@concordia>

On 07/24/2013 09:16 AM, Michael Ellerman wrote:
> On Wed, Jul 24, 2013 at 08:28:07AM +0800, Chen Gang wrote:
>> > On 07/23/2013 09:44 PM, Michael Ellerman wrote:
>>> > > On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote:
>>>> > >> On 07/22/2013 12:10 PM, Chen Gang wrote:
>>>>> > >>> Since not need 'max_cpus' after the related commit, the related code
>>>>> > >>> are useless too, need be removed.
>>>>> > >>>
>>>>> > >>> The related commit:
>>>>> > >>>
>>>>> > >>>   c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase
>>>>> > >>>
>>>>> > >>> The related warning:
>>>>> > >>>
>>>>> > >>>   arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter]
>>>>> > >>>
>>>>> > >>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
>>>> > >>
>>>> > >> This version looks good.
>>> > > 
>>> > > Agreed.
>>> > > 
>>> > > A good follow up patch, or actually series of patches, would be to
>>> > > change the prototype of smp_ops->probe() to return void, and fix all the
>>> > > implementations to no longer return anything.
>>> > > 
>> > 
>> > Hmm... normally, a function need have a return value, it will make it
>> > more extensible (especially, it is an API which need be implemented in
>> > various sub modules).
> A function doesn't need a return value, and if it needs one in future then
> we'll add it then. We don't carry code around "just in case".
> 

But for API (also include the internal API), at least, better to always
provide the return value which can indicate failure by negative number
(if succeed can return the meanness value, e.g. the number of cpus).


>> > Even though the return value may be useless, now, if the performance is
>> > not quite important in our case, I still suggest to have it (especially
>> > each various original implementation already has it).
> It's dead code, it should be removed.

For API, if not cause the real world issue, better to keep compatible
(especially, the return value still can indicate failure by negative
number).


Thanks.
-- 
Chen Gang

^ permalink raw reply

* [PATCH v2] powerpc/fsl-booke: Work around erratum A-006958
From: Scott Wood @ 2013-07-24  1:21 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, James Yang, Andy Fleming, Zhao Chenhui

Erratum A-006598 says that 64-bit mftb is not atomic -- it's subject
to a similar race condition as doing mftbu/mftbl on 32-bit.  The lower
half of timebase is updated before the upper half; thus, we can share
the workaround for a similar bug on Cell.  This workaround involves
looping if the lower half of timebase is zero, thus avoiding the need
for a scratch register (other than CR0).  This workaround must be
avoided when the timebase is frozen, such as during the timebase sync
code.

This deals with kernel and vdso accesses, but other userspace accesses
will of course need to be fixed elsewhere.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Cc: Zhao Chenhui <chenhui.zhao@freescale.com>
Cc: Andy Fleming <afleming@freescale.com>
Cc: James Yang <James.Yang@freescale.com>
---
v2: re-use the existing cell workaround

 arch/powerpc/include/asm/cputable.h |  9 +++++++--
 arch/powerpc/include/asm/ppc_asm.h  |  2 +-
 arch/powerpc/include/asm/reg.h      |  2 +-
 arch/powerpc/platforms/85xx/smp.c   | 23 +++++++++++++++++++++++
 4 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 6f3887d..0d4939b 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -371,14 +371,19 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_E500MC	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
 	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
 	    CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
+/*
+ * e5500/e6500 erratum A-006958 is a timebase bug that can use the
+ * same workaround as CPU_FTR_CELL_TB_BUG.
+ */
 #define CPU_FTRS_E5500	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
 	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
 	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
+	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_CELL_TB_BUG)
 #define CPU_FTRS_E6500	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
 	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
 	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP)
+	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \
+	    CPU_FTR_CELL_TB_BUG)
 #define CPU_FTRS_GENERIC_32	(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 2f1b6c5..fe713b6 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -443,7 +443,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
 #define ISYNC_601
 #endif
 
-#ifdef CONFIG_PPC_CELL
+#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E)
 #define MFTB(dest)			\
 90:	mftb  dest;			\
 BEGIN_FTR_SECTION_NESTED(96);		\
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 5d7d9c2..aa49fdb 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1116,7 +1116,7 @@
 				     : "memory")
 
 #ifdef __powerpc64__
-#ifdef CONFIG_PPC_CELL
+#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E)
 #define mftb()		({unsigned long rval;				\
 			asm volatile(					\
 				"90:	mftb %0;\n"			\
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 5ced4f5..f60eae2 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -69,7 +69,30 @@ static void mpc85xx_give_timebase(void)
 	tb_req = 0;
 
 	mpc85xx_timebase_freeze(1);
+#ifdef CONFIG_PPC64
+	/*
+	 * e5500/e6500 have a workaround for erratum A-006958 in place
+	 * that will reread the timebase until TBL is non-zero.
+	 * That would be a bad thing when the timebase is frozen.
+	 *
+	 * Thus, we read it manually, and instead of checking that
+	 * TBL is non-zero, we ensure that TB does not change.  We don't
+	 * do that for the main mftb implementation, because it requires
+	 * a scratch register
+	 */
+	{
+		u64 prev;
+
+		asm volatile("mftb %0" : "=r" (timebase));
+
+		do {
+			prev = timebase;
+			asm volatile("mftb %0" : "=r" (timebase));
+		} while (prev != timebase);
+	}
+#else
 	timebase = get_tb();
+#endif
 	mb();
 	tb_valid = 1;
 
-- 
1.8.1.2

^ permalink raw reply related

* Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
From: Michael Ellerman @ 2013-07-24  1:16 UTC (permalink / raw)
  To: Chen Gang
  Cc: linuxppc-dev@lists.ozlabs.org, Thomas Gleixner, paulus@samba.org,
	chenhui.zhao, Srivatsa S. Bhat
In-Reply-To: <51EF1F97.3070409@asianux.com>

On Wed, Jul 24, 2013 at 08:28:07AM +0800, Chen Gang wrote:
> On 07/23/2013 09:44 PM, Michael Ellerman wrote:
> > On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote:
> >> On 07/22/2013 12:10 PM, Chen Gang wrote:
> >>> Since not need 'max_cpus' after the related commit, the related code
> >>> are useless too, need be removed.
> >>>
> >>> The related commit:
> >>>
> >>>   c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase
> >>>
> >>> The related warning:
> >>>
> >>>   arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter]
> >>>
> >>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
> >>
> >> This version looks good.
> > 
> > Agreed.
> > 
> > A good follow up patch, or actually series of patches, would be to
> > change the prototype of smp_ops->probe() to return void, and fix all the
> > implementations to no longer return anything.
> > 
> 
> Hmm... normally, a function need have a return value, it will make it
> more extensible (especially, it is an API which need be implemented in
> various sub modules).

A function doesn't need a return value, and if it needs one in future then
we'll add it then. We don't carry code around "just in case".

> Even though the return value may be useless, now, if the performance is
> not quite important in our case, I still suggest to have it (especially
> each various original implementation already has it).

It's dead code, it should be removed.

cheers

^ permalink raw reply

* [PATCH 1/2 V2] Powerpc: Add voltage support in dts file
From: Haijun Zhang @ 2013-07-23 23:53 UTC (permalink / raw)
  To: linux-mmc, linuxppc-dev
  Cc: scottwood, cjb, AFLEMING, Haijun Zhang, cbouatmailru

eSDHC of T4240 had 1.8v voltage support. Add this node to specify
eSDHC voltage capacity. If this node not specified eSDHC driver
still can read from eSDHC host capacity register.

Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
---
changes for v2:
	- rewrite the voltage-ranges description

 Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | 4 ++++
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi         | 1 +
 2 files changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
index bd9be0b..b7943f3 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
@@ -19,6 +19,9 @@ Optional properties:
     "bus-width = <1>" property.
   - sdhci,auto-cmd12: specifies that a controller can only handle auto
     CMD12.
+  - voltage-ranges : two cells are required, first cell specifies minimum
+    slot voltage (mV), second cell specifies maximum slot voltage (mV).
+    Several ranges could be specified.
 
 Example:
 
@@ -29,4 +32,5 @@ sdhci@2e000 {
 	interrupt-parent = <&ipic>;
 	/* Filled in by U-Boot */
 	clock-frequency = <0>;
+	voltage-ranges = <3300 3300>;
 };
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index bd611a9..567d0fb 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -399,6 +399,7 @@
 	sdhc@114000 {
 		compatible = "fsl,t4240-esdhc", "fsl,esdhc";
 		sdhci,auto-cmd12;
+		voltage-ranges = <1800 1800>;
 	};
 /include/ "qoriq-i2c-0.dtsi"
 /include/ "qoriq-i2c-1.dtsi"
-- 
1.8.0

^ permalink raw reply related

* Re: [Suggestion] powerpc: xmon: about 'longjmp' related warning.
From: Chen Gang @ 2013-07-24  0:38 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Michael Neuling, paulus@samba.org, Andrew Morton,
	linuxppc-dev@lists.ozlabs.org, jovi.zhangwei
In-Reply-To: <20130723135809.GG31944@concordia>

On 07/23/2013 09:58 PM, Michael Ellerman wrote:
> On Mon, Jul 22, 2013 at 03:02:53PM +0800, Chen Gang wrote:
>> Hello Maintainers:
>>
>> With allmodconfig and EXTRA_CFLAGS=-W", it reports warnings below:
> 
>>
>> arch/powerpc/xmon/xmon.c:3027:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
>> arch/powerpc/xmon/xmon.c:3068:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
> 
> In both these cases we are inside the body of a for loop and we do a
> if (setjmp) / else block. Although looking at the source the value of i
> is not modified by the setjmp, I guess it's possible that the compiler
> might reorder the increment of i inside the setjmp and loose the value
> when we longjmp.
> 

I should continue to confirm the details based on your valuable
information, thanks.


>> arch/powerpc/xmon/xmon.c:352:48: warning: argument ‘fromipi’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
> 
> This one I can't see, but I assume it's a similar case.
> 

OK, I should continue for it.


>> Excuse me, I am not quite sure about it whether can cause issue or not.
> 
> I've never seen it get stuck in those loops or anything, but I guess
> it's possible.
> 

OK, I should make the confirmation.

> The first thing to do would be to analyse the generated assembler code
> to determine if there really is any possiblity of the value being
> clobbered, or if it's just a theoretical bug.
>

Thank you for your valuable information again.

Excuse me, I have to do another things within this month, so I should
provide the confirmation within next month (2013-08-31), is it OK (no
reply means OK).

Welcome any suggestions or completions.


Thanks.
-- 
Chen Gang

^ permalink raw reply

* Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
From: Chen Gang @ 2013-07-24  0:28 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linuxppc-dev@lists.ozlabs.org, Thomas Gleixner, paulus@samba.org,
	chenhui.zhao, Srivatsa S. Bhat
In-Reply-To: <20130723134431.GF31944@concordia>

On 07/23/2013 09:44 PM, Michael Ellerman wrote:
> On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote:
>> On 07/22/2013 12:10 PM, Chen Gang wrote:
>>> Since not need 'max_cpus' after the related commit, the related code
>>> are useless too, need be removed.
>>>
>>> The related commit:
>>>
>>>   c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase
>>>
>>> The related warning:
>>>
>>>   arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter]
>>>
>>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
>>
>> This version looks good.
> 
> Agreed.
> 
> A good follow up patch, or actually series of patches, would be to
> change the prototype of smp_ops->probe() to return void, and fix all the
> implementations to no longer return anything.
> 

Hmm... normally, a function need have a return value, it will make it
more extensible (especially, it is an API which need be implemented in
various sub modules).

Even though the return value may be useless, now, if the performance is
not quite important in our case, I still suggest to have it (especially
each various original implementation already has it).


> cheers
> 
> 

Thanks.
-- 
Chen Gang

^ permalink raw reply

* Re: [PATCH] Update compilation flags with core specific options
From: Scott Wood @ 2013-07-24  0:11 UTC (permalink / raw)
  To: Catalin Udma; +Cc: linuxppc-dev
In-Reply-To: <1372764004-18896-1-git-send-email-catalin.udma@freescale.com>

On 07/02/2013 06:20:04 AM, Catalin Udma wrote:
> If CONFIG_E500 is enabled, the compilation flags are updated
> specifying the target core -mcpu=3De5500/e500mc/8540
> Also remove -Wa,-me500, being incompatible with -mcpu=3De5500/e6500
> The assembler option is redundant if the -mcpu=3D flag is set.
> The patch fixes the kernel compilation problem for e5500/e6500
> when using gcc option -mcpu=3De5500/e6500.
>=20
> Signed-off-by: Catalin Udma <catalin.udma@freescale.com>
> ---
>  arch/powerpc/Makefile |   13 ++++++++++++-
>  1 files changed, 12 insertions(+), 1 deletions(-)
>=20
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index 0624909..82808b5 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -140,6 +140,18 @@ ifeq ($(CONFIG_6xx),y)
>  KBUILD_CFLAGS		+=3D -mcpu=3Dpowerpc
>  endif
>=20
> +ifeq ($(CONFIG_E500),y)
> +ifeq ($(CONFIG_64BIT),y)
> +KBUILD_CFLAGS		+=3D -mcpu=3De5500
> +else
> +ifeq ($(CONFIG_PPC_E500MC),y)
> +KBUILD_CFLAGS		+=3D -mcpu=3De500mc
> +else
> +KBUILD_CFLAGS		+=3D -mcpu=3D8540
> +endif
> +endif
> +endif
> +
>  # Work around a gcc code-gen bug with -fno-omit-frame-pointer.
>  ifeq ($(CONFIG_FUNCTION_TRACER),y)
>  KBUILD_CFLAGS		+=3D -mno-sched-epilog
> @@ -147,7 +159,6 @@ endif
>=20
>  cpu-as-$(CONFIG_4xx)		+=3D -Wa,-m405
>  cpu-as-$(CONFIG_ALTIVEC)	+=3D -Wa,-maltivec
> -cpu-as-$(CONFIG_E500)		+=3D -Wa,-me500
>  cpu-as-$(CONFIG_E200)		+=3D -Wa,-me200
>=20
>  KBUILD_AFLAGS +=3D $(cpu-as-y)

This breaks the vdso for e500v1/v2 (userspace dies with SIGILL), since =20
KBUILD_CFLAGS doesn't get used when building asm files, and the vdso =20
uses mftbu/mftbl which are not being assembled to the form that =20
e500v1/v2 support.

We should be setting -mcpu=3Dwhatever and -msoft-float in both CFLAGS and =20
AFLAGS, since we don't call "as" directly, and target selection should =20
not differ based on whether we're building a C file or an asm file.

-Scott=

^ permalink raw reply

* Re: [1/4] powerpc/85xx: Add SEC6.0 device tree
From: Scott Wood @ 2013-07-23 23:24 UTC (permalink / raw)
  To: Liu Po-B43644
  Cc: Wood Scott-B07421, Hu Mingkai-B21284, linuxppc-dev@ozlabs.org
In-Reply-To: <D473A0D087F4EA47A30C37E4637E25E609DAD274@039-SN2MPN1-021.039d.mgd.msft.net>

On 07/23/2013 03:01:17 AM, Liu Po-B43644 wrote:
>=20
> >  -----Original Message-----
> >  From: Wood Scott-B07421
> >  Sent: Tuesday, July 23, 2013 6:41 AM
> >  To: Liu Po-B43644
> >  Cc: linuxppc-dev@ozlabs.org; Hu Mingkai-B21284
> >  Subject: Re: [1/4] powerpc/85xx: Add SEC6.0 device tree
> >
> >  On Thu, Apr 25, 2013 at 09:54:14AM +0800, Po Liu wrote:
> >  > From: Mingkai Hu <Mingkai.Hu@freescale.com>
> >  >
> >  > Add device tree for SEC 6.0 used on C29x silicon.
> >  >
> >  > Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
> >  > Singed-off-by: Po Liu <Po.Liu@freescale.com>
> >
> >  I've heard of patches being flamed, but here we want signing, not
> >  singeing. :-)
> >
> >  Don't forget that you can use the -s option to have git add the =20
> signoff
> >  for you.
> >
> >  > ---
> >  > Base on git://git.am.freescale.net/gitolite/mirrors/linux-2.6.git
> >
> >  This URL is not accessible outside Freescale, so don't reference =20
> it when
> >  posting patches publicly.
> >
> >  If your patch is against the latest upstream code, you don't need =20
> to say
> >  anything special about that.  You only need to make a note when =20
> it's
> >  against some other yet-to-be-merged tree or patch.
> >
> >  > +	compatible =3D "fsl,sec-v6.0", "fsl,sec-v5.2",
> >  > +		     "fsl,sec-v5.0", "fsl,sec-v4.4",
> >  > +		     "fsl,sec-v4.0";
> >  > +	fsl,sec-era =3D <6>;
> >  > +	#address-cells =3D <1>;
> >  > +	#size-cells =3D <1>;
> >  > +
> >  > +	jr@1000 {
> >  > +		compatible =3D "fsl,sec-v6.0-job-ring",
> >  > +			     "fsl,sec-v5.2-job-ring",
> >  > +			     "fsl,sec-v5.0-job-ring",
> >  > +			     "fsl,sec-v4.4-job-ring",
> >  > +			     "fsl,sec-v4.0-job-ring";
> >  > +		reg	   =3D <0x1000 0x1000>;
> >  > +	};
> >  > +
> >  > +	jr@2000 {
> >  > +		compatible =3D "fsl,sec-v6.0-job-ring",
> >  > +			     "fsl,sec-v5.2-job-ring",
> >  > +			     "fsl,sec-v5.0-job-ring",
> >  > +			     "fsl,sec-v4.4-job-ring",
> >  > +			     "fsl,sec-v4.0-job-ring";
> >  > +		reg	   =3D <0x2000 0x1000>;
> >  > +	};
> >
> >  You claim compatibility with a bunch of prior SECs, but sec-v5.2 =20
> has four
> >  job rings and an rtic node.  Likewise for the previous compatibles =20
> listed.
> >  This has two job rings and no rtic.
> So, shall I remove "fsl,sec-v5.2","fsl,sec-v5.0", "fsl,sec-v4.4", =20
> "fsl,sec-v4.0" since all other SEC with 4 job rings? and only leave =20
> "fsl,sec-v6.0"?

Yes, I think so.

> >  Can you point to where in the SEC v4.0 binding (I don't see a =20
> binding for
> >  the subsequent versions), it says that these are optional?
> I found SEC V4.0 in file qoriq-sec4.0-0.dtsi. If "fsl,sec-v4.0" not =20
> in the compatible list, it is no use in this compatible list. But =20
> seems keep the "fsl,sec-v4.0-job-ring" job ring compatible is ok. Is =20
> that what you were ask?

No, I was talking about binding documents:
Documentation/devicetree/bindings/crypto/

-Scott=

^ permalink raw reply

* Re: [PATCH 1/3] powerpc/mpc85xx: remove the unneeded pci init functions for corenet ds board
From: Scott Wood @ 2013-07-23 22:31 UTC (permalink / raw)
  To: Kevin Hao; +Cc: linuxppc, Alexander Graf
In-Reply-To: <20130607020020.GA4678@pek-khao-d1.corp.ad.wrs.com>

On 06/06/2013 09:00:20 PM, Kevin Hao wrote:
> On Mon, Jun 03, 2013 at 11:42:03AM -0500, Scott Wood wrote:
> > On 06/01/2013 07:07:20 PM, Kevin Hao wrote:
> > >On Sat, Jun 01, 2013 at 09:47:16PM +1000, Benjamin Herrenschmidt
> > >wrote:
> > >> On Sat, 2013-06-01 at 18:59 +0800, Kevin Hao wrote:
> > >>
> > >> > The effect of this change is that the isa_io_base will be 0
> > >and the IO
> > >> > resource are equal to the virtual address of the IO space. But
> > >the IO
> > >> > functions such as outx/inx should work as well. This is why I
> > >ask the
> > >> > above question. What do you think about this? Are there any
> > >subtle bugs
> > >> > that will be triggered by this?
> > >>
> > >> I don't see any obvious reason why that wouldn't work but like
> > >anything
> > >> in that area, it needs a bit of testing & hammering to be sure =20
> ;-)
> > >
> > >Agreed.
> >
> > Please include QEMU in your testing, as that was where breakage was
> > observed that caused us to add the default primary.
>=20
> I tested this on a qemu with the following command:
>   ./qemu-system-ppc -m 1024 -nographic -M ppce500 -kernel ./uImage \
>   -initrd /root/initrd.gz \
>   -append "root=3D/dev/ram rw console=3DttyS0,115200 =20
> ramdisk_size=3D0x60000"  \
>   -cpu e500mc -machine dt_compatible=3Dfsl,,P4080DS
>=20
> Before applying my patch:
>   PCI: Probing PCI hardware
>   fsl-pci e0008000.pci: PCI host bridge to bus 0000:00
>   pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
>   pci_bus 0000:00: root bus resource [mem 0xc0000000-0xdfffffff]
>   pci_bus 0000:00: root bus resource [bus 00-ff]
>   pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to ff
>   pci 0000:00:00.0: [1957:0030] type 01 class 0x060400
>   pci 0000:00:00.0: reg 10: [mem 0xfff00000-0xffffffff]
>   pci 0000:00:01.0: [1af4:1000] type 00 class 0x020000
>   pci 0000:00:01.0: reg 10: [io  0x0000-0x001f]
>   pci 0000:00:01.0: reg 14: [mem 0x00000000-0x00000fff]
>   pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), =20
> reconfiguring
>   pci 0000:00:00.0: PCI bridge to [bus 01-ff]
>   pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
>   pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff]
>   pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff pref]
>   pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
>   pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
>   PCI: Cannot allocate resource region 0 of device 0000:00:00.0, will =20
> remap
>   PCI 0000:00 Cannot reserve Legacy IO [io  0x0000-0x0fff]
>   pci 0000:00:00.0: BAR 0: assigned [mem 0xc0000000-0xc00fffff]
>   pci 0000:00:00.0: BAR 8: assigned [mem 0xc0100000-0xc01fffff]
>   pci 0000:00:01.0: BAR 1: assigned [mem 0xc0200000-0xc0200fff]
>   pci 0000:00:01.0: BAR 0: assigned [io  0x1000-0x101f]
>   pci 0000:00:00.0: PCI bridge to [bus 01]
>   pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
>   pci 0000:00:00.0:   bridge window [mem 0xc0100000-0xc01fffff]
>   pci_bus 0000:00: resource 4 [io  0x0000-0xffff]
>   pci_bus 0000:00: resource 5 [mem 0xc0000000-0xdfffffff]
>   pci_bus 0000:01: resource 0 [io  0x0000-0x0fff]
>   pci_bus 0000:01: resource 1 [mem 0xc0100000-0xc01fffff]
>=20
>   # lspci -vvv
>   00:00.0 PCI bridge: Freescale Semiconductor Inc MPC8533E (prog-if =20
> 00 [Normal decode])
>           Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- =20
> ParErr- Stepping- SERR+ FastB2B- DisINTx-
>           Status: Cap- 66MHz- UDF- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>           Latency: 0
>           Region 0: Memory at c0000000 (32-bit, non-prefetchable) =20
> [size=3D1M]
>           Bus: primary=3D00, secondary=3D00, subordinate=3D00, sec-latenc=
y=3D0
>           I/O behind bridge: 00000000-00000fff
>           Memory behind bridge: 00000000-000fffff
>           Prefetchable memory behind bridge: 00000000-000fffff
>           Secondary status: 66MHz- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
>           BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- =20
> FastB2B-
>                   PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
>=20
>   00:01.0 Ethernet controller: Red Hat, Inc Virtio network device
>           Subsystem: Red Hat, Inc Device 0001
>           Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- =20
> ParErr- Stepping- SERR- FastB2B- DisINTx-
>           Status: Cap+ 66MHz- UDF- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>           Interrupt: pin A routed to IRQ 17
>           Region 0: I/O ports at 1000 [disabled] [size=3D32]
>           Region 1: Memory at c0200000 (32-bit, non-prefetchable) =20
> [disabled] [size=3D4K]
>           Capabilities: [40] MSI-X: Enable- Count=3D3 Masked-
>                   Vector table: BAR=3D1 offset=3D00000000
>                   PBA: BAR=3D1 offset=3D00000800
>=20
> After applying my patch:
>   PCI: Probing PCI hardware
>   fsl-pci e0008000.pci: PCI host bridge to bus 0000:00
>   pci_bus 0000:00: root bus resource [io  0xf1020000-0xf102ffff] (bus =20
> address [0x0000-0xffff])
>   pci_bus 0000:00: root bus resource [mem 0xc0000000-0xdfffffff]
>   pci_bus 0000:00: root bus resource [bus 00-ff]
>   pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to ff
>   pci 0000:00:00.0: [1957:0030] type 01 class 0x060400
>   pci 0000:00:00.0: reg 10: [mem 0xfff00000-0xffffffff]
>   pci 0000:00:01.0: [1af4:1000] type 00 class 0x020000
>   pci 0000:00:01.0: reg 10: [io  0xf1020000-0xf102001f]
>   pci 0000:00:01.0: reg 14: [mem 0x00000000-0x00000fff]
>   pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), =20
> reconfiguring
>   pci 0000:00:00.0: PCI bridge to [bus 01-ff]
>   pci 0000:00:00.0:   bridge window [io  0xf1020000-0xf1020fff]
>   pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff]
>   pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff pref]
>   pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
>   pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
>   PCI: Cannot allocate resource region 0 of device 0000:00:00.0, will =20
> remap
>   PCI: Cannot allocate resource region 0 of device 0000:00:01.0, will =20
> remap
>   PCI 0000:00 Cannot reserve Legacy IO [io  0xf1020000-0xf1020fff]
>   pci 0000:00:00.0: BAR 0: assigned [mem 0xc0000000-0xc00fffff]
>   pci 0000:00:00.0: BAR 8: assigned [mem 0xc0100000-0xc01fffff]
>   pci 0000:00:01.0: BAR 1: assigned [mem 0xc0200000-0xc0200fff]
>   pci 0000:00:01.0: BAR 0: assigned [io  0xf1021000-0xf102101f]
>   pci 0000:00:00.0: PCI bridge to [bus 01]
>   pci 0000:00:00.0:   bridge window [io  0xf1020000-0xf1020fff]
>   pci 0000:00:00.0:   bridge window [mem 0xc0100000-0xc01fffff]
>   pci_bus 0000:00: resource 4 [io  0xf1020000-0xf102ffff]
>   pci_bus 0000:00: resource 5 [mem 0xc0000000-0xdfffffff]
>   pci_bus 0000:01: resource 0 [io  0xf1020000-0xf1020fff]
>   pci_bus 0000:01: resource 1 [mem 0xc0100000-0xc01fffff]
>=20
>   # lspci -vvv
>   00:00.0 PCI bridge: Freescale Semiconductor Inc MPC8533E (prog-if =20
> 00 [Normal decode])
>           Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- =20
> ParErr- Stepping- SERR+ FastB2B- DisINTx-
>           Status: Cap- 66MHz- UDF- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>           Latency: 0
>           Region 0: Memory at c0000000 (32-bit, non-prefetchable) =20
> [size=3D1M]
>           Bus: primary=3D00, secondary=3D00, subordinate=3D00, sec-latenc=
y=3D0
>           I/O behind bridge: 00000000-00000fff
>           Memory behind bridge: 00000000-000fffff
>           Prefetchable memory behind bridge: 00000000-000fffff
>           Secondary status: 66MHz- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
>           BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- =20
> FastB2B-
>                   PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
>=20
>   00:01.0 Ethernet controller: Red Hat, Inc Virtio network device
>           Subsystem: Red Hat, Inc Device 0001
>           Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- =20
> ParErr- Stepping- SERR- FastB2B- DisINTx-
>           Status: Cap+ 66MHz- UDF- FastB2B- ParErr- =20
> DEVSEL=3Dfast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>           Interrupt: pin A routed to IRQ 17
>           Region 0: I/O ports at 1000 [disabled] [size=3D32]
>           Region 1: Memory at c0200000 (32-bit, non-prefetchable) =20
> [disabled] [size=3D4K]
>           Capabilities: [40] MSI-X: Enable- Count=3D3 Masked-
>                   Vector table: BAR=3D1 offset=3D00000000
>                   PBA: BAR=3D1 offset=3D00000800
>=20
>=20
> As you can see, the only difference between these two logs is the
> io resource address and all the mem and bus address are still the
> same.

I dug a bit deeper into this, and it's making by head hurt.  It seems =20
that we're now getting saved by the host bridge (that for some reason =20
has the class code of a PCI-to-PCI bridge rather than a host bridge) =20
having I/O space of 0x1000 bytes[1], which gets allocated at zero.  =20
There have been some changes in the QEMU PCI code since I saw the =20
problem, including changing the class code of the bridge, so that's =20
probably why it sort-of works now.

What QEMU is doing does not match what real hardware does, though.  At =20
least on mpc8536 which is similar to mpc8544 (I wasn't able to quickly =20
get access to a working mpc8544 to test on), the PCI bridge has class =20
code Processor, rather than bridge of any sort.  Thus, on real hardware =20
we would not get the 0x1000 reservation.  What hardware does seems =20
broken to me (when PCI is configured as a host rather than as an =20
endpoint), but so does calling a host bridge a PCI-to-PCI bridge, and =20
so does relying on this mess (not that the primary-bus hack is much =20
better...).

Note that in the case of PCIe -- but not PCI -- Linux has a quirk that =20
relabels the "Processor" on FSL chips as a PCI-to-PCI bridge.  Despite =20
the "Processor" labelling, Freescale PCIe (but not PCI) devices appear =20
to have a type 1 config space layout in host mode.   I guess this is =20
considered to be the virtual root port.

-Scott

[1] Really, it's the bridge not having any I/O, but this is how an I/O =20
base/limit of zero are interpreted.=

^ permalink raw reply

* Re: [PATCH 2/2] cpuidle: export cpuidle_idle_call symbol
From: Rafael J. Wysocki @ 2013-07-23 21:33 UTC (permalink / raw)
  To: Dongsheng Wang; +Cc: daniel.lezcano, linuxppc-dev, linux-pm
In-Reply-To: <1374571681-31911-2-git-send-email-dongsheng.wang@freescale.com>

On Tuesday, July 23, 2013 05:28:01 PM Dongsheng Wang wrote:
> From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> Export cpuidle_idle_call symbol, make this function can be invoked
> in the module.

Why?

Rafael


> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> ---
> Branch: pm-cpuidle
> 
>  drivers/cpuidle/cpuidle.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 534320a..d0a61d6 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -168,6 +168,7 @@ int cpuidle_idle_call(void)
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(cpuidle_idle_call);
>  
>  /**
>   * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 1/2] cpuidle: fix cpu idle driver as a module can not remove
From: Rafael J. Wysocki @ 2013-07-23 21:32 UTC (permalink / raw)
  To: Dongsheng Wang; +Cc: daniel.lezcano, linuxppc-dev, linux-pm
In-Reply-To: <1374571681-31911-1-git-send-email-dongsheng.wang@freescale.com>

On Tuesday, July 23, 2013 05:28:00 PM Dongsheng Wang wrote:
> From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> The module can not be removed when execute "rmmod". rmmod not use
> "--force".
> 
> Log:
> root:~# rmmod cpuidle-e500
> incs[9], decs[1]
> rmmod: can't unload 'cpuidle_e500': Resource temporarily unavailable
> 
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

Can you please check the current linux-next branch of the linux-pm.git tree
and see if that doesn't conflict with the material in there?

Also please explain in the changelog how your changes help to fix the problem.

Thanks,
Rafael


> ---
> Branch: pm-cpuidle
> 
>  drivers/cpuidle/cpuidle.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index fdc432f..534320a 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -386,6 +386,9 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
>  		goto err_coupled;
>  
>  	dev->registered = 1;
> +
> +	module_put(drv->owner);
> +
>  	return 0;
>  
>  err_coupled:
> @@ -432,8 +435,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device);
>   */
>  void cpuidle_unregister_device(struct cpuidle_device *dev)
>  {
> -	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
> -
>  	if (dev->registered == 0)
>  		return;
>  
> @@ -448,8 +449,6 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
>  	cpuidle_coupled_unregister_device(dev);
>  
>  	cpuidle_resume_and_unlock();
> -
> -	module_put(drv->owner);
>  }
>  
>  EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
From: Rafael J. Wysocki @ 2013-07-23 21:20 UTC (permalink / raw)
  To: Aaro Koskinen; +Cc: Nick Piggin, Viresh Kumar, linux-pm, linuxppc-dev
In-Reply-To: <1374611079-28091-1-git-send-email-aaro.koskinen@iki.fi>

On Tuesday, July 23, 2013 11:24:37 PM Aaro Koskinen wrote:
> Some functions on switch path use msleep() which is inaccurate, and
> depends on HZ. With HZ=100 msleep(1) takes actually over ten times longer.
> Using usleep_range() we get more accurate sleeps.
> 
> I measured the "pfunc_slewing_done" polling to take 300us at max (on
> 2.3GHz dual-processor Xserve G5), so using 500us sleep there should
> be fine.
> 
> With the patch, g5_switch_freq() duration drops from ~50ms to ~10ms on
> Xserve with HZ=100.
> 
> Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>

All looks good in the patchset from 10000 feet (or more), but I need Ben to
speak here.

Thanks,
Rafael


> ---
>  drivers/cpufreq/pmac64-cpufreq.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
> index 7ba4234..674807d 100644
> --- a/drivers/cpufreq/pmac64-cpufreq.c
> +++ b/drivers/cpufreq/pmac64-cpufreq.c
> @@ -141,7 +141,7 @@ static void g5_vdnap_switch_volt(int speed_mode)
>  		pmf_call_one(pfunc_vdnap0_complete, &args);
>  		if (done)
>  			break;
> -		msleep(1);
> +		usleep_range(1000, 1000);
>  	}
>  	if (done == 0)
>  		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
> @@ -240,7 +240,7 @@ static void g5_pfunc_switch_volt(int speed_mode)
>  		if (pfunc_cpu1_volt_low)
>  			pmf_call_one(pfunc_cpu1_volt_low, NULL);
>  	}
> -	msleep(10); /* should be faster , to fix */
> +	usleep_range(10000, 10000); /* should be faster , to fix */
>  }
>  
>  /*
> @@ -285,7 +285,7 @@ static int g5_pfunc_switch_freq(int speed_mode)
>  		pmf_call_one(pfunc_slewing_done, &args);
>  		if (done)
>  			break;
> -		msleep(1);
> +		usleep_range(500, 500);
>  	}
>  	if (done == 0)
>  		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
From: Benjamin Herrenschmidt @ 2013-07-23 21:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Nick Piggin, Viresh Kumar, linux-pm, linuxppc-dev, Aaro Koskinen
In-Reply-To: <9298823.WUCyZreP9q@vostro.rjw.lan>

On Tue, 2013-07-23 at 23:20 +0200, Rafael J. Wysocki wrote:
> All looks good in the patchset from 10000 feet (or more), but I need
> Ben to speak here.

I want to give it a quick spin on the HW here, I'll ack then. But yes,
it looks good.

Cheers,
Ben.

^ permalink raw reply

* Re: [RFC] power/mpc85xx: Add delay after enabling I2C master
From: York Sun @ 2013-07-23 20:32 UTC (permalink / raw)
  To: Scott Wood; +Cc: albrecht.dress, linuxppc-dev
In-Reply-To: <1374604984.15592.34@snotra>

On 07/23/2013 11:43 AM, Scott Wood wrote:
>>
>> Yes. The max divider from sys clock to i2c clcok is 32K.
>> i2c->real_clk is the clock I2C controller pumps out, not its internal
>> operation clock.
> 
> 32K is the max for all implementations?

Yes, according to application note 2919 (published).

> 
> BTW, Where does the "2000000" come from?  Shouldn't it be 1000000 if
> you're converting to usec?  If you're trying to add some slack, say so
> rather than having a comment suggest that the output of that formula is
> 64K cycles.  Or is there an implicit assumption that i2c runs at half
> the system frequency?  Is that assumption true for all implementations
> that have this erratum?

The clock source is half the sysclk. This erratum applies to selected
85xx SoCs. I have confirmed with application team that it is safe to
apply the delay to all 85xx.

> 
>> > In any case, you should send this patch to the i2c maintainer and list.
>> >
>>
>> I don't have the name on top of my head. Is that
>> linux-i2c@vger.kernel.org?
> 
> Yes, and Wolfram Sang <wsa@the-dreams.de> is the maintainer.  This is
> listed in the MAINTAINERS file.
> 

I can resubmit this patch after the feedback is addressed.

York

^ permalink raw reply

* [PATCH 3/3] cpufreq: pmac64: enable cpufreq on iMac G5 (iSight) model
From: Aaro Koskinen @ 2013-07-23 20:24 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, Benjamin Herrenschmidt,
	Nick Piggin, linux-pm, linuxppc-dev
  Cc: Aaro Koskinen
In-Reply-To: <1374611079-28091-1-git-send-email-aaro.koskinen@iki.fi>

Enable cpufreq on iMac G5 (iSight) model. Tested with the 2.1 GHz version.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
 drivers/cpufreq/pmac64-cpufreq.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index f9e399b..1f352e5 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -399,7 +399,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
 	/* Check supported platforms */
 	if (of_machine_is_compatible("PowerMac8,1") ||
 	    of_machine_is_compatible("PowerMac8,2") ||
-	    of_machine_is_compatible("PowerMac9,1"))
+	    of_machine_is_compatible("PowerMac9,1") ||
+	    of_machine_is_compatible("PowerMac12,1"))
 		use_volts_smu = 1;
 	else if (of_machine_is_compatible("PowerMac11,2"))
 		use_volts_vdnap = 1;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 2/3] cpufreq: pmac64: re-estimate G5 cpufreq transition latency
From: Aaro Koskinen @ 2013-07-23 20:24 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, Benjamin Herrenschmidt,
	Nick Piggin, linux-pm, linuxppc-dev
  Cc: Aaro Koskinen
In-Reply-To: <1374611079-28091-1-git-send-email-aaro.koskinen@iki.fi>

The latency is in milliseconds scale rather than microseconds based on
measurements on iMac G5 and Xscale G5. The patch also enables to use
ondemand governor on the latter.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
 drivers/cpufreq/pmac64-cpufreq.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 674807d..f9e399b 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -85,7 +85,8 @@ static int (*g5_query_freq)(void);
 
 static DEFINE_MUTEX(g5_switch_mutex);
 
-static unsigned long transition_latency;
+/* A conservative estimate, based on Xserve G5 and iMac G5 (iSight). */
+static const unsigned long transition_latency = 10 * NSEC_PER_MSEC;
 
 #ifdef CONFIG_PMAC_SMU
 
@@ -499,7 +500,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
 	g5_cpu_freqs[1].frequency = max_freq/2;
 
 	/* Set callbacks */
-	transition_latency = 12000;
 	g5_switch_freq = g5_scom_switch_freq;
 	g5_query_freq = g5_scom_query_freq;
 	freq_method = "SCOM";
@@ -675,7 +675,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
 	g5_cpu_freqs[1].frequency = min_freq;
 
 	/* Set callbacks */
-	transition_latency = CPUFREQ_ETERNAL;
 	g5_switch_volt = g5_pfunc_switch_volt;
 	g5_switch_freq = g5_pfunc_switch_freq;
 	g5_query_freq = g5_pfunc_query_freq;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
From: Aaro Koskinen @ 2013-07-23 20:24 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar, Benjamin Herrenschmidt,
	Nick Piggin, linux-pm, linuxppc-dev
  Cc: Aaro Koskinen

Some functions on switch path use msleep() which is inaccurate, and
depends on HZ. With HZ=100 msleep(1) takes actually over ten times longer.
Using usleep_range() we get more accurate sleeps.

I measured the "pfunc_slewing_done" polling to take 300us at max (on
2.3GHz dual-processor Xserve G5), so using 500us sleep there should
be fine.

With the patch, g5_switch_freq() duration drops from ~50ms to ~10ms on
Xserve with HZ=100.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
 drivers/cpufreq/pmac64-cpufreq.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 7ba4234..674807d 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -141,7 +141,7 @@ static void g5_vdnap_switch_volt(int speed_mode)
 		pmf_call_one(pfunc_vdnap0_complete, &args);
 		if (done)
 			break;
-		msleep(1);
+		usleep_range(1000, 1000);
 	}
 	if (done == 0)
 		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
@@ -240,7 +240,7 @@ static void g5_pfunc_switch_volt(int speed_mode)
 		if (pfunc_cpu1_volt_low)
 			pmf_call_one(pfunc_cpu1_volt_low, NULL);
 	}
-	msleep(10); /* should be faster , to fix */
+	usleep_range(10000, 10000); /* should be faster , to fix */
 }
 
 /*
@@ -285,7 +285,7 @@ static int g5_pfunc_switch_freq(int speed_mode)
 		pmf_call_one(pfunc_slewing_done, &args);
 		if (done)
 			break;
-		msleep(1);
+		usleep_range(500, 500);
 	}
 	if (done == 0)
 		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
-- 
1.8.3.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox