summaryrefslogtreecommitdiffstats
path: root/drivers/mfd/cros_ec.c
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@chromium.org>2014-06-18 20:14:07 +0200
committerLee Jones <lee.jones@linaro.org>2014-07-09 15:58:20 +0200
commitd1fd345e2087f0362c92bd3b0a1cea7fe636ac3a (patch)
tree38c93059a128db984ff4d95ee2c2f35f02275fa6 /drivers/mfd/cros_ec.c
parentmfd: cros_ec: ec_dev->cmd_xfer() returns number of bytes received from EC (diff)
downloadlinux-d1fd345e2087f0362c92bd3b0a1cea7fe636ac3a.tar.xz
linux-d1fd345e2087f0362c92bd3b0a1cea7fe636ac3a.zip
mfd: cros_ec: Move EC interrupt to cros_ec_keyb
If we receive EC interrupts after the cros_ec driver has probed, but before the cros_ec_keyb driver has probed, the cros_ec IRQ handler will not run the cros_ec_keyb notifier and the EC will leave the IRQ line asserted. The cros_ec IRQ handler then returns IRQ_HANDLED and the resulting flood of interrupts causes the machine to hang. Since the EC interrupt is currently only used for the keyboard, move the setup and handling of the EC interrupt to the cros_ec_keyb driver. Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Signed-off-by: Doug Anderson <dianders@chromium.org> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/cros_ec.c')
-rw-r--r--drivers/mfd/cros_ec.c35
1 files changed, 1 insertions, 34 deletions
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 83e30c663578..4873f9c50452 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -62,18 +62,6 @@ int cros_ec_check_result(struct cros_ec_device *ec_dev,
}
EXPORT_SYMBOL(cros_ec_check_result);
-static irqreturn_t ec_irq_thread(int irq, void *data)
-{
- struct cros_ec_device *ec_dev = data;
-
- if (device_may_wakeup(ec_dev->dev))
- pm_wakeup_event(ec_dev->dev, 0);
-
- blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev);
-
- return IRQ_HANDLED;
-}
-
static const struct mfd_cell cros_devs[] = {
{
.name = "cros-ec-keyb",
@@ -92,8 +80,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
struct device *dev = ec_dev->dev;
int err = 0;
- BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
-
if (ec_dev->din_size) {
ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
if (!ec_dev->din)
@@ -105,42 +91,23 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
return -ENOMEM;
}
- if (!ec_dev->irq) {
- dev_dbg(dev, "no valid IRQ: %d\n", ec_dev->irq);
- return err;
- }
-
- err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "chromeos-ec", ec_dev);
- if (err) {
- dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err);
- return err;
- }
-
err = mfd_add_devices(dev, 0, cros_devs,
ARRAY_SIZE(cros_devs),
NULL, ec_dev->irq, NULL);
if (err) {
dev_err(dev, "failed to add mfd devices\n");
- goto fail_mfd;
+ return err;
}
dev_info(dev, "Chrome EC device registered\n");
return 0;
-
-fail_mfd:
- free_irq(ec_dev->irq, ec_dev);
-
- return err;
}
EXPORT_SYMBOL(cros_ec_register);
int cros_ec_remove(struct cros_ec_device *ec_dev)
{
mfd_remove_devices(ec_dev->dev);
- free_irq(ec_dev->irq, ec_dev);
return 0;
}