aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/pm2301_charger.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c
index eed8a89ba4f0..fde5805fdab0 100644
--- a/drivers/power/pm2301_charger.c
+++ b/drivers/power/pm2301_charger.c
@@ -29,6 +29,7 @@
29#include <linux/mfd/abx500/ux500_chargalg.h> 29#include <linux/mfd/abx500/ux500_chargalg.h>
30#include <linux/pm2301_charger.h> 30#include <linux/pm2301_charger.h>
31#include <linux/gpio.h> 31#include <linux/gpio.h>
32#include <linux/pm_runtime.h>
32 33
33#include "pm2301_charger.h" 34#include "pm2301_charger.h"
34 35
@@ -36,6 +37,7 @@
36 struct pm2xxx_charger, ac_chg) 37 struct pm2xxx_charger, ac_chg)
37#define SLEEP_MIN 50 38#define SLEEP_MIN 50
38#define SLEEP_MAX 100 39#define SLEEP_MAX 100
40#define PM2XXX_AUTOSUSPEND_DELAY 500
39 41
40static int pm2xxx_interrupt_registers[] = { 42static int pm2xxx_interrupt_registers[] = {
41 PM2XXX_REG_INT1, 43 PM2XXX_REG_INT1,
@@ -493,6 +495,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data)
493 struct pm2xxx_interrupts *interrupt = pm2->pm2_int; 495 struct pm2xxx_interrupts *interrupt = pm2->pm2_int;
494 int i; 496 int i;
495 497
498 /* wake up the device */
499 pm_runtime_get_sync(pm2->dev);
500
496 do { 501 do {
497 for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { 502 for (i = 0; i < PM2XXX_NUM_INT_REG; i++) {
498 pm2xxx_reg_read(pm2, 503 pm2xxx_reg_read(pm2,
@@ -504,6 +509,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data)
504 } 509 }
505 } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); 510 } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0);
506 511
512 pm_runtime_mark_last_busy(pm2->dev);
513 pm_runtime_put_autosuspend(pm2->dev);
514
507 return IRQ_HANDLED; 515 return IRQ_HANDLED;
508} 516}
509 517
@@ -946,6 +954,53 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client,
946 return 0; 954 return 0;
947} 955}
948 956
957#ifdef CONFIG_PM
958static int pm2xxx_runtime_suspend(struct device *dev)
959{
960 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
961 struct pm2xxx_charger *pm2;
962 int ret = 0;
963
964 pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
965 if (!pm2) {
966 dev_err(pm2->dev, "no pm2xxx_charger data supplied\n");
967 ret = -EINVAL;
968 return ret;
969 }
970
971 clear_lpn_pin(pm2);
972
973 return ret;
974}
975
976static int pm2xxx_runtime_resume(struct device *dev)
977{
978 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
979 struct pm2xxx_charger *pm2;
980 int ret = 0;
981
982 pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
983 if (!pm2) {
984 dev_err(pm2->dev, "no pm2xxx_charger data supplied\n");
985 ret = -EINVAL;
986 return ret;
987 }
988
989 if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0)
990 set_lpn_pin(pm2);
991
992 return ret;
993}
994
995static const struct dev_pm_ops pm2xxx_pm_ops = {
996 .runtime_suspend = pm2xxx_runtime_suspend,
997 .runtime_resume = pm2xxx_runtime_resume,
998};
999#define PM2XXX_PM_OPS (&pm2xxx_pm_ops)
1000#else
1001#define PM2XXX_PM_OPS NULL
1002#endif
1003
949static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, 1004static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
950 const struct i2c_device_id *id) 1005 const struct i2c_device_id *id)
951{ 1006{
@@ -1077,6 +1132,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
1077 gpio_to_irq(pm2->pdata->gpio_irq_number), ret); 1132 gpio_to_irq(pm2->pdata->gpio_irq_number), ret);
1078 goto unregister_pm2xxx_charger; 1133 goto unregister_pm2xxx_charger;
1079 } 1134 }
1135
1136 ret = pm_runtime_set_active(pm2->dev);
1137 if (ret)
1138 dev_err(pm2->dev, "set active Error\n");
1139
1140 pm_runtime_enable(pm2->dev);
1141 pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY);
1142 pm_runtime_use_autosuspend(pm2->dev);
1143 pm_runtime_resume(pm2->dev);
1144
1080 /* pm interrupt can wake up system */ 1145 /* pm interrupt can wake up system */
1081 ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); 1146 ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
1082 if (ret) { 1147 if (ret) {
@@ -1148,6 +1213,8 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client)
1148{ 1213{
1149 struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); 1214 struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client);
1150 1215
1216 /* Disable pm_runtime */
1217 pm_runtime_disable(pm2->dev);
1151 /* Disable AC charging */ 1218 /* Disable AC charging */
1152 pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); 1219 pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0);
1153 1220
@@ -1189,6 +1256,7 @@ static struct i2c_driver pm2xxx_charger_driver = {
1189 .driver = { 1256 .driver = {
1190 .name = "pm2xxx-wall_charger", 1257 .name = "pm2xxx-wall_charger",
1191 .owner = THIS_MODULE, 1258 .owner = THIS_MODULE,
1259 .pm = PM2XXX_PM_OPS,
1192 }, 1260 },
1193 .id_table = pm2xxx_id, 1261 .id_table = pm2xxx_id,
1194}; 1262};