summaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/axp20x-pek.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/axp20x-pek.c')
-rw-r--r--drivers/input/misc/axp20x-pek.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
index debeeaeb8812..c8f87df93a50 100644
--- a/drivers/input/misc/axp20x-pek.c
+++ b/drivers/input/misc/axp20x-pek.c
@@ -191,19 +191,17 @@ static ssize_t axp20x_store_attr_shutdown(struct device *dev,
axp20x_pek->info->shutdown_mask, buf, count);
}
-DEVICE_ATTR(startup, 0644, axp20x_show_attr_startup, axp20x_store_attr_startup);
-DEVICE_ATTR(shutdown, 0644, axp20x_show_attr_shutdown,
- axp20x_store_attr_shutdown);
+static DEVICE_ATTR(startup, 0644, axp20x_show_attr_startup,
+ axp20x_store_attr_startup);
+static DEVICE_ATTR(shutdown, 0644, axp20x_show_attr_shutdown,
+ axp20x_store_attr_shutdown);
-static struct attribute *axp20x_attributes[] = {
+static struct attribute *axp20x_attrs[] = {
&dev_attr_startup.attr,
&dev_attr_shutdown.attr,
NULL,
};
-
-static const struct attribute_group axp20x_attribute_group = {
- .attrs = axp20x_attributes,
-};
+ATTRIBUTE_GROUPS(axp20x);
static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
{
@@ -232,20 +230,14 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
int error;
axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
- if (axp20x_pek->irq_dbr < 0) {
- dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
- axp20x_pek->irq_dbr);
+ if (axp20x_pek->irq_dbr < 0)
return axp20x_pek->irq_dbr;
- }
axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
axp20x_pek->irq_dbr);
axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
- if (axp20x_pek->irq_dbf < 0) {
- dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
- axp20x_pek->irq_dbf);
+ if (axp20x_pek->irq_dbf < 0)
return axp20x_pek->irq_dbf;
- }
axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
axp20x_pek->irq_dbf);
@@ -288,8 +280,7 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
return error;
}
- if (axp20x_pek->axp20x->variant == AXP288_ID)
- enable_irq_wake(axp20x_pek->irq_dbr);
+ device_init_wakeup(&pdev->dev, true);
return 0;
}
@@ -356,14 +347,41 @@ static int axp20x_pek_probe(struct platform_device *pdev)
axp20x_pek->info = (struct axp20x_info *)match->driver_data;
- error = devm_device_add_group(&pdev->dev, &axp20x_attribute_group);
- if (error) {
- dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n",
- error);
- return error;
+ platform_set_drvdata(pdev, axp20x_pek);
+
+ return 0;
+}
+
+static int __maybe_unused axp20x_pek_suspend(struct device *dev)
+{
+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+
+ /*
+ * As nested threaded IRQs are not automatically disabled during
+ * suspend, we must explicitly disable non-wakeup IRQs.
+ */
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(axp20x_pek->irq_dbf);
+ enable_irq_wake(axp20x_pek->irq_dbr);
+ } else {
+ disable_irq(axp20x_pek->irq_dbf);
+ disable_irq(axp20x_pek->irq_dbr);
}
- platform_set_drvdata(pdev, axp20x_pek);
+ return 0;
+}
+
+static int __maybe_unused axp20x_pek_resume(struct device *dev)
+{
+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev)) {
+ disable_irq_wake(axp20x_pek->irq_dbf);
+ disable_irq_wake(axp20x_pek->irq_dbr);
+ } else {
+ enable_irq(axp20x_pek->irq_dbf);
+ enable_irq(axp20x_pek->irq_dbr);
+ }
return 0;
}
@@ -387,6 +405,7 @@ static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
}
static const struct dev_pm_ops axp20x_pek_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(axp20x_pek_suspend, axp20x_pek_resume)
#ifdef CONFIG_PM_SLEEP
.resume_noirq = axp20x_pek_resume_noirq,
#endif
@@ -411,6 +430,7 @@ static struct platform_driver axp20x_pek_driver = {
.driver = {
.name = "axp20x-pek",
.pm = &axp20x_pek_pm_ops,
+ .dev_groups = axp20x_groups,
},
};
module_platform_driver(axp20x_pek_driver);
OpenPOWER on IntegriCloud