All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Add GPIO brownout detection support
@ 2018-09-25  9:42 Marco Felsch
  2018-09-25  9:42 ` [PATCH 1/3] spi: switch to SPDX license identifier Marco Felsch
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Marco Felsch @ 2018-09-25  9:42 UTC (permalink / raw)
  To: dmitry.torokhov, broonie, mark.rutland, robh+dt
  Cc: linux-spi, devicetree, linux-input, kernel

Hi,

this small series adds a generic gpio-based brownout detection driver to
inform the userspace that something went wrong.

Additional there is a optional support to release devices from their
drivers, because there are board power designs which cut of external
devices supply immediately and keep the host (SoC) alive for a few
seconds to switch into a safe state. Due to the hard power cut some
external devices throw interrupts and depending of the amount of
external devices these interrupts will flood the host. The driver
unloads all specified devices from their drivers so the interrupts are
ignored. At the moment only spi and i2c devices are supported.

I've tested the driver on a customer arm based board, but other testers
are welcome. Maybe there are problems unloading device drivers which have a
incorrect .remove() or devm_alloc() order. Then these drivers must be
fixed.

Regards,
Marco

Marco Felsch (3):
  spi: switch to SPDX license identifier
  spi: make OF helper available for others
  Input: add generic gpio brownout driver

 .../bindings/input/gpio-brownout.txt          |  36 ++++
 drivers/input/misc/Kconfig                    |  12 ++
 drivers/input/misc/Makefile                   |   1 +
 drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
 drivers/spi/spi.c                             |  18 +-
 include/linux/spi/spi.h                       |  30 ++--
 6 files changed, 239 insertions(+), 24 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
 create mode 100644 drivers/input/misc/gpio-brownout.c

-- 
2.19.0

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

* [PATCH 1/3] spi: switch to SPDX license identifier
  2018-09-25  9:42 [PATCH 0/3] Add GPIO brownout detection support Marco Felsch
@ 2018-09-25  9:42 ` Marco Felsch
  2018-09-27 22:40   ` Applied "spi: switch to SPDX license identifier" to the spi tree Mark Brown
  2018-09-25  9:42 ` [PATCH 2/3] spi: make OF helper available for others Marco Felsch
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Marco Felsch @ 2018-09-25  9:42 UTC (permalink / raw)
  To: dmitry.torokhov, broonie, mark.rutland, robh+dt
  Cc: linux-spi, devicetree, linux-input, kernel

Use the appropriate SPDX license identifier and drop the previous
license text.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/spi/spi.c       | 11 +----------
 include/linux/spi/spi.h | 13 ++-----------
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ec395a6baf9c..3a8f1224edfc 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * SPI init/core code
  *
  * Copyright (C) 2005 David Brownell
  * Copyright (C) 2008 Secret Lab Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index a64235e05321..95c0243dc74a 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1,15 +1,6 @@
-/*
- * Copyright (C) 2005 David Brownell
+/* SPDX-License-Identifier: GPL-2.0-or-later
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Copyright (C) 2005 David Brownell
  */
 
 #ifndef __LINUX_SPI_H
-- 
2.19.0

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

* [PATCH 2/3] spi: make OF helper available for others
  2018-09-25  9:42 [PATCH 0/3] Add GPIO brownout detection support Marco Felsch
  2018-09-25  9:42 ` [PATCH 1/3] spi: switch to SPDX license identifier Marco Felsch
@ 2018-09-25  9:42 ` Marco Felsch
  2018-09-27 22:38   ` Mark Brown
  2018-09-27 22:40   ` Applied "spi: make OF helper available for others" to the spi tree Mark Brown
  2018-09-25  9:42 ` [PATCH 3/3] Input: add generic gpio brownout driver Marco Felsch
  2018-09-25 17:09 ` [PATCH 0/3] Add GPIO brownout detection support Mark Brown
  3 siblings, 2 replies; 14+ messages in thread
From: Marco Felsch @ 2018-09-25  9:42 UTC (permalink / raw)
  To: dmitry.torokhov, broonie, mark.rutland, robh+dt
  Cc: linux-spi, devicetree, linux-input, kernel

The of_find_spi_device_by_node() helper function is useful for other
modules too. Export the funciton as GPL like all other spi helper
functions and make it available if CONFIG_OF is enabled, because it isn't
related to the CONFIG_OF_DYNAMIC context. Finally add a stub if
CONFIG_OF isn't enabled, so others must not care about it.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/spi/spi.c       |  7 +++++--
 include/linux/spi/spi.h | 17 ++++++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 3a8f1224edfc..2983c3f69fb0 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3305,20 +3305,23 @@ EXPORT_SYMBOL_GPL(spi_write_then_read);
 
 /*-------------------------------------------------------------------------*/
 
-#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+#if IS_ENABLED(CONFIG_OF)
 static int __spi_of_device_match(struct device *dev, void *data)
 {
 	return dev->of_node == data;
 }
 
 /* must call put_device() when done with returned spi_device device */
-static struct spi_device *of_find_spi_device_by_node(struct device_node *node)
+struct spi_device *of_find_spi_device_by_node(struct device_node *node)
 {
 	struct device *dev = bus_find_device(&spi_bus_type, NULL, node,
 						__spi_of_device_match);
 	return dev ? to_spi_device(dev) : NULL;
 }
+EXPORT_SYMBOL_GPL(of_find_spi_device_by_node);
+#endif /* IS_ENABLED(CONFIG_OF) */
 
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
 static int __spi_of_controller_match(struct device *dev, const void *data)
 {
 	return dev->of_node == data;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 95c0243dc74a..b53f4e348b24 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1268,7 +1268,6 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
 	{ return 0; }
 #endif
 
-
 /* If you're hotplugging an adapter with devices (parport, usb, etc)
  * use spi_new_device() to describe each device.  You can also call
  * spi_unregister_device() to start making that device vanish, but
@@ -1300,6 +1299,22 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer)
 	return list_is_last(&xfer->transfer_list, &ctlr->cur_msg->transfers);
 }
 
+/* OF support code */
+#if IS_ENABLED(CONFIG_OF)
+
+/* must call put_device() when done with returned spi_device device */
+extern struct spi_device *
+of_find_spi_device_by_node(struct device_node *node);
+
+#else
+
+static inline struct spi_device *
+of_find_spi_device_by_node(struct device_node *node)
+{
+	return NULL;
+}
+
+#endif /* IS_ENABLED(CONFIG_OF) */
 
 /* Compatibility layer */
 #define spi_master			spi_controller
-- 
2.19.0

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

* [PATCH 3/3] Input: add generic gpio brownout driver
  2018-09-25  9:42 [PATCH 0/3] Add GPIO brownout detection support Marco Felsch
  2018-09-25  9:42 ` [PATCH 1/3] spi: switch to SPDX license identifier Marco Felsch
  2018-09-25  9:42 ` [PATCH 2/3] spi: make OF helper available for others Marco Felsch
@ 2018-09-25  9:42 ` Marco Felsch
  2018-09-29  0:19   ` Dmitry Torokhov
  2018-09-25 17:09 ` [PATCH 0/3] Add GPIO brownout detection support Mark Brown
  3 siblings, 1 reply; 14+ messages in thread
From: Marco Felsch @ 2018-09-25  9:42 UTC (permalink / raw)
  To: dmitry.torokhov, broonie, mark.rutland, robh+dt
  Cc: linux-spi, devicetree, linux-input, kernel

A brownout can be detected in several ways e.g. a deticated pin on the
soc, a external pmic or by another external hardware which informs the
host via a gpio line.

This patch adds the support for a generic gpio-based brownout
detection. Upon a brownout the host system gets informed and the driver
sends a keycode signal to the userspace. Per default this signal is
mapped to KEY_POWER, so the system will shoutdown.

Additional the driver supports releasing registered devices from their
drivers, see Documentation/devicetree/bindings/input/gpio-brownout.txt
for more details.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 .../bindings/input/gpio-brownout.txt          |  36 ++++
 drivers/input/misc/Kconfig                    |  12 ++
 drivers/input/misc/Makefile                   |   1 +
 drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
 4 files changed, 215 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
 create mode 100644 drivers/input/misc/gpio-brownout.c

diff --git a/Documentation/devicetree/bindings/input/gpio-brownout.txt b/Documentation/devicetree/bindings/input/gpio-brownout.txt
new file mode 100644
index 000000000000..55fbe2aa52a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-brownout.txt
@@ -0,0 +1,36 @@
+Device-Tree bindings for input/gpio_brownout.c driver
+
+Required properties:
+- compatible: Must be "gpio-brownout"
+- interrupt-parent: The phandle to the interrupt controller. For more details
+  see ../interrupt-controller/interrupts.txt.
+- interrupts: The interrupt line for a brownout detection. For more details
+  see ../interrupt-controller/interrupts.txt.
+
+Optional properties:
+- linux,code: Keycode to emit upon a brownout detection, default: KEY_POWER.
+- release-devices: A list of i2c or spi device phandles. All listed devices
+  will be released from their drivers in the order they listed upon a brownout
+  detection. This can be helpful to avoid a interrupt flood, because some
+  system designs power off all external devices immediately and keep the host
+  on for a certain time.
+
+Example:
+
+i2c3 {
+	temp_core: lm75@48 { };
+	temp_chassis: lm75@49 { };
+};
+
+spi1 {
+	ts: ad7879@1 { };
+};
+
+/ {
+	gpio_brownout_det {
+		compatible = "gpio-brownout";
+		interrupts-parent = <&gpio3>;
+		interrupts = <3 IRQ_TYPE_EDGE_LOW>:
+		release-devices = <&temp_core &ts>;
+	};
+};
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index ca59a2be9bc5..6b49e681cca7 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -268,6 +268,18 @@ config INPUT_GPIO_BEEPER
 	  To compile this driver as a module, choose M here: the
 	  module will be called gpio-beeper.
 
+config INPUT_GPIO_BROWNOUT
+	tristate "Generic GPIO Brownout detection support"
+	depends on GPIOLIB || COMPILE_TEST
+	help
+	  Say Y here if you have a brownout signal connected to a GPIO pin
+	  and want to report a keycode signal on a brownout detection.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gpio-brownout.
+
 config INPUT_GPIO_DECODER
 	tristate "Polled GPIO Decoder Input driver"
 	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 9d0f9d1ff68f..8b872b5fc84a 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_INPUT_DRV2665_HAPTICS)	+= drv2665.o
 obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
+obj-$(CONFIG_INPUT_GPIO_BROWNOUT)	+= gpio-brownout.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
diff --git a/drivers/input/misc/gpio-brownout.c b/drivers/input/misc/gpio-brownout.c
new file mode 100644
index 000000000000..23992b9e2814
--- /dev/null
+++ b/drivers/input/misc/gpio-brownout.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * gpio-brownout.c - Generic power fail driver
+ *
+ * Copyright (C) 2018 Pengutronix, Marco Felsch <kernel@pengutronix.de>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#define GPIO_BROWNOUT_MOD_NAME "gpio-brownout"
+
+struct gpio_brownout_device {
+	struct list_head  list;
+	struct device *dev;
+};
+
+struct gpio_brownout {
+	struct device *dev;
+	struct input_dev *idev;
+	unsigned short kcode;
+	struct list_head devices;
+};
+
+static irqreturn_t gpio_brownout_isr(int irq, void *dev_id)
+{
+	struct gpio_brownout *gb = dev_id;
+	struct input_dev *idev = gb->idev;
+	struct gpio_brownout_device *bout_dev, *tmp;
+
+	/* first inform userspace */
+	input_report_key(idev, gb->kcode, 1);
+	input_sync(idev);
+
+	/* now unregister registered drivers */
+	list_for_each_entry_safe(bout_dev, tmp, &gb->devices, list) {
+		device_release_driver(bout_dev->dev);
+		list_del(&bout_dev->list);
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_OF
+static int gpio_brownout_probe_dt(struct gpio_brownout *gb)
+{
+	struct device_node *np = gb->dev->of_node;
+	struct of_phandle_iterator it;
+	unsigned int kcode;
+	int ret;
+
+	/* all dt-properties are optional */
+	of_property_read_u32(np, "linux,code", &kcode);
+	gb->kcode = kcode;
+
+	/*
+	 * Register all devices which should be unbinded upon a brownout
+	 * detection. At the moment only i2c and spi devices are supported
+	 */
+	of_for_each_phandle(&it, ret, np, "release-devices", NULL, 0) {
+		struct gpio_brownout_device *elem;
+		struct i2c_client *i2c_c;
+		struct spi_device *spi_c;
+
+		i2c_c = of_find_i2c_device_by_node(it.node);
+		spi_c = of_find_spi_device_by_node(it.node);
+
+		if (!i2c_c && !spi_c)
+			return -EPROBE_DEFER;
+		else if (i2c_c && spi_c)
+			return -EINVAL;
+
+		elem = devm_kzalloc(gb->dev, sizeof(*elem), GFP_KERNEL);
+		if (!elem)
+			return -ENOMEM;
+
+		elem->dev = i2c_c ? &i2c_c->dev : &spi_c->dev;
+
+		INIT_LIST_HEAD(&elem->list);
+		list_add_tail(&elem->list, &gb->devices);
+	}
+
+	return 0;
+}
+#endif
+
+static int gpio_brownout_probe(struct platform_device *pdev)
+{
+	struct gpio_brownout *gb;
+	struct input_dev *idev;
+	int ret, irq;
+
+	gb = devm_kzalloc(&pdev->dev, sizeof(*gb), GFP_KERNEL);
+	if (!gb)
+		return -ENOMEM;
+
+	idev = devm_input_allocate_device(&pdev->dev);
+	if (!idev)
+		return -ENOMEM;
+
+	gb->dev = &pdev->dev;
+	gb->idev = idev;
+	INIT_LIST_HEAD(&gb->devices);
+
+	if (IS_ENABLED(CONFIG_OF)) {
+		ret = gpio_brownout_probe_dt(gb);
+		if (ret) {
+			dev_err(&pdev->dev, "probe_dt failed: %d\n", ret);
+			return ret;
+		}
+	}
+
+	idev->name = pdev->name;
+	gb->kcode = gb->kcode == KEY_RESERVED ? KEY_POWER : gb->kcode;
+
+	input_set_capability(idev, EV_KEY, gb->kcode);
+
+	irq = platform_get_irq(pdev, 0);
+	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+					gpio_brownout_isr, IRQF_ONESHOT,
+					GPIO_BROWNOUT_MOD_NAME, gb);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "IRQ request failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = input_register_device(idev);
+	if (ret) {
+		dev_err(&pdev->dev, "Input register failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_brownout_of_match[] = {
+	{ .compatible = GPIO_BROWNOUT_MOD_NAME, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, arm_gpio_brownout_of_match);
+#endif
+
+static struct platform_driver gpio_brownout_driver = {
+	.driver = {
+		.name = GPIO_BROWNOUT_MOD_NAME,
+		.of_match_table = of_match_ptr(gpio_brownout_of_match)
+	},
+	.probe = gpio_brownout_probe,
+};
+
+module_platform_driver(gpio_brownout_driver);
+
+MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
+MODULE_DESCRIPTION("GPIO Brownout Detection");
+MODULE_LICENSE("GPL v2");
-- 
2.19.0

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

* Re: [PATCH 0/3] Add GPIO brownout detection support
  2018-09-25  9:42 [PATCH 0/3] Add GPIO brownout detection support Marco Felsch
                   ` (2 preceding siblings ...)
  2018-09-25  9:42 ` [PATCH 3/3] Input: add generic gpio brownout driver Marco Felsch
@ 2018-09-25 17:09 ` Mark Brown
  2018-09-26  8:15   ` Marco Felsch
  3 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2018-09-25 17:09 UTC (permalink / raw)
  To: Marco Felsch
  Cc: dmitry.torokhov, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

[-- Attachment #1: Type: text/plain, Size: 902 bytes --]

On Tue, Sep 25, 2018 at 11:42:27AM +0200, Marco Felsch wrote:

> Marco Felsch (3):
>   spi: switch to SPDX license identifier

This seems like a completely unrelated change, why is it part of this
series?

>   spi: make OF helper available for others
>   Input: add generic gpio brownout driver
> 
>  .../bindings/input/gpio-brownout.txt          |  36 ++++
>  drivers/input/misc/Kconfig                    |  12 ++
>  drivers/input/misc/Makefile                   |   1 +
>  drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
>  drivers/spi/spi.c                             |  18 +-
>  include/linux/spi/spi.h                       |  30 ++--
>  6 files changed, 239 insertions(+), 24 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
>  create mode 100644 drivers/input/misc/gpio-brownout.c
> 
> -- 
> 2.19.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 0/3] Add GPIO brownout detection support
  2018-09-25 17:09 ` [PATCH 0/3] Add GPIO brownout detection support Mark Brown
@ 2018-09-26  8:15   ` Marco Felsch
  2018-09-26 12:19     ` Mark Brown
  0 siblings, 1 reply; 14+ messages in thread
From: Marco Felsch @ 2018-09-26  8:15 UTC (permalink / raw)
  To: Mark Brown
  Cc: dmitry.torokhov, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

On 18-09-25 10:09, Mark Brown wrote:
> On Tue, Sep 25, 2018 at 11:42:27AM +0200, Marco Felsch wrote:
> 
> > Marco Felsch (3):
> >   spi: switch to SPDX license identifier
> 
> This seems like a completely unrelated change, why is it part of this
> series?

You're right. I saw the old header during my work on this topic. I can
exclude it as a own patch.

Regards,
Marco

> 
> >   spi: make OF helper available for others
> >   Input: add generic gpio brownout driver
> > 
> >  .../bindings/input/gpio-brownout.txt          |  36 ++++
> >  drivers/input/misc/Kconfig                    |  12 ++
> >  drivers/input/misc/Makefile                   |   1 +
> >  drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
> >  drivers/spi/spi.c                             |  18 +-
> >  include/linux/spi/spi.h                       |  30 ++--
> >  6 files changed, 239 insertions(+), 24 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
> >  create mode 100644 drivers/input/misc/gpio-brownout.c
> > 
> > -- 
> > 2.19.0
> > 

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

* Re: [PATCH 0/3] Add GPIO brownout detection support
  2018-09-26  8:15   ` Marco Felsch
@ 2018-09-26 12:19     ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-09-26 12:19 UTC (permalink / raw)
  To: Marco Felsch
  Cc: dmitry.torokhov, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

[-- Attachment #1: Type: text/plain, Size: 583 bytes --]

On Wed, Sep 26, 2018 at 10:15:44AM +0200, Marco Felsch wrote:
> On 18-09-25 10:09, Mark Brown wrote:

> > > Marco Felsch (3):
> > >   spi: switch to SPDX license identifier

> > This seems like a completely unrelated change, why is it part of this
> > series?

> You're right. I saw the old header during my work on this topic. I can
> exclude it as a own patch.

OK, no need to resend or anything here but in general it's a better idea
to do that - it avoids confusion with dependencies or with things
getting tied up in review of the rest of the series when they don't need
to be.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 2/3] spi: make OF helper available for others
  2018-09-25  9:42 ` [PATCH 2/3] spi: make OF helper available for others Marco Felsch
@ 2018-09-27 22:38   ` Mark Brown
  2018-09-27 22:40   ` Applied "spi: make OF helper available for others" to the spi tree Mark Brown
  1 sibling, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-09-27 22:38 UTC (permalink / raw)
  To: Marco Felsch
  Cc: dmitry.torokhov, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

[-- Attachment #1: Type: text/plain, Size: 1209 bytes --]

On Tue, Sep 25, 2018 at 11:42:29AM +0200, Marco Felsch wrote:
> The of_find_spi_device_by_node() helper function is useful for other
> modules too. Export the funciton as GPL like all other spi helper
> functions and make it available if CONFIG_OF is enabled, because it isn't
> related to the CONFIG_OF_DYNAMIC context. Finally add a stub if
> CONFIG_OF isn't enabled, so others must not care about it.

The following changes since commit 5b394b2ddf0347bef56e50c69a58773c94343ff3:

  Linux 4.19-rc1 (2018-08-26 14:11:59 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git tags/spi-find-by-node

for you to fetch changes up to 5f143af7501e7c435c56e181a655493edaa92509:

  spi: make OF helper available for others (2018-09-27 23:36:03 +0100)

----------------------------------------------------------------
spi: Export _find_by_node() for users

It's useful for some bindings.

----------------------------------------------------------------
Marco Felsch (1):
      spi: make OF helper available for others

 drivers/spi/spi.c       |  7 +++++--
 include/linux/spi/spi.h | 17 ++++++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Applied "spi: make OF helper available for others" to the spi tree
  2018-09-25  9:42 ` [PATCH 2/3] spi: make OF helper available for others Marco Felsch
  2018-09-27 22:38   ` Mark Brown
@ 2018-09-27 22:40   ` Mark Brown
  1 sibling, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-09-27 22:40 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Mark Brown, dmitry.torokhov

The patch

   spi: make OF helper available for others

has been applied to the spi tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 5f143af7501e7c435c56e181a655493edaa92509 Mon Sep 17 00:00:00 2001
From: Marco Felsch <m.felsch@pengutronix.de>
Date: Tue, 25 Sep 2018 11:42:29 +0200
Subject: [PATCH] spi: make OF helper available for others

The of_find_spi_device_by_node() helper function is useful for other
modules too. Export the funciton as GPL like all other spi helper
functions and make it available if CONFIG_OF is enabled, because it isn't
related to the CONFIG_OF_DYNAMIC context. Finally add a stub if
CONFIG_OF isn't enabled, so others must not care about it.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi.c       |  7 +++++--
 include/linux/spi/spi.h | 17 ++++++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ec395a6baf9c..f939f585e917 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3314,20 +3314,23 @@ EXPORT_SYMBOL_GPL(spi_write_then_read);
 
 /*-------------------------------------------------------------------------*/
 
-#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+#if IS_ENABLED(CONFIG_OF)
 static int __spi_of_device_match(struct device *dev, void *data)
 {
 	return dev->of_node == data;
 }
 
 /* must call put_device() when done with returned spi_device device */
-static struct spi_device *of_find_spi_device_by_node(struct device_node *node)
+struct spi_device *of_find_spi_device_by_node(struct device_node *node)
 {
 	struct device *dev = bus_find_device(&spi_bus_type, NULL, node,
 						__spi_of_device_match);
 	return dev ? to_spi_device(dev) : NULL;
 }
+EXPORT_SYMBOL_GPL(of_find_spi_device_by_node);
+#endif /* IS_ENABLED(CONFIG_OF) */
 
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
 static int __spi_of_controller_match(struct device *dev, const void *data)
 {
 	return dev->of_node == data;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index a64235e05321..e9ebfcd2e932 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1277,7 +1277,6 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
 	{ return 0; }
 #endif
 
-
 /* If you're hotplugging an adapter with devices (parport, usb, etc)
  * use spi_new_device() to describe each device.  You can also call
  * spi_unregister_device() to start making that device vanish, but
@@ -1309,6 +1308,22 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer)
 	return list_is_last(&xfer->transfer_list, &ctlr->cur_msg->transfers);
 }
 
+/* OF support code */
+#if IS_ENABLED(CONFIG_OF)
+
+/* must call put_device() when done with returned spi_device device */
+extern struct spi_device *
+of_find_spi_device_by_node(struct device_node *node);
+
+#else
+
+static inline struct spi_device *
+of_find_spi_device_by_node(struct device_node *node)
+{
+	return NULL;
+}
+
+#endif /* IS_ENABLED(CONFIG_OF) */
 
 /* Compatibility layer */
 #define spi_master			spi_controller
-- 
2.19.0

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

* Applied "spi: switch to SPDX license identifier" to the spi tree
  2018-09-25  9:42 ` [PATCH 1/3] spi: switch to SPDX license identifier Marco Felsch
@ 2018-09-27 22:40   ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-09-27 22:40 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Mark Brown, dmitry.torokhov

The patch

   spi: switch to SPDX license identifier

has been applied to the spi tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From b445bfcb9081ae90fec90b828f3aacc565776901 Mon Sep 17 00:00:00 2001
From: Marco Felsch <m.felsch@pengutronix.de>
Date: Tue, 25 Sep 2018 11:42:28 +0200
Subject: [PATCH] spi: switch to SPDX license identifier

Use the appropriate SPDX license identifier and drop the previous
license text.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi.c       | 11 +----------
 include/linux/spi/spi.h | 13 ++-----------
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a358acdd98d3..2cfc3df821f6 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * SPI init/core code
  *
  * Copyright (C) 2005 David Brownell
  * Copyright (C) 2008 Secret Lab Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 7bb36145e2ba..f08824ea1968 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1,15 +1,6 @@
-/*
- * Copyright (C) 2005 David Brownell
+/* SPDX-License-Identifier: GPL-2.0-or-later
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Copyright (C) 2005 David Brownell
  */
 
 #ifndef __LINUX_SPI_H
-- 
2.19.0

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

* Re: [PATCH 3/3] Input: add generic gpio brownout driver
  2018-09-25  9:42 ` [PATCH 3/3] Input: add generic gpio brownout driver Marco Felsch
@ 2018-09-29  0:19   ` Dmitry Torokhov
  2018-10-01  7:19     ` Marco Felsch
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Torokhov @ 2018-09-29  0:19 UTC (permalink / raw)
  To: Marco Felsch
  Cc: broonie, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

Hi Marco,

On Tue, Sep 25, 2018 at 11:42:30AM +0200, Marco Felsch wrote:
> A brownout can be detected in several ways e.g. a deticated pin on the
> soc, a external pmic or by another external hardware which informs the
> host via a gpio line.
> 
> This patch adds the support for a generic gpio-based brownout
> detection. Upon a brownout the host system gets informed and the driver
> sends a keycode signal to the userspace. Per default this signal is
> mapped to KEY_POWER, so the system will shoutdown.

I do not believe this functionality should be exposed as an input
device, as it has nothing to do with human interaction with the
computing device. To me this is akin over-current on a USB port, or
carrier signal on network interfaces.

Why don't you simply send uevent for this platform device when you
detect brownout, and have whatever entity is responsible for power
management policy on your system listen to such events?

Thanks.

> 
> Additional the driver supports releasing registered devices from their
> drivers, see Documentation/devicetree/bindings/input/gpio-brownout.txt
> for more details.
> 
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  .../bindings/input/gpio-brownout.txt          |  36 ++++
>  drivers/input/misc/Kconfig                    |  12 ++
>  drivers/input/misc/Makefile                   |   1 +
>  drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
>  4 files changed, 215 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
>  create mode 100644 drivers/input/misc/gpio-brownout.c
> 
> diff --git a/Documentation/devicetree/bindings/input/gpio-brownout.txt b/Documentation/devicetree/bindings/input/gpio-brownout.txt
> new file mode 100644
> index 000000000000..55fbe2aa52a9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/gpio-brownout.txt
> @@ -0,0 +1,36 @@
> +Device-Tree bindings for input/gpio_brownout.c driver
> +
> +Required properties:
> +- compatible: Must be "gpio-brownout"
> +- interrupt-parent: The phandle to the interrupt controller. For more details
> +  see ../interrupt-controller/interrupts.txt.
> +- interrupts: The interrupt line for a brownout detection. For more details
> +  see ../interrupt-controller/interrupts.txt.
> +
> +Optional properties:
> +- linux,code: Keycode to emit upon a brownout detection, default: KEY_POWER.
> +- release-devices: A list of i2c or spi device phandles. All listed devices
> +  will be released from their drivers in the order they listed upon a brownout
> +  detection. This can be helpful to avoid a interrupt flood, because some
> +  system designs power off all external devices immediately and keep the host
> +  on for a certain time.
> +
> +Example:
> +
> +i2c3 {
> +	temp_core: lm75@48 { };
> +	temp_chassis: lm75@49 { };
> +};
> +
> +spi1 {
> +	ts: ad7879@1 { };
> +};
> +
> +/ {
> +	gpio_brownout_det {
> +		compatible = "gpio-brownout";
> +		interrupts-parent = <&gpio3>;
> +		interrupts = <3 IRQ_TYPE_EDGE_LOW>:
> +		release-devices = <&temp_core &ts>;
> +	};
> +};
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index ca59a2be9bc5..6b49e681cca7 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -268,6 +268,18 @@ config INPUT_GPIO_BEEPER
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called gpio-beeper.
>  
> +config INPUT_GPIO_BROWNOUT
> +	tristate "Generic GPIO Brownout detection support"
> +	depends on GPIOLIB || COMPILE_TEST
> +	help
> +	  Say Y here if you have a brownout signal connected to a GPIO pin
> +	  and want to report a keycode signal on a brownout detection.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called gpio-brownout.
> +
>  config INPUT_GPIO_DECODER
>  	tristate "Polled GPIO Decoder Input driver"
>  	depends on GPIOLIB || COMPILE_TEST
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 9d0f9d1ff68f..8b872b5fc84a 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_INPUT_DRV2665_HAPTICS)	+= drv2665.o
>  obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
>  obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
>  obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
> +obj-$(CONFIG_INPUT_GPIO_BROWNOUT)	+= gpio-brownout.o
>  obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
>  obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
>  obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
> diff --git a/drivers/input/misc/gpio-brownout.c b/drivers/input/misc/gpio-brownout.c
> new file mode 100644
> index 000000000000..23992b9e2814
> --- /dev/null
> +++ b/drivers/input/misc/gpio-brownout.c
> @@ -0,0 +1,166 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * gpio-brownout.c - Generic power fail driver
> + *
> + * Copyright (C) 2018 Pengutronix, Marco Felsch <kernel@pengutronix.de>
> + */
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/spi/spi.h>
> +
> +#define GPIO_BROWNOUT_MOD_NAME "gpio-brownout"
> +
> +struct gpio_brownout_device {
> +	struct list_head  list;
> +	struct device *dev;
> +};
> +
> +struct gpio_brownout {
> +	struct device *dev;
> +	struct input_dev *idev;
> +	unsigned short kcode;
> +	struct list_head devices;
> +};
> +
> +static irqreturn_t gpio_brownout_isr(int irq, void *dev_id)
> +{
> +	struct gpio_brownout *gb = dev_id;
> +	struct input_dev *idev = gb->idev;
> +	struct gpio_brownout_device *bout_dev, *tmp;
> +
> +	/* first inform userspace */
> +	input_report_key(idev, gb->kcode, 1);
> +	input_sync(idev);
> +
> +	/* now unregister registered drivers */
> +	list_for_each_entry_safe(bout_dev, tmp, &gb->devices, list) {
> +		device_release_driver(bout_dev->dev);
> +		list_del(&bout_dev->list);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +#ifdef CONFIG_OF
> +static int gpio_brownout_probe_dt(struct gpio_brownout *gb)
> +{
> +	struct device_node *np = gb->dev->of_node;
> +	struct of_phandle_iterator it;
> +	unsigned int kcode;
> +	int ret;
> +
> +	/* all dt-properties are optional */
> +	of_property_read_u32(np, "linux,code", &kcode);
> +	gb->kcode = kcode;
> +
> +	/*
> +	 * Register all devices which should be unbinded upon a brownout
> +	 * detection. At the moment only i2c and spi devices are supported
> +	 */
> +	of_for_each_phandle(&it, ret, np, "release-devices", NULL, 0) {
> +		struct gpio_brownout_device *elem;
> +		struct i2c_client *i2c_c;
> +		struct spi_device *spi_c;
> +
> +		i2c_c = of_find_i2c_device_by_node(it.node);
> +		spi_c = of_find_spi_device_by_node(it.node);
> +
> +		if (!i2c_c && !spi_c)
> +			return -EPROBE_DEFER;
> +		else if (i2c_c && spi_c)
> +			return -EINVAL;
> +
> +		elem = devm_kzalloc(gb->dev, sizeof(*elem), GFP_KERNEL);
> +		if (!elem)
> +			return -ENOMEM;
> +
> +		elem->dev = i2c_c ? &i2c_c->dev : &spi_c->dev;
> +
> +		INIT_LIST_HEAD(&elem->list);
> +		list_add_tail(&elem->list, &gb->devices);
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static int gpio_brownout_probe(struct platform_device *pdev)
> +{
> +	struct gpio_brownout *gb;
> +	struct input_dev *idev;
> +	int ret, irq;
> +
> +	gb = devm_kzalloc(&pdev->dev, sizeof(*gb), GFP_KERNEL);
> +	if (!gb)
> +		return -ENOMEM;
> +
> +	idev = devm_input_allocate_device(&pdev->dev);
> +	if (!idev)
> +		return -ENOMEM;
> +
> +	gb->dev = &pdev->dev;
> +	gb->idev = idev;
> +	INIT_LIST_HEAD(&gb->devices);
> +
> +	if (IS_ENABLED(CONFIG_OF)) {
> +		ret = gpio_brownout_probe_dt(gb);
> +		if (ret) {
> +			dev_err(&pdev->dev, "probe_dt failed: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	idev->name = pdev->name;
> +	gb->kcode = gb->kcode == KEY_RESERVED ? KEY_POWER : gb->kcode;
> +
> +	input_set_capability(idev, EV_KEY, gb->kcode);
> +
> +	irq = platform_get_irq(pdev, 0);
> +	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> +					gpio_brownout_isr, IRQF_ONESHOT,
> +					GPIO_BROWNOUT_MOD_NAME, gb);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "IRQ request failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = input_register_device(idev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Input register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id gpio_brownout_of_match[] = {
> +	{ .compatible = GPIO_BROWNOUT_MOD_NAME, },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, arm_gpio_brownout_of_match);
> +#endif
> +
> +static struct platform_driver gpio_brownout_driver = {
> +	.driver = {
> +		.name = GPIO_BROWNOUT_MOD_NAME,
> +		.of_match_table = of_match_ptr(gpio_brownout_of_match)
> +	},
> +	.probe = gpio_brownout_probe,
> +};
> +
> +module_platform_driver(gpio_brownout_driver);
> +
> +MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
> +MODULE_DESCRIPTION("GPIO Brownout Detection");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.19.0
> 

-- 
Dmitry

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

* Re: [PATCH 3/3] Input: add generic gpio brownout driver
  2018-09-29  0:19   ` Dmitry Torokhov
@ 2018-10-01  7:19     ` Marco Felsch
  2018-10-01 16:35       ` Trent Piepho
  0 siblings, 1 reply; 14+ messages in thread
From: Marco Felsch @ 2018-10-01  7:19 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: broonie, mark.rutland, robh+dt, linux-spi, devicetree,
	linux-input, kernel

Hi Dmitry,

On 18-09-28 17:19, Dmitry Torokhov wrote:
> Hi Marco,
> 
> On Tue, Sep 25, 2018 at 11:42:30AM +0200, Marco Felsch wrote:
> > A brownout can be detected in several ways e.g. a deticated pin on the
> > soc, a external pmic or by another external hardware which informs the
> > host via a gpio line.
> > 
> > This patch adds the support for a generic gpio-based brownout
> > detection. Upon a brownout the host system gets informed and the driver
> > sends a keycode signal to the userspace. Per default this signal is
> > mapped to KEY_POWER, so the system will shoutdown.
> 
> I do not believe this functionality should be exposed as an input
> device, as it has nothing to do with human interaction with the
> computing device. To me this is akin over-current on a USB port, or
> carrier signal on network interfaces.

I'm still uncertain putting the code into the input framework. I tought
a lot about the correct place. For me it's like a button, which is
'pressed' by the hardware. Yes, it's a bit abstract..
 
> Why don't you simply send uevent for this platform device when you
> detect brownout, and have whatever entity is responsible for power
> management policy on your system listen to such events?

Since it is a special trigger (something went wrong with the supply), the
system should shutdown. Many systems are using systemd (embedded ones too)
which has a solid built-in mechanism to handle KEY_POWER events. This
avoids rewriting services.

I got your doubts. Can you give me your feedback? Maybe change rename it
to a specific platform instead of the 'generic'.

Thanks,
Marco

> Thanks.
> 
> > 
> > Additional the driver supports releasing registered devices from their
> > drivers, see Documentation/devicetree/bindings/input/gpio-brownout.txt
> > for more details.
> > 
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  .../bindings/input/gpio-brownout.txt          |  36 ++++
> >  drivers/input/misc/Kconfig                    |  12 ++
> >  drivers/input/misc/Makefile                   |   1 +
> >  drivers/input/misc/gpio-brownout.c            | 166 ++++++++++++++++++
> >  4 files changed, 215 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/input/gpio-brownout.txt
> >  create mode 100644 drivers/input/misc/gpio-brownout.c
> > 
> > diff --git a/Documentation/devicetree/bindings/input/gpio-brownout.txt b/Documentation/devicetree/bindings/input/gpio-brownout.txt
> > new file mode 100644
> > index 000000000000..55fbe2aa52a9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/gpio-brownout.txt
> > @@ -0,0 +1,36 @@
> > +Device-Tree bindings for input/gpio_brownout.c driver
> > +
> > +Required properties:
> > +- compatible: Must be "gpio-brownout"
> > +- interrupt-parent: The phandle to the interrupt controller. For more details
> > +  see ../interrupt-controller/interrupts.txt.
> > +- interrupts: The interrupt line for a brownout detection. For more details
> > +  see ../interrupt-controller/interrupts.txt.
> > +
> > +Optional properties:
> > +- linux,code: Keycode to emit upon a brownout detection, default: KEY_POWER.
> > +- release-devices: A list of i2c or spi device phandles. All listed devices
> > +  will be released from their drivers in the order they listed upon a brownout
> > +  detection. This can be helpful to avoid a interrupt flood, because some
> > +  system designs power off all external devices immediately and keep the host
> > +  on for a certain time.
> > +
> > +Example:
> > +
> > +i2c3 {
> > +	temp_core: lm75@48 { };
> > +	temp_chassis: lm75@49 { };
> > +};
> > +
> > +spi1 {
> > +	ts: ad7879@1 { };
> > +};
> > +
> > +/ {
> > +	gpio_brownout_det {
> > +		compatible = "gpio-brownout";
> > +		interrupts-parent = <&gpio3>;
> > +		interrupts = <3 IRQ_TYPE_EDGE_LOW>:
> > +		release-devices = <&temp_core &ts>;
> > +	};
> > +};
> > diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> > index ca59a2be9bc5..6b49e681cca7 100644
> > --- a/drivers/input/misc/Kconfig
> > +++ b/drivers/input/misc/Kconfig
> > @@ -268,6 +268,18 @@ config INPUT_GPIO_BEEPER
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called gpio-beeper.
> >  
> > +config INPUT_GPIO_BROWNOUT
> > +	tristate "Generic GPIO Brownout detection support"
> > +	depends on GPIOLIB || COMPILE_TEST
> > +	help
> > +	  Say Y here if you have a brownout signal connected to a GPIO pin
> > +	  and want to report a keycode signal on a brownout detection.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called gpio-brownout.
> > +
> >  config INPUT_GPIO_DECODER
> >  	tristate "Polled GPIO Decoder Input driver"
> >  	depends on GPIOLIB || COMPILE_TEST
> > diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> > index 9d0f9d1ff68f..8b872b5fc84a 100644
> > --- a/drivers/input/misc/Makefile
> > +++ b/drivers/input/misc/Makefile
> > @@ -35,6 +35,7 @@ obj-$(CONFIG_INPUT_DRV2665_HAPTICS)	+= drv2665.o
> >  obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
> >  obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
> >  obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
> > +obj-$(CONFIG_INPUT_GPIO_BROWNOUT)	+= gpio-brownout.o
> >  obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
> >  obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
> >  obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
> > diff --git a/drivers/input/misc/gpio-brownout.c b/drivers/input/misc/gpio-brownout.c
> > new file mode 100644
> > index 000000000000..23992b9e2814
> > --- /dev/null
> > +++ b/drivers/input/misc/gpio-brownout.c
> > @@ -0,0 +1,166 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * gpio-brownout.c - Generic power fail driver
> > + *
> > + * Copyright (C) 2018 Pengutronix, Marco Felsch <kernel@pengutronix.de>
> > + */
> > +
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/i2c.h>
> > +#include <linux/input.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/kernel.h>
> > +#include <linux/list.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#define GPIO_BROWNOUT_MOD_NAME "gpio-brownout"
> > +
> > +struct gpio_brownout_device {
> > +	struct list_head  list;
> > +	struct device *dev;
> > +};
> > +
> > +struct gpio_brownout {
> > +	struct device *dev;
> > +	struct input_dev *idev;
> > +	unsigned short kcode;
> > +	struct list_head devices;
> > +};
> > +
> > +static irqreturn_t gpio_brownout_isr(int irq, void *dev_id)
> > +{
> > +	struct gpio_brownout *gb = dev_id;
> > +	struct input_dev *idev = gb->idev;
> > +	struct gpio_brownout_device *bout_dev, *tmp;
> > +
> > +	/* first inform userspace */
> > +	input_report_key(idev, gb->kcode, 1);
> > +	input_sync(idev);
> > +
> > +	/* now unregister registered drivers */
> > +	list_for_each_entry_safe(bout_dev, tmp, &gb->devices, list) {
> > +		device_release_driver(bout_dev->dev);
> > +		list_del(&bout_dev->list);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +#ifdef CONFIG_OF
> > +static int gpio_brownout_probe_dt(struct gpio_brownout *gb)
> > +{
> > +	struct device_node *np = gb->dev->of_node;
> > +	struct of_phandle_iterator it;
> > +	unsigned int kcode;
> > +	int ret;
> > +
> > +	/* all dt-properties are optional */
> > +	of_property_read_u32(np, "linux,code", &kcode);
> > +	gb->kcode = kcode;
> > +
> > +	/*
> > +	 * Register all devices which should be unbinded upon a brownout
> > +	 * detection. At the moment only i2c and spi devices are supported
> > +	 */
> > +	of_for_each_phandle(&it, ret, np, "release-devices", NULL, 0) {
> > +		struct gpio_brownout_device *elem;
> > +		struct i2c_client *i2c_c;
> > +		struct spi_device *spi_c;
> > +
> > +		i2c_c = of_find_i2c_device_by_node(it.node);
> > +		spi_c = of_find_spi_device_by_node(it.node);
> > +
> > +		if (!i2c_c && !spi_c)
> > +			return -EPROBE_DEFER;
> > +		else if (i2c_c && spi_c)
> > +			return -EINVAL;
> > +
> > +		elem = devm_kzalloc(gb->dev, sizeof(*elem), GFP_KERNEL);
> > +		if (!elem)
> > +			return -ENOMEM;
> > +
> > +		elem->dev = i2c_c ? &i2c_c->dev : &spi_c->dev;
> > +
> > +		INIT_LIST_HEAD(&elem->list);
> > +		list_add_tail(&elem->list, &gb->devices);
> > +	}
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> > +static int gpio_brownout_probe(struct platform_device *pdev)
> > +{
> > +	struct gpio_brownout *gb;
> > +	struct input_dev *idev;
> > +	int ret, irq;
> > +
> > +	gb = devm_kzalloc(&pdev->dev, sizeof(*gb), GFP_KERNEL);
> > +	if (!gb)
> > +		return -ENOMEM;
> > +
> > +	idev = devm_input_allocate_device(&pdev->dev);
> > +	if (!idev)
> > +		return -ENOMEM;
> > +
> > +	gb->dev = &pdev->dev;
> > +	gb->idev = idev;
> > +	INIT_LIST_HEAD(&gb->devices);
> > +
> > +	if (IS_ENABLED(CONFIG_OF)) {
> > +		ret = gpio_brownout_probe_dt(gb);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "probe_dt failed: %d\n", ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	idev->name = pdev->name;
> > +	gb->kcode = gb->kcode == KEY_RESERVED ? KEY_POWER : gb->kcode;
> > +
> > +	input_set_capability(idev, EV_KEY, gb->kcode);
> > +
> > +	irq = platform_get_irq(pdev, 0);
> > +	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> > +					gpio_brownout_isr, IRQF_ONESHOT,
> > +					GPIO_BROWNOUT_MOD_NAME, gb);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "IRQ request failed: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = input_register_device(idev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Input register failed: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id gpio_brownout_of_match[] = {
> > +	{ .compatible = GPIO_BROWNOUT_MOD_NAME, },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, arm_gpio_brownout_of_match);
> > +#endif
> > +
> > +static struct platform_driver gpio_brownout_driver = {
> > +	.driver = {
> > +		.name = GPIO_BROWNOUT_MOD_NAME,
> > +		.of_match_table = of_match_ptr(gpio_brownout_of_match)
> > +	},
> > +	.probe = gpio_brownout_probe,
> > +};
> > +
> > +module_platform_driver(gpio_brownout_driver);
> > +
> > +MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
> > +MODULE_DESCRIPTION("GPIO Brownout Detection");
> > +MODULE_LICENSE("GPL v2");
> > -- 
> > 2.19.0
> > 
> 
> -- 
> Dmitry
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 3/3] Input: add generic gpio brownout driver
  2018-10-01  7:19     ` Marco Felsch
@ 2018-10-01 16:35       ` Trent Piepho
  2018-10-09 22:43         ` Marco Felsch
  0 siblings, 1 reply; 14+ messages in thread
From: Trent Piepho @ 2018-10-01 16:35 UTC (permalink / raw)
  To: dmitry.torokhov, m.felsch
  Cc: linux-spi, mark.rutland, linux-input, broonie, robh+dt,
	devicetree, kernel

On Mon, 2018-10-01 at 09:19 +0200, Marco Felsch wrote:
> On 18-09-28 17:19, Dmitry Torokhov wrote:
> > 
> > > 
> > > This patch adds the support for a generic gpio-based brownout
> > > detection. Upon a brownout the host system gets informed and the driver
> > > sends a keycode signal to the userspace. Per default this signal is
> > > mapped to KEY_POWER, so the system will shoutdown.
> > 
> > I do not believe this functionality should be exposed as an input
> > device, as it has nothing to do with human interaction with the
> > computing device. To me this is akin over-current on a USB port, or
> > carrier signal on network interfaces.
> 
> I'm still uncertain putting the code into the input framework. I tought
> a lot about the correct place. For me it's like a button, which is
> 'pressed' by the hardware. Yes, it's a bit abstract..

For quite a few years, the hwmon subsystem has had devices that will
generate an interrupt on low voltage (or high voltage, or high
temperature ...) and drivers that export that interrupt to userspace.

This device doesn't seem any different that a somewhat limited hwmon
device with just an "in0_alarm" attribute.

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

* Re: [PATCH 3/3] Input: add generic gpio brownout driver
  2018-10-01 16:35       ` Trent Piepho
@ 2018-10-09 22:43         ` Marco Felsch
  0 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2018-10-09 22:43 UTC (permalink / raw)
  To: Trent Piepho
  Cc: dmitry.torokhov, linux-spi, mark.rutland, linux-input, broonie,
	robh+dt, devicetree, kernel

Hi Trent,

On 18-10-01 16:35, Trent Piepho wrote:
> On Mon, 2018-10-01 at 09:19 +0200, Marco Felsch wrote:
> > On 18-09-28 17:19, Dmitry Torokhov wrote:
> > > 
> > > > 
> > > > This patch adds the support for a generic gpio-based brownout
> > > > detection. Upon a brownout the host system gets informed and the driver
> > > > sends a keycode signal to the userspace. Per default this signal is
> > > > mapped to KEY_POWER, so the system will shoutdown.
> > > 
> > > I do not believe this functionality should be exposed as an input
> > > device, as it has nothing to do with human interaction with the
> > > computing device. To me this is akin over-current on a USB port, or
> > > carrier signal on network interfaces.
> > 
> > I'm still uncertain putting the code into the input framework. I tought
> > a lot about the correct place. For me it's like a button, which is
> > 'pressed' by the hardware. Yes, it's a bit abstract..
> 
> For quite a few years, the hwmon subsystem has had devices that will
> generate an interrupt on low voltage (or high voltage, or high
> temperature ...) and drivers that export that interrupt to userspace.
> 
> This device doesn't seem any different that a somewhat limited hwmon
> device with just an "in0_alarm" attribute.

Thanks for the feedback and the idea. I will migrate the driver to the
hwmon subsystem.

Regards,
Marco

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

end of thread, other threads:[~2018-10-09 22:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25  9:42 [PATCH 0/3] Add GPIO brownout detection support Marco Felsch
2018-09-25  9:42 ` [PATCH 1/3] spi: switch to SPDX license identifier Marco Felsch
2018-09-27 22:40   ` Applied "spi: switch to SPDX license identifier" to the spi tree Mark Brown
2018-09-25  9:42 ` [PATCH 2/3] spi: make OF helper available for others Marco Felsch
2018-09-27 22:38   ` Mark Brown
2018-09-27 22:40   ` Applied "spi: make OF helper available for others" to the spi tree Mark Brown
2018-09-25  9:42 ` [PATCH 3/3] Input: add generic gpio brownout driver Marco Felsch
2018-09-29  0:19   ` Dmitry Torokhov
2018-10-01  7:19     ` Marco Felsch
2018-10-01 16:35       ` Trent Piepho
2018-10-09 22:43         ` Marco Felsch
2018-09-25 17:09 ` [PATCH 0/3] Add GPIO brownout detection support Mark Brown
2018-09-26  8:15   ` Marco Felsch
2018-09-26 12:19     ` Mark Brown

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.