summaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 02:17:39 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 02:17:39 +0200
commit54c72d5987ff9f3cf59529d5d4f5cf19eae3f695 (patch)
tree3fee972d54926627895aa07684ddb2e2388e4614 /drivers/input/keyboard
parentMerge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm (diff)
parentMAINTAINERS: Update MFD repo location (diff)
downloadlinux-54c72d5987ff9f3cf59529d5d4f5cf19eae3f695.tar.xz
linux-54c72d5987ff9f3cf59529d5d4f5cf19eae3f695.zip
Merge tag 'mfd-for-linus-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD update from Lee Jones: "Changes to existing drivers: - checkpatch fixes throughout the subsystem - use Regmap to handle IRQs in max77686, extcon-max77693 and mc13xxx-core - use DMA in rtsx_pcr - restrict building on unsupported architectures on timberdale, cs5535 - SPI hardening in cros_ec_spi - more robust error handing in asic3, cros_ec, ab8500-debugfs, max77686 and pcf50633-core - reorder PM runtime and regulator handing during shutdown in arizona - enable wakeup in cros_ec_spi - unused variable/code clean-up in pm8921-core, cros_ec, htc-i2cpld, tps65912-spi, wm5110-tables and ab8500-debugfs - add regulator handing into suspend() in sec-core - remove pointless wrapper functions in extcon-max77693 and i2c-cros-ec-tunnel - use cross-architecture friendly data sizes in stmpe-i2c, arizona, max77686 and tps65910 - devicetree documentation updates throughout - provide power management support in max77686 - few OF clean-ups in max77686 - use manged resources in tps6105x New drivers/supported devices: - add support for s2mpu02 to sec-core - add support for Allwinner A32 to sun6i-prcm - add support for Maxim 77802 in max77686 - add support for DA9063 AD in da9063 - new driver for Intel PMICs (generic) and specifically Crystal Cove (Re-)moved drivers == - move out keyboard functionality cros_ec ==> input/keyboard/cros_ec_keyb" * tag 'mfd-for-linus-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (101 commits) MAINTAINERS: Update MFD repo location mfd: omap-usb-host: Fix improper mask use. mfd: arizona: Only free the CTRLIF_ERR IRQ if we requested it mfd: arizona: Add missing handling for ISRC3 under/overclocked mfd: wm5110: Add new interrupt register definitions mfd: arizona: Rename thermal shutdown interrupt mfd: wm5110: Add in the output done interrupts mfd: wm5110: Remove non-existant interrupts mfd: tps65912-spi: Remove unused variable mfd: htc-i2cpld: Remove unused code mfd: da9063: Add support for AD silicon variant mfd: arizona: Map MICVDD from extcon device to the Arizona core mfd: arizona: Add MICVDD to mapped regulators for wm8997 mfd: max77686: Ensure device type IDs are architecture agnostic mfd: max77686: Add Maxim 77802 PMIC support mfd: tps6105x: Use managed resources when allocating memory mfd: wm8997-tables: Suppress 'line over 80 chars' warnings mfd: kempld-core: Correct a variety of checkpatch warnings mfd: ipaq-micro: Fix coding style errors/warnings reported by checkpatch mfd: si476x-cmd: Remedy checkpatch style complains ...
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 408379669d3c..791781ade4e7 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -24,8 +24,8 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
-#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/input/matrix_keypad.h>
@@ -42,7 +42,6 @@
* @dev: Device pointer
* @idev: Input device
* @ec: Top level ChromeOS device to use to talk to EC
- * @event_notifier: interrupt event notifier for transport devices
*/
struct cros_ec_keyb {
unsigned int rows;
@@ -55,7 +54,6 @@ struct cros_ec_keyb {
struct device *dev;
struct input_dev *idev;
struct cros_ec_device *ec;
- struct notifier_block notifier;
};
@@ -173,41 +171,55 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
input_sync(ckdev->idev);
}
-static int cros_ec_keyb_open(struct input_dev *dev)
-{
- struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
-
- return blocking_notifier_chain_register(&ckdev->ec->event_notifier,
- &ckdev->notifier);
-}
-
-static void cros_ec_keyb_close(struct input_dev *dev)
-{
- struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
-
- blocking_notifier_chain_unregister(&ckdev->ec->event_notifier,
- &ckdev->notifier);
-}
-
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
- return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE,
- kb_state, ckdev->cols);
+ struct cros_ec_command msg = {
+ .version = 0,
+ .command = EC_CMD_MKBP_STATE,
+ .outdata = NULL,
+ .outsize = 0,
+ .indata = kb_state,
+ .insize = ckdev->cols,
+ };
+
+ return ckdev->ec->cmd_xfer(ckdev->ec, &msg);
}
-static int cros_ec_keyb_work(struct notifier_block *nb,
- unsigned long state, void *_notify)
+static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
+ struct cros_ec_keyb *ckdev = data;
+ struct cros_ec_device *ec = ckdev->ec;
int ret;
- struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
- notifier);
uint8_t kb_state[ckdev->cols];
+ if (device_may_wakeup(ec->dev))
+ pm_wakeup_event(ec->dev, 0);
+
ret = cros_ec_keyb_get_state(ckdev, kb_state);
if (ret >= 0)
cros_ec_keyb_process(ckdev, kb_state, ret);
+ else
+ dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);
- return NOTIFY_DONE;
+ return IRQ_HANDLED;
+}
+
+static int cros_ec_keyb_open(struct input_dev *dev)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
+ struct cros_ec_device *ec = ckdev->ec;
+
+ return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "cros_ec_keyb", ckdev);
+}
+
+static void cros_ec_keyb_close(struct input_dev *dev)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
+ struct cros_ec_device *ec = ckdev->ec;
+
+ free_irq(ec->irq, ckdev);
}
static int cros_ec_keyb_probe(struct platform_device *pdev)
@@ -238,8 +250,12 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
if (!idev)
return -ENOMEM;
+ if (!ec->irq) {
+ dev_err(dev, "no EC IRQ specified\n");
+ return -EINVAL;
+ }
+
ckdev->ec = ec;
- ckdev->notifier.notifier_call = cros_ec_keyb_work;
ckdev->dev = dev;
dev_set_drvdata(&pdev->dev, ckdev);