Re: [PATCH v2 2/3] soc: brcmstb: Add Bus Interface Unit control setup

2015-09-18 Thread Gregory Fong
On Thu, Sep 17, 2015 at 10:42 AM, Florian Fainelli  wrote:
> On 16/09/15 23:08, Gregory Fong wrote:
>>> [...]
>>> diff --git a/drivers/soc/brcmstb/biuctrl.c b/drivers/soc/brcmstb/biuctrl.c
>>> new file mode 100644
>>> index ..1d4deada1c4d
>>> --- /dev/null
>>> +++ b/drivers/soc/brcmstb/biuctrl.c
>>> @@ -0,0 +1,119 @@
>>> [...]
>>> +int __init brcmstb_biuctrl_init(void)
>>> +{
>>> +   int ret = 0;
>>> +
>>> +   ret = setup_hifcpubiuctrl_regs();
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   ret = mcp_write_pairing_set();
>>> +   if (ret) {
>>> +   pr_err("MCP: Unable to disable write pairing!\n");
>>> +   return ret;
>>
>> The return value isn't used in patch 3.  Is there a point to returning
>> an error from this function in either of the above two locations,
>> considering that?
>>
>> Looks good otherwise.
>>
>> Acked-by: Gregory Fong 
>
> Not really, how about this:
>
> void __init brcmstb_biuctrl_init(void)
> {
> int ret;
>
> setup_hifcpubiuctrl_regs();
>
> ret = mcp_write_pairing_set();
> if (ret) {
> pr_err("MCP: Unable to disable write pairing!\n");
> return;
> }
>
> #ifdef CONFIG_PM_SLEEP
> register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
> #endif
> }
>
> and updating the function prototype accordingly in the header file?

Sure, that works.

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/3] ARM: brcmstb: Setup BIU control registers during boot

2015-09-16 Thread Gregory Fong
On Tue, Sep 15, 2015 at 11:15 AM, Florian Fainelli  wrote:
> Call brcmstb_biuctrl_init() in brcmstb's init_irq machine descriptor
> callback since we need to setup the Bus Interface Unit before SMP in
> particular, but we also need to be able to remap registers.
>
> Signed-off-by: Florian Fainelli 

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] Documentation: bindings: brcmstb: Document write-pairing

2015-09-16 Thread Gregory Fong
On Tue, Sep 15, 2015 at 11:14 AM, Florian Fainelli  wrote:
> Document the hif-cpubiuctrl node a bit more, and add a documentation
> entry for the optional "brcm,write-pairing" property.
>
> Signed-off-by: Florian Fainelli 

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/3] soc: brcmstb: Add Bus Interface Unit control setup

2015-09-16 Thread Gregory Fong
On Tue, Sep 15, 2015 at 11:14 AM, Florian Fainelli  wrote:
> Broadcom STB SoCs (brcmstb) require an early setup of their Bus
> Interface Unit control register, this needs to happen before SMP is
> brought up because it affects how the CPU complex will be interfaced to
> the memory controller.
>
> Add support code which properly initializes the BIU registers based on
> whether "brcm,write-pairing" is present in Device Tree, and take care of
> saving and restoring credit register settings during system-wide
> suspend/resume operations.
>
> Signed-off-by: Florian Fainelli 
> ---
> Changes in v2:
>
> - add a pr_fmt prefix which is more descriptive
>
>  drivers/soc/brcmstb/Makefile|   2 +-
>  drivers/soc/brcmstb/biuctrl.c   | 119 
> 
>  include/linux/soc/brcmstb/brcmstb.h |  10 +++
>  3 files changed, 130 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/soc/brcmstb/biuctrl.c
>  create mode 100644 include/linux/soc/brcmstb/brcmstb.h
>
> [...]
> diff --git a/drivers/soc/brcmstb/biuctrl.c b/drivers/soc/brcmstb/biuctrl.c
> new file mode 100644
> index ..1d4deada1c4d
> --- /dev/null
> +++ b/drivers/soc/brcmstb/biuctrl.c
> @@ -0,0 +1,119 @@
> [...]
> +int __init brcmstb_biuctrl_init(void)
> +{
> +   int ret = 0;
> +
> +   ret = setup_hifcpubiuctrl_regs();
> +   if (ret)
> +   return ret;
> +
> +   ret = mcp_write_pairing_set();
> +   if (ret) {
> +   pr_err("MCP: Unable to disable write pairing!\n");
> +   return ret;

The return value isn't used in patch 3.  Is there a point to returning
an error from this function in either of the above two locations,
considering that?

Looks good otherwise.

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] watchdog: Watchdog driver for Broadcom Set-Top Box

2015-08-27 Thread Gregory Fong
Gah, sorry, my email client did something really weird.  Sorry for the
duplication, please don't reply to those.

-- 
Gregory--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] watchdog: bcm7038: add device tree binding documentation

2015-08-27 Thread Gregory Fong
Add device tree binding documentation for the watchdog hardware block
on bcm7038 and newer SoCs.

Signed-off-by: Justin Chen 
---
 .../devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt | 19 +++
 1 file changed, 19 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt 
b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt
new file mode 100644
index 000..39e5cf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt
@@ -0,0 +1,19 @@
+BCM7038 Watchdog timer
+
+Required properties:
+
+- compatible : should be "brcm,bcm7038-wdt"
+- reg : Specifies base physical address and size of the registers.
+
+Optional properties:
+
+- clocks: The clock running the watchdog. If no clock is found the
+ driver will default to 2700 HZ.
+
+Example:
+
+watchdog {
+   compatible = "brcm,bcm7038-wdt";
+   clocks = <&upg_fixed>;
+   reg = <0xf040a7e8 0x16>;
+};
-- 
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] watchdog: Watchdog driver for Broadcom Set-Top Box

2015-08-27 Thread Gregory Fong
Watchdog driver for Broadcom 7038 and newer chips.

Signed-off-by: Justin Chen 
---
 drivers/watchdog/Kconfig   |   8 ++
 drivers/watchdog/Makefile  |   1 +
 drivers/watchdog/bcm7038_wdt.c | 235 +
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/watchdog/bcm7038_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 241fafd..4fbe8ab 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1291,6 +1291,14 @@ config BCM_KONA_WDT_DEBUG
 
  If in doubt, say 'N'.
 
+config BCM7038_WDT
+   tristate "BCM7038 Watchdog"
+   select WATCHDOG_CORE
+   help
+Watchdog driver for the built-in hardware in Broadcom 7038 SoCs.
+
+Say 'Y or 'M' here to enable the driver.
+
 config IMGPDC_WDT
tristate "Imagination Technologies PDC Watchdog Timer"
depends on HAS_IOMEM
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 59ea9a1..65d4169 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
 obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
 obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
 obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
+obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
 
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c
new file mode 100644
index 000..5e54c1b
--- /dev/null
+++ b/drivers/watchdog/bcm7038_wdt.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define WDT_START_10xff00
+#define WDT_START_20x00ff
+#define WDT_STOP_1 0xee00
+#define WDT_STOP_2 0x00ee
+
+#define WDT_TIMEOUT_REG0x0
+#define WDT_CMD_REG0x4
+
+#define WDT_MIN_TIMEOUT1 /* seconds */
+#define WDT_DEFAULT_TIMEOUT30 /* seconds */
+#define WDT_DEFAULT_RATE   2700
+
+struct bcm7038_watchdog {
+   void __iomem*base;
+   struct watchdog_device  wdd;
+   u32 rate;
+   struct clk  *clk;
+};
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+static void bcm7038_wdt_set_timeout_reg(struct watchdog_device *wdog)
+{
+   struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog);
+   u32 timeout;
+
+   timeout = wdt->rate * wdog->timeout;
+
+   writel(timeout, wdt->base + WDT_TIMEOUT_REG);
+}
+
+static int bcm7038_wdt_ping(struct watchdog_device *wdog)
+{
+   struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog);
+
+   writel(WDT_START_1, wdt->base + WDT_CMD_REG);
+   writel(WDT_START_2, wdt->base + WDT_CMD_REG);
+
+   return 0;
+}
+
+static int bcm7038_wdt_start(struct watchdog_device *wdog)
+{
+   bcm7038_wdt_set_timeout_reg(wdog);
+   bcm7038_wdt_ping(wdog);
+
+   return 0;
+}
+
+static int bcm7038_wdt_stop(struct watchdog_device *wdog)
+{
+   struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog);
+
+   writel(WDT_STOP_1, wdt->base + WDT_CMD_REG);
+   writel(WDT_STOP_2, wdt->base + WDT_CMD_REG);
+
+   return 0;
+}
+
+static int bcm7038_wdt_set_timeout(struct watchdog_device *wdog,
+  unsigned int t)
+{
+   /* Can't modify timeout value if watchdog timer is running */
+   bcm7038_wdt_stop(wdog);
+   wdog->timeout = t;
+   bcm7038_wdt_start(wdog);
+
+   return 0;
+}
+
+static unsigned int bcm7038_wdt_get_timeleft(struct watchdog_device *wdog)
+{
+   struct bcm7038_watchdog *wdt = watchdog_get_drvdata(wdog);
+   u32 time_left;
+
+   time_left = readl(wdt->base + WDT_CMD_REG);
+
+   return time_left / wdt->rate;
+}
+
+static struct watchdog_info bcm7038_wdt_info = {
+   .identity   = "Broadcom BCM7038 Watchdog Timer",
+   .options= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+   WDIOF_MAGICCLOSE
+};
+
+static struct watchdog_ops bcm7038_wdt_ops = {
+   .owner  = THIS_MODULE,
+   .start  = bcm7038_wdt_start,
+   .stop   = bcm7038_wdt_stop,
+   .set_timeout= bcm7038_wdt_set_timeout,
+   .get_timeleft   = bcm7038_wdt_get_timeleft,
+};
+
+static int bcm7038_wdt_probe(struct platform_device *pdev)
+{
+   struct devic

[PATCH v2 0/2] watchdog: driver for BCM7038 and newer chips.

2015-08-27 Thread Gregory Fong
This driver is for a watchdog block contained in all Broadcom Set-top
Box chips since BCM7038. BCM7038 was made public during the 2004 CES,
and since then, many chips use this watchdog block including some cable
modem chips.

Changes since v1:
Removed clock-frequency because it brought unnecessary complexity to the
driver.
Renamed a few variables.

Patch 1: watchdog device tree binding documentation

Patch 2: watchdog driver

Justin Chen (2):
  watchdog: bcm7038: add device tree binding documentation
  watchdog: Watchdog driver for Broadcom Set-Top Box

 .../bindings/watchdog/brcm,bcm7038-wdt.txt |  19 ++
 drivers/watchdog/Kconfig   |   8 +
 drivers/watchdog/Makefile  |   1 +
 drivers/watchdog/bcm7038_wdt.c | 235 +
 4 files changed, 263 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.txt
 create mode 100644 drivers/watchdog/bcm7038_wdt.c

-- 
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 2/4] gpio: brcmstb: Add interrupt and wakeup source support

2015-08-13 Thread Gregory Fong
On Thu, Aug 13, 2015 at 4:11 AM, Linus Walleij  wrote:
> On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong  wrote:
>
>> Uses the gpiolib irqchip helpers.  For this to work, the irq setup
>> function is called once per bank instead of once per device.  Note
>> that all known uses of this block have a BCM7120 L2 interrupt
>> controller as a parent.  Supports interrupts for all GPIOs.
>>
>> In the IRQ handler, we check for raised IRQs for invalid GPIOs and
>> warn (ratelimited) if they're encountered.
>>
>> Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
>> configured as wakeup sources, and this GPIO controller supports that
>> through a separate interrupt path.
>>
>> The de-facto standard DT property "wakeup-source" is checked, since
>> that indicates whether the GPIO controller hardware can wake.  Uses
>> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
>> any of its own wakeup source configuration.
>>
>> Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
>> that you can have multiple chained irqchips and associated IRQ domains
>> for a single parent IRQ, and as long as the xlate function is written
>> correctly, a GPIO IRQ request end up checking the correct domain and
>> will get associated with the correct IRQ.  What helps make this clear
>> is to read
>>   drivers/gpio/gpiolib-of.c:
>>- of_gpiochip_find_and_xlate()
>>- of_get_named_gpiod_flags()
>>   drivers/gpio/gpiolib.c:
>>- gpiochip_find()
>>
>> Signed-off-by: Gregory Fong 
>> ---
>> v4:
>> - when checking parent_irq, use <= 0 or > 0 since 0 is NO_IRQ.
>
> Patch applied, but:
>
>
>> +   if (of_property_read_bool(np, "interrupt-controller")) {
>> +   priv->parent_irq = platform_get_irq(pdev, 0);
>> +   if (priv->parent_irq <= 0) {
>> +   dev_err(dev, "Couldn't get IRQ");
>> +   return -ENOENT;
>> +   }
>> +   } else {
>> +   priv->parent_irq = -ENOENT;
>> +   }
>> +
>> if (brcmstb_gpio_sanity_check_banks(dev, np, res))
>> return -EINVAL;
>
> This patch does not apply cleanly because the version in my
> tree has INIT_LIST_HEAD(&priv->bank_list);
> before the sanity check.
>
> I applied it manually, but check that things are working right.

Your tree seems to be missing

commit 2252607d327d5219a6331b50e6ec266d56402be0
Author: Gregory Fong 
Date:   Wed Jun 17 18:00:40 2015 -0700

gpio: brcmstb: fix null ptr dereference in driver remove

which you had pulled in and sent for 4.2-rc1.  It should apply cleanly
on top of that.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 1/4] dt-bindings: brcmstb-gpio: document properties for wakeup

2015-07-31 Thread Gregory Fong
Some brcmstb GPIO controllers can be used to wake from suspend, so use
the de facto standard property 'wakeup-source' to mark the nodes of
controllers with that capability.

Also document interrupts-extended, which will be used for wakeup
handling because the interrupt parent for the wake IRQ is different
from the regular IRQ.

While we're at it, a few more fixes: We don't actually use the
"interrupt-names" property, so remove it from the listed optional
properties and from the examples.  And since we're modifying the
examples, also follow Brian's suggestions to:
- change #gpio-cells, #interrupt-cells, and brcm,gpio-bank-widths from
  hex to dec
- use phandles

Reviewed-by: Brian Norris 
Acked-by: Florian Fainelli 
Signed-off-by: Gregory Fong 
---
v4: no changes from v3

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt | 35 +-
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt 
b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
index 435f1bc..b405b44 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
@@ -33,6 +33,13 @@ Optional properties:
 - interrupt-parent:
 phandle of the parent interrupt controller
 
+- interrupts-extended:
+Alternate form of specifying interrupts and parents that allows for
+multiple parents.  This takes precedence over 'interrupts' and
+'interrupt-parent'.  Wakeup-capable GPIO controllers often route their
+wakeup interrupt lines through a different interrupt controller than the
+primary interrupt line, making this property necessary.
+
 - #interrupt-cells:
 Should be <2>.  The first cell is the GPIO number, the second should 
specify
 flags.  The following subset of flags is supported:
@@ -47,19 +54,33 @@ Optional properties:
 - interrupt-controller:
 Marks the device node as an interrupt controller
 
-- interrupt-names:
-The name of the IRQ resource used by this controller
+- wakeup-source:
+GPIOs for this controller can be used as a wakeup source
 
 Example:
upg_gio: gpio@f040a700 {
-   #gpio-cells = <0x2>;
-   #interrupt-cells = <0x2>;
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
gpio-controller;
interrupt-controller;
reg = <0xf040a700 0x80>;
-   interrupt-parent = <0xf>;
+   interrupt-parent = <&irq0_intc>;
+   interrupts = <0x6>;
+   brcm,gpio-bank-widths = <32 32 32 24>;
+   };
+
+   upg_gio_aon: gpio@f04172c0 {
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
+   compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
+   gpio-controller;
+   interrupt-controller;
+   reg = <0xf04172c0 0x40>;
+   interrupt-parent = <&irq0_aon_intc>;
interrupts = <0x6>;
-   interrupt-names = "upg_gio";
-   brcm,gpio-bank-widths = <0x20 0x20 0x20 0x18>;
+   interrupts-extended = <&irq0_aon_intc 0x6>,
+   <&aon_pm_l2_intc 0x5>;
+   wakeup-source;
+   brcm,gpio-bank-widths = <18 4>;
};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 4/4] ARM: dts: brcmstb: add BCM7445 GPIO nodes

2015-07-31 Thread Gregory Fong
Need the aon_pm_l2_intc and irq0_aon_intc descriptions, so included
those as well.

Signed-off-by: Gregory Fong 
---
New in v4.

 arch/arm/boot/dts/bcm7445.dtsi | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm/boot/dts/bcm7445.dtsi b/arch/arm/boot/dts/bcm7445.dtsi
index 58dcd66..3b6b175 100644
--- a/arch/arm/boot/dts/bcm7445.dtsi
+++ b/arch/arm/boot/dts/bcm7445.dtsi
@@ -109,6 +109,20 @@
brcm,int-fwd-mask = <0x7>;
};
 
+   irq0_aon_intc: interrupt-controller@417280 {
+   compatible = "brcm,bcm7120-l2-intc";
+   reg = <0x417280 0x8>;
+   interrupt-parent = <&gic>;
+   #interrupt-cells = <1>;
+   interrupt-controller;
+   interrupts = ,
+,
+;
+   brcm,int-map-mask = <0x1e3 0x1800 0x10>;
+   brcm,int-fwd-mask = <0x0>;
+   brcm,irq-can-wake;
+   };
+
hif_intr2_intc: interrupt-controller@3e1000 {
compatible = "brcm,l2-intc";
reg = <0x3e1000 0x30>;
@@ -119,6 +133,16 @@
interrupt-names = "hif";
};
 
+aon_pm_l2_intc: interrupt-controller@410640 {
+   compatible = "brcm,l2-intc";
+   reg = <0x410640 0x30>;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+   interrupts = ;
+   interrupt-parent = <&gic>;
+   brcm,irq-can-wake;
+   };
+
nand: nand@3e2800 {
status = "disabled";
#address-cells = <1>;
@@ -167,6 +191,32 @@
#phy-cells = <0>;
};
};
+
+   upg_gio: gpio@40a700 {
+   compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
+   reg = <0x40a700 0x80>;
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
+   gpio-controller;
+   interrupt-controller;
+   interrupt-parent = <&irq0_intc>;
+   interrupts = <6>;
+   brcm,gpio-bank-widths = <32 32 32 24>;
+   };
+
+   upg_gio_aon: gpio@4172c0 {
+   compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
+   reg = <0x4172c0 0x40>;
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
+   gpio-controller;
+   interrupt-controller;
+   interrupts-extended = <&irq0_aon_intc 0x6>,
+ <&aon_pm_l2_intc 0x5>;
+   wakeup-source;
+   brcm,gpio-bank-widths = <18 4>;
+   };
+
};
 
smpboot {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 3/4] gpio: brcmstb: support wakeup from S5 cold boot

2015-07-31 Thread Gregory Fong
For wake from S5, we need to:
- register a reboot handler
- set wakeup capability before requesting IRQ so wakeup count is
  incremented
- mask all GPIO IRQs and clear any pending interrupts during driver
  probe to since no driver will yet be registered to handle any IRQs
  carried over from boot at that time, and it's possible that the
  booted kernel does not request the same IRQ anyway.

This means that /sys/.../power/wakeup_count is valid at boot time, and
we can properly account for S5 wakeup stats. e.g.:

  ### After waking from S5 from a GPIO key
  # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup
  enabled
  # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup_count
  1

Signed-off-by: Gregory Fong 
---
v4: rename __brcmstb_gpio_irq_set_wake() to brcmstb_gpio_priv_set_wake().

 drivers/gpio/gpio-brcmstb.c | 56 -
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 46cc4e9..9ea86d2 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -48,6 +49,7 @@ struct brcmstb_gpio_priv {
int gpio_base;
bool can_wake;
int parent_wake_irq;
+   struct notifier_block reboot_notifier;
 };
 
 #define MAX_GPIO_PER_BANK   32
@@ -167,10 +169,9 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, 
unsigned int type)
return 0;
 }
 
-static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
+static int brcmstb_gpio_priv_set_wake(struct brcmstb_gpio_priv *priv,
+   unsigned int enable)
 {
-   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
int ret = 0;
 
/*
@@ -188,6 +189,14 @@ static int brcmstb_gpio_irq_set_wake(struct irq_data *d, 
unsigned int enable)
return ret;
 }
 
+static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
+
+   return brcmstb_gpio_priv_set_wake(priv, enable);
+}
+
 static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data)
 {
struct brcmstb_gpio_priv *priv = data;
@@ -246,6 +255,19 @@ static void brcmstb_gpio_irq_handler(unsigned int irq, 
struct irq_desc *desc)
chained_irq_exit(chip, desc);
 }
 
+static int brcmstb_gpio_reboot(struct notifier_block *nb,
+   unsigned long action, void *data)
+{
+   struct brcmstb_gpio_priv *priv =
+   container_of(nb, struct brcmstb_gpio_priv, reboot_notifier);
+
+   /* Enable GPIO for S5 cold boot */
+   if (action == SYS_POWER_OFF)
+   brcmstb_gpio_priv_set_wake(priv, 1);
+
+   return NOTIFY_DONE;
+}
+
 /* Make sure that the number of banks matches up between properties */
 static int brcmstb_gpio_sanity_check_banks(struct device *dev,
struct device_node *np, struct resource *res)
@@ -285,6 +307,12 @@ static int brcmstb_gpio_remove(struct platform_device 
*pdev)
if (ret)
dev_err(&pdev->dev, "gpiochip_remove fail in 
cleanup\n");
}
+   if (priv->reboot_notifier.notifier_call) {
+   ret = unregister_reboot_notifier(&priv->reboot_notifier);
+   if (ret)
+   dev_err(&pdev->dev,
+   "failed to unregister reboot notifier\n");
+   }
return ret;
 }
 
@@ -342,7 +370,16 @@ static int brcmstb_gpio_irq_setup(struct platform_device 
*pdev,
dev_warn(dev,
"Couldn't get wake IRQ - GPIOs will not be able 
to wake from sleep");
} else {
-   int err = devm_request_irq(dev, priv->parent_wake_irq,
+   int err;
+
+   /*
+* Set wakeup capability before requesting wakeup
+* interrupt, so we can process boot-time "wakeups"
+* (e.g., from S5 cold boot)
+*/
+   device_set_wakeup_capable(dev, true);
+   device_wakeup_enable(dev);
+   err = devm_request_irq(dev, priv->parent_wake_irq,
brcmstb_gpio_wake_irq_handler, 0,
"brcmstb-gpio-wake", priv);
 
@@ -351,8 +388,9 @@ static int brcmstb_gpio_irq_setup(struct platform_device 
*pdev,
return err;
}
 
-   

[PATCH v4 2/4] gpio: brcmstb: Add interrupt and wakeup source support

2015-07-31 Thread Gregory Fong
Uses the gpiolib irqchip helpers.  For this to work, the irq setup
function is called once per bank instead of once per device.  Note
that all known uses of this block have a BCM7120 L2 interrupt
controller as a parent.  Supports interrupts for all GPIOs.

In the IRQ handler, we check for raised IRQs for invalid GPIOs and
warn (ratelimited) if they're encountered.

Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
configured as wakeup sources, and this GPIO controller supports that
through a separate interrupt path.

The de-facto standard DT property "wakeup-source" is checked, since
that indicates whether the GPIO controller hardware can wake.  Uses
the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
any of its own wakeup source configuration.

Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
that you can have multiple chained irqchips and associated IRQ domains
for a single parent IRQ, and as long as the xlate function is written
correctly, a GPIO IRQ request end up checking the correct domain and
will get associated with the correct IRQ.  What helps make this clear
is to read
  drivers/gpio/gpiolib-of.c:
   - of_gpiochip_find_and_xlate()
   - of_get_named_gpiod_flags()
  drivers/gpio/gpiolib.c:
   - gpiochip_find()

Signed-off-by: Gregory Fong 
---
v4:
- when checking parent_irq, use <= 0 or > 0 since 0 is NO_IRQ.

 drivers/gpio/Kconfig|   1 +
 drivers/gpio/gpio-brcmstb.c | 262 +++-
 2 files changed, 257 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8f1fe73..0b77175 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -131,6 +131,7 @@ config GPIO_BRCMSTB
default y if ARCH_BRCMSTB
depends on OF_GPIO && (ARCH_BRCMSTB || COMPILE_TEST)
select GPIO_GENERIC
+   select GPIOLIB_IRQCHIP
help
  Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
 
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 4630a81..46cc4e9 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -17,6 +17,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -34,14 +37,17 @@ struct brcmstb_gpio_bank {
struct bgpio_chip bgc;
struct brcmstb_gpio_priv *parent_priv;
u32 width;
+   struct irq_chip irq_chip;
 };
 
 struct brcmstb_gpio_priv {
struct list_head bank_list;
void __iomem *reg_base;
-   int num_banks;
struct platform_device *pdev;
+   int parent_irq;
int gpio_base;
+   bool can_wake;
+   int parent_wake_irq;
 };
 
 #define MAX_GPIO_PER_BANK   32
@@ -63,6 +69,183 @@ brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
return bank->parent_priv;
 }
 
+static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
+   unsigned int offset, bool enable)
+{
+   struct bgpio_chip *bgc = &bank->bgc;
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = bgc->pin2mask(bgc, offset);
+   u32 imask;
+   unsigned long flags;
+
+   spin_lock_irqsave(&bgc->lock, flags);
+   imask = bgc->read_reg(priv->reg_base + GIO_MASK(bank->id));
+   if (enable)
+   imask |= mask;
+   else
+   imask &= ~mask;
+   bgc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
+   spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+/*  IRQ chip functions  */
+
+static void brcmstb_gpio_irq_mask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+
+   brcmstb_gpio_set_imask(bank, d->hwirq, false);
+}
+
+static void brcmstb_gpio_irq_unmask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+
+   brcmstb_gpio_set_imask(bank, d->hwirq, true);
+}
+
+static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = BIT(d->hwirq);
+   u32 edge_insensitive, iedge_insensitive;
+   u32 edge_config, iedge_config;
+   u32 level, ilevel;
+   unsigned long flags;
+
+   switch (type) {
+   case IRQ_TYPE_LEVEL_LOW:
+   level = 0;
+   edge_config = 0;
+   edge_insensitive = 0;
+   break;
+   case IRQ_TYPE_LEVEL_HIGH:
+   level = mask;
+   edge_conf

[PATCH v4 0/4] GPIO support for BRCMSTB

2015-07-31 Thread Gregory Fong
Adds interrupt support for the GPIO controller (UPG GIO) used on Broadcom's
various BRCMSTB SoCs (BCM7XXX and others).  For all existing hardware, this
block hooks up to the BCM7120 L2 IRQ controller and so will require
CONFIG_BCM7120_L2_IRQ=y.

New in v4:
- add nodes for the BRCMSTB GPIO controller to the BCM7445 dts file
- a few improvements suggested by Linus Walleij on v3
- remove unused 'irq' argument to brcmstb_gpio_irq_bank_handler()

The following are not included in this patchset:
- Initial device tree bindings (merged from v1 to GPIO tree)
- Initial GPIO support w/o interrupts (merged from v2 to GPIO tree)
- ARM Kconfig changes (merged from v2 to arm-soc tree)
- fix for null ptr deref in driver remove (merged from v3)

Previous versions:
v1: https://lkml.org/lkml/2015/5/6/199
v2: https://lkml.org/lkml/2015/5/28/853
v3: https://lkml.org/lkml/2015/6/17/960

Gregory Fong (4):
  dt-bindings: brcmstb-gpio: document properties for wakeup
  gpio: brcmstb: Add interrupt and wakeup source support
  gpio: brcmstb: support wakeup from S5 cold boot
  ARM: dts: brcmstb: add BCM7445 GPIO nodes

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt |  35 ++-
 arch/arm/boot/dts/bcm7445.dtsi |  50 
 drivers/gpio/Kconfig   |   1 +
 drivers/gpio/gpio-brcmstb.c| 306 -
 4 files changed, 379 insertions(+), 13 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 4/4] gpio: brcmstb: support wakeup from S5 cold boot

2015-07-13 Thread Gregory Fong
On Mon, Jul 13, 2015 at 6:03 AM, Linus Walleij  wrote:
> On Thu, Jun 18, 2015 at 3:00 AM, Gregory Fong  wrote:
>
>> For wake from S5, we need to:
>> - register a reboot handler
>> - set wakeup capability before requesting IRQ so wakeup count is
>>   incremented
>> - mask all GPIO IRQs and clear any pending interrupts during driver
>>   probe to since no driver will yet be registered to handle any IRQs
>>   carried over from boot at that time, and it's possible that the
>>   booted kernel does not request the same IRQ anyway.
>>
>> This means that /sys/.../power/wakeup_count is valid at boot time, and
>> we can properly account for S5 wakeup stats. e.g.:
>>
>>   ### After waking from S5 from a GPIO key
>>   # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup
>>   enabled
>>   # cat 
>> /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup_count
>>   1
>>
>> Signed-off-by: Gregory Fong 
>
> (...)
>> -static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int 
>> enable)
>> +static int __brcmstb_gpio_irq_set_wake(struct brcmstb_gpio_priv *priv,
>> +   unsigned int enable)
>>  {
>> -   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
>> -   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
>> int ret = 0;
>
> I don't usually like to refactor code with __foo wrapper functions with
> underscores or double underscores in front of them.
>
> Is it possible to give this a more unique name?

Sure, just have to come up with a good one :-).

>
>> +   /*
>> +* Mask all interrupts by default, since wakeup interrupts 
>> may
>> +* be retained from S5 cold boot
>> +*/
>> +   bank->bgc.write_reg(reg_base + GIO_MASK(bank->id), 0);
>
> Aha I see, that's some clever code, nice.
>
> Yours,
> Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 3/4] gpio: brcmstb: Add interrupt and wakeup source support

2015-07-13 Thread Gregory Fong
On Mon, Jul 13, 2015 at 5:58 AM, Linus Walleij  wrote:
> On Thu, Jun 18, 2015 at 3:00 AM, Gregory Fong  wrote:
>
>> Uses the gpiolib irqchip helpers.  For this to work, the irq setup
>> function is called once per bank instead of once per device.  Note
>> that all known uses of this block have a BCM7120 L2 interrupt
>> controller as a parent.  Supports interrupts for all GPIOs.
>>
>> In the IRQ handler, we check for raised IRQs for invalid GPIOs and
>> warn (ratelimited) if they're encountered.
>>
>> Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
>> configured as wakeup sources, and this GPIO controller supports that
>> through a separate interrupt path.
>>
>> The de-facto standard DT property "wakeup-source" is checked, since
>> that indicates whether the GPIO controller hardware can wake.  Uses
>> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
>> any of its own wakeup source configuration.
>>
>> Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
>> that you can have multiple chained irqchips and associated IRQ domains
>> for a single parent IRQ, and as long as the xlate function is written
>> correctly, a GPIO IRQ request end up checking the correct domain and
>> will get associated with the correct IRQ.  What helps make this clear
>> is to read
>>   drivers/gpio/gpiolib-of.c:
>>- of_gpiochip_find_and_xlate()
>>- of_get_named_gpiod_flags()
>>   drivers/gpio/gpiolib.c:
>>- gpiochip_find()
>
> Sorry for the unclarities, this is a bit hairy. Suggestions as to
> how we can make it easier and/or bring code for this into gpiolib
> are welcome. Right now I have a hard time seeing any way to
> make this more generic and helpful :/

I'll see about putting together an update to the documentation
discussing more about the case where you have one IRQ shared by
multiple GPIO banks.

>
> Overall this patch looks real nice. Some nitpicks below.
>
>> @@ -164,6 +398,16 @@ static int brcmstb_gpio_probe(struct platform_device 
>> *pdev)
>> priv->reg_base = reg_base;
>> priv->pdev = pdev;
>>
>> +   if (of_property_read_bool(np, "interrupt-controller")) {
>> +   priv->parent_irq = platform_get_irq(pdev, 0);
>> +   if (priv->parent_irq < 0) {
>
> This should be <= 0 since 0 is NO_IRQ

Will fix.

>
>> +   dev_err(dev, "Couldn't get IRQ");
>> +   return -ENOENT;
>> +   }
>> +   } else {
>> +   priv->parent_irq = -ENOENT;
>> +   }
>
> Why should this code only execute if the node is marked
> "interrupt-controller"? It makes it seem like IRQs cannot arrive
> to it unless it is intended to serve other consumers.
>
> Maybe in practice this is true, but...

If the node does not contain the "interrupt-controller" property, the
hardware does not support GPIO interrupts, and I designed the driver
specifically to allow that to work.
If the node does contain that property, then being unable to complete
IRQ setup is a fatal error, because something is badly misconfigured.

>
>> +   if (priv->parent_irq >= 0) {
>> +   err = brcmstb_gpio_irq_setup(pdev, bank);
>> +   if (err)
>> +   goto fail;
>> +   }
>
> Again 0 is NO_IRQ so this should be > 0 not >= 0.

OK, will change.

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/7] soc: brcmstb: add system suspend support for STB SoCs

2015-06-18 Thread Gregory Fong
On Thu, Jun 18, 2015 at 5:11 PM, Brian Norris
 wrote:
> Hi,
>
> This patch set introduces system suspend/resume support for Broadcom STB SoCs.
> There are two suspend modes (S2 and S3) as well as a related low-power 
> shutdown
> mode (S5).
>
> Along with the core PM support, include a driver for the wakeup-timer, which
> allows for simple testing of suspend/resume wakeup cycles.
>
> Brian
>
> Brian Norris (7):
>   Documentation: dt: brcmstb: add system PM bindings
>   Documentation: dt: brcmstb: add waketimer documentation
>   soc: add stubs for brcmstb SoC's
>   soc: brcmstb: add PM suspend/resume support (S2/S3/S5)
>   soc: brcmstb: add wake-timer driver
>   ARM: brcmstb: mask GIC IRQs on suspend
>   ARM: dts: brcmstb: add BCM7445 system PM DT nodes
>

I tested this series two ways: with the device tree built into the
bootloader (BOLT) on BCM7445 and by using
arch/arm/boot/dts/bcm7445-bcm97445svmb.dtb

With the device tree from BOLT, everything works fine.  Tested the
waketimer for S2, S3, and S5.

With the device tree in arch/arm/boot/dts/bcm7445-bcm97445svmb.dts, S2
works, but S3 and S5 do not.  It comes back up but doesn't reach the
prompt:

[6.050808] PM: suspend of devices complete after 1.425 msecs
[6.051760] PM: late suspend of devices complete after 0.947 msecs
[6.052535] PM: noirq suspend of devices complete after 0.770 msecs
[6.052537] Disabling non-boot CPUs ...
[6.053005] CPU1: shutdown
[6.065914] CPU2: shutdown
[6.080756] CPU3: shutdown
[6.095214] Enabling non-boot CPUs ...
[6.111496] CPU1 is up
[6.126934] CPU2 is up
[6.142511] CPU3 is up
[6.145308] PM: noirq resume of devices complete after 2.772 msecs
[6.148022] PM: early resume of devices complete after 2.626 msecs
[6.151017] PM: resume of devices complete after 2.976 msecs
[6.212771] Restarting tasks ... done.
[[[ output stops here ]]]

I suspect there might be an issue somewhere in
[PATCH 7/7] ARM: dts: brcmstb: add BCM7445 system PM DT nodes.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/7] soc: brcmstb: add wake-timer driver

2015-06-18 Thread Gregory Fong
On Thu, Jun 18, 2015 at 5:11 PM, Brian Norris
 wrote:
> Useful for waking the system from suspend after a specified period of
> time.
>
> This IP could potentially be supported as an RTC driver (for use with
> the 'rtcwake' utility), but it is not battery backed, so that's not a
> great fit. Implement a custom sysfs interface instead.
>
> Signed-off-by: Brian Norris 
> ---
>  .../ABI/testing/sysfs-driver-wktmr-brcmstb |  12 +
>  drivers/soc/brcmstb/Kconfig|   3 +
>  drivers/soc/brcmstb/Makefile   |   1 +
>  drivers/soc/brcmstb/wktmr.c| 242 
> +
>  4 files changed, 258 insertions(+)
>  create mode 100644 Documentation/ABI/testing/sysfs-driver-wktmr-brcmstb
>  create mode 100644 drivers/soc/brcmstb/wktmr.c
>
> diff --git a/Documentation/ABI/testing/sysfs-driver-wktmr-brcmstb 
> b/Documentation/ABI/testing/sysfs-driver-wktmr-brcmstb
> new file mode 100644
> index ..e563f8b8d969
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-driver-wktmr-brcmstb
> @@ -0,0 +1,12 @@
> +What:  
> /sys/bus/platform/drivers/brcm-waketimer/.waketimer/timeout
> +Date:  November 21, 2014
> +KernelVersion: 3.14
> +Contact:   Brian Norris 

Shouldn't this be "Brian Norris "?

> +Description:   The control file for the wakeup timer. This integer value
> +   represents the number of seconds between a suspend operation
> +   (e.g., S3 suspend-to-RAM) and the time at which the wakeup
> +   timer should fire.
> [...]
> diff --git a/drivers/soc/brcmstb/wktmr.c b/drivers/soc/brcmstb/wktmr.c
> new file mode 100644
> index ..89f989724d3c
> --- /dev/null
> +++ b/drivers/soc/brcmstb/wktmr.c
> @@ -0,0 +1,242 @@
> [...]
> +
> +static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer,
> +   unsigned int secs)
> +{
> +   unsigned int t;

Use u32.

> +
> +   brcmstb_waketmr_clear_alarm(timer);
> +
> +   t = readl_relaxed(timer->base + BRCMSTB_WKTMR_COUNTER);
> +   writel_relaxed(t + secs + 1, timer->base + BRCMSTB_WKTMR_ALARM);
> +}
> +
> [...]
> +static int brcmstb_waketmr_probe(struct platform_device *pdev)
> +{
> [...]
> +   /*
> +* Set wakeup capability before requesting wakeup interrupt, so we can
> +* process boot-time "wakeups" (e.g., from S5 soft-off)
> +*/
> +   device_set_wakeup_capable(dev, true);
> +   device_wakeup_enable(dev);
> +
> +   timer->irq = platform_get_irq(pdev, 0);
> +   if ((int)timer->irq < 0)

Probably better to just have timer->irq be a signed int so you don't
need this cast.

> [snip]

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/7] Documentation: dt: brcmstb: add waketimer documentation

2015-06-18 Thread Gregory Fong
On Thu, Jun 18, 2015 at 5:11 PM, Brian Norris
 wrote:
> Signed-off-by: Brian Norris 

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/7] ARM: brcmstb: mask GIC IRQs on suspend

2015-06-18 Thread Gregory Fong
On Thu, Jun 18, 2015 at 5:11 PM, Brian Norris
 wrote:
> Lazily-masked IRQs can cause system suspend problems (e.g., spurious
> wakeups from WFI), so we need to be sure non-wakeup GIC interrupts get
> masked, not just disabled, during system suspend.
>
> Signed-off-by: Brian Norris 

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/4] gpio: brcmstb: support wakeup from S5 cold boot

2015-06-17 Thread Gregory Fong
For wake from S5, we need to:
- register a reboot handler
- set wakeup capability before requesting IRQ so wakeup count is
  incremented
- mask all GPIO IRQs and clear any pending interrupts during driver
  probe to since no driver will yet be registered to handle any IRQs
  carried over from boot at that time, and it's possible that the
  booted kernel does not request the same IRQ anyway.

This means that /sys/.../power/wakeup_count is valid at boot time, and
we can properly account for S5 wakeup stats. e.g.:

  ### After waking from S5 from a GPIO key
  # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup
  enabled
  # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup_count
  1

Signed-off-by: Gregory Fong 
---
New in v3.

 drivers/gpio/gpio-brcmstb.c | 56 -
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 141509b..dedb35c 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -48,6 +49,7 @@ struct brcmstb_gpio_priv {
int gpio_base;
bool can_wake;
int parent_wake_irq;
+   struct notifier_block reboot_notifier;
 };
 
 #define MAX_GPIO_PER_BANK   32
@@ -167,10 +169,9 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, 
unsigned int type)
return 0;
 }
 
-static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
+static int __brcmstb_gpio_irq_set_wake(struct brcmstb_gpio_priv *priv,
+   unsigned int enable)
 {
-   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
int ret = 0;
 
/*
@@ -188,6 +189,14 @@ static int brcmstb_gpio_irq_set_wake(struct irq_data *d, 
unsigned int enable)
return ret;
 }
 
+static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
+
+   return __brcmstb_gpio_irq_set_wake(priv, enable);
+}
+
 static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data)
 {
struct brcmstb_gpio_priv *priv = data;
@@ -247,6 +256,19 @@ static void brcmstb_gpio_irq_handler(unsigned int irq, 
struct irq_desc *desc)
chained_irq_exit(chip, desc);
 }
 
+static int brcmstb_gpio_reboot(struct notifier_block *nb,
+   unsigned long action, void *data)
+{
+   struct brcmstb_gpio_priv *priv =
+   container_of(nb, struct brcmstb_gpio_priv, reboot_notifier);
+
+   /* Enable GPIO for S5 cold boot */
+   if (action == SYS_POWER_OFF)
+   __brcmstb_gpio_irq_set_wake(priv, 1);
+
+   return NOTIFY_DONE;
+}
+
 /* Make sure that the number of banks matches up between properties */
 static int brcmstb_gpio_sanity_check_banks(struct device *dev,
struct device_node *np, struct resource *res)
@@ -286,6 +308,12 @@ static int brcmstb_gpio_remove(struct platform_device 
*pdev)
if (ret)
dev_err(&pdev->dev, "gpiochip_remove fail in 
cleanup\n");
}
+   if (priv->reboot_notifier.notifier_call) {
+   ret = unregister_reboot_notifier(&priv->reboot_notifier);
+   if (ret)
+   dev_err(&pdev->dev,
+   "failed to unregister reboot notifier\n");
+   }
return ret;
 }
 
@@ -343,7 +371,16 @@ static int brcmstb_gpio_irq_setup(struct platform_device 
*pdev,
dev_warn(dev,
"Couldn't get wake IRQ - GPIOs will not be able 
to wake from sleep");
} else {
-   int err = devm_request_irq(dev, priv->parent_wake_irq,
+   int err;
+
+   /*
+* Set wakeup capability before requesting wakeup
+* interrupt, so we can process boot-time "wakeups"
+* (e.g., from S5 cold boot)
+*/
+   device_set_wakeup_capable(dev, true);
+   device_wakeup_enable(dev);
+   err = devm_request_irq(dev, priv->parent_wake_irq,
brcmstb_gpio_wake_irq_handler, 0,
"brcmstb-gpio-wake", priv);
 
@@ -352,8 +389,9 @@ static int brcmstb_gpio_irq_setup(struct platform_device 
*pdev,
return err;
}
 
-   device_set_wakeup_capable(dev, true);
-   

[PATCH v3 3/4] gpio: brcmstb: Add interrupt and wakeup source support

2015-06-17 Thread Gregory Fong
Uses the gpiolib irqchip helpers.  For this to work, the irq setup
function is called once per bank instead of once per device.  Note
that all known uses of this block have a BCM7120 L2 interrupt
controller as a parent.  Supports interrupts for all GPIOs.

In the IRQ handler, we check for raised IRQs for invalid GPIOs and
warn (ratelimited) if they're encountered.

Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
configured as wakeup sources, and this GPIO controller supports that
through a separate interrupt path.

The de-facto standard DT property "wakeup-source" is checked, since
that indicates whether the GPIO controller hardware can wake.  Uses
the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
any of its own wakeup source configuration.

Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
that you can have multiple chained irqchips and associated IRQ domains
for a single parent IRQ, and as long as the xlate function is written
correctly, a GPIO IRQ request end up checking the correct domain and
will get associated with the correct IRQ.  What helps make this clear
is to read
  drivers/gpio/gpiolib-of.c:
   - of_gpiochip_find_and_xlate()
   - of_get_named_gpiod_flags()
  drivers/gpio/gpiolib.c:
   - gpiochip_find()

Signed-off-by: Gregory Fong 
---
v3:
- combine commits to add interrupt support and allow GPIOs to be wakeup sources
- change to use the gpiolib irqchip helpers, reducing unnecessary code
  duplication.

 drivers/gpio/Kconfig|   1 +
 drivers/gpio/gpio-brcmstb.c | 263 +++-
 2 files changed, 258 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5f79b7f..f723c7e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -131,6 +131,7 @@ config GPIO_BRCMSTB
default y if ARCH_BRCMSTB
depends on OF_GPIO && (ARCH_BRCMSTB || COMPILE_TEST)
select GPIO_GENERIC
+   select GPIOLIB_IRQCHIP
help
  Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
 
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 4630a81..141509b 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -17,6 +17,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -34,14 +37,17 @@ struct brcmstb_gpio_bank {
struct bgpio_chip bgc;
struct brcmstb_gpio_priv *parent_priv;
u32 width;
+   struct irq_chip irq_chip;
 };
 
 struct brcmstb_gpio_priv {
struct list_head bank_list;
void __iomem *reg_base;
-   int num_banks;
struct platform_device *pdev;
+   int parent_irq;
int gpio_base;
+   bool can_wake;
+   int parent_wake_irq;
 };
 
 #define MAX_GPIO_PER_BANK   32
@@ -63,6 +69,184 @@ brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
return bank->parent_priv;
 }
 
+static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
+   unsigned int offset, bool enable)
+{
+   struct bgpio_chip *bgc = &bank->bgc;
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = bgc->pin2mask(bgc, offset);
+   u32 imask;
+   unsigned long flags;
+
+   spin_lock_irqsave(&bgc->lock, flags);
+   imask = bgc->read_reg(priv->reg_base + GIO_MASK(bank->id));
+   if (enable)
+   imask |= mask;
+   else
+   imask &= ~mask;
+   bgc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
+   spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+/*  IRQ chip functions  */
+
+static void brcmstb_gpio_irq_mask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+
+   brcmstb_gpio_set_imask(bank, d->hwirq, false);
+}
+
+static void brcmstb_gpio_irq_unmask(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+
+   brcmstb_gpio_set_imask(bank, d->hwirq, true);
+}
+
+static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_bank *bank = brcmstb_gpio_gc_to_bank(gc);
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = BIT(d->hwirq);
+   u32 edge_insensitive, iedge_insensitive;
+   u32 edge_config, iedge_config;
+   u32 level, ilevel;
+   unsigned long flags;
+
+   switch (type) {
+   case IRQ_TYPE_LEVEL_LOW:
+   level = 0;
+   edge_config = 0;
+   edge_insensitive = 0;
+   break

[PATCH v3 2/4] dt-bindings: brcmstb-gpio: document properties for wakeup

2015-06-17 Thread Gregory Fong
Some brcmstb GPIO controllers can be used to wake from suspend, so use
the de facto standard property 'wakeup-source' to mark the nodes of
controllers with that capability.

Also document interrupts-extended, which will be used for wakeup
handling because the interrupt parent for the wake IRQ is different
from the regular IRQ.

While we're at it, a few more fixes: We don't actually use the
"interrupt-names" property, so remove it from the listed optional
properties and from the examples.  And since we're modifying the
examples, also follow Brian's suggestions to:
- change #gpio-cells, #interrupt-cells, and brcm,gpio-bank-widths from
  hex to dec
- use phandles

Reviewed-by: Brian Norris 
Signed-off-by: Gregory Fong 
---
v3: Update per Brian's suggestions described in above message.

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt | 35 +-
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt 
b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
index 435f1bc..b405b44 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
@@ -33,6 +33,13 @@ Optional properties:
 - interrupt-parent:
 phandle of the parent interrupt controller
 
+- interrupts-extended:
+Alternate form of specifying interrupts and parents that allows for
+multiple parents.  This takes precedence over 'interrupts' and
+'interrupt-parent'.  Wakeup-capable GPIO controllers often route their
+wakeup interrupt lines through a different interrupt controller than the
+primary interrupt line, making this property necessary.
+
 - #interrupt-cells:
 Should be <2>.  The first cell is the GPIO number, the second should 
specify
 flags.  The following subset of flags is supported:
@@ -47,19 +54,33 @@ Optional properties:
 - interrupt-controller:
 Marks the device node as an interrupt controller
 
-- interrupt-names:
-The name of the IRQ resource used by this controller
+- wakeup-source:
+GPIOs for this controller can be used as a wakeup source
 
 Example:
upg_gio: gpio@f040a700 {
-   #gpio-cells = <0x2>;
-   #interrupt-cells = <0x2>;
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
gpio-controller;
interrupt-controller;
reg = <0xf040a700 0x80>;
-   interrupt-parent = <0xf>;
+   interrupt-parent = <&irq0_intc>;
+   interrupts = <0x6>;
+   brcm,gpio-bank-widths = <32 32 32 24>;
+   };
+
+   upg_gio_aon: gpio@f04172c0 {
+   #gpio-cells = <2>;
+   #interrupt-cells = <2>;
+   compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
+   gpio-controller;
+   interrupt-controller;
+   reg = <0xf04172c0 0x40>;
+   interrupt-parent = <&irq0_aon_intc>;
interrupts = <0x6>;
-   interrupt-names = "upg_gio";
-   brcm,gpio-bank-widths = <0x20 0x20 0x20 0x18>;
+   interrupts-extended = <&irq0_aon_intc 0x6>,
+   <&aon_pm_l2_intc 0x5>;
+   wakeup-source;
+   brcm,gpio-bank-widths = <18 4>;
};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/4] gpio: brcmstb: fix null ptr dereference in driver remove

2015-06-17 Thread Gregory Fong
If a failure occurs during probe, brcmstb_gpio_remove() is called. In
remove, we call platform_get_drvdata(), but at the time of failure in
the probe the driver data hadn't yet been set which leads to a NULL
ptr dereference in the remove's list_for_each.  Call
platform_set_drvdata() and set up list head right after allocating the
priv struct to both avoid the null pointer dereference that could
occur today.  To guard against potential future changes, check for
null pointer in remove.

Reported-by: Tim Ross 
Signed-off-by: Gregory Fong 
---
New in v3.

 drivers/gpio/gpio-brcmstb.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 7a3cb1f..4630a81 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -87,6 +87,15 @@ static int brcmstb_gpio_remove(struct platform_device *pdev)
struct brcmstb_gpio_bank *bank;
int ret = 0;
 
+   if (!priv) {
+   dev_err(&pdev->dev, "called %s without drvdata!\n", __func__);
+   return -EFAULT;
+   }
+
+   /*
+* You can lose return values below, but we report all errors, and it's
+* more important to actually perform all of the steps.
+*/
list_for_each(pos, &priv->bank_list) {
bank = list_entry(pos, struct brcmstb_gpio_bank, node);
ret = bgpio_remove(&bank->bgc);
@@ -143,6 +152,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
+   platform_set_drvdata(pdev, priv);
+   INIT_LIST_HEAD(&priv->bank_list);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg_base = devm_ioremap_resource(dev, res);
@@ -153,7 +164,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
priv->reg_base = reg_base;
priv->pdev = pdev;
 
-   INIT_LIST_HEAD(&priv->bank_list);
if (brcmstb_gpio_sanity_check_banks(dev, np, res))
return -EINVAL;
 
@@ -221,8 +231,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n",
priv->num_banks, priv->gpio_base, gpio_base - 1);
 
-   platform_set_drvdata(pdev, priv);
-
return 0;
 
 fail:
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/4] GPIO support for BRCMSTB

2015-06-17 Thread Gregory Fong
Adds interrupt support for the GPIO controller (UPG GIO) used on Broadcom's
various BRCMSTB SoCs (BCM7XXX and others).  For all existing hardware, this
block hooks up to the BCM7120 L2 IRQ controller and so will require
CONFIG_BCM7120_L2_IRQ=y.

New in v3:
- fix a null pointer dereference noticed by Tim Ross
- use the gpiolib irqchip helpers as recommended by Linus Walleij
- update device tree bindings as suggested by Brian Norris:
  https://lkml.org/lkml/2015/5/29/802
- add S5 (cold boot) support

The following are not included in this patchset:
- Initial device tree bindings (merged from v1 to GPIO tree)
- Initial GPIO support w/o interrupts (merged from v2 to GPIO tree)
- ARM Kconfig changes (merged from v2 to arm-soc tree)

Previous revisions:
v1: https://lkml.org/lkml/2015/5/6/199
v2: https://lkml.org/lkml/2015/5/28/853

Gregory Fong (4):
  gpio: brcmstb: fix null ptr dereference in driver remove
  dt-bindings: brcmstb-gpio: document properties for wakeup
  gpio: brcmstb: Add interrupt and wakeup source support
  gpio: brcmstb: support wakeup from S5 cold boot

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt |  35 ++-
 drivers/gpio/Kconfig   |   1 +
 drivers/gpio/gpio-brcmstb.c| 321 -
 3 files changed, 341 insertions(+), 16 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] GPIO support for BRCMSTB

2015-06-02 Thread Gregory Fong
On Tue, Jun 2, 2015 at 2:05 AM, Linus Walleij  wrote:
> On Wed, May 27, 2015 at 5:26 AM, Gregory Fong  wrote:
>> I've now actually attempted to use the gpiolib irqchip code.  This
>> driver can't directly use gpiochip_irqchip_add() because of the
>> multiple gpiochip : one irqchip map.  At first, I thought it might be
>> possible to simply add a new argument (or break things into a helper
>> function) to allow setting the associated IRQ domain, but then I can't
>> use the generic map and unmap functions which expect the irq_domain
>> host_data member to be struct gpiochip *, which makes no sense in this
>> case.  That puts me right back to implementing a special version of
>> the map and unmap function.
>
> I see.
>

I think I was wrong, it isn't actually necessary to have a single
irq_chip as long as all of the IRQs use the same handler.  I have a
preliminary implementation doing that instead that seems to work fine.
Once I've had a chance to verify that it works in all cases, will post
that as v3.

Cheers,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/6] gpio: brcmstb: Allow GPIOs to be wakeup sources

2015-06-02 Thread Gregory Fong
On Tue, Jun 2, 2015 at 6:45 AM, Linus Walleij  wrote:
> On Fri, May 29, 2015 at 4:14 AM, Gregory Fong  wrote:
>
>> Several drivers (e.g. gpio-keys) allow for GPIOs to be configured as
>> wakeup sources, and this GPIO controller supports that through a
>> separate interrupt path.
>>
>> The de-facto standard DT property "wakeup-source" is checked, since
>> that indicates whether the GPIO controller hardware can wake.  Uses
>> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
>> any of its own wakeup source configuration.
>>
>> Signed-off-by: Gregory Fong 
>
> (...)
>> +   if (enable)
>> +   enable_irq_wake(priv->parent_wake_irq);
>> +   else
>> +   disable_irq_wake(priv->parent_wake_irq);
>> +   return 0;
>
> No error handling? If the code assumes these calls will
> always succeed, atleast write that in a comment.

Will add error handling.

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/6] gpio: brcmstb: Allow GPIOs to be wakeup sources

2015-06-02 Thread Gregory Fong
On Fri, May 29, 2015 at 5:43 PM, Brian Norris
 wrote:
> On Thu, May 28, 2015 at 07:14:08PM -0700, Gregory Fong wrote:
>> Several drivers (e.g. gpio-keys) allow for GPIOs to be configured as
>> wakeup sources, and this GPIO controller supports that through a
>> separate interrupt path.
>>
>> The de-facto standard DT property "wakeup-source" is checked, since
>> that indicates whether the GPIO controller hardware can wake.  Uses
>> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
>> any of its own wakeup source configuration.
>>
>> Signed-off-by: Gregory Fong 
>> ---
>> New in v2.
>>
>>  drivers/gpio/gpio-brcmstb.c | 53 
>> +
>>  1 file changed, 53 insertions(+)
>>
>> diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
>> index b9962ff..2598c1e 100644
>> --- a/drivers/gpio/gpio-brcmstb.c
>> +++ b/drivers/gpio/gpio-brcmstb.c
>> [...]
>> @@ -369,6 +396,32 @@ static int brcmstb_gpio_irq_setup(struct 
>> platform_device *pdev,
>>   priv->irq_chip.irq_mask = brcmstb_gpio_irq_mask;
>>   priv->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask;
>>   priv->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type;
>> +
>> + /* Ensures that all non-wakeup IRQs are disabled at suspend */
>> + priv->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
>> +
>> + if (IS_ENABLED(CONFIG_PM_SLEEP) &&
>> + of_get_property(np, "wakeup-source", NULL)) {
>
> of_property_read_bool()?

Will change.

>
>> + priv->parent_wake_irq = platform_get_irq(pdev, 1);
>> + if (priv->parent_wake_irq < 0)  {
>> + dev_warn(dev,
>> + "Couldn't get wake IRQ - GPIOs will not be 
>> able to wake from sleep");
>> + } else {
>> + int err = devm_request_irq(dev, priv->parent_wake_irq,
>> + brcmstb_gpio_wake_irq_handler, 0,
>> + "brcmstb-gpio-wake", priv);
>> +
>> + if (err < 0) {
>> + dev_err(dev, "Couldn't request wake IRQ");
>> + return err;
>> + }
>> +
>> + device_set_wakeup_capable(dev, true);
>> + device_wakeup_enable(dev);
>
> Might want to move these two lines above the devm_request_irq(), so that
> you're ready to record PM events immediately at probe time. This is
> important when waking from S5 states, where we sometimes want to be able
> to check the /sys/devices/.../wakeup_count stats to see what woke us up.

Makes sense.  We'll also need a reboot notifier for S5 to work.

>
>> + priv->irq_chip.irq_set_wake = 
>> brcmstb_gpio_irq_set_wake;
>> + }
>> + }
>> +
>>   priv->irq_domain =
>>   irq_domain_add_linear(np, priv->num_gpios,
>> &brcmstb_gpio_irq_domain_ops,
>
> With that:
>
> Reviewed-by: Brian Norris 

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/6] dt-bindings: brcmstb-gpio: document properties for wakeup

2015-05-29 Thread Gregory Fong
On Fri, May 29, 2015 at 6:37 PM, Brian Norris
 wrote:
> On Fri, May 29, 2015 at 05:57:50PM -0700, Gregory Fong wrote:
>> On Fri, May 29, 2015 at 5:36 PM, Brian Norris
>>  wrote:
>> > On Thu, May 28, 2015 at 07:14:07PM -0700, Gregory Fong wrote:
>> >> --- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
>> >> +++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
>> >> @@ -33,6 +33,12 @@ Optional properties:
> ...
>> >>  - #interrupt-cells:
>> >>  Should be <2>.  The first cell is the GPIO number, the second should 
>> >> specify
>> >>  flags.  The following subset of flags is supported:
>> >> @@ -48,7 +54,10 @@ Optional properties:
>> >>  Marks the device node as an interrupt controller
>> >>
>> >>  - interrupt-names:
>> >> -The name of the IRQ resource used by this controller
>> >> +The names of the IRQ resources used by this controller
>> >
>> > If you're specifying names, you should list them here.
>>
>> I was wondering about that.  Some bindings have them listed, some
>> don't.  In this case I know what names currently exist but there could
>> certainly be different ones in the future.  How does that work?  Or am
>> I misunderstanding what this field is used for?  Where are the
>> documented rules for this?
>
> The only documentation I see is:
> Documentation/devicetree/bindings/resource-names.txt
>
> That documents the basics of the *-names properties, not their expected
> usage.
>
> In practice, they're only useful if you have enough optional resources
> that fixed indexing isn't sufficient, and you need to use
> platform_get_resource_byname().
>
> So IMO, their purposes seems to be one of these:
> (1) functional (e.g., for get_resource_byname(), when you have more than
> one optional resource)
> (2) self-documentation (which might run counter to #1, as you begin
> generating too many unique names)
> (3) no purpose
>
> So IMO, if you ever want (1), they shouldn't have instance-specific
> naming, but should use something generic to the device class. Otherwise,
> they are just self-documentation, and aren't functionally useful. So
> IMO, these sorts of names:
>
> interrupt-names = "upg_gio_aon", "upg_gio_aon_wakeup";
>
> work better as functional descriptions:
>
> interrupt-names = "gio", "wakeup";
>
> But in the end, I wouldn't foresee you needing to do (1), so you're left
> with (2) or (3), at which point I'm not sure if you should even mention
> the property.

I'm fine with leaving out the interrupt-names property, since we're
not using it here anyway.  Unless there are serious objections, I'll
plan on remove it from the bindings doc next round.

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/6] gpio: brcmstb: Add interrupt support

2015-05-29 Thread Gregory Fong
On Fri, May 29, 2015 at 5:10 PM, Brian Norris
 wrote:
> A few small comments:
>
> On Thu, May 28, 2015 at 07:14:06PM -0700, Gregory Fong wrote:
>> v2:
>> - since imask member of bank struct was removed, just read and write from 
>> mask
>>   reg and don't maintain a shadow
>
> ^^ this comment may be addressing what I'm going to ask about below? Not
> sure why this was changed, actually.

Yes, see below...

>
>> - warn on invalid IRQs
>> - move some irq setup to a separate function since probe is getting unwieldy
>>
>>  drivers/gpio/Kconfig|   1 +
>>  drivers/gpio/gpio-brcmstb.c | 276 
>> 
>>  2 files changed, 277 insertions(+)
>>
> ...
>> diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
>> index 7a3cb1f..b9962ff 100644
>> --- a/drivers/gpio/gpio-brcmstb.c
>> +++ b/drivers/gpio/gpio-brcmstb.c
> ...
>> @@ -63,6 +69,231 @@ brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
> ...
>> +static void brcmstb_gpio_irq_bank_handler(int irq,
>> + struct brcmstb_gpio_bank *bank)
>> +{
>> + struct brcmstb_gpio_priv *priv = bank->parent_priv;
>> + void __iomem *reg_base = priv->reg_base;
>> + unsigned long status;
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&bank->bgc.lock, flags);
>> + while ((status = bank->bgc.read_reg(reg_base + GIO_STAT(bank->id)) &
>> +  bank->bgc.read_reg(reg_base + GIO_MASK(bank->id {
>
> In case you do run this loop multiple times (multiple interrupts in
> progress?), wouldn't it make sense to stash the mask exactly once,
> outside the loop? It's probably not a real big deal in practice, I
> guess.

I made this change after Linus's remark at
https://lkml.org/lkml/2015/5/12/303 on v1, which I agree with mostly
since it's a premature optimization---I haven't determined whether
keeping a shadow mask actually helps performance at all in practice,
and better to keep it simpler without actual data.

>
>> + int bit;
>> + for_each_set_bit(bit, &status, 32) {
>> + int hwirq = bank->bgc.gc.base -
>> + priv->gpio_base + bit;
>> + int child_irq =
>> + irq_find_mapping(priv->irq_domain,
>> +  hwirq);
>> + u32 stat = bank->bgc.read_reg(reg_base +
>> +   GIO_STAT(bank->id));
>> + if (bit >= bank->width)
>> + dev_warn(&priv->pdev->dev,
>> +  "IRQ for invalid GPIO (bank=%d, 
>> offset=%d)\n",
>> +  bank->id, bit);
>> + bank->bgc.write_reg(reg_base + GIO_STAT(bank->id),
>> + stat | BIT(bit));
>> + generic_handle_irq(child_irq);
>> + }
>> + }
>> + spin_unlock_irqrestore(&bank->bgc.lock, flags);
>> +}
> ...
>> @@ -153,6 +410,16 @@ static int brcmstb_gpio_probe(struct platform_device 
>> *pdev)
>>   priv->reg_base = reg_base;
>>   priv->pdev = pdev;
>>
>> + if (of_find_property(np, "interrupt-controller", NULL)) {
>
> of_property_read_bool()?

OK.

>
>> + priv->parent_irq = platform_get_irq(pdev, 0);
>> + if (priv->parent_irq < 0) {
>> + dev_err(dev, "Couldn't get IRQ");
>> + return -ENOENT;
>> + }
>> + } else {
>> + priv->parent_irq = -ENOENT;
>> + }
>> +
>>   INIT_LIST_HEAD(&priv->bank_list);
>>   if (brcmstb_gpio_sanity_check_banks(dev, np, res))
>>   return -EINVAL;
>
> Otherwise, looks OK to my inexpert eyes.
>
> Reviewed-by: Brian Norris 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/6] dt-bindings: brcmstb-gpio: document properties for wakeup

2015-05-29 Thread Gregory Fong
On Fri, May 29, 2015 at 5:36 PM, Brian Norris
 wrote:
> On Thu, May 28, 2015 at 07:14:07PM -0700, Gregory Fong wrote:
>> Some brcmstb GPIO controllers can be used to wake from suspend, so use the
>> de facto standard property 'wakeup-source' to mark the nodes of controllers
>> with that capability.
>>
>> Also document interrupts-extended, which will be used for wakeup handling
>> because the interrupt parent for the wake IRQ is different from the regular
>> IRQ.
>>
>> Signed-off-by: Gregory Fong 
>> ---
>> New in v2.
>>
>>  .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt | 26 
>> +-
>>  1 file changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt 
>> b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
>> index 435f1bc..568814f 100644
>> --- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
>> +++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
>> @@ -33,6 +33,12 @@ Optional properties:
>>  - interrupt-parent:
>>  phandle of the parent interrupt controller
>>
>> +- interrupts-extended:
>> +Alternate form of specifying interrupts and parents that allows for
>> +multiple parents.  This takes precedence over 'interrupts' and
>> +'interrupt-parent'.  This probably must be used if the wakeup-source
>> +property is provided because that may have a different interrupt parent.
>> +
>
> "This probably must be used" seems a little awkward, especially when
> you're just explaining an implementation detail of our SoCs, rather than
> something unique about this binding. Maybe:
>
>   "Wakeup-capable GPIO controllers often route their wakeup interrupt
>   lines through a different interrupt controller than the primary
>   interrupt line, making this property necessary."

That wording does seem better, will change.

>
>>  - #interrupt-cells:
>>  Should be <2>.  The first cell is the GPIO number, the second should 
>> specify
>>  flags.  The following subset of flags is supported:
>> @@ -48,7 +54,10 @@ Optional properties:
>>  Marks the device node as an interrupt controller
>>
>>  - interrupt-names:
>> -The name of the IRQ resource used by this controller
>> +The names of the IRQ resources used by this controller
>
> If you're specifying names, you should list them here.

I was wondering about that.  Some bindings have them listed, some
don't.  In this case I know what names currently exist but there could
certainly be different ones in the future.  How does that work?  Or am
I misunderstanding what this field is used for?  Where are the
documented rules for this?

>
>> +
>> +- wakeup-source:
>> +GPIOs for this controller can be used as a wakeup source
>>
>>  Example:
>>   upg_gio: gpio@f040a700 {
>> @@ -63,3 +72,18 @@ Example:
>>   interrupt-names = "upg_gio";
>>   brcm,gpio-bank-widths = <0x20 0x20 0x20 0x18>;
>>   };
>> +
>> + upg_gio_aon: gpio@f04172c0 {
>> + #gpio-cells = <0x2>;
>> + #interrupt-cells = <0x2>;
>
> Might use decimal instead of hex for the above 2 lines?

Sure.

>
>> + compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
>> + gpio-controller;
>> + interrupt-controller;
>> + reg = <0xf04172c0 0x40>;
>> + interrupt-parent = <0xc>;
>
> That should be a phandle, not an int (I realize phandles resolve down to
> an integer, but we're speaking DTS, not DTB).

OK.

>
>> + interrupts = <0x6>;
>> + interrupts-extended = <0xc 0x6 0xa 0x5>;
>
> Same here (phandles).
>
> Also, even though the interrupt binding semantics specify precedence
> between interrupts and interrupts-extended, I'd think an example should
> stick to one or the other, no?

This is the output that we actually get from the bootloader.  But
regardless, IMO the example should have both cases: precedence is
well-defined, both sets of information are valid, and the driver can
handle the case where interrupts-extended is not an understood
property.

>
>> + interrupt-names = "upg_gio_aon", "upg_gio_aon_wakeup";
>> + wakeup-source;
>> + brcm,gpio-bank-widths = <0x12 0x4>;
>> + };
>
> Reviewed-by: Brian Norris 

Thanks for the review,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/6] gpio: Add GPIO support for Broadcom STB SoCs

2015-05-28 Thread Gregory Fong
This adds support for the GPIO IP "UPG GIO" used on Broadcom STB SoCs
(BCM7XXX and some others).  Uses basic_mmio_gpio to instantiate a
gpio_chip for each bank.  The driver assumes that it handles the base
set of GPIOs on the system and that it can start its numbering sequence
from 0, so any GPIO expanders used with it must dynamically assign GPIO
numbers after this driver has finished registering its GPIOs.

Does not implement the interrupt-controller portion yet, will be done in a
future commit.

List-usage-fixed-by: Brian Norris 
Signed-off-by: Gregory Fong 
---
v2:
- change include to use  instead of 
- get rid of unnecessary imask member in struct bank
- rename GPIO_PER_BANK -> MAX_GPIO_PER_BANK
- always have 32 GPIOs per bank and add 'width' member in struct bank to hold
  actual number of GPIOs in use
- mark of_match table as const

 MAINTAINERS |   7 ++
 drivers/gpio/Kconfig|   8 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-brcmstb.c | 252 
 4 files changed, 268 insertions(+)
 create mode 100644 drivers/gpio/gpio-brcmstb.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 198a429..1d1b6f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2290,6 +2290,13 @@ N:   bcm9583*
 N: bcm583*
 N: bcm113*
 
+BROADCOM BRCMSTB GPIO DRIVER
+M: Gregory Fong 
+L: bcm-kernel-feedback-l...@broadcom.com>
+S: Supported
+F: drivers/gpio/gpio-brcmstb.c
+F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
+
 BROADCOM KONA GPIO DRIVER
 M: Ray Jui 
 L: bcm-kernel-feedback-l...@broadcom.com
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5faaf5f..d86de6a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -126,6 +126,14 @@ config GPIO_BCM_KONA
help
  Turn on GPIO support for Broadcom "Kona" chips.
 
+config GPIO_BRCMSTB
+   tristate "BRCMSTB GPIO support"
+   default y if ARCH_BRCMSTB
+   depends on OF_GPIO && (ARCH_BRCMSTB || COMPILE_TEST)
+   select GPIO_GENERIC
+   help
+ Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
+
 config GPIO_CLPS711X
tristate "CLPS711X GPIO support"
depends on ARCH_CLPS711X || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1b55fda..893bbff 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
 obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
 obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
 obj-$(CONFIG_GPIO_BCM_KONA)+= gpio-bcm-kona.o
+obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)   += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
new file mode 100644
index 000..7a3cb1f
--- /dev/null
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GIO_BANK_SIZE   0x20
+#define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
+#define GIO_DATA(bank)  (((bank) * GIO_BANK_SIZE) + 0x04)
+#define GIO_IODIR(bank) (((bank) * GIO_BANK_SIZE) + 0x08)
+#define GIO_EC(bank)(((bank) * GIO_BANK_SIZE) + 0x0c)
+#define GIO_EI(bank)(((bank) * GIO_BANK_SIZE) + 0x10)
+#define GIO_MASK(bank)  (((bank) * GIO_BANK_SIZE) + 0x14)
+#define GIO_LEVEL(bank) (((bank) * GIO_BANK_SIZE) + 0x18)
+#define GIO_STAT(bank)  (((bank) * GIO_BANK_SIZE) + 0x1c)
+
+struct brcmstb_gpio_bank {
+   struct list_head node;
+   int id;
+   struct bgpio_chip bgc;
+   struct brcmstb_gpio_priv *parent_priv;
+   u32 width;
+};
+
+struct brcmstb_gpio_priv {
+   struct list_head bank_list;
+   void __iomem *reg_base;
+   int num_banks;
+   struct platform_device *pdev;
+   int gpio_base;
+};
+
+#define MAX_GPIO_PER_BANK   32
+#define GPIO_BANK(gpio) ((gpio) >> 5)
+/* assumes MAX_GPIO_PER_BANK is a multiple of 2 */
+#define GPIO_BIT(gpio)  ((gpio) & (MAX_GPIO_PER_BANK - 1))
+
+static inline struct brcmstb_gpio_bank *
+brcmstb_gpio_gc_to_bank(struct gpio_chip *gc)
+{
+   struct bgpio_chip *bgc = to_bgpio_chip(gc);
+   return container_

[PATCH v2 2/6] gpio: brcmstb: Add interrupt support

2015-05-28 Thread Gregory Fong
Create an irq_chip for each GIO block.  Uses chained IRQ handling since
known uses of this block have a BCM7120 L2 interrupt controller as a
parent.  Supports interrupts for all GPIOs.

In the IRQ handler, we check for raised IRQs for invalid GPIOs and warn
(ratelimited) if they're encountered.

Signed-off-by: Gregory Fong 
---
v2:
- since imask member of bank struct was removed, just read and write from mask
  reg and don't maintain a shadow
- warn on invalid IRQs
- move some irq setup to a separate function since probe is getting unwieldy

 drivers/gpio/Kconfig|   1 +
 drivers/gpio/gpio-brcmstb.c | 276 
 2 files changed, 277 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d86de6a..7249dba 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -131,6 +131,7 @@ config GPIO_BRCMSTB
default y if ARCH_BRCMSTB
depends on OF_GPIO && (ARCH_BRCMSTB || COMPILE_TEST)
select GPIO_GENERIC
+   select IRQ_DOMAIN
help
  Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
 
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index 7a3cb1f..b9962ff 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -40,7 +42,11 @@ struct brcmstb_gpio_priv {
struct list_head bank_list;
void __iomem *reg_base;
int num_banks;
+   int num_gpios;
struct platform_device *pdev;
+   struct irq_chip irq_chip;
+   struct irq_domain *irq_domain;
+   int parent_irq;
int gpio_base;
 };
 
@@ -63,6 +69,231 @@ brcmstb_gpio_gc_to_priv(struct gpio_chip *gc)
return bank->parent_priv;
 }
 
+static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
+   unsigned int offset, bool enable)
+{
+   struct bgpio_chip *bgc = &bank->bgc;
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = bgc->pin2mask(bgc, offset);
+   u32 imask;
+   unsigned long flags;
+
+   spin_lock_irqsave(&bgc->lock, flags);
+   imask = bgc->read_reg(priv->reg_base + GIO_MASK(bank->id));
+   if (enable)
+   imask |= mask;
+   else
+   imask &= ~mask;
+   bgc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
+   spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned gc_offset)
+{
+   struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
+   /* gc_offset is relative to this gpio_chip; want real offset */
+   int offset = gc_offset + (gc->base - priv->gpio_base);
+
+   if (offset >= priv->num_gpios)
+   return -ENXIO;
+   return irq_create_mapping(priv->irq_domain, offset);
+}
+
+/*  IRQ chip functions  */
+
+static int brcmstb_gpio_hwirq_to_offset(irq_hw_number_t hwirq,
+   struct brcmstb_gpio_bank *bank)
+{
+   return hwirq - (bank->bgc.gc.base - bank->parent_priv->gpio_base);
+}
+
+static void brcmstb_gpio_irq_mask(struct irq_data *d)
+{
+   struct brcmstb_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+   int offset = brcmstb_gpio_hwirq_to_offset(d->hwirq, bank);
+
+   brcmstb_gpio_set_imask(bank, offset, false);
+}
+
+static void brcmstb_gpio_irq_unmask(struct irq_data *d)
+{
+   struct brcmstb_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+   int offset = brcmstb_gpio_hwirq_to_offset(d->hwirq, bank);
+
+   brcmstb_gpio_set_imask(bank, offset, true);
+}
+
+static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+   struct brcmstb_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+   u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank));
+   u32 edge_insensitive, iedge_insensitive;
+   u32 edge_config, iedge_config;
+   u32 level, ilevel;
+   unsigned long flags;
+
+   switch (type) {
+   case IRQ_TYPE_LEVEL_LOW:
+   level = 0;
+   edge_config = 0;
+   edge_insensitive = 0;
+   break;
+   case IRQ_TYPE_LEVEL_HIGH:
+   level = mask;
+   edge_config = 0;
+   edge_insensitive = 0;
+   break;
+   case IRQ_TYPE_EDGE_FALLING:
+   level = 0;
+   edge_config = 0;
+   edge_insensitive = 0;
+   break;
+   case IRQ_TYPE_EDGE_RISING:
+   level = 0;
+   edge_config = mask;
+   edge_insensitive = 0;
+   break;
+   case IRQ_TYPE_E

[PATCH v2 4/6] gpio: brcmstb: Allow GPIOs to be wakeup sources

2015-05-28 Thread Gregory Fong
Several drivers (e.g. gpio-keys) allow for GPIOs to be configured as
wakeup sources, and this GPIO controller supports that through a
separate interrupt path.

The de-facto standard DT property "wakeup-source" is checked, since
that indicates whether the GPIO controller hardware can wake.  Uses
the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
any of its own wakeup source configuration.

Signed-off-by: Gregory Fong 
---
New in v2.

 drivers/gpio/gpio-brcmstb.c | 53 +
 1 file changed, 53 insertions(+)

diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index b9962ff..2598c1e 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define GIO_BANK_SIZE   0x20
 #define GIO_ODEN(bank)  (((bank) * GIO_BANK_SIZE) + 0x00)
@@ -48,6 +49,7 @@ struct brcmstb_gpio_priv {
struct irq_domain *irq_domain;
int parent_irq;
int gpio_base;
+   int parent_wake_irq;
 };
 
 #define MAX_GPIO_PER_BANK   32
@@ -183,6 +185,31 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, 
unsigned int type)
return 0;
 }
 
+static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
+{
+   struct brcmstb_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+   struct brcmstb_gpio_priv *priv = bank->parent_priv;
+
+   /*
+* Only enable wake IRQ once for however many hwirqs can wake
+* since they all use the same wake IRQ.  Mask will be set
+* up appropriately thanks to IRQCHIP_MASK_ON_SUSPEND flag.
+*/
+   if (enable)
+   enable_irq_wake(priv->parent_wake_irq);
+   else
+   disable_irq_wake(priv->parent_wake_irq);
+   return 0;
+}
+
+static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data)
+{
+   struct brcmstb_gpio_priv *priv = data;
+
+   pm_wakeup_event(&priv->pdev->dev, 0);
+   return IRQ_HANDLED;
+}
+
 static void brcmstb_gpio_irq_bank_handler(int irq,
struct brcmstb_gpio_bank *bank)
 {
@@ -369,6 +396,32 @@ static int brcmstb_gpio_irq_setup(struct platform_device 
*pdev,
priv->irq_chip.irq_mask = brcmstb_gpio_irq_mask;
priv->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask;
priv->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type;
+
+   /* Ensures that all non-wakeup IRQs are disabled at suspend */
+   priv->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
+
+   if (IS_ENABLED(CONFIG_PM_SLEEP) &&
+   of_get_property(np, "wakeup-source", NULL)) {
+   priv->parent_wake_irq = platform_get_irq(pdev, 1);
+   if (priv->parent_wake_irq < 0)  {
+   dev_warn(dev,
+   "Couldn't get wake IRQ - GPIOs will not be able 
to wake from sleep");
+   } else {
+   int err = devm_request_irq(dev, priv->parent_wake_irq,
+   brcmstb_gpio_wake_irq_handler, 0,
+   "brcmstb-gpio-wake", priv);
+
+   if (err < 0) {
+   dev_err(dev, "Couldn't request wake IRQ");
+   return err;
+   }
+
+   device_set_wakeup_capable(dev, true);
+   device_wakeup_enable(dev);
+   priv->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake;
+   }
+   }
+
priv->irq_domain =
irq_domain_add_linear(np, priv->num_gpios,
  &brcmstb_gpio_irq_domain_ops,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 6/6] ARM: brcmstb: Add default gpio number

2015-05-28 Thread Gregory Fong
Out of the brcmstb SoCs that I know, BCM3390 has the largest numbers
of GPIOs, with its
- 320 "peripheral" GPIOs
- 5*32 = 160 UPG GPIOs (counting unused lines, which do get counted)
- 2*32 = 64 UPG AON GPIOs (counting unused lines)
Total: 544

I suspect that the upper limit will only need to be higher in the
future, so set it to 1024.

Signed-off-by: Gregory Fong 
---
New in v2.

 arch/arm/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e717642..bbe6bf7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1509,7 +1509,8 @@ config ARM_PSCI
 # selected platforms.
 config ARCH_NR_GPIO
int
-   default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
+   default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
+   ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
default 416 if ARCH_SUNXI
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/6] dt-bindings: brcmstb-gpio: document properties for wakeup

2015-05-28 Thread Gregory Fong
Some brcmstb GPIO controllers can be used to wake from suspend, so use the
de facto standard property 'wakeup-source' to mark the nodes of controllers
with that capability.

Also document interrupts-extended, which will be used for wakeup handling
because the interrupt parent for the wake IRQ is different from the regular
IRQ.

Signed-off-by: Gregory Fong 
---
New in v2.

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt 
b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
index 435f1bc..568814f 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
@@ -33,6 +33,12 @@ Optional properties:
 - interrupt-parent:
 phandle of the parent interrupt controller
 
+- interrupts-extended:
+Alternate form of specifying interrupts and parents that allows for
+multiple parents.  This takes precedence over 'interrupts' and
+'interrupt-parent'.  This probably must be used if the wakeup-source
+property is provided because that may have a different interrupt parent.
+
 - #interrupt-cells:
 Should be <2>.  The first cell is the GPIO number, the second should 
specify
 flags.  The following subset of flags is supported:
@@ -48,7 +54,10 @@ Optional properties:
 Marks the device node as an interrupt controller
 
 - interrupt-names:
-The name of the IRQ resource used by this controller
+The names of the IRQ resources used by this controller
+
+- wakeup-source:
+GPIOs for this controller can be used as a wakeup source
 
 Example:
upg_gio: gpio@f040a700 {
@@ -63,3 +72,18 @@ Example:
interrupt-names = "upg_gio";
brcm,gpio-bank-widths = <0x20 0x20 0x20 0x18>;
};
+
+   upg_gio_aon: gpio@f04172c0 {
+   #gpio-cells = <0x2>;
+   #interrupt-cells = <0x2>;
+   compatible = "brcm,bcm7445-gpio", "brcm,brcmstb-gpio";
+   gpio-controller;
+   interrupt-controller;
+   reg = <0xf04172c0 0x40>;
+   interrupt-parent = <0xc>;
+   interrupts = <0x6>;
+   interrupts-extended = <0xc 0x6 0xa 0x5>;
+   interrupt-names = "upg_gio_aon", "upg_gio_aon_wakeup";
+   wakeup-source;
+   brcm,gpio-bank-widths = <0x12 0x4>;
+   };
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/6] ARM: brcmstb: Select ARCH_WANT_OPTIONAL_GPIOLIB

2015-05-28 Thread Gregory Fong
Select ARCH_WANT_OPTIONAL_GPIOLIB from BRCMSTB to allow GPIOLIB and
GPIO_BRCMSTB to be enabled.

Signed-off-by: Gregory Fong 
---
v2: this was split out so that it can go through the ARM SoC tree.

 arch/arm/mach-bcm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 8b11f44..0ac9e4b3 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -144,6 +144,7 @@ config ARCH_BRCMSTB
select BRCMSTB_GISB_ARB
select BRCMSTB_L2_IRQ
select BCM7120_L2_IRQ
+   select ARCH_WANT_OPTIONAL_GPIOLIB
help
  Say Y if you intend to run the kernel on a Broadcom ARM-based STB
  chipset.
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/6] GPIO support for BRCMSTB

2015-05-28 Thread Gregory Fong
This patchset adds support for the GPIO controller (UPG GIO) used on Broadcom's
various BRCMSTB SoCs (BCM7XXX and others). It uses the "basic-mmio-gpio"
interface to try to reduce duplication of the base logic.

For all existing hardware, this block hooked up to the BCM7120 L2 IRQ
controller and so will require CONFIG_BCM7120_L2_IRQ=y.

New in v2:
- fix license mismatch as pointed out by Paul Bolle
- move select ARCH_WANT_OPTIONAL_GPIOLIB to separate patch
- change to have 32 lines per bank per Linus Walleij's comments
- allow this controller to be used as a wakeup source
- add default GPIO number for BRCMSTB

The device tree bindings from v1 were merged to the GPIO tree, so this patchset
only contains an addition to allow GPIOs to be used as a wakeup source
(patch 3).  The initial bindings from v1 can be found at
https://lkml.org/lkml/2015/5/6/200 .

Gregory Fong (6):
  gpio: Add GPIO support for Broadcom STB SoCs
  gpio: brcmstb: Add interrupt support
  dt-bindings: brcmstb-gpio: document properties for wakeup
  gpio: brcmstb: Allow GPIOs to be wakeup sources
  ARM: brcmstb: Select ARCH_WANT_OPTIONAL_GPIOLIB
  ARM: brcmstb: Add default gpio number

 .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt |  26 +-
 MAINTAINERS|   7 +
 arch/arm/Kconfig   |   3 +-
 arch/arm/mach-bcm/Kconfig  |   1 +
 drivers/gpio/Kconfig   |   9 +
 drivers/gpio/Makefile  |   1 +
 drivers/gpio/gpio-brcmstb.c| 581 +
 7 files changed, 626 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpio/gpio-brcmstb.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] GPIO support for BRCMSTB

2015-05-26 Thread Gregory Fong
Hi Linus,

On Wed, May 13, 2015 at 1:59 AM, Linus Walleij  wrote:
> On Tue, May 12, 2015 at 9:38 PM, Gregory Fong  wrote:
>> On Tue, May 12, 2015 at 3:59 AM, Linus Walleij  
>> wrote:
>>> On Wed, May 6, 2015 at 10:37 AM, Gregory Fong  
>>> wrote:
>>>
>>>> There is only one IRQ for each GIO IP block (i.e. several register banks 
>>>> share
>>>> an IRQ).  After briefly looking into the generic IRQ chip implementation, 
>>>> it
>>>> seemed like in this case that using it would result in the driver being 
>>>> more
>>>> complex than necessary because AFAICT it expects a 1:1 mapping of
>>>> irq_chip_generic to gpio_chip.  It seemed like less of a pain to have a 
>>>> single
>>>> irq_chip since we have a single IRQ for all register banks (multiple
>>>> gpio_chips).  I might be missing something, maybe using a shared IRQ across
>>>> multiple irq_chips is easier than I think?  Suggestions welcome.
>>>
>>> What is needed is a 1:1 mapping between GPIO offsets and IRQ
>>> offsets.
>>>
>>> If you just number your GPIOs 0...n and your IRQs 0...n
>>> it should work just fine with one irqchip for all banks.
>>>
>>> What screws things up is likely that the hardware supports
>>> 32 lines per bank and not all are used.
>>>
>>> I suggest you enable 32 line and 32 IRQs per bank,
>>> so that hwirq maps nicely 1:1 on the GPIO offsets,
>>> then just use the width thing to NACK operations on
>>> GPIO lines you are not using. This way you can also
>>> decode and warn on spurious IRQs on the unused lines.
>>
>> For having 32 lines per bank, the big problem here is the upper limit
>> of 256 GPIOs.
>
> Which arch is this?
> Usually this limit comes from
> arch/*/include/asm/gpio.h
>
> For ARM that was bumped to 512 a while back. It is also possible
> to define a custom value for your system by defining
> ARCH_NR_GPIOS
>
>> Anyway, I don't think I understand IRQ domains and irq_chip_generic
>> very well.  One possibility _might_ be to use multiple irq_chips.
>
> That is probably not possible if there is just one IRQ for all
> banks.
>
> The task of the irqdomain is a 1-to-1 translation from one
> hardware numberspace to the Linux IRQ number space.
>
> In your case the hardware IRQ (hwirq) numberspace
> should be:
>
> bank0: 0..31
> bank1: 32..63
> 
> bankn: 32*n..32*n+31
>
> I think the gpiolib irqchip code can translate that properly
> as it is just a simple 0...x mapping, the irq handler need
> some magic to loop over all banks from 0..n though.

I've now actually attempted to use the gpiolib irqchip code.  This
driver can't directly use gpiochip_irqchip_add() because of the
multiple gpiochip : one irqchip map.  At first, I thought it might be
possible to simply add a new argument (or break things into a helper
function) to allow setting the associated IRQ domain, but then I can't
use the generic map and unmap functions which expect the irq_domain
host_data member to be struct gpiochip *, which makes no sense in this
case.  That puts me right back to implementing a special version of
the map and unmap function.

Since there doesn't appear to be any benefit to using the gpiolib
irqchip code for this case, I'm going to stick with my implementation
from patch 3 of this patchset.  I've also added to it to allow for
using the GPIOs as a wakeup source, and will submit that as well with
V2.

Thanks,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] gpio: Add GPIO support for Broadcom STB SoCs

2015-05-07 Thread Gregory Fong
On Thu, May 07, 2015 at 10:18:49AM +0200, Paul Bolle wrote:
> Just a nit: a license mismatch.
> 
> On Wed, 2015-05-06 at 01:37 -0700, Gregory Fong wrote:
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-brcmstb.c
> 
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation version 2.
> > + *
> > + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> > + * kind, whether express or implied; without even the implied warranty
> > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> 
> This states the license is GPL v2.
> 
> > +MODULE_LICENSE("GPL");
> 
> And, according to include/linux/module.h, this states the license is GPL
> v2 or later. So I think either the comment at the top of this file or
> the ident used in the MODULE_LICENSE() macro needs to change.

Will fix that, thanks.

Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] ARM: dts: brcmstb: un-hexify clock frequency

2015-03-18 Thread Gregory Fong
On Wed, Mar 18, 2015 at 5:31 PM, Brian Norris
 wrote:
> This value makes much more sense in decimal.
>
> Signed-off-by: Brian Norris 

Acked-by: Gregory Fong 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 5/9] ARM: Enable erratum 798181 for Broadcom Brahma-B15

2014-02-26 Thread Gregory Fong
Hi Will,

On Wed, Feb 26, 2014 at 2:47 AM, Will Deacon  wrote:
> On Wed, Feb 26, 2014 at 10:29:08AM +, Marc Carino wrote:
>> From: Gregory Fong 
>>
>> Broadcom Brahma-B15 (r0p0..r0p2) is also affected by Cortex-A15
>> erratum 798181, so enable the workaround for Brahma-B15.
>
> Really... *exactly* the same erratum? That sounds pretty unlikely, so I'd
> really like to be sure that the workaround we have indeed solves your
> problem (issuing a dummy TLBI to 0x0 + dsb, then followed by a dmb + clrex
> on each core). The point is that the workaround doesn't simply perform
> non-shareable invalidation on each core using IPIs.

Yes, it should be the same.  I've sent you more detail off-list.

Regards,
Gregory
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html