linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler
@ 2014-05-14 19:10 Florian Fainelli
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB arbiter bus " Florian Fainelli
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: marc.ceeeee, computersforpeace, gregory.0xf0, Florian Fainelli,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

Hi all,

This patch adds support for the Broadcom GISB bus arbiter timeout/error handler.
GISB is a custom and proprietary bus used in the Broadcom Set Top Box devices
exclusively. The bus arbiter offers the possibly to decode faulting masters as
well as masters that are timing out on the bus.

Florian Fainelli (3):
  bus: add Broadcom GISB arbiter bus timeout/error handler
  Documentation: devicetree: add Broadcom GISB arbiter bindings
  Documentation: sysfs: add Broadcom GISB arbiter sysfs properties

 .../ABI/testing/sysfs-platform-brcmstb-gisb-arb    |   8 +
 .../devicetree/bindings/bus/brcm,gisb-arb.txt      |  30 +++
 drivers/bus/Kconfig                                |  11 +-
 drivers/bus/Makefile                               |   1 +
 drivers/bus/brcmstb_gisb.c                         | 289 +++++++++++++++++++++
 5 files changed, 338 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb
 create mode 100644 Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
 create mode 100644 drivers/bus/brcmstb_gisb.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] bus: add Broadcom GISB arbiter bus timeout/error handler
  2014-05-14 19:10 [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler Florian Fainelli
@ 2014-05-14 19:10 ` Florian Fainelli
  2014-05-14 19:33   ` Arnd Bergmann
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB bus arbiter " Florian Fainelli
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: marc.ceeeee, computersforpeace, gregory.0xf0, Florian Fainelli,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

This patch adds support for the Broadcom GISB arbiter bus timeout/error
handler. GISB is a proprietary bus used by Broadcom Set Top Box
System-on-a-chip devices (BCM7xxx) which allows multiple masters and
clients to be interfaced with each other.

The bus arbiter offers support for generating two interrupts towards the
host CPU, thus allowing us to "catch" clock gated masters, or masters
being volontarily blocked for powersaving purposes, or do general system
troubleshooting.

We also register a hook with the ARM fault exception handling to allow
printing a more informative message than "imprecise external abort at
0x00000000" for instance.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/bus/Kconfig        |  11 +-
 drivers/bus/Makefile       |   1 +
 drivers/bus/brcmstb_gisb.c | 289 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/brcmstb_gisb.c

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 552373c4e362..985db51c0b11 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -40,5 +40,14 @@ config ARM_CCI
 	depends on ARM
 	help
 	  Driver supporting the CCI cache coherent interconnect for ARM
-	  platforms.
+	  kplatforms.
+
+config BRCMSTB_GISB_ARB
+	bool "Broadcom STB GISB bus arbiter"
+	depends on ARM
+	help
+	  Driver for the Broadcom Set Top Box System-on-a-chip internal bus
+	  arbiter. This driver provides timeout and target abort error handling
+	  and internal bus master decoding.
+
 endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 8947bdd0de8b..48617169d59b 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OMAP_OCP2SCP)	+= omap-ocp2scp.o
 obj-$(CONFIG_OMAP_INTERCONNECT)	+= omap_l3_smx.o omap_l3_noc.o
 # CCI cache coherent interconnect for ARM platforms
 obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
+obj-$(CONFIG_BRCMSTB_GISB_ARB)	+= brcmstb-gisb.o
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
new file mode 100644
index 000000000000..a0872b5d521c
--- /dev/null
+++ b/drivers/bus/brcmstb_gisb.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/bitops.h>
+
+#include <asm/bug.h>
+#include <asm/signal.h>
+
+#define ARB_TIMER			0x008
+#define ARB_ERR_CAP_CLR			0x7e4
+#define  ARB_ERR_CAP_CLEAR		(1 << 0)
+#define ARB_ERR_CAP_HI_ADDR		0x7e8
+#define ARB_ERR_CAP_ADDR		0x7ec
+#define ARB_ERR_CAP_DATA		0x7f0
+#define ARB_ERR_CAP_STATUS		0x7f4
+#define  ARB_ERR_CAP_STATUS_TIMEOUT	(1 << 12)
+#define  ARB_ERR_CAP_STATUS_TEA		(1 << 11)
+#define  ARB_ERR_CAP_STATUS_BS_SHIFT	(1 << 2)
+#define  ARB_ERR_CAP_STATUS_BS_MASK	0x3c
+#define  ARB_ERR_CAP_STATUS_WRITE	(1 << 1)
+#define  ARB_ERR_CAP_STATUS_VALID	(1 << 0)
+#define ARB_ERR_CAP_MASTER		0x7f8
+
+struct brcmstb_gisb_arb_device {
+	void __iomem	*base;
+	struct mutex	lock;
+	struct list_head next;
+	u32 valid_mask;
+	const char *master_names[sizeof(u32) * BITS_PER_BYTE];
+};
+
+static LIST_HEAD(brcmstb_gisb_arb_device_list);
+
+static ssize_t gisb_arb_get_timeout(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+	u32 timeout;
+
+	mutex_lock(&gdev->lock);
+	timeout = ioread32(gdev->base + ARB_TIMER);
+	mutex_unlock(&gdev->lock);
+
+	return sprintf(buf, "%d", timeout);
+}
+
+static ssize_t gisb_arb_set_timeout(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+	int val, ret;
+
+	ret = kstrtoint(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val == 0 || val >= 0xffffffff)
+		return -EINVAL;
+
+	mutex_lock(&gdev->lock);
+	iowrite32(val, gdev->base + ARB_TIMER);
+	mutex_unlock(&gdev->lock);
+
+	return count;
+}
+
+static const char *
+brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev,
+						u32 masters)
+{
+	u32 mask = gdev->valid_mask & masters;
+
+	if (hweight_long(mask) != 1)
+		return NULL;
+
+	return gdev->master_names[ffs(mask) - 1];
+}
+
+static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
+					const char *reason)
+{
+	u32 cap_status;
+	unsigned long arb_addr;
+	u32 master;
+	const char *m_name;
+	char m_fmt[11];
+
+	cap_status = ioread32(gdev->base + ARB_ERR_CAP_STATUS);
+
+	/* Invalid captured address, bail out */
+	if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
+		return 1;
+
+	/* Read the address and master */
+	arb_addr = ioread32(gdev->base + ARB_ERR_CAP_ADDR) & 0xffffffff;
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	arb_addr |= (u64)ioread32(gdev->base + ARB_ERR_CAP_HI_ADDR) << 32;
+#endif
+	master = ioread32(gdev->base + ARB_ERR_CAP_MASTER);
+
+	m_name = brcmstb_gisb_master_to_str(gdev, master);
+	if (!m_name) {
+		snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
+		m_name = m_fmt;
+	}
+
+	pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n",
+		__func__, reason, arb_addr,
+		cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
+		cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
+		m_name);
+
+	/* clear the GISB error */
+	iowrite32(ARB_ERR_CAP_CLEAR, gdev->base + ARB_ERR_CAP_CLR);
+
+	return 0;
+}
+
+static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
+				     struct pt_regs *regs)
+{
+	int ret = 0;
+	struct brcmstb_gisb_arb_device *gdev;
+
+	/* iterate over each GISB arb registered handlers */
+	list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
+		ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	*/
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return ret;
+}
+
+void __init brcmstb_hook_fault_code(void)
+{
+	hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
+			"imprecise external abort");
+}
+
+static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
+{
+	brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
+{
+	brcmstb_gisb_arb_decode_addr(dev_id, "target abort");
+
+	return IRQ_HANDLED;
+}
+
+static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
+		gisb_arb_get_timeout, gisb_arb_set_timeout);
+
+static struct attribute *gisb_arb_sysfs_attrs[] = {
+	&dev_attr_gisb_arb_timeout.attr,
+	NULL,
+};
+
+static struct attribute_group gisb_arb_sysfs_attr_group = {
+	.attrs = gisb_arb_sysfs_attrs,
+};
+
+static int brcmstb_gisb_arb_probe(struct platform_device *pdev)
+{
+	struct device_node *dn = pdev->dev.of_node;
+	struct brcmstb_gisb_arb_device *gdev;
+	struct resource *r;
+	int err, timeout_irq, tea_irq;
+	unsigned int num_masters, j = 0;
+	int i, first, last;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	timeout_irq = platform_get_irq(pdev, 0);
+	tea_irq = platform_get_irq(pdev, 1);
+
+	gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
+	if (!gdev)
+		return -ENOMEM;
+
+	mutex_init(&gdev->lock);
+	INIT_LIST_HEAD(&gdev->next);
+
+	gdev->base = devm_request_and_ioremap(&pdev->dev, r);
+	if (!gdev->base)
+		return -ENOMEM;
+
+	err = devm_request_irq(&pdev->dev, timeout_irq,
+				brcmstb_gisb_timeout_handler, 0, pdev->name,
+				gdev);
+	if (err < 0)
+		return err;
+
+	err = devm_request_irq(&pdev->dev, tea_irq,
+				brcmstb_gisb_tea_handler, 0, pdev->name,
+				gdev);
+	if (err < 0)
+		return err;
+
+	/* If we do not have a valid mask, assume all masters are enabled */
+	if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
+				&gdev->valid_mask))
+		gdev->valid_mask = 0xffffffff;
+
+	/* Proceed with reading the litteral names if we agree on the
+	 * number of masters
+	 */
+	num_masters = of_property_count_strings(dn,
+			"brcm,gisb-arb-master-names");
+	if (hweight_long(gdev->valid_mask) == num_masters) {
+		first = ffs(gdev->valid_mask) - 1;
+		last = fls(gdev->valid_mask) - 1;
+
+		for (i = first; i < last; i++) {
+			if (!(gdev->valid_mask & BIT(i)))
+				continue;
+
+			of_property_read_string_index(dn,
+					"brcm,gisb-arb-master-names", j,
+					&gdev->master_names[i]);
+			j++;
+		}
+	}
+
+	err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, gdev);
+
+	list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
+
+	dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",
+			gdev->base, timeout_irq, tea_irq);
+
+	return 0;
+}
+
+static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
+	{ .compatible = "brcm,gisb-arb" },
+	{ },
+};
+
+static struct platform_driver brcmstb_gisb_arb_driver = {
+	.probe	= brcmstb_gisb_arb_probe,
+	.driver = {
+		.name	= "brcm-gisb-arb",
+		.owner	= THIS_MODULE,
+		.of_match_table = brcmstb_gisb_arb_of_match,
+	},
+};
+
+static int __init brcm_gisb_driver_init(void)
+{
+	return platform_driver_register(&brcmstb_gisb_arb_driver);
+}
+
+module_init(brcm_gisb_driver_init);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 1/3] bus: add Broadcom GISB bus arbiter timeout/error handler
  2014-05-14 19:10 [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler Florian Fainelli
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB arbiter bus " Florian Fainelli
@ 2014-05-14 19:10 ` Florian Fainelli
       [not found]   ` <5373C2EB.8020806@infradead.org>
  2014-05-14 19:10 ` [PATCH 2/3] Documentation: devicetree: add Broadcom GISB arbiter bindings Florian Fainelli
  2014-05-14 19:10 ` [PATCH 3/3] Documentation: sysfs: add Broadcom GISB arbiter sysfs properties Florian Fainelli
  3 siblings, 1 reply; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: marc.ceeeee, computersforpeace, gregory.0xf0, Florian Fainelli,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

This patch adds support for the Broadcom GISB arbiter bus timeout/error
handler. GISB is a proprietary bus used by Broadcom Set Top Box
System-on-a-chip devices (BCM7xxx) which allows multiple masters and
clients to be interfaced with each other.

The bus arbiter offers support for generating two interrupts towards the
host CPU, thus allowing us to "catch" clock gated masters, or masters
being volontarily blocked for powersaving purposes, or do general system
troubleshooting.

We also register a hook with the ARM fault exception handling to allow
printing a more informative message than "imprecise external abort at
0x00000000" for instance.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/bus/Kconfig        |  11 +-
 drivers/bus/Makefile       |   1 +
 drivers/bus/brcmstb_gisb.c | 289 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/brcmstb_gisb.c

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 552373c4e362..985db51c0b11 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -40,5 +40,14 @@ config ARM_CCI
 	depends on ARM
 	help
 	  Driver supporting the CCI cache coherent interconnect for ARM
-	  platforms.
+	  kplatforms.
+
+config BRCMSTB_GISB_ARB
+	bool "Broadcom STB GISB bus arbiter"
+	depends on ARM
+	help
+	  Driver for the Broadcom Set Top Box System-on-a-chip internal bus
+	  arbiter. This driver provides timeout and target abort error handling
+	  and internal bus master decoding.
+
 endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 8947bdd0de8b..48617169d59b 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OMAP_OCP2SCP)	+= omap-ocp2scp.o
 obj-$(CONFIG_OMAP_INTERCONNECT)	+= omap_l3_smx.o omap_l3_noc.o
 # CCI cache coherent interconnect for ARM platforms
 obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
+obj-$(CONFIG_BRCMSTB_GISB_ARB)	+= brcmstb-gisb.o
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
new file mode 100644
index 000000000000..a0872b5d521c
--- /dev/null
+++ b/drivers/bus/brcmstb_gisb.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/bitops.h>
+
+#include <asm/bug.h>
+#include <asm/signal.h>
+
+#define ARB_TIMER			0x008
+#define ARB_ERR_CAP_CLR			0x7e4
+#define  ARB_ERR_CAP_CLEAR		(1 << 0)
+#define ARB_ERR_CAP_HI_ADDR		0x7e8
+#define ARB_ERR_CAP_ADDR		0x7ec
+#define ARB_ERR_CAP_DATA		0x7f0
+#define ARB_ERR_CAP_STATUS		0x7f4
+#define  ARB_ERR_CAP_STATUS_TIMEOUT	(1 << 12)
+#define  ARB_ERR_CAP_STATUS_TEA		(1 << 11)
+#define  ARB_ERR_CAP_STATUS_BS_SHIFT	(1 << 2)
+#define  ARB_ERR_CAP_STATUS_BS_MASK	0x3c
+#define  ARB_ERR_CAP_STATUS_WRITE	(1 << 1)
+#define  ARB_ERR_CAP_STATUS_VALID	(1 << 0)
+#define ARB_ERR_CAP_MASTER		0x7f8
+
+struct brcmstb_gisb_arb_device {
+	void __iomem	*base;
+	struct mutex	lock;
+	struct list_head next;
+	u32 valid_mask;
+	const char *master_names[sizeof(u32) * BITS_PER_BYTE];
+};
+
+static LIST_HEAD(brcmstb_gisb_arb_device_list);
+
+static ssize_t gisb_arb_get_timeout(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+	u32 timeout;
+
+	mutex_lock(&gdev->lock);
+	timeout = ioread32(gdev->base + ARB_TIMER);
+	mutex_unlock(&gdev->lock);
+
+	return sprintf(buf, "%d", timeout);
+}
+
+static ssize_t gisb_arb_set_timeout(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
+	int val, ret;
+
+	ret = kstrtoint(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val == 0 || val >= 0xffffffff)
+		return -EINVAL;
+
+	mutex_lock(&gdev->lock);
+	iowrite32(val, gdev->base + ARB_TIMER);
+	mutex_unlock(&gdev->lock);
+
+	return count;
+}
+
+static const char *
+brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev,
+						u32 masters)
+{
+	u32 mask = gdev->valid_mask & masters;
+
+	if (hweight_long(mask) != 1)
+		return NULL;
+
+	return gdev->master_names[ffs(mask) - 1];
+}
+
+static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
+					const char *reason)
+{
+	u32 cap_status;
+	unsigned long arb_addr;
+	u32 master;
+	const char *m_name;
+	char m_fmt[11];
+
+	cap_status = ioread32(gdev->base + ARB_ERR_CAP_STATUS);
+
+	/* Invalid captured address, bail out */
+	if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
+		return 1;
+
+	/* Read the address and master */
+	arb_addr = ioread32(gdev->base + ARB_ERR_CAP_ADDR) & 0xffffffff;
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	arb_addr |= (u64)ioread32(gdev->base + ARB_ERR_CAP_HI_ADDR) << 32;
+#endif
+	master = ioread32(gdev->base + ARB_ERR_CAP_MASTER);
+
+	m_name = brcmstb_gisb_master_to_str(gdev, master);
+	if (!m_name) {
+		snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
+		m_name = m_fmt;
+	}
+
+	pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n",
+		__func__, reason, arb_addr,
+		cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
+		cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
+		m_name);
+
+	/* clear the GISB error */
+	iowrite32(ARB_ERR_CAP_CLEAR, gdev->base + ARB_ERR_CAP_CLR);
+
+	return 0;
+}
+
+static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
+				     struct pt_regs *regs)
+{
+	int ret = 0;
+	struct brcmstb_gisb_arb_device *gdev;
+
+	/* iterate over each GISB arb registered handlers */
+	list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
+		ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	*/
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return ret;
+}
+
+void __init brcmstb_hook_fault_code(void)
+{
+	hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
+			"imprecise external abort");
+}
+
+static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
+{
+	brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
+{
+	brcmstb_gisb_arb_decode_addr(dev_id, "target abort");
+
+	return IRQ_HANDLED;
+}
+
+static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
+		gisb_arb_get_timeout, gisb_arb_set_timeout);
+
+static struct attribute *gisb_arb_sysfs_attrs[] = {
+	&dev_attr_gisb_arb_timeout.attr,
+	NULL,
+};
+
+static struct attribute_group gisb_arb_sysfs_attr_group = {
+	.attrs = gisb_arb_sysfs_attrs,
+};
+
+static int brcmstb_gisb_arb_probe(struct platform_device *pdev)
+{
+	struct device_node *dn = pdev->dev.of_node;
+	struct brcmstb_gisb_arb_device *gdev;
+	struct resource *r;
+	int err, timeout_irq, tea_irq;
+	unsigned int num_masters, j = 0;
+	int i, first, last;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	timeout_irq = platform_get_irq(pdev, 0);
+	tea_irq = platform_get_irq(pdev, 1);
+
+	gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
+	if (!gdev)
+		return -ENOMEM;
+
+	mutex_init(&gdev->lock);
+	INIT_LIST_HEAD(&gdev->next);
+
+	gdev->base = devm_request_and_ioremap(&pdev->dev, r);
+	if (!gdev->base)
+		return -ENOMEM;
+
+	err = devm_request_irq(&pdev->dev, timeout_irq,
+				brcmstb_gisb_timeout_handler, 0, pdev->name,
+				gdev);
+	if (err < 0)
+		return err;
+
+	err = devm_request_irq(&pdev->dev, tea_irq,
+				brcmstb_gisb_tea_handler, 0, pdev->name,
+				gdev);
+	if (err < 0)
+		return err;
+
+	/* If we do not have a valid mask, assume all masters are enabled */
+	if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
+				&gdev->valid_mask))
+		gdev->valid_mask = 0xffffffff;
+
+	/* Proceed with reading the litteral names if we agree on the
+	 * number of masters
+	 */
+	num_masters = of_property_count_strings(dn,
+			"brcm,gisb-arb-master-names");
+	if (hweight_long(gdev->valid_mask) == num_masters) {
+		first = ffs(gdev->valid_mask) - 1;
+		last = fls(gdev->valid_mask) - 1;
+
+		for (i = first; i < last; i++) {
+			if (!(gdev->valid_mask & BIT(i)))
+				continue;
+
+			of_property_read_string_index(dn,
+					"brcm,gisb-arb-master-names", j,
+					&gdev->master_names[i]);
+			j++;
+		}
+	}
+
+	err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, gdev);
+
+	list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
+
+	dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",
+			gdev->base, timeout_irq, tea_irq);
+
+	return 0;
+}
+
+static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
+	{ .compatible = "brcm,gisb-arb" },
+	{ },
+};
+
+static struct platform_driver brcmstb_gisb_arb_driver = {
+	.probe	= brcmstb_gisb_arb_probe,
+	.driver = {
+		.name	= "brcm-gisb-arb",
+		.owner	= THIS_MODULE,
+		.of_match_table = brcmstb_gisb_arb_of_match,
+	},
+};
+
+static int __init brcm_gisb_driver_init(void)
+{
+	return platform_driver_register(&brcmstb_gisb_arb_driver);
+}
+
+module_init(brcm_gisb_driver_init);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] Documentation: devicetree: add Broadcom GISB arbiter bindings
  2014-05-14 19:10 [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler Florian Fainelli
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB arbiter bus " Florian Fainelli
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB bus arbiter " Florian Fainelli
@ 2014-05-14 19:10 ` Florian Fainelli
  2014-05-14 19:10 ` [PATCH 3/3] Documentation: sysfs: add Broadcom GISB arbiter sysfs properties Florian Fainelli
  3 siblings, 0 replies; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: marc.ceeeee, computersforpeace, gregory.0xf0, Florian Fainelli,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

This patch adds the Broadcom GISB arbiter Device Tree binding that is
used on all Broadcom Set-top-box System-on-a-chip.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 .../devicetree/bindings/bus/brcm,gisb-arb.txt      | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt

diff --git a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
new file mode 100644
index 000000000000..e2d501d20c9a
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
@@ -0,0 +1,30 @@
+Broadcom GISB bus Arbiter controller
+
+Required properties:
+
+- compatible: should be "brcm,gisb-arb"
+- reg: specifies the base physical address and size of the registers
+- interrupt-parent: specifies the phandle to the parent interrupt controller
+  this arbiter gets interrupt line from
+- interrupts: specifies the two interrupts (timeout and TEA) to be used from
+  the parent interrupt controller
+
+Optional properties:
+
+- brcm,gisb-arb-master-mask: 32-bits wide bitmask used to specify which GISB
+  masters are valid at the system level
+- brcm,gisb-arb-master-names: string list of the litteral name of the GISB
+  masters. Should match the number of bits set in brcm,gisb-master-mask and
+  the order in which they appear
+
+Example:
+
+gisb-arb@f0400000 {
+	compatible = "brcm,gisb-arb";
+	reg = <0xf0400000 0x800>;
+	interrupts = <0>, <2>;
+	interrupt-parent = <&sun_l2_intc>;
+
+	brcm,gisb-arb-master-mask = <0x7>;
+	brcm,gisb-arb-master-names = "bsp_0", "scpu_0", "cpu_0";
+};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] Documentation: sysfs: add Broadcom GISB arbiter sysfs properties
  2014-05-14 19:10 [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler Florian Fainelli
                   ` (2 preceding siblings ...)
  2014-05-14 19:10 ` [PATCH 2/3] Documentation: devicetree: add Broadcom GISB arbiter bindings Florian Fainelli
@ 2014-05-14 19:10 ` Florian Fainelli
  3 siblings, 0 replies; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: marc.ceeeee, computersforpeace, gregory.0xf0, Florian Fainelli,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

This patch documents the sysfs properties exposed by the Broadcom GISB
bus arbiter hardware.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb

diff --git a/Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb b/Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb
new file mode 100644
index 000000000000..f1bad92bbe27
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-brcmstb-gisb-arb
@@ -0,0 +1,8 @@
+What:		/sys/devices/../../gisb_arb_timeout
+Date:		May 2014
+KernelVersion:	3.17
+Contact:	Florian Fainelli <f.fainelli@gmail.com>
+Description:
+		Returns the currently configured raw timeout value of the
+		Broadcom Set Top Box internal GISB bus arbiter. Minimum value
+		is 1, and maximum value is 0xffffffff.
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] bus: add Broadcom GISB bus arbiter timeout/error handler
       [not found]   ` <5373C2EB.8020806@infradead.org>
@ 2014-05-14 19:26     ` Florian Fainelli
  0 siblings, 0 replies; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:26 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: linux-kernel, Marc Carino, Brian Norris, Gregory Fong,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Grant Likely, Shawn Guo, Sascha Hauer, Nicolas Pitre,
	Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION <linux-doc@vger.kernel.org>,
	open list:OPEN FIRMWARE AND...

2014-05-14 12:24 GMT-07:00 Randy Dunlap <rdunlap@infradead.org>:
> On 05/14/2014 12:10 PM, Florian Fainelli wrote:
>> This patch adds support for the Broadcom GISB arbiter bus timeout/error
>> handler. GISB is a proprietary bus used by Broadcom Set Top Box
>> System-on-a-chip devices (BCM7xxx) which allows multiple masters and
>> clients to be interfaced with each other.
>>
>> The bus arbiter offers support for generating two interrupts towards the
>> host CPU, thus allowing us to "catch" clock gated masters, or masters
>> being volontarily blocked for powersaving purposes, or do general system
>> troubleshooting.
>>
>> We also register a hook with the ARM fault exception handling to allow
>> printing a more informative message than "imprecise external abort at
>> 0x00000000" for instance.
>>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>>  drivers/bus/Kconfig        |  11 +-
>>  drivers/bus/Makefile       |   1 +
>>  drivers/bus/brcmstb_gisb.c | 289 +++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 300 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/bus/brcmstb_gisb.c
>>
>> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
>> index 552373c4e362..985db51c0b11 100644
>> --- a/drivers/bus/Kconfig
>> +++ b/drivers/bus/Kconfig
>> @@ -40,5 +40,14 @@ config ARM_CCI
>>       depends on ARM
>>       help
>>         Driver supporting the CCI cache coherent interconnect for ARM
>> -       platforms.
>> +       kplatforms.
>
> Is that a typo?  if not, what are kplatforms?

This is indeed a typo.
-- 
Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] bus: add Broadcom GISB arbiter bus timeout/error handler
  2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB arbiter bus " Florian Fainelli
@ 2014-05-14 19:33   ` Arnd Bergmann
  2014-05-14 19:46     ` Florian Fainelli
  0 siblings, 1 reply; 9+ messages in thread
From: Arnd Bergmann @ 2014-05-14 19:33 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-kernel, marc.ceeeee, computersforpeace, gregory.0xf0,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

On Wednesday 14 May 2014 12:10:46 Florian Fainelli wrote:
> This patch adds support for the Broadcom GISB arbiter bus timeout/error
> handler. GISB is a proprietary bus used by Broadcom Set Top Box
> System-on-a-chip devices (BCM7xxx) which allows multiple masters and
> clients to be interfaced with each other.
> 
> The bus arbiter offers support for generating two interrupts towards the
> host CPU, thus allowing us to "catch" clock gated masters, or masters
> being volontarily blocked for powersaving purposes, or do general system
> troubleshooting.
> 
> We also register a hook with the ARM fault exception handling to allow
> printing a more informative message than "imprecise external abort at
> 0x00000000" for instance.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Looks pretty good to me.

> +static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
> +					const char *reason)
> +{
> +	u32 cap_status;
> +	unsigned long arb_addr;
> +	u32 master;
> +	const char *m_name;
> +	char m_fmt[11];
> +
> +	cap_status = ioread32(gdev->base + ARB_ERR_CAP_STATUS);
> +
> +	/* Invalid captured address, bail out */
> +	if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
> +		return 1;
> +
> +	/* Read the address and master */
> +	arb_addr = ioread32(gdev->base + ARB_ERR_CAP_ADDR) & 0xffffffff;
> +#ifdef CONFIG_PHYS_ADDR_T_64BIT
> +	arb_addr |= (u64)ioread32(gdev->base + ARB_ERR_CAP_HI_ADDR) << 32;
> +#endif

Can you use 'if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))' here, or does that
cause a warning?

> +static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
> +				     struct pt_regs *regs)
> +{
> +	int ret = 0;
> +	struct brcmstb_gisb_arb_device *gdev;
> +
> +	/* iterate over each GISB arb registered handlers */
> +	list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
> +		ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
> +	/*
> +	 * If it was an imprecise abort, then we need to correct the
> +	 * return address to be _after_ the instruction.
> +	*/
> +	if (fsr & (1 << 10))
> +		regs->ARM_pc += 4;
> +
> +	return ret;
> +}

This will cause the normal abort handler to trigger if the GISB
arbiter doesn't know what happened, right?

	Arnd


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] bus: add Broadcom GISB arbiter bus timeout/error handler
  2014-05-14 19:33   ` Arnd Bergmann
@ 2014-05-14 19:46     ` Florian Fainelli
  2014-05-14 19:50       ` Arnd Bergmann
  0 siblings, 1 reply; 9+ messages in thread
From: Florian Fainelli @ 2014-05-14 19:46 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-kernel, Marc Carino, Brian Norris, Gregory Fong,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

2014-05-14 12:33 GMT-07:00 Arnd Bergmann <arnd@arndb.de>:
> On Wednesday 14 May 2014 12:10:46 Florian Fainelli wrote:
>> This patch adds support for the Broadcom GISB arbiter bus timeout/error
>> handler. GISB is a proprietary bus used by Broadcom Set Top Box
>> System-on-a-chip devices (BCM7xxx) which allows multiple masters and
>> clients to be interfaced with each other.
>>
>> The bus arbiter offers support for generating two interrupts towards the
>> host CPU, thus allowing us to "catch" clock gated masters, or masters
>> being volontarily blocked for powersaving purposes, or do general system
>> troubleshooting.
>>
>> We also register a hook with the ARM fault exception handling to allow
>> printing a more informative message than "imprecise external abort at
>> 0x00000000" for instance.
>>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Looks pretty good to me.

Cool, thanks!, BTW, which tree should we attempt to get this merged into?

>
>> +static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
>> +                                     const char *reason)
>> +{
>> +     u32 cap_status;
>> +     unsigned long arb_addr;
>> +     u32 master;
>> +     const char *m_name;
>> +     char m_fmt[11];
>> +
>> +     cap_status = ioread32(gdev->base + ARB_ERR_CAP_STATUS);
>> +
>> +     /* Invalid captured address, bail out */
>> +     if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
>> +             return 1;
>> +
>> +     /* Read the address and master */
>> +     arb_addr = ioread32(gdev->base + ARB_ERR_CAP_ADDR) & 0xffffffff;
>> +#ifdef CONFIG_PHYS_ADDR_T_64BIT
>> +     arb_addr |= (u64)ioread32(gdev->base + ARB_ERR_CAP_HI_ADDR) << 32;
>> +#endif
>
> Can you use 'if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))' here, or does that
> cause a warning?

No warning is issued, I will use that instead. Thanks!

>
>> +static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
>> +                                  struct pt_regs *regs)
>> +{
>> +     int ret = 0;
>> +     struct brcmstb_gisb_arb_device *gdev;
>> +
>> +     /* iterate over each GISB arb registered handlers */
>> +     list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
>> +             ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
>> +     /*
>> +      * If it was an imprecise abort, then we need to correct the
>> +      * return address to be _after_ the instruction.
>> +     */
>> +     if (fsr & (1 << 10))
>> +             regs->ARM_pc += 4;
>> +
>> +     return ret;
>> +}
>
> This will cause the normal abort handler to trigger if the GISB
> arbiter doesn't know what happened, right?

That's right, one of the very first things that the GISB arbiter
checks is whether the faulting error is valid or not, if it is not, it
bails out and so we keep on processing the other exception handlers.
-- 
Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] bus: add Broadcom GISB arbiter bus timeout/error handler
  2014-05-14 19:46     ` Florian Fainelli
@ 2014-05-14 19:50       ` Arnd Bergmann
  0 siblings, 0 replies; 9+ messages in thread
From: Arnd Bergmann @ 2014-05-14 19:50 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-kernel, Marc Carino, Brian Norris, Gregory Fong,
	Randy Dunlap, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Shawn Guo, Sascha Hauer,
	Nicolas Pitre, Lorenzo Pieralisi, Alexander Shiyan, Huang Shijie,
	open list:DOCUMENTATION, open list:OPEN FIRMWARE AND...

On Wednesday 14 May 2014 12:46:06 Florian Fainelli wrote:
> 2014-05-14 12:33 GMT-07:00 Arnd Bergmann <arnd@arndb.de>:
> > On Wednesday 14 May 2014 12:10:46 Florian Fainelli wrote:
> >> This patch adds support for the Broadcom GISB arbiter bus timeout/error
> >> handler. GISB is a proprietary bus used by Broadcom Set Top Box
> >> System-on-a-chip devices (BCM7xxx) which allows multiple masters and
> >> clients to be interfaced with each other.
> >>
> >> The bus arbiter offers support for generating two interrupts towards the
> >> host CPU, thus allowing us to "catch" clock gated masters, or masters
> >> being volontarily blocked for powersaving purposes, or do general system
> >> troubleshooting.
> >>
> >> We also register a hook with the ARM fault exception handling to allow
> >> printing a more informative message than "imprecise external abort at
> >> 0x00000000" for instance.
> >>
> >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> >
> > Looks pretty good to me.
> 
> Cool, thanks!, BTW, which tree should we attempt to get this merged into?

We can probably take it through arm-soc along with the other platform
specific changes for bcm7xxx, since there is no maintainer for drivers/bus yet.

> >> +static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
> >> +                                  struct pt_regs *regs)
> >> +{
> >> +     int ret = 0;
> >> +     struct brcmstb_gisb_arb_device *gdev;
> >> +
> >> +     /* iterate over each GISB arb registered handlers */
> >> +     list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
> >> +             ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
> >> +     /*
> >> +      * If it was an imprecise abort, then we need to correct the
> >> +      * return address to be _after_ the instruction.
> >> +     */
> >> +     if (fsr & (1 << 10))
> >> +             regs->ARM_pc += 4;
> >> +
> >> +     return ret;
> >> +}
> >
> > This will cause the normal abort handler to trigger if the GISB
> > arbiter doesn't know what happened, right?
> 
> That's right, one of the very first things that the GISB arbiter
> checks is whether the faulting error is valid or not, if it is not, it
> bails out and so we keep on processing the other exception handlers.

Ok, good.

	Arnd

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-05-14 19:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-14 19:10 [PATCH 0/3] bus: add Broadcom GISB bus arbiter timeout/error handler Florian Fainelli
2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB arbiter bus " Florian Fainelli
2014-05-14 19:33   ` Arnd Bergmann
2014-05-14 19:46     ` Florian Fainelli
2014-05-14 19:50       ` Arnd Bergmann
2014-05-14 19:10 ` [PATCH 1/3] bus: add Broadcom GISB bus arbiter " Florian Fainelli
     [not found]   ` <5373C2EB.8020806@infradead.org>
2014-05-14 19:26     ` Florian Fainelli
2014-05-14 19:10 ` [PATCH 2/3] Documentation: devicetree: add Broadcom GISB arbiter bindings Florian Fainelli
2014-05-14 19:10 ` [PATCH 3/3] Documentation: sysfs: add Broadcom GISB arbiter sysfs properties Florian Fainelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).