All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/3] mfd: palmas: add optional wakeup irq
@ 2014-09-05 20:51 ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

Hi,

V2 of the series based on review conclusion in
https://patchwork.kernel.org/patch/4743321/

based on v3.17-rc1

Wakeup irq is a interrupt path which is provided by the pinctrl
hardware of certain SoCs such as TI's OMAP family of processors that
generates an interrupt for waking up from deep power saving modes.

Nishanth Menon (3):
  Documentation: dt-bindings: mfd: palmas: Fix example style of i2c
    peripheral
  Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
  mfd: palmas: Add support for optional wakeup

 Documentation/devicetree/bindings/mfd/palmas.txt |   22 +++++++-
 drivers/mfd/palmas.c                             |   59 ++++++++++++++++++++++
 include/linux/mfd/palmas.h                       |    2 +
 3 files changed, 82 insertions(+), 1 deletion(-)

Regards,
	Nishanth Menon
-- 
1.7.9.5


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

* [PATCH V2 0/3] mfd: palmas: add optional wakeup irq
@ 2014-09-05 20:51 ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Keerthy, Mark Brown,
	Nishanth Menon, Samuel Ortiz, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	Tony Lindgren, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi,

V2 of the series based on review conclusion in
https://patchwork.kernel.org/patch/4743321/

based on v3.17-rc1

Wakeup irq is a interrupt path which is provided by the pinctrl
hardware of certain SoCs such as TI's OMAP family of processors that
generates an interrupt for waking up from deep power saving modes.

Nishanth Menon (3):
  Documentation: dt-bindings: mfd: palmas: Fix example style of i2c
    peripheral
  Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
  mfd: palmas: Add support for optional wakeup

 Documentation/devicetree/bindings/mfd/palmas.txt |   22 +++++++-
 drivers/mfd/palmas.c                             |   59 ++++++++++++++++++++++
 include/linux/mfd/palmas.h                       |    2 +
 3 files changed, 82 insertions(+), 1 deletion(-)

Regards,
	Nishanth Menon
-- 
1.7.9.5

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

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

* [PATCH V2 0/3] mfd: palmas: add optional wakeup irq
@ 2014-09-05 20:51 ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

V2 of the series based on review conclusion in
https://patchwork.kernel.org/patch/4743321/

based on v3.17-rc1

Wakeup irq is a interrupt path which is provided by the pinctrl
hardware of certain SoCs such as TI's OMAP family of processors that
generates an interrupt for waking up from deep power saving modes.

Nishanth Menon (3):
  Documentation: dt-bindings: mfd: palmas: Fix example style of i2c
    peripheral
  Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
  mfd: palmas: Add support for optional wakeup

 Documentation/devicetree/bindings/mfd/palmas.txt |   22 +++++++-
 drivers/mfd/palmas.c                             |   59 ++++++++++++++++++++++
 include/linux/mfd/palmas.h                       |    2 +
 3 files changed, 82 insertions(+), 1 deletion(-)

Regards,
	Nishanth Menon
-- 
1.7.9.5

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

* [PATCH V2 1/3] Documentation: dt-bindings: mfd: palmas: Fix example style of i2c peripheral
  2014-09-05 20:51 ` Nishanth Menon
  (?)
@ 2014-09-05 20:51   ` Nishanth Menon
  -1 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

Use device@address as name for device nodes.

Suggested-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index eda8989..d193859 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -33,7 +33,7 @@ Optional properties:
 
 Example:
 
-palmas {
+palmas@48 {
 	compatible = "ti,twl6035", "ti,palmas";
 	reg = <0x48>
 	interrupt-parent = <&intc>;
-- 
1.7.9.5


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

* [PATCH V2 1/3] Documentation: dt-bindings: mfd: palmas: Fix example style of i2c peripheral
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

Use device@address as name for device nodes.

Suggested-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index eda8989..d193859 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -33,7 +33,7 @@ Optional properties:
 
 Example:
 
-palmas {
+palmas@48 {
 	compatible = "ti,twl6035", "ti,palmas";
 	reg = <0x48>
 	interrupt-parent = <&intc>;
-- 
1.7.9.5

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

* [PATCH V2 1/3] Documentation: dt-bindings: mfd: palmas: Fix example style of i2c peripheral
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

Use device at address as name for device nodes.

Suggested-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index eda8989..d193859 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -33,7 +33,7 @@ Optional properties:
 
 Example:
 
-palmas {
+palmas at 48 {
 	compatible = "ti,twl6035", "ti,palmas";
 	reg = <0x48>
 	interrupt-parent = <&intc>;
-- 
1.7.9.5

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

* [PATCH V2 2/3] Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
  2014-09-05 20:51 ` Nishanth Menon
  (?)
@ 2014-09-05 20:51   ` Nishanth Menon
  -1 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

With the recent pinctrl-single changes, SoCs such as OMAP family can
treat wake-up events from deeper low power states as interrupts.

This is usable when the wakeup from deeper low power states is
triggered by a different hardware mechanism tied to pinctrl compared
to the routine interrupt handling generating the reqular interrupt
events. This is usually done on SoCs where the routine interrupt
sources such as GPIO need to be disabled to be actually achieve low
power state and wakeup is triggered from pinctrl interrupt source.

Provide documentation example for the case where the system needs two
interrupt sources when SoC is in deep sleep(1 to exit from deep sleep,
and other from the module handling the actual event).

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index d193859..1c821d6 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -51,3 +51,23 @@ palmas@48 {
 		....
 	};
 }
+
+Example: With interrupts extended
+ See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ Use pinmux 0x418 as wakeup interrupt and gpio1_0 as interrupt source
+
+palmas@48 {
+	compatible = "ti,twl6035", "ti,palmas";
+	reg = <0x48>
+	interrupt-parent = <&intc>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts-extended = <&gpio1 0 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pinmux 0x418>;
+	pmic {
+		compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
+		....
+	};
+}
-- 
1.7.9.5


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

* [PATCH V2 2/3] Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

With the recent pinctrl-single changes, SoCs such as OMAP family can
treat wake-up events from deeper low power states as interrupts.

This is usable when the wakeup from deeper low power states is
triggered by a different hardware mechanism tied to pinctrl compared
to the routine interrupt handling generating the reqular interrupt
events. This is usually done on SoCs where the routine interrupt
sources such as GPIO need to be disabled to be actually achieve low
power state and wakeup is triggered from pinctrl interrupt source.

Provide documentation example for the case where the system needs two
interrupt sources when SoC is in deep sleep(1 to exit from deep sleep,
and other from the module handling the actual event).

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index d193859..1c821d6 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -51,3 +51,23 @@ palmas@48 {
 		....
 	};
 }
+
+Example: With interrupts extended
+ See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ Use pinmux 0x418 as wakeup interrupt and gpio1_0 as interrupt source
+
+palmas@48 {
+	compatible = "ti,twl6035", "ti,palmas";
+	reg = <0x48>
+	interrupt-parent = <&intc>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts-extended = <&gpio1 0 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pinmux 0x418>;
+	pmic {
+		compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
+		....
+	};
+}
-- 
1.7.9.5

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

* [PATCH V2 2/3] Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

With the recent pinctrl-single changes, SoCs such as OMAP family can
treat wake-up events from deeper low power states as interrupts.

This is usable when the wakeup from deeper low power states is
triggered by a different hardware mechanism tied to pinctrl compared
to the routine interrupt handling generating the reqular interrupt
events. This is usually done on SoCs where the routine interrupt
sources such as GPIO need to be disabled to be actually achieve low
power state and wakeup is triggered from pinctrl interrupt source.

Provide documentation example for the case where the system needs two
interrupt sources when SoC is in deep sleep(1 to exit from deep sleep,
and other from the module handling the actual event).

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 Documentation/devicetree/bindings/mfd/palmas.txt |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index d193859..1c821d6 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -51,3 +51,23 @@ palmas at 48 {
 		....
 	};
 }
+
+Example: With interrupts extended
+ See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ Use pinmux 0x418 as wakeup interrupt and gpio1_0 as interrupt source
+
+palmas at 48 {
+	compatible = "ti,twl6035", "ti,palmas";
+	reg = <0x48>
+	interrupt-parent = <&intc>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts-extended = <&gpio1 0 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pinmux 0x418>;
+	pmic {
+		compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
+		....
+	};
+}
-- 
1.7.9.5

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
  2014-09-05 20:51 ` Nishanth Menon
  (?)
@ 2014-09-05 20:51   ` Nishanth Menon
  -1 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, devicetree, Keerthy, Mark Brown, Nishanth Menon,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   59 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 61 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..11186ab 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,22 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       IRQF_ONESHOT | pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0)
+		goto err_i2c;
+
+	/* We use wakeirq only during suspend-resume path */
+	device_set_wakeup_capable(palmas->dev, true);
+	disable_irq_nosync(palmas->wakeirq);
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +735,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +778,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5


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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: Nishanth Menon, devicetree, Samuel Ortiz, Mark Brown,
	Tony Lindgren, Keerthy, linux-kernel, linux-omap,
	linux-arm-kernel

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   59 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 61 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..11186ab 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,22 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       IRQF_ONESHOT | pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0)
+		goto err_i2c;
+
+	/* We use wakeirq only during suspend-resume path */
+	device_set_wakeup_capable(palmas->dev, true);
+	disable_irq_nosync(palmas->wakeirq);
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +735,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +778,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-05 20:51   ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-05 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   59 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 61 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..11186ab 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,22 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       IRQF_ONESHOT | pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0)
+		goto err_i2c;
+
+	/* We use wakeirq only during suspend-resume path */
+	device_set_wakeup_capable(palmas->dev, true);
+	disable_irq_nosync(palmas->wakeirq);
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +735,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +778,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-05 21:13     ` Thomas Gleixner
  0 siblings, 0 replies; 24+ messages in thread
From: Thomas Gleixner @ 2014-09-05 21:13 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Lee Jones, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On Fri, 5 Sep 2014, Nishanth Menon wrote:
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       IRQF_ONESHOT | pdata->irq_flags,

Why is this marked IRQF_ONESHOT?

> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0)
> +		goto err_i2c;

Why err and not doing the obvious clearing of palmas->wakeirq and
keep at least the i2c functional?

Thanks,

	tglx

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-05 21:13     ` Thomas Gleixner
  0 siblings, 0 replies; 24+ messages in thread
From: Thomas Gleixner @ 2014-09-05 21:13 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Lee Jones, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, 5 Sep 2014, Nishanth Menon wrote:
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       IRQF_ONESHOT | pdata->irq_flags,

Why is this marked IRQF_ONESHOT?

> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0)
> +		goto err_i2c;

Why err and not doing the obvious clearing of palmas->wakeirq and
keep at least the i2c functional?

Thanks,

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

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-05 21:13     ` Thomas Gleixner
  0 siblings, 0 replies; 24+ messages in thread
From: Thomas Gleixner @ 2014-09-05 21:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 5 Sep 2014, Nishanth Menon wrote:
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       IRQF_ONESHOT | pdata->irq_flags,

Why is this marked IRQF_ONESHOT?

> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0)
> +		goto err_i2c;

Why err and not doing the obvious clearing of palmas->wakeirq and
keep at least the i2c functional?

Thanks,

	tglx

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
  2014-09-05 21:13     ` Thomas Gleixner
  (?)
@ 2014-09-08 15:41       ` Nishanth Menon
  -1 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-08 15:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Lee Jones, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On 23:13-20140905, Thomas Gleixner wrote:
> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       IRQF_ONESHOT | pdata->irq_flags,
> 
> Why is this marked IRQF_ONESHOT?

Uggh.. should have dropped it. my bad.. removed in the revision below.
Thanks for catching it.
> 
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0)
> > +		goto err_i2c;
> 
> Why err and not doing the obvious clearing of palmas->wakeirq and
> keep at least the i2c functional?
Hmmm.. true.. we can stay alive even though without wakeup capability if
someone messes up configuration..

Fixed version below. Let me know if you are ok with the following.
----8<----
>From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Tue, 12 Aug 2014 12:00:52 -0500
Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..de7d204 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0) {
+		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
+			palmas->wakeirq, ret);
+		palmas->wakeirq = 0;
+	} else {
+		/* We use wakeirq only during suspend-resume path */
+		device_set_wakeup_capable(palmas->dev, true);
+		disable_irq_nosync(palmas->wakeirq);
+	}
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5


-- 
Regards,
Nishanth Menon

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-08 15:41       ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-08 15:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Lee Jones, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On 23:13-20140905, Thomas Gleixner wrote:
> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       IRQF_ONESHOT | pdata->irq_flags,
> 
> Why is this marked IRQF_ONESHOT?

Uggh.. should have dropped it. my bad.. removed in the revision below.
Thanks for catching it.
> 
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0)
> > +		goto err_i2c;
> 
> Why err and not doing the obvious clearing of palmas->wakeirq and
> keep at least the i2c functional?
Hmmm.. true.. we can stay alive even though without wakeup capability if
someone messes up configuration..

Fixed version below. Let me know if you are ok with the following.
----8<----
>From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Tue, 12 Aug 2014 12:00:52 -0500
Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..de7d204 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0) {
+		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
+			palmas->wakeirq, ret);
+		palmas->wakeirq = 0;
+	} else {
+		/* We use wakeirq only during suspend-resume path */
+		device_set_wakeup_capable(palmas->dev, true);
+		disable_irq_nosync(palmas->wakeirq);
+	}
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5


-- 
Regards,
Nishanth Menon

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-08 15:41       ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-08 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 23:13-20140905, Thomas Gleixner wrote:
> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       IRQF_ONESHOT | pdata->irq_flags,
> 
> Why is this marked IRQF_ONESHOT?

Uggh.. should have dropped it. my bad.. removed in the revision below.
Thanks for catching it.
> 
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0)
> > +		goto err_i2c;
> 
> Why err and not doing the obvious clearing of palmas->wakeirq and
> keep at least the i2c functional?
Hmmm.. true.. we can stay alive even though without wakeup capability if
someone messes up configuration..

Fixed version below. Let me know if you are ok with the following.
----8<----
>From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Tue, 12 Aug 2014 12:00:52 -0500
Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup

With the recent pinctrl-single changes, omaps can treat wake-up events
from deeper power  states as interrupts.

This is to handle the case where the system needs two interrupt
sources when SoC is in deep sleep(1 to exit from deep power mode such
as sleep, and other from the module handling the actual event during
system active state). This is not the same as threaded interrupts as the
wakeup interrupt source is used only as part of deeper power saving
mode.

Let's add support for the optional second interrupt for wake-up
events. And then SoC can wakeup and handle the event using it's
regular handler.

This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
support for optional wake-up")

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/palmas.h |    2 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..de7d204 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
 			PALMAS_INT1_MASK),
 };
 
+static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
+{
+	/*
+	 * Return Not handled so that interrupt is disabled.
+	 * Level event ensures that the event is eventually handled
+	 * by the appropriate chip handler already registered
+	 */
+	return IRQ_NONE;
+}
+
 int palmas_ext_control_req_config(struct palmas *palmas,
 	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
@@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
 		pdata->mux_from_pdata = 1;
 		pdata->pad2 = prop;
 	}
+	pdata->wakeirq = irq_of_parse_and_map(node, 1);
 
 	/* The default for this register is all masked */
 	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
@@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
 	palmas->irq = i2c->irq;
+	palmas->wakeirq = pdata->wakeirq;
 
 	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
 
@@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 	if (ret < 0)
 		goto err_i2c;
 
+	if (!palmas->wakeirq)
+		goto no_wake_irq;
+
+	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
+			       palmas_wake_irq,
+			       pdata->irq_flags,
+			       dev_name(palmas->dev),
+			       &palmas);
+	if (ret < 0) {
+		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
+			palmas->wakeirq, ret);
+		palmas->wakeirq = 0;
+	} else {
+		/* We use wakeirq only during suspend-resume path */
+		device_set_wakeup_capable(palmas->dev, true);
+		disable_irq_nosync(palmas->wakeirq);
+	}
+
+no_wake_irq:
 no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
@@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		enable_irq(palmas->wakeirq);
+
+	return 0;
+}
+
+static int palmas_i2c_resume(struct i2c_client *i2c)
+{
+	struct palmas *palmas = i2c_get_clientdata(i2c);
+	struct device *dev = &i2c->dev;
+
+	if (!palmas->wakeirq)
+		return 0;
+
+	if (device_may_wakeup(dev))
+		disable_irq_nosync(palmas->wakeirq);
+
+	return 0;
+}
+
 static const struct i2c_device_id palmas_i2c_id[] = {
 	{ "palmas", },
 	{ "twl6035", },
@@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
 		   .of_match_table = of_palmas_match_tbl,
 		   .owner = THIS_MODULE,
 	},
+	.suspend = palmas_i2c_suspend,
+	.resume = palmas_i2c_resume,
 	.probe = palmas_i2c_probe,
 	.remove = palmas_i2c_remove,
 	.id_table = palmas_i2c_id,
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..e8cf4c2 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -75,6 +75,7 @@ struct palmas {
 	/* IRQ Data */
 	int irq;
 	u32 irq_mask;
+	int wakeirq;
 	struct mutex irq_lock;
 	struct regmap_irq_chip_data *irq_data;
 
@@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
 
 struct palmas_platform_data {
 	int irq_flags;
+	int wakeirq;
 	int gpio_base;
 
 	/* bit value to be loaded to the POWER_CTRL register */
-- 
1.7.9.5


-- 
Regards,
Nishanth Menon

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
  2014-09-08 15:41       ` Nishanth Menon
  (?)
@ 2014-09-18 13:54         ` Nishanth Menon
  -1 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-18 13:54 UTC (permalink / raw)
  To: Lee Jones
  Cc: Thomas Gleixner, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> On 23:13-20140905, Thomas Gleixner wrote:
>> On Fri, 5 Sep 2014, Nishanth Menon wrote:
>>> +	if (!palmas->wakeirq)
>>> +		goto no_wake_irq;
>>> +
>>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
>>> +			       palmas_wake_irq,
>>> +			       IRQF_ONESHOT | pdata->irq_flags,
>>
>> Why is this marked IRQF_ONESHOT?
> 
> Uggh.. should have dropped it. my bad.. removed in the revision below.
> Thanks for catching it.
>>
>>> +			       dev_name(palmas->dev),
>>> +			       &palmas);
>>> +	if (ret < 0)
>>> +		goto err_i2c;
>>
>> Why err and not doing the obvious clearing of palmas->wakeirq and
>> keep at least the i2c functional?
> Hmmm.. true.. we can stay alive even though without wakeup capability if
> someone messes up configuration..
> 
> Fixed version below. Let me know if you are ok with the following.

Gentle ping. Would you like me to repost this series over again?

> ----8<----
> From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> From: Nishanth Menon <nm@ti.com>
> Date: Tue, 12 Aug 2014 12:00:52 -0500
> Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> 
> With the recent pinctrl-single changes, omaps can treat wake-up events
> from deeper power  states as interrupts.
> 
> This is to handle the case where the system needs two interrupt
> sources when SoC is in deep sleep(1 to exit from deep power mode such
> as sleep, and other from the module handling the actual event during
> system active state). This is not the same as threaded interrupts as the
> wakeup interrupt source is used only as part of deeper power saving
> mode.
> 
> Let's add support for the optional second interrupt for wake-up
> events. And then SoC can wakeup and handle the event using it's
> regular handler.
> 
> This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> support for optional wake-up")
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/palmas.h |    2 ++
>  2 files changed, 64 insertions(+)
> 
> diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> index 28cb048..de7d204 100644
> --- a/drivers/mfd/palmas.c
> +++ b/drivers/mfd/palmas.c
> @@ -24,6 +24,7 @@
>  #include <linux/mfd/core.h>
>  #include <linux/mfd/palmas.h>
>  #include <linux/of_device.h>
> +#include <linux/of_irq.h>
>  
>  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
>  	{
> @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
>  			PALMAS_INT1_MASK),
>  };
>  
> +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> +{
> +	/*
> +	 * Return Not handled so that interrupt is disabled.
> +	 * Level event ensures that the event is eventually handled
> +	 * by the appropriate chip handler already registered
> +	 */
> +	return IRQ_NONE;
> +}
> +
>  int palmas_ext_control_req_config(struct palmas *palmas,
>  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
>  {
> @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
>  		pdata->mux_from_pdata = 1;
>  		pdata->pad2 = prop;
>  	}
> +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
>  
>  	/* The default for this register is all masked */
>  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	i2c_set_clientdata(i2c, palmas);
>  	palmas->dev = &i2c->dev;
>  	palmas->irq = i2c->irq;
> +	palmas->wakeirq = pdata->wakeirq;
>  
>  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
>  
> @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	if (ret < 0)
>  		goto err_i2c;
>  
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       pdata->irq_flags,
> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0) {
> +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> +			palmas->wakeirq, ret);
> +		palmas->wakeirq = 0;
> +	} else {
> +		/* We use wakeirq only during suspend-resume path */
> +		device_set_wakeup_capable(palmas->dev, true);
> +		disable_irq_nosync(palmas->wakeirq);
> +	}
> +
> +no_wake_irq:
>  no_irq:
>  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
>  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
>  	return 0;
>  }
>  
> +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		enable_irq(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
> +static int palmas_i2c_resume(struct i2c_client *i2c)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		disable_irq_nosync(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
>  static const struct i2c_device_id palmas_i2c_id[] = {
>  	{ "palmas", },
>  	{ "twl6035", },
> @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
>  		   .of_match_table = of_palmas_match_tbl,
>  		   .owner = THIS_MODULE,
>  	},
> +	.suspend = palmas_i2c_suspend,
> +	.resume = palmas_i2c_resume,
>  	.probe = palmas_i2c_probe,
>  	.remove = palmas_i2c_remove,
>  	.id_table = palmas_i2c_id,
> diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> index fb0390a..e8cf4c2 100644
> --- a/include/linux/mfd/palmas.h
> +++ b/include/linux/mfd/palmas.h
> @@ -75,6 +75,7 @@ struct palmas {
>  	/* IRQ Data */
>  	int irq;
>  	u32 irq_mask;
> +	int wakeirq;
>  	struct mutex irq_lock;
>  	struct regmap_irq_chip_data *irq_data;
>  
> @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
>  
>  struct palmas_platform_data {
>  	int irq_flags;
> +	int wakeirq;
>  	int gpio_base;
>  
>  	/* bit value to be loaded to the POWER_CTRL register */
> 


-- 
Regards,
Nishanth Menon

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-18 13:54         ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-18 13:54 UTC (permalink / raw)
  To: Lee Jones
  Cc: Thomas Gleixner, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> On 23:13-20140905, Thomas Gleixner wrote:
>> On Fri, 5 Sep 2014, Nishanth Menon wrote:
>>> +	if (!palmas->wakeirq)
>>> +		goto no_wake_irq;
>>> +
>>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
>>> +			       palmas_wake_irq,
>>> +			       IRQF_ONESHOT | pdata->irq_flags,
>>
>> Why is this marked IRQF_ONESHOT?
> 
> Uggh.. should have dropped it. my bad.. removed in the revision below.
> Thanks for catching it.
>>
>>> +			       dev_name(palmas->dev),
>>> +			       &palmas);
>>> +	if (ret < 0)
>>> +		goto err_i2c;
>>
>> Why err and not doing the obvious clearing of palmas->wakeirq and
>> keep at least the i2c functional?
> Hmmm.. true.. we can stay alive even though without wakeup capability if
> someone messes up configuration..
> 
> Fixed version below. Let me know if you are ok with the following.

Gentle ping. Would you like me to repost this series over again?

> ----8<----
> From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> From: Nishanth Menon <nm@ti.com>
> Date: Tue, 12 Aug 2014 12:00:52 -0500
> Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> 
> With the recent pinctrl-single changes, omaps can treat wake-up events
> from deeper power  states as interrupts.
> 
> This is to handle the case where the system needs two interrupt
> sources when SoC is in deep sleep(1 to exit from deep power mode such
> as sleep, and other from the module handling the actual event during
> system active state). This is not the same as threaded interrupts as the
> wakeup interrupt source is used only as part of deeper power saving
> mode.
> 
> Let's add support for the optional second interrupt for wake-up
> events. And then SoC can wakeup and handle the event using it's
> regular handler.
> 
> This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> support for optional wake-up")
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/palmas.h |    2 ++
>  2 files changed, 64 insertions(+)
> 
> diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> index 28cb048..de7d204 100644
> --- a/drivers/mfd/palmas.c
> +++ b/drivers/mfd/palmas.c
> @@ -24,6 +24,7 @@
>  #include <linux/mfd/core.h>
>  #include <linux/mfd/palmas.h>
>  #include <linux/of_device.h>
> +#include <linux/of_irq.h>
>  
>  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
>  	{
> @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
>  			PALMAS_INT1_MASK),
>  };
>  
> +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> +{
> +	/*
> +	 * Return Not handled so that interrupt is disabled.
> +	 * Level event ensures that the event is eventually handled
> +	 * by the appropriate chip handler already registered
> +	 */
> +	return IRQ_NONE;
> +}
> +
>  int palmas_ext_control_req_config(struct palmas *palmas,
>  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
>  {
> @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
>  		pdata->mux_from_pdata = 1;
>  		pdata->pad2 = prop;
>  	}
> +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
>  
>  	/* The default for this register is all masked */
>  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	i2c_set_clientdata(i2c, palmas);
>  	palmas->dev = &i2c->dev;
>  	palmas->irq = i2c->irq;
> +	palmas->wakeirq = pdata->wakeirq;
>  
>  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
>  
> @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	if (ret < 0)
>  		goto err_i2c;
>  
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       pdata->irq_flags,
> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0) {
> +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> +			palmas->wakeirq, ret);
> +		palmas->wakeirq = 0;
> +	} else {
> +		/* We use wakeirq only during suspend-resume path */
> +		device_set_wakeup_capable(palmas->dev, true);
> +		disable_irq_nosync(palmas->wakeirq);
> +	}
> +
> +no_wake_irq:
>  no_irq:
>  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
>  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
>  	return 0;
>  }
>  
> +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		enable_irq(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
> +static int palmas_i2c_resume(struct i2c_client *i2c)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		disable_irq_nosync(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
>  static const struct i2c_device_id palmas_i2c_id[] = {
>  	{ "palmas", },
>  	{ "twl6035", },
> @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
>  		   .of_match_table = of_palmas_match_tbl,
>  		   .owner = THIS_MODULE,
>  	},
> +	.suspend = palmas_i2c_suspend,
> +	.resume = palmas_i2c_resume,
>  	.probe = palmas_i2c_probe,
>  	.remove = palmas_i2c_remove,
>  	.id_table = palmas_i2c_id,
> diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> index fb0390a..e8cf4c2 100644
> --- a/include/linux/mfd/palmas.h
> +++ b/include/linux/mfd/palmas.h
> @@ -75,6 +75,7 @@ struct palmas {
>  	/* IRQ Data */
>  	int irq;
>  	u32 irq_mask;
> +	int wakeirq;
>  	struct mutex irq_lock;
>  	struct regmap_irq_chip_data *irq_data;
>  
> @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
>  
>  struct palmas_platform_data {
>  	int irq_flags;
> +	int wakeirq;
>  	int gpio_base;
>  
>  	/* bit value to be loaded to the POWER_CTRL register */
> 


-- 
Regards,
Nishanth Menon

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-18 13:54         ` Nishanth Menon
  0 siblings, 0 replies; 24+ messages in thread
From: Nishanth Menon @ 2014-09-18 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> On 23:13-20140905, Thomas Gleixner wrote:
>> On Fri, 5 Sep 2014, Nishanth Menon wrote:
>>> +	if (!palmas->wakeirq)
>>> +		goto no_wake_irq;
>>> +
>>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
>>> +			       palmas_wake_irq,
>>> +			       IRQF_ONESHOT | pdata->irq_flags,
>>
>> Why is this marked IRQF_ONESHOT?
> 
> Uggh.. should have dropped it. my bad.. removed in the revision below.
> Thanks for catching it.
>>
>>> +			       dev_name(palmas->dev),
>>> +			       &palmas);
>>> +	if (ret < 0)
>>> +		goto err_i2c;
>>
>> Why err and not doing the obvious clearing of palmas->wakeirq and
>> keep at least the i2c functional?
> Hmmm.. true.. we can stay alive even though without wakeup capability if
> someone messes up configuration..
> 
> Fixed version below. Let me know if you are ok with the following.

Gentle ping. Would you like me to repost this series over again?

> ----8<----
> From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> From: Nishanth Menon <nm@ti.com>
> Date: Tue, 12 Aug 2014 12:00:52 -0500
> Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> 
> With the recent pinctrl-single changes, omaps can treat wake-up events
> from deeper power  states as interrupts.
> 
> This is to handle the case where the system needs two interrupt
> sources when SoC is in deep sleep(1 to exit from deep power mode such
> as sleep, and other from the module handling the actual event during
> system active state). This is not the same as threaded interrupts as the
> wakeup interrupt source is used only as part of deeper power saving
> mode.
> 
> Let's add support for the optional second interrupt for wake-up
> events. And then SoC can wakeup and handle the event using it's
> regular handler.
> 
> This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> support for optional wake-up")
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/palmas.h |    2 ++
>  2 files changed, 64 insertions(+)
> 
> diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> index 28cb048..de7d204 100644
> --- a/drivers/mfd/palmas.c
> +++ b/drivers/mfd/palmas.c
> @@ -24,6 +24,7 @@
>  #include <linux/mfd/core.h>
>  #include <linux/mfd/palmas.h>
>  #include <linux/of_device.h>
> +#include <linux/of_irq.h>
>  
>  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
>  	{
> @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
>  			PALMAS_INT1_MASK),
>  };
>  
> +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> +{
> +	/*
> +	 * Return Not handled so that interrupt is disabled.
> +	 * Level event ensures that the event is eventually handled
> +	 * by the appropriate chip handler already registered
> +	 */
> +	return IRQ_NONE;
> +}
> +
>  int palmas_ext_control_req_config(struct palmas *palmas,
>  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
>  {
> @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
>  		pdata->mux_from_pdata = 1;
>  		pdata->pad2 = prop;
>  	}
> +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
>  
>  	/* The default for this register is all masked */
>  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	i2c_set_clientdata(i2c, palmas);
>  	palmas->dev = &i2c->dev;
>  	palmas->irq = i2c->irq;
> +	palmas->wakeirq = pdata->wakeirq;
>  
>  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
>  
> @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
>  	if (ret < 0)
>  		goto err_i2c;
>  
> +	if (!palmas->wakeirq)
> +		goto no_wake_irq;
> +
> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> +			       palmas_wake_irq,
> +			       pdata->irq_flags,
> +			       dev_name(palmas->dev),
> +			       &palmas);
> +	if (ret < 0) {
> +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> +			palmas->wakeirq, ret);
> +		palmas->wakeirq = 0;
> +	} else {
> +		/* We use wakeirq only during suspend-resume path */
> +		device_set_wakeup_capable(palmas->dev, true);
> +		disable_irq_nosync(palmas->wakeirq);
> +	}
> +
> +no_wake_irq:
>  no_irq:
>  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
>  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
>  	return 0;
>  }
>  
> +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		enable_irq(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
> +static int palmas_i2c_resume(struct i2c_client *i2c)
> +{
> +	struct palmas *palmas = i2c_get_clientdata(i2c);
> +	struct device *dev = &i2c->dev;
> +
> +	if (!palmas->wakeirq)
> +		return 0;
> +
> +	if (device_may_wakeup(dev))
> +		disable_irq_nosync(palmas->wakeirq);
> +
> +	return 0;
> +}
> +
>  static const struct i2c_device_id palmas_i2c_id[] = {
>  	{ "palmas", },
>  	{ "twl6035", },
> @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
>  		   .of_match_table = of_palmas_match_tbl,
>  		   .owner = THIS_MODULE,
>  	},
> +	.suspend = palmas_i2c_suspend,
> +	.resume = palmas_i2c_resume,
>  	.probe = palmas_i2c_probe,
>  	.remove = palmas_i2c_remove,
>  	.id_table = palmas_i2c_id,
> diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> index fb0390a..e8cf4c2 100644
> --- a/include/linux/mfd/palmas.h
> +++ b/include/linux/mfd/palmas.h
> @@ -75,6 +75,7 @@ struct palmas {
>  	/* IRQ Data */
>  	int irq;
>  	u32 irq_mask;
> +	int wakeirq;
>  	struct mutex irq_lock;
>  	struct regmap_irq_chip_data *irq_data;
>  
> @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
>  
>  struct palmas_platform_data {
>  	int irq_flags;
> +	int wakeirq;
>  	int gpio_base;
>  
>  	/* bit value to be loaded to the POWER_CTRL register */
> 


-- 
Regards,
Nishanth Menon

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
  2014-09-18 13:54         ` Nishanth Menon
  (?)
@ 2014-09-18 17:33           ` Lee Jones
  -1 siblings, 0 replies; 24+ messages in thread
From: Lee Jones @ 2014-09-18 17:33 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Thomas Gleixner, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On Thu, 18 Sep 2014, Nishanth Menon wrote:

> On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> > On 23:13-20140905, Thomas Gleixner wrote:
> >> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> >>> +	if (!palmas->wakeirq)
> >>> +		goto no_wake_irq;
> >>> +
> >>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> >>> +			       palmas_wake_irq,
> >>> +			       IRQF_ONESHOT | pdata->irq_flags,
> >>
> >> Why is this marked IRQF_ONESHOT?
> > 
> > Uggh.. should have dropped it. my bad.. removed in the revision below.
> > Thanks for catching it.
> >>
> >>> +			       dev_name(palmas->dev),
> >>> +			       &palmas);
> >>> +	if (ret < 0)
> >>> +		goto err_i2c;
> >>
> >> Why err and not doing the obvious clearing of palmas->wakeirq and
> >> keep at least the i2c functional?
> > Hmmm.. true.. we can stay alive even though without wakeup capability if
> > someone messes up configuration..
> > 
> > Fixed version below. Let me know if you are ok with the following.
> 
> Gentle ping. Would you like me to repost this series over again?

Yes, always.

> > ----8<----
> > From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> > From: Nishanth Menon <nm@ti.com>
> > Date: Tue, 12 Aug 2014 12:00:52 -0500
> > Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> > 
> > With the recent pinctrl-single changes, omaps can treat wake-up events
> > from deeper power  states as interrupts.
> > 
> > This is to handle the case where the system needs two interrupt
> > sources when SoC is in deep sleep(1 to exit from deep power mode such
> > as sleep, and other from the module handling the actual event during
> > system active state). This is not the same as threaded interrupts as the
> > wakeup interrupt source is used only as part of deeper power saving
> > mode.
> > 
> > Let's add support for the optional second interrupt for wake-up
> > events. And then SoC can wakeup and handle the event using it's
> > regular handler.
> > 
> > This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> > support for optional wake-up")
> > 
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > ---
> >  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/mfd/palmas.h |    2 ++
> >  2 files changed, 64 insertions(+)
> > 
> > diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> > index 28cb048..de7d204 100644
> > --- a/drivers/mfd/palmas.c
> > +++ b/drivers/mfd/palmas.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/mfd/core.h>
> >  #include <linux/mfd/palmas.h>
> >  #include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> >  
> >  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
> >  	{
> > @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
> >  			PALMAS_INT1_MASK),
> >  };
> >  
> > +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> > +{
> > +	/*
> > +	 * Return Not handled so that interrupt is disabled.
> > +	 * Level event ensures that the event is eventually handled
> > +	 * by the appropriate chip handler already registered
> > +	 */
> > +	return IRQ_NONE;
> > +}
> > +
> >  int palmas_ext_control_req_config(struct palmas *palmas,
> >  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
> >  {
> > @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
> >  		pdata->mux_from_pdata = 1;
> >  		pdata->pad2 = prop;
> >  	}
> > +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
> >  
> >  	/* The default for this register is all masked */
> >  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> > @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	i2c_set_clientdata(i2c, palmas);
> >  	palmas->dev = &i2c->dev;
> >  	palmas->irq = i2c->irq;
> > +	palmas->wakeirq = pdata->wakeirq;
> >  
> >  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
> >  
> > @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	if (ret < 0)
> >  		goto err_i2c;
> >  
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       pdata->irq_flags,
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0) {
> > +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> > +			palmas->wakeirq, ret);
> > +		palmas->wakeirq = 0;
> > +	} else {
> > +		/* We use wakeirq only during suspend-resume path */
> > +		device_set_wakeup_capable(palmas->dev, true);
> > +		disable_irq_nosync(palmas->wakeirq);
> > +	}
> > +
> > +no_wake_irq:
> >  no_irq:
> >  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
> >  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> > @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
> >  	return 0;
> >  }
> >  
> > +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		enable_irq(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> > +static int palmas_i2c_resume(struct i2c_client *i2c)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		disable_irq_nosync(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> >  static const struct i2c_device_id palmas_i2c_id[] = {
> >  	{ "palmas", },
> >  	{ "twl6035", },
> > @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
> >  		   .of_match_table = of_palmas_match_tbl,
> >  		   .owner = THIS_MODULE,
> >  	},
> > +	.suspend = palmas_i2c_suspend,
> > +	.resume = palmas_i2c_resume,
> >  	.probe = palmas_i2c_probe,
> >  	.remove = palmas_i2c_remove,
> >  	.id_table = palmas_i2c_id,
> > diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> > index fb0390a..e8cf4c2 100644
> > --- a/include/linux/mfd/palmas.h
> > +++ b/include/linux/mfd/palmas.h
> > @@ -75,6 +75,7 @@ struct palmas {
> >  	/* IRQ Data */
> >  	int irq;
> >  	u32 irq_mask;
> > +	int wakeirq;
> >  	struct mutex irq_lock;
> >  	struct regmap_irq_chip_data *irq_data;
> >  
> > @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
> >  
> >  struct palmas_platform_data {
> >  	int irq_flags;
> > +	int wakeirq;
> >  	int gpio_base;
> >  
> >  	/* bit value to be loaded to the POWER_CTRL register */
> > 
> 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-18 17:33           ` Lee Jones
  0 siblings, 0 replies; 24+ messages in thread
From: Lee Jones @ 2014-09-18 17:33 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Thomas Gleixner, linux-kernel, devicetree, Keerthy, Mark Brown,
	Samuel Ortiz, linux-omap, Tony Lindgren, linux-arm-kernel

On Thu, 18 Sep 2014, Nishanth Menon wrote:

> On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> > On 23:13-20140905, Thomas Gleixner wrote:
> >> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> >>> +	if (!palmas->wakeirq)
> >>> +		goto no_wake_irq;
> >>> +
> >>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> >>> +			       palmas_wake_irq,
> >>> +			       IRQF_ONESHOT | pdata->irq_flags,
> >>
> >> Why is this marked IRQF_ONESHOT?
> > 
> > Uggh.. should have dropped it. my bad.. removed in the revision below.
> > Thanks for catching it.
> >>
> >>> +			       dev_name(palmas->dev),
> >>> +			       &palmas);
> >>> +	if (ret < 0)
> >>> +		goto err_i2c;
> >>
> >> Why err and not doing the obvious clearing of palmas->wakeirq and
> >> keep at least the i2c functional?
> > Hmmm.. true.. we can stay alive even though without wakeup capability if
> > someone messes up configuration..
> > 
> > Fixed version below. Let me know if you are ok with the following.
> 
> Gentle ping. Would you like me to repost this series over again?

Yes, always.

> > ----8<----
> > From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> > From: Nishanth Menon <nm@ti.com>
> > Date: Tue, 12 Aug 2014 12:00:52 -0500
> > Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> > 
> > With the recent pinctrl-single changes, omaps can treat wake-up events
> > from deeper power  states as interrupts.
> > 
> > This is to handle the case where the system needs two interrupt
> > sources when SoC is in deep sleep(1 to exit from deep power mode such
> > as sleep, and other from the module handling the actual event during
> > system active state). This is not the same as threaded interrupts as the
> > wakeup interrupt source is used only as part of deeper power saving
> > mode.
> > 
> > Let's add support for the optional second interrupt for wake-up
> > events. And then SoC can wakeup and handle the event using it's
> > regular handler.
> > 
> > This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> > support for optional wake-up")
> > 
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > ---
> >  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/mfd/palmas.h |    2 ++
> >  2 files changed, 64 insertions(+)
> > 
> > diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> > index 28cb048..de7d204 100644
> > --- a/drivers/mfd/palmas.c
> > +++ b/drivers/mfd/palmas.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/mfd/core.h>
> >  #include <linux/mfd/palmas.h>
> >  #include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> >  
> >  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
> >  	{
> > @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
> >  			PALMAS_INT1_MASK),
> >  };
> >  
> > +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> > +{
> > +	/*
> > +	 * Return Not handled so that interrupt is disabled.
> > +	 * Level event ensures that the event is eventually handled
> > +	 * by the appropriate chip handler already registered
> > +	 */
> > +	return IRQ_NONE;
> > +}
> > +
> >  int palmas_ext_control_req_config(struct palmas *palmas,
> >  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
> >  {
> > @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
> >  		pdata->mux_from_pdata = 1;
> >  		pdata->pad2 = prop;
> >  	}
> > +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
> >  
> >  	/* The default for this register is all masked */
> >  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> > @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	i2c_set_clientdata(i2c, palmas);
> >  	palmas->dev = &i2c->dev;
> >  	palmas->irq = i2c->irq;
> > +	palmas->wakeirq = pdata->wakeirq;
> >  
> >  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
> >  
> > @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	if (ret < 0)
> >  		goto err_i2c;
> >  
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       pdata->irq_flags,
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0) {
> > +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> > +			palmas->wakeirq, ret);
> > +		palmas->wakeirq = 0;
> > +	} else {
> > +		/* We use wakeirq only during suspend-resume path */
> > +		device_set_wakeup_capable(palmas->dev, true);
> > +		disable_irq_nosync(palmas->wakeirq);
> > +	}
> > +
> > +no_wake_irq:
> >  no_irq:
> >  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
> >  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> > @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
> >  	return 0;
> >  }
> >  
> > +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		enable_irq(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> > +static int palmas_i2c_resume(struct i2c_client *i2c)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		disable_irq_nosync(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> >  static const struct i2c_device_id palmas_i2c_id[] = {
> >  	{ "palmas", },
> >  	{ "twl6035", },
> > @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
> >  		   .of_match_table = of_palmas_match_tbl,
> >  		   .owner = THIS_MODULE,
> >  	},
> > +	.suspend = palmas_i2c_suspend,
> > +	.resume = palmas_i2c_resume,
> >  	.probe = palmas_i2c_probe,
> >  	.remove = palmas_i2c_remove,
> >  	.id_table = palmas_i2c_id,
> > diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> > index fb0390a..e8cf4c2 100644
> > --- a/include/linux/mfd/palmas.h
> > +++ b/include/linux/mfd/palmas.h
> > @@ -75,6 +75,7 @@ struct palmas {
> >  	/* IRQ Data */
> >  	int irq;
> >  	u32 irq_mask;
> > +	int wakeirq;
> >  	struct mutex irq_lock;
> >  	struct regmap_irq_chip_data *irq_data;
> >  
> > @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
> >  
> >  struct palmas_platform_data {
> >  	int irq_flags;
> > +	int wakeirq;
> >  	int gpio_base;
> >  
> >  	/* bit value to be loaded to the POWER_CTRL register */
> > 
> 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup
@ 2014-09-18 17:33           ` Lee Jones
  0 siblings, 0 replies; 24+ messages in thread
From: Lee Jones @ 2014-09-18 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 18 Sep 2014, Nishanth Menon wrote:

> On 09/08/2014 10:41 AM, Nishanth Menon wrote:
> > On 23:13-20140905, Thomas Gleixner wrote:
> >> On Fri, 5 Sep 2014, Nishanth Menon wrote:
> >>> +	if (!palmas->wakeirq)
> >>> +		goto no_wake_irq;
> >>> +
> >>> +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> >>> +			       palmas_wake_irq,
> >>> +			       IRQF_ONESHOT | pdata->irq_flags,
> >>
> >> Why is this marked IRQF_ONESHOT?
> > 
> > Uggh.. should have dropped it. my bad.. removed in the revision below.
> > Thanks for catching it.
> >>
> >>> +			       dev_name(palmas->dev),
> >>> +			       &palmas);
> >>> +	if (ret < 0)
> >>> +		goto err_i2c;
> >>
> >> Why err and not doing the obvious clearing of palmas->wakeirq and
> >> keep at least the i2c functional?
> > Hmmm.. true.. we can stay alive even though without wakeup capability if
> > someone messes up configuration..
> > 
> > Fixed version below. Let me know if you are ok with the following.
> 
> Gentle ping. Would you like me to repost this series over again?

Yes, always.

> > ----8<----
> > From 6da58ac66eedea46cf7282c6644c76c8f328f5ee Mon Sep 17 00:00:00 2001
> > From: Nishanth Menon <nm@ti.com>
> > Date: Tue, 12 Aug 2014 12:00:52 -0500
> > Subject: [PATCH V3 3/3] mfd: palmas: Add support for optional wakeup
> > 
> > With the recent pinctrl-single changes, omaps can treat wake-up events
> > from deeper power  states as interrupts.
> > 
> > This is to handle the case where the system needs two interrupt
> > sources when SoC is in deep sleep(1 to exit from deep power mode such
> > as sleep, and other from the module handling the actual event during
> > system active state). This is not the same as threaded interrupts as the
> > wakeup interrupt source is used only as part of deeper power saving
> > mode.
> > 
> > Let's add support for the optional second interrupt for wake-up
> > events. And then SoC can wakeup and handle the event using it's
> > regular handler.
> > 
> > This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add
> > support for optional wake-up")
> > 
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > ---
> >  drivers/mfd/palmas.c       |   62 ++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/mfd/palmas.h |    2 ++
> >  2 files changed, 64 insertions(+)
> > 
> > diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> > index 28cb048..de7d204 100644
> > --- a/drivers/mfd/palmas.c
> > +++ b/drivers/mfd/palmas.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/mfd/core.h>
> >  #include <linux/mfd/palmas.h>
> >  #include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> >  
> >  static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
> >  	{
> > @@ -326,6 +327,16 @@ static struct regmap_irq_chip tps65917_irq_chip = {
> >  			PALMAS_INT1_MASK),
> >  };
> >  
> > +static irqreturn_t palmas_wake_irq(int irq, void *_palmas)
> > +{
> > +	/*
> > +	 * Return Not handled so that interrupt is disabled.
> > +	 * Level event ensures that the event is eventually handled
> > +	 * by the appropriate chip handler already registered
> > +	 */
> > +	return IRQ_NONE;
> > +}
> > +
> >  int palmas_ext_control_req_config(struct palmas *palmas,
> >  	enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
> >  {
> > @@ -409,6 +420,7 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
> >  		pdata->mux_from_pdata = 1;
> >  		pdata->pad2 = prop;
> >  	}
> > +	pdata->wakeirq = irq_of_parse_and_map(node, 1);
> >  
> >  	/* The default for this register is all masked */
> >  	ret = of_property_read_u32(node, "ti,power-ctrl", &prop);
> > @@ -521,6 +533,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	i2c_set_clientdata(i2c, palmas);
> >  	palmas->dev = &i2c->dev;
> >  	palmas->irq = i2c->irq;
> > +	palmas->wakeirq = pdata->wakeirq;
> >  
> >  	match = of_match_device(of_palmas_match_tbl, &i2c->dev);
> >  
> > @@ -587,6 +600,25 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
> >  	if (ret < 0)
> >  		goto err_i2c;
> >  
> > +	if (!palmas->wakeirq)
> > +		goto no_wake_irq;
> > +
> > +	ret = devm_request_irq(palmas->dev, palmas->wakeirq,
> > +			       palmas_wake_irq,
> > +			       pdata->irq_flags,
> > +			       dev_name(palmas->dev),
> > +			       &palmas);
> > +	if (ret < 0) {
> > +		dev_err(palmas->dev, "Invalid wakeirq(%d) (res: %d), skiping\n",
> > +			palmas->wakeirq, ret);
> > +		palmas->wakeirq = 0;
> > +	} else {
> > +		/* We use wakeirq only during suspend-resume path */
> > +		device_set_wakeup_capable(palmas->dev, true);
> > +		disable_irq_nosync(palmas->wakeirq);
> > +	}
> > +
> > +no_wake_irq:
> >  no_irq:
> >  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
> >  	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
> > @@ -706,6 +738,34 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
> >  	return 0;
> >  }
> >  
> > +static int palmas_i2c_suspend(struct i2c_client *i2c,  pm_message_t mesg)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		enable_irq(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> > +static int palmas_i2c_resume(struct i2c_client *i2c)
> > +{
> > +	struct palmas *palmas = i2c_get_clientdata(i2c);
> > +	struct device *dev = &i2c->dev;
> > +
> > +	if (!palmas->wakeirq)
> > +		return 0;
> > +
> > +	if (device_may_wakeup(dev))
> > +		disable_irq_nosync(palmas->wakeirq);
> > +
> > +	return 0;
> > +}
> > +
> >  static const struct i2c_device_id palmas_i2c_id[] = {
> >  	{ "palmas", },
> >  	{ "twl6035", },
> > @@ -721,6 +781,8 @@ static struct i2c_driver palmas_i2c_driver = {
> >  		   .of_match_table = of_palmas_match_tbl,
> >  		   .owner = THIS_MODULE,
> >  	},
> > +	.suspend = palmas_i2c_suspend,
> > +	.resume = palmas_i2c_resume,
> >  	.probe = palmas_i2c_probe,
> >  	.remove = palmas_i2c_remove,
> >  	.id_table = palmas_i2c_id,
> > diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> > index fb0390a..e8cf4c2 100644
> > --- a/include/linux/mfd/palmas.h
> > +++ b/include/linux/mfd/palmas.h
> > @@ -75,6 +75,7 @@ struct palmas {
> >  	/* IRQ Data */
> >  	int irq;
> >  	u32 irq_mask;
> > +	int wakeirq;
> >  	struct mutex irq_lock;
> >  	struct regmap_irq_chip_data *irq_data;
> >  
> > @@ -377,6 +378,7 @@ struct palmas_clk_platform_data {
> >  
> >  struct palmas_platform_data {
> >  	int irq_flags;
> > +	int wakeirq;
> >  	int gpio_base;
> >  
> >  	/* bit value to be loaded to the POWER_CTRL register */
> > 
> 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

end of thread, other threads:[~2014-09-18 17:33 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-05 20:51 [PATCH V2 0/3] mfd: palmas: add optional wakeup irq Nishanth Menon
2014-09-05 20:51 ` Nishanth Menon
2014-09-05 20:51 ` Nishanth Menon
2014-09-05 20:51 ` [PATCH V2 1/3] Documentation: dt-bindings: mfd: palmas: Fix example style of i2c peripheral Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 20:51 ` [PATCH V2 2/3] Documentation: dt-bindings: mfd: palmas: document optional wakeup IRQ Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 20:51 ` [PATCH V2 3/3] mfd: palmas: Add support for optional wakeup Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 20:51   ` Nishanth Menon
2014-09-05 21:13   ` Thomas Gleixner
2014-09-05 21:13     ` Thomas Gleixner
2014-09-05 21:13     ` Thomas Gleixner
2014-09-08 15:41     ` Nishanth Menon
2014-09-08 15:41       ` Nishanth Menon
2014-09-08 15:41       ` Nishanth Menon
2014-09-18 13:54       ` Nishanth Menon
2014-09-18 13:54         ` Nishanth Menon
2014-09-18 13:54         ` Nishanth Menon
2014-09-18 17:33         ` Lee Jones
2014-09-18 17:33           ` Lee Jones
2014-09-18 17:33           ` Lee Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.