From f1bee783dd37d088a8a7924205476ba1cf675378 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 18 Sep 2014 12:32:10 -0700 Subject: bus: brcmstb_gisb: register the fault code hook Commit 44127b771d9c31 ("bus: add Broadcom GISB bus arbiter timeout/error handler") added everything that is required to register an ARM fault handler for imprecise external aborts, except that there is nothing calling this currently. We do not need to export that specific function and have to update arch/arm/mach-bcm/brcmstb.c to call it, simply, register the fault handler during the probe() function of the driver. Signed-off-by: Florian Fainelli --- drivers/bus/brcmstb_gisb.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/bus/brcmstb_gisb.c') diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index f2cd6a2d..41b0941 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -160,12 +160,6 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr, 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"); @@ -261,6 +255,9 @@ static int brcmstb_gisb_arb_probe(struct platform_device *pdev) list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); + hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, + "imprecise external abort"); + dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", gdev->base, timeout_irq, tea_irq); -- cgit v1.1 From 203bb85ed605e43eadca62afb3a8cd128a8ec10a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 18 Sep 2014 12:37:14 -0700 Subject: bus: brcmstb_gisb: save and restore GISB timeout When the system enters S3, we will lose the GISB timeout value we have configured, make sure that we do save this timeout value, and restore this timeout value prior to re-enabling interrupts such that the GISB timeout interrupt will fire with the expected timeout. Signed-off-by: Florian Fainelli --- drivers/bus/brcmstb_gisb.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/bus/brcmstb_gisb.c') diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index 41b0941..e7ccd21 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ struct brcmstb_gisb_arb_device { struct list_head next; u32 valid_mask; const char *master_names[sizeof(u32) * BITS_PER_BYTE]; + u32 saved_timeout; }; static LIST_HEAD(brcmstb_gisb_arb_device_list); @@ -264,6 +266,39 @@ static int brcmstb_gisb_arb_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int brcmstb_gisb_arb_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); + + gdev->saved_timeout = ioread32(gdev->base + ARB_TIMER); + + return 0; +} + +/* Make sure we provide the same timeout value that was configured before, and + * do this before the GISB timeout interrupt handler has any chance to run. + */ +static int brcmstb_gisb_arb_resume_noirq(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); + + iowrite32(gdev->saved_timeout, gdev->base + ARB_TIMER); + + return 0; +} +#else +#define brcmstb_gisb_arb_suspend NULL +#define brcmstb_gisb_arb_resume_noirq NULL +#endif + +static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = { + .suspend = brcmstb_gisb_arb_suspend, + .resume_noirq = brcmstb_gisb_arb_resume_noirq, +}; + static const struct of_device_id brcmstb_gisb_arb_of_match[] = { { .compatible = "brcm,gisb-arb" }, { }, @@ -275,6 +310,7 @@ static struct platform_driver brcmstb_gisb_arb_driver = { .name = "brcm-gisb-arb", .owner = THIS_MODULE, .of_match_table = brcmstb_gisb_arb_of_match, + .pm = &brcmstb_gisb_arb_pm_ops, }, }; -- cgit v1.1