From 126e31faa12c0d40c3b603adb9ac6d72dd424860 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 8 Nov 2014 10:30:32 +1100 Subject: [PATCH 1/3] w1: omap-hdq: support device probing with device-tree This driver has no 'compatible' string and so is not found when using device-tree. Add one with value to match hdqw1w: 1w@480b2000 { device in omap3.dtsi. Signed-off-by: NeilBrown Acked-by: Evgeniy Polyakov Signed-off-by: Tony Lindgren --- .../devicetree/bindings/w1/omap-hdq.txt | 17 +++++++++++++++++ drivers/w1/masters/omap_hdq.c | 7 +++++++ 2 files changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/w1/omap-hdq.txt diff --git a/Documentation/devicetree/bindings/w1/omap-hdq.txt b/Documentation/devicetree/bindings/w1/omap-hdq.txt new file mode 100644 index 000000000000..fef794741bd1 --- /dev/null +++ b/Documentation/devicetree/bindings/w1/omap-hdq.txt @@ -0,0 +1,17 @@ +* OMAP HDQ One wire bus master controller + +Required properties: +- compatible : should be "ti,omap3-1w" +- reg : Address and length of the register set for the device +- interrupts : interrupt line. +- ti,hwmods : "hdq1w" + +Example: + +- From omap3.dtsi + hdqw1w: 1w@480b2000 { + compatible = "ti,omap3-1w"; + reg = <0x480b2000 0x1000>; + interrupts = <58>; + ti,hwmods = "hdq1w"; + }; diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 9900e8ec7393..03321d6a2684 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -72,11 +72,18 @@ struct hdq_data { static int omap_hdq_probe(struct platform_device *pdev); static int omap_hdq_remove(struct platform_device *pdev); +static struct of_device_id omap_hdq_dt_ids[] = { + { .compatible = "ti,omap3-1w" }, + {} +}; +MODULE_DEVICE_TABLE(of, omap_hdq_dt_ids); + static struct platform_driver omap_hdq_driver = { .probe = omap_hdq_probe, .remove = omap_hdq_remove, .driver = { .name = "omap_hdq", + .of_match_table = omap_hdq_dt_ids, }, }; From 61b43d4e919e8fa5e10c77ee32ba328da07e0264 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 10 Nov 2014 23:49:47 +0530 Subject: [PATCH 2/3] bus: omap_l3_noc: Add resume hook to restore context On certain SoCs such as AM437x SoC, L3_noc error registers are maintained in power domain such as per domain which looses context as part of low power state such as RTC+DDR mode. On these platforms when we mask interrupts which we cannot handle, the source of these interrupts still remain on resume, however, the flag mux registers now contain their reset value (unmasked) - this breaks the system with infinite interrupts since we do not these interrupts to take place ever again. To handle this: restore the masking of interrupts which we have already recorded in the system as ones we cannot handle. Fixes: 2100b595b7 ("bus: omap_l3_noc: ignore masked out unclearable targets") Acked-by: Nishanth Menon Signed-off-by: Keerthy Signed-off-by: Tony Lindgren --- drivers/bus/omap_l3_noc.c | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index 531ae591783b..b5eac29d8f6e 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -296,11 +296,66 @@ static int omap_l3_probe(struct platform_device *pdev) return ret; } +#ifdef CONFIG_PM + +/** + * l3_resume_noirq() - resume function for l3_noc + * @dev: pointer to l3_noc device structure + * + * We only have the resume handler only since we + * have already maintained the delta register + * configuration as part of configuring the system + */ +static int l3_resume_noirq(struct device *dev) +{ + struct omap_l3 *l3 = dev_get_drvdata(dev); + int i; + struct l3_flagmux_data *flag_mux; + void __iomem *base, *mask_regx = NULL; + u32 mask_val; + + for (i = 0; i < l3->num_modules; i++) { + base = l3->l3_base[i]; + flag_mux = l3->l3_flagmux[i]; + if (!flag_mux->mask_app_bits && !flag_mux->mask_dbg_bits) + continue; + + mask_regx = base + flag_mux->offset + L3_FLAGMUX_MASK0 + + (L3_APPLICATION_ERROR << 3); + mask_val = readl_relaxed(mask_regx); + mask_val &= ~(flag_mux->mask_app_bits); + + writel_relaxed(mask_val, mask_regx); + mask_regx = base + flag_mux->offset + L3_FLAGMUX_MASK0 + + (L3_DEBUG_ERROR << 3); + mask_val = readl_relaxed(mask_regx); + mask_val &= ~(flag_mux->mask_dbg_bits); + + writel_relaxed(mask_val, mask_regx); + } + + /* Dummy read to force OCP barrier */ + if (mask_regx) + (void)readl(mask_regx); + + return 0; +} + +static const struct dev_pm_ops l3_dev_pm_ops = { + .resume_noirq = l3_resume_noirq, +}; + +#define L3_DEV_PM_OPS (&l3_dev_pm_ops) +#else +#define L3_DEV_PM_OPS NULL +#endif + static struct platform_driver omap_l3_driver = { .probe = omap_l3_probe, .driver = { .name = "omap_l3_noc", .owner = THIS_MODULE, + .pm = L3_DEV_PM_OPS, .of_match_table = of_match_ptr(l3_noc_match), }, }; From c4cf0935a2d8fe6d186bf4253ea3c4b4a8a8a710 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 10 Nov 2014 23:49:48 +0530 Subject: [PATCH 3/3] bus: omap_l3_noc: Correct returning IRQ_HANDLED unconditionally in the irq handler Correct returning IRQ_HANDLED unconditionally in the irq handler. Return IRQ_NONE for some interrupt which we do not expect to be handled in this handler. This prevents kernel stalling with back to back spurious interrupts. Fixes: 2722e56de6 ("OMAP4: l3: Introduce l3-interconnect error handling driver") Acked-by: Nishanth Menon Signed-off-by: Keerthy Signed-off-by: Tony Lindgren --- drivers/bus/omap_l3_noc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index b5eac29d8f6e..17d86595951c 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -222,10 +222,14 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) } /* Error found so break the for loop */ - break; + return IRQ_HANDLED; } } - return IRQ_HANDLED; + + dev_err(l3->dev, "L3 %s IRQ not handled!!\n", + inttype ? "debug" : "application"); + + return IRQ_NONE; } static const struct of_device_id l3_noc_match[] = {