diff mbox

[1/3] drivers: input: powerkey for HISI 65xx SoC

Message ID 1465536877-18452-2-git-send-email-john.stultz@linaro.org
State Superseded
Headers show

Commit Message

John Stultz June 10, 2016, 5:34 a.m. UTC
From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>


This driver provides a input driver for the power button on the
HiSi 65xx SoC for boards like HiKey.

This driver was originally by Zhiliang Xue <xuezhiliang@huawei.com>
then basically rewritten by Jorge, but preserving the original
module author credits.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Cc: Feng Chen <puck.chen@hisilicon.com>
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Guodong Xu <guodong.xu@linaro.org>
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>

[jstultz: Reworked commit message, folded in other fixes/cleanups
from Jorge, implemented some larger cleanups suggested by DmitryT]
Signed-off-by: John Stultz <john.stultz@linaro.org>

---
v2: Major rework integrating feedback from Dmitry.
v3: Dropped of_match compatible line since no longer using DT
    for this.

 drivers/input/misc/Kconfig         |   9 +++
 drivers/input/misc/Makefile        |   1 +
 drivers/input/misc/hisi_powerkey.c | 149 +++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)
 create mode 100644 drivers/input/misc/hisi_powerkey.c

-- 
1.9.1

Comments

John Stultz June 10, 2016, 7:09 a.m. UTC | #1
On Thu, Jun 9, 2016 at 11:44 PM, kbuild test robot <lkp@intel.com> wrote:
> Hi,

>

> [auto build test ERROR on ljones-mfd/for-mfd-next]

> [also build test ERROR on v4.7-rc2 next-20160609]

> [cannot apply to input/next]

> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

>

> url:    https://github.com/0day-ci/linux/commits/John-Stultz/Hi655x-powerkey-support-for-HiKey-v3/20160610-133804

> base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next

> config: i386-allmodconfig (attached as .config)

> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430

> reproduce:

>         # save the attached .config to linux build tree

>         make ARCH=i386

>

> All error/warnings (new ones prefixed by >>):

>

>    In file included from drivers/input/misc/hisi_powerkey.c:21:0:

>>> drivers/input/misc/hisi_powerkey.c:135:25: error: 'hi65xx_powerkey_of_match' undeclared here (not in a function)

>     MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match);

>                             ^

>    include/linux/module.h:223:21: note: in definition of macro 'MODULE_DEVICE_TABLE'

>     extern const typeof(name) __mod_##type##__##name##_device_table  \

>                         ^~~~

>>> include/linux/module.h:223:27: error: '__mod_of__hi65xx_powerkey_of_match_device_table' aliased to undefined symbol 'hi65xx_powerkey_of_match'

>     extern const typeof(name) __mod_##type##__##name##_device_table  \

>                               ^

>>> drivers/input/misc/hisi_powerkey.c:135:1: note: in expansion of macro 'MODULE_DEVICE_TABLE'

>     MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match);

>     ^~~~~~~~~~~~~~~~~~~


Yep. Sorry, I realized right after I sent this that I had left the
MODULE_DEVICE_TABLE entry in there. I've already yanked it in my tree
and will resubmit with the fix next week.

Please do let me know if you have any other feedback or issues in the meantime!

Apologies and Thanks!
-john
diff mbox

Patch

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1f2337a..07aacfc 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -796,4 +796,13 @@  config INPUT_DRV2667_HAPTICS
 	  To compile this driver as a module, choose M here: the
 	  module will be called drv2667-haptics.
 
+config HISI_POWERKEY
+	tristate "Hisilicon PMIC ONKEY support"
+	depends on ARCH_HISI || COMPILE_TEST
+	help
+	  Say Y to enable support for PMIC ONKEY.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hisi_powerkey.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 0357a08..f264777 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -75,3 +75,4 @@  obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
 obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR)	+= ideapad_slidebar.o
+obj-$(CONFIG_HISI_POWERKEY)		+= hisi_powerkey.o
diff --git a/drivers/input/misc/hisi_powerkey.c b/drivers/input/misc/hisi_powerkey.c
new file mode 100644
index 0000000..d3afebc
--- /dev/null
+++ b/drivers/input/misc/hisi_powerkey.c
@@ -0,0 +1,149 @@ 
+/*
+ * Hisilicon PMIC powerkey driver
+ *
+ * Copyright (C) 2013 Hisilicon Ltd.
+ * Copyright (C) 2015, 2016 Linaro Ltd.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * 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/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+
+/* the held interrupt will trigger after 4 seconds */
+#define MAX_HELD_TIME	(4 * MSEC_PER_SEC)
+
+
+enum id_action { ID_PRESSED, ID_RELEASED, ID_HELD, ID_LAST };
+const char *const irq_names[ID_LAST] = {"down", "up", "hold 4s"};
+
+struct hi65xx_priv {
+	struct input_dev *input;
+};
+
+static irqreturn_t hi65xx_power_press_isr(int irq, void *q)
+{
+	struct hi65xx_priv *p = q;
+
+	pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME);
+	input_report_key(p->input, KEY_POWER, 1);
+	input_sync(p->input);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t hi65xx_power_release_isr(int irq, void *q)
+{
+	struct hi65xx_priv *p = q;
+
+	pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME);
+	input_report_key(p->input, KEY_POWER, 0);
+	input_sync(p->input);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t hi65xx_restart_toggle_isr(int irq, void *q)
+{
+	struct hi65xx_priv *p = q;
+	int value = test_bit(KEY_RESTART, p->input->key);
+
+	pm_wakeup_event(p->input->dev.parent, MAX_HELD_TIME);
+	input_report_key(p->input, KEY_RESTART, !value);
+	input_sync(p->input);
+
+	return IRQ_HANDLED;
+}
+
+irqreturn_t (*irq_handlers[ID_LAST])(int irq, void *q) = {
+	hi65xx_power_press_isr,
+	hi65xx_power_release_isr,
+	hi65xx_restart_toggle_isr,
+};
+
+static int hi65xx_powerkey_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hi65xx_priv *priv;
+	int irq, i, ret;
+
+	priv = devm_kzalloc(dev, sizeof(struct hi65xx_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->input = devm_input_allocate_device(&pdev->dev);
+	if (!priv->input) {
+		dev_err(&pdev->dev, "failed to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	priv->input->phys = "hisi_on/input0";
+	priv->input->name = "HISI 65xx PowerOn Key";
+
+	input_set_capability(priv->input, EV_KEY, KEY_POWER);
+	input_set_capability(priv->input, EV_KEY, KEY_RESTART);
+
+	for (i = 0; i < ID_LAST; i++) {
+
+		irq = platform_get_irq_byname(pdev, irq_names[i]);
+		if (irq < 0) {
+			dev_err(dev, "couldn't get irq %s\n", irq_names[i]);
+			return irq;
+		}
+
+		ret = devm_request_any_context_irq(dev, irq,
+					irq_handlers[i], IRQF_ONESHOT,
+					irq_names[i], priv);
+		if (ret < 0) {
+			dev_err(dev, "couldn't get irq %s\n", irq_names[i]);
+			return ret;
+		}
+	}
+
+	ret = input_register_device(priv->input);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register input device: %d\n",
+			ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+}
+
+static int hi65xx_powerkey_remove(struct platform_device *pdev)
+{
+	device_init_wakeup(&pdev->dev, 0);
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, hi65xx_powerkey_of_match);
+
+static struct platform_driver hi65xx_powerkey_driver = {
+	.driver = {
+		.name = "hi65xx-powerkey",
+	},
+	.probe = hi65xx_powerkey_probe,
+	.remove  = hi65xx_powerkey_remove,
+};
+
+module_platform_driver(hi65xx_powerkey_driver);
+
+MODULE_AUTHOR("Zhiliang Xue <xuezhiliang@huawei.com");
+MODULE_DESCRIPTION("Hisi PMIC Power key driver");
+MODULE_LICENSE("GPL v2");