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

Commit 9eb60880 authored by Doug Berger's avatar Doug Berger Committed by Florian Fainelli
Browse files

bus: brcmstb_gisb: add notifier handling



Check for GISB arbitration errors through a chained notifier
when a process dies or a kernel panic occurs.  This allows a
meaningful GISB diagnostic message to occur along with other
diagnostic information from the event.

Signed-off-by: default avatarDoug Berger <opendmb@gmail.com>
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
parent 0c2aa0e4
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@
#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/pm.h>
#include <linux/kernel.h>
#include <linux/kdebug.h>
#include <linux/notifier.h>

#ifdef CONFIG_ARM
#include <asm/bug.h>
@@ -283,6 +286,36 @@ static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
	return IRQ_HANDLED;
}

/*
 * Dump out gisb errors on die or panic.
 */
static int dump_gisb_error(struct notifier_block *self, unsigned long v,
			   void *p);

static struct notifier_block gisb_die_notifier = {
	.notifier_call = dump_gisb_error,
};

static struct notifier_block gisb_panic_notifier = {
	.notifier_call = dump_gisb_error,
};

static int dump_gisb_error(struct notifier_block *self, unsigned long v,
			   void *p)
{
	struct brcmstb_gisb_arb_device *gdev;
	const char *reason = "panic";

	if (self == &gisb_die_notifier)
		reason = "die";

	/* iterate over each GISB arb registered handlers */
	list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
		brcmstb_gisb_arb_decode_addr(gdev, reason);

	return NOTIFY_DONE;
}

static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
		gisb_arb_get_timeout, gisb_arb_set_timeout);

@@ -390,6 +423,12 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
	board_be_handler = brcmstb_bus_error_handler;
#endif

	if (list_is_singular(&brcmstb_gisb_arb_device_list)) {
		register_die_notifier(&gisb_die_notifier);
		atomic_notifier_chain_register(&panic_notifier_list,
					       &gisb_panic_notifier);
	}

	dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",
			gdev->base, timeout_irq, tea_irq);