From 116c326e74494806f2524ea07dc256f12b245652 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:26:52 +0000 Subject: pm2301_charger: Remove __exit, __init and __devexit_p() Signed-off-by: Lee Jones --- drivers/power/pm2301_charger.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ed48d75bb786..ca424b844b21 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -851,7 +851,7 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, return 0; } -static int __devinit pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, +static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; @@ -1021,7 +1021,7 @@ free_device_info: return ret; } -static int __devexit pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) +static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) { struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); @@ -1058,7 +1058,7 @@ MODULE_DEVICE_TABLE(i2c, pm2xxx_id); static struct i2c_driver pm2xxx_charger_driver = { .probe = pm2xxx_wall_charger_probe, - .remove = __devexit_p(pm2xxx_wall_charger_remove), + .remove = pm2xxx_wall_charger_remove, .suspend = pm2xxx_wall_charger_suspend, .resume = pm2xxx_wall_charger_resume, .driver = { -- cgit v1.2.1 From 584f970339bb259d4ac7dd82b355f283550193b2 Mon Sep 17 00:00:00 2001 From: Rajkumar Kasirajan Date: Tue, 5 Jun 2012 12:31:25 +0530 Subject: pm2301-charger: Enable SW EOC control on the ab9540 End of charging is managed by SW. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Lee Jones Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/power/pm2301_charger.c | 48 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ca424b844b21..b2f2d4188da9 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -192,11 +192,22 @@ static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2) { int ret; + /* Disable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, PM2XXX_SWCTRL_HW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } + /* Disable charging */ ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, (PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS)); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } - return ret; + return 0; } static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val) @@ -245,13 +256,29 @@ static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val) { + int ret; + switch (val) { case PM2XXX_INT1_ITVBATLOWR: dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n"); + /* Enable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, + PM2XXX_SWCTRL_SW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } break; case PM2XXX_INT1_ITVBATLOWF: dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n"); + /* Disable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, + PM2XXX_SWCTRL_HW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } break; default: @@ -322,16 +349,27 @@ static int pm2_int_reg0(void *pm2_data, int val) struct pm2xxx_charger *pm2 = pm2_data; int ret = 0; - if (val & (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)) { - ret = pm2xxx_charger_vbat_lsig_mngt(pm2, val & - (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)); + if (val & PM2XXX_INT1_ITVBATLOWR) { + ret = pm2xxx_charger_vbat_lsig_mngt(pm2, + PM2XXX_INT1_ITVBATLOWR); + if (ret < 0) + goto out; + } + + if (val & PM2XXX_INT1_ITVBATLOWF) { + ret = pm2xxx_charger_vbat_lsig_mngt(pm2, + PM2XXX_INT1_ITVBATLOWF); + if (ret < 0) + goto out; } if (val & PM2XXX_INT1_ITVBATDISCONNECT) { ret = pm2xxx_charger_bat_disc_mngt(pm2, PM2XXX_INT1_ITVBATDISCONNECT); + if (ret < 0) + goto out; } - +out: return ret; } -- cgit v1.2.1 From 789ca7b46877f29b2aaa94401319c50be35b184f Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Tue, 19 Jun 2012 10:21:24 +0530 Subject: pm2301-charger: Support for over voltage protection on the ab9540 Added support for main charger over voltage protection. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Tested-by: Michel JAOUEN --- drivers/power/pm2301_charger.c | 50 ++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b2f2d4188da9..b560fa5ac4e7 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -227,21 +227,14 @@ int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val) static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) { - int ret = 0; + dev_err(pm2->dev, "Overvoltage detected\n"); + pm2->flags.ovv = true; + power_supply_changed(&pm2->ac_chg.psy); - pm2->failure_input_ovv++; - if (pm2->failure_input_ovv < 4) { - ret = pm2xxx_charging_enable_mngt(pm2); - goto out; - } else { - pm2->failure_input_ovv = 0; - dev_err(pm2->dev, "Overvoltage detected\n"); - pm2->flags.ovv = true; - power_supply_changed(&pm2->ac_chg.psy); - } + /* Schedule a new HW failure check */ + queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0); -out: - return ret; + return 0; } static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) @@ -630,6 +623,8 @@ static int pm2xxx_charger_ac_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_HEALTH_DEAD; else if (pm2->flags.main_thermal_prot) val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + else if (pm2->flags.ovv) + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; else val->intval = POWER_SUPPLY_HEALTH_GOOD; break; @@ -860,6 +855,30 @@ static void pm2xxx_charger_ac_work(struct work_struct *work) sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); }; +static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) +{ + u8 reg_value; + + struct pm2xxx_charger *pm2 = container_of(work, + struct pm2xxx_charger, check_hw_failure_work.work); + + if (pm2->flags.ovv) { + pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, ®_value); + + if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV | + PM2XXX_INT4_S_ITVPWR2OVV))) { + pm2->flags.ovv = false; + power_supply_changed(&pm2->ac_chg.psy); + } + } + + /* If we still have a failure, schedule a new check */ + if (pm2->flags.ovv) { + queue_delayed_work(pm2->charger_wq, + &pm2->check_hw_failure_work, round_jiffies(HZ)); + } +} + static void pm2xxx_charger_check_main_thermal_prot_work( struct work_struct *work) { @@ -983,6 +1002,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, INIT_WORK(&pm2->check_main_thermal_prot_work, pm2xxx_charger_check_main_thermal_prot_work); + /* Init work for HW failure check */ + INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work, + pm2xxx_charger_check_hw_failure_work); + /* * VDD ADC supply needs to be enabled from this driver when there * is a charger connected to avoid erroneous BTEMP_HIGH/LOW @@ -1123,4 +1146,3 @@ MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); MODULE_ALIAS("platform:pm2xxx-charger"); MODULE_DESCRIPTION("PM2xxx charger management driver"); - -- cgit v1.2.1 From 8891716e24d7b0f4b1c3b4fdff641bcb1fb282c4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 13 Feb 2013 11:39:19 +0000 Subject: ab8500-bm: Charge only mode fixes for the ab9540 Fix for charging not getting enabled in charge only mode by external charger. Signed-off-by: Lee Jones --- drivers/power/pm2301_charger.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b560fa5ac4e7..45ef3b9de6b9 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1059,6 +1059,13 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { + /* + * When boot is due to AC charger plug-in, + * read interrupt registers + */ + pm2xxx_reg_read(pm2, PM2XXX_REG_INT1, &val); + pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); + pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; pm2->ac_conn = true; power_supply_changed(&pm2->ac_chg.psy); -- cgit v1.2.1 From 54fbbb6242247d06d21e21bbcf4ae8339bd75592 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Thu, 5 Jul 2012 16:52:55 +0200 Subject: pm2301-charger: Force main charger detect Force main charger detect in turn on status. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Per Forlin Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Tested-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 45ef3b9de6b9..3f02636c48a5 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1067,6 +1067,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; + ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, + AB8500_MAIN_CH_DET); pm2->ac_conn = true; power_supply_changed(&pm2->ac_chg.psy); sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); -- cgit v1.2.1 From 49fddeec9fbb0dd58507185104812fde77c38def Mon Sep 17 00:00:00 2001 From: Mustapha Ben Zoubeir Date: Wed, 27 Jun 2012 15:40:58 +0200 Subject: pm2301-charger: Resolve I2C detection problem on ab9540 Signed-off-by: Mustapha Ben Zoubeir Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS Tested-by: Olivier CLERGEAUD --- drivers/power/pm2301_charger.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 3f02636c48a5..a95edae925f8 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -34,6 +34,8 @@ #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ struct pm2xxx_charger, ac_chg) +#define SLEEP_MIN 50 +#define SLEEP_MAX 100 static int pm2xxx_interrupt_registers[] = { PM2XXX_REG_INT1, @@ -113,17 +115,14 @@ static const struct i2c_device_id pm2xxx_ident[] = { static void set_lpn_pin(struct pm2xxx_charger *pm2) { - if (pm2->ac.charger_connected) - return; gpio_set_value(pm2->lpn_pin, 1); + usleep_range(SLEEP_MIN, SLEEP_MAX); return; } static void clear_lpn_pin(struct pm2xxx_charger *pm2) { - if (pm2->ac.charger_connected) - return; gpio_set_value(pm2->lpn_pin, 0); return; @@ -139,7 +138,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) * and receive I2C "acknowledge" from PM2301. */ mutex_lock(&pm2->lock); - set_lpn_pin(pm2); ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, val); @@ -147,7 +145,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); else ret = 0; - clear_lpn_pin(pm2); mutex_unlock(&pm2->lock); return ret; @@ -163,7 +160,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) * and receive I2C "acknowledge" from PM2301. */ mutex_lock(&pm2->lock); - set_lpn_pin(pm2); ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, &val); @@ -171,7 +167,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); else ret = 0; - clear_lpn_pin(pm2); mutex_unlock(&pm2->lock); return ret; @@ -478,7 +473,6 @@ static int pm2_int_reg5(void *pm2_data, int val) struct pm2xxx_charger *pm2 = pm2_data; int ret = 0; - if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); } @@ -899,12 +893,34 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = { static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) { + struct pm2xxx_charger *pm2; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); + set_lpn_pin(pm2); + + /* If we still have a HW failure, schedule a new check */ + if (pm2->flags.ovv) + queue_delayed_work(pm2->charger_wq, + &pm2->check_hw_failure_work, 0); + return 0; } static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, pm_message_t state) { + struct pm2xxx_charger *pm2; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); + clear_lpn_pin(pm2); + + /* Cancel any pending HW failure check */ + if (delayed_work_pending(&pm2->check_hw_failure_work)) + cancel_delayed_work(&pm2->check_hw_failure_work); + + flush_work(&pm2->ac_work); + flush_work(&pm2->check_main_thermal_prot_work); + return 0; } @@ -1056,6 +1072,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, goto free_gpio; } + set_lpn_pin(pm2); ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { -- cgit v1.2.1 From da9e83d496039458fe9863540cf52b3f9b450675 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Mon, 16 Jul 2012 12:45:19 +0530 Subject: pm2301-charger: Die temp thermal protection This patch adds support for die temperature thermal protection in pm2301 driver. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Hakan BERG Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a95edae925f8..ae647c41c535 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -876,7 +876,27 @@ static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) static void pm2xxx_charger_check_main_thermal_prot_work( struct work_struct *work) { -}; + int ret; + u8 val; + + struct pm2xxx_charger *pm2 = container_of(work, struct pm2xxx_charger, + check_main_thermal_prot_work); + + /* Check if die temp warning is still active */ + ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT5, &val); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); + return; + } + if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGRISE + | PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE)) + pm2->flags.main_thermal_prot = true; + else if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGFALL + | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL)) + pm2->flags.main_thermal_prot = false; + + power_supply_changed(&pm2->ac_chg.psy); +} static struct pm2xxx_interrupts pm2xxx_int = { .handler[0] = pm2_int_reg0, -- cgit v1.2.1 From d4f510f6c3f579bac0dbeaa8dc7c2dc768c31786 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Thu, 28 Jun 2012 18:31:19 +0530 Subject: pm2301-charger: Wake system when ext charger is plugged-in When in suspend state, upon plug-in of external AC charger the device needs to wake-up and charging operation started. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ae647c41c535..b8eafc3850d0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1072,6 +1072,12 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); goto unregister_pm2xxx_charger; } + /* pm interrupt can wake up system */ + ret = enable_irq_wake(pm2->pdata->irq_number); + if (ret) { + dev_err(pm2->dev, "failed to set irq wake\n"); + goto unregister_pm2xxx_interrupt; + } /*Initialize lock*/ mutex_init(&pm2->lock); @@ -1084,7 +1090,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); if (ret < 0) { dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); - goto unregister_pm2xxx_charger; + goto disable_pm2_irq_wake; } ret = gpio_direction_output(pm2->lpn_pin, 0); if (ret < 0) { @@ -1115,6 +1121,11 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, free_gpio: gpio_free(pm2->lpn_pin); +disable_pm2_irq_wake: + disable_irq_wake(pm2->pdata->irq_number); +unregister_pm2xxx_interrupt: + /* disable interrupt */ + free_irq(pm2->pdata->irq_number, pm2); unregister_pm2xxx_charger: /* unregister power supply */ power_supply_unregister(&pm2->ac_chg.psy); @@ -1125,6 +1136,7 @@ free_charger_wq: destroy_workqueue(pm2->charger_wq); free_device_info: kfree(pm2); + return ret; } @@ -1135,6 +1147,9 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) /* Disable AC charging */ pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); + /* Disable wake by pm interrupt */ + disable_irq_wake(pm2->pdata->irq_number); + /* Disable interrupts */ free_irq(pm2->pdata->irq_number, pm2); -- cgit v1.2.1 From f4095a0f06476e5914f2c58b4e96258b2e2ba6b7 Mon Sep 17 00:00:00 2001 From: M BenZoubeir Date: Thu, 13 Sep 2012 10:34:18 +0200 Subject: pm2301-charger: Adjust interrupt handler behavior Signed-off-by: M BenZoubeir Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 45 ++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b8eafc3850d0..eed8a89ba4f0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -493,14 +493,16 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) struct pm2xxx_interrupts *interrupt = pm2->pm2_int; int i; - for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { - pm2xxx_reg_read(pm2, + do { + for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { + pm2xxx_reg_read(pm2, pm2xxx_interrupt_registers[i], &(interrupt->reg[i])); - if (interrupt->reg[i] > 0) - interrupt->handler[i](pm2, interrupt->reg[i]); - } + if (interrupt->reg[i] > 0) + interrupt->handler[i](pm2, interrupt->reg[i]); + } + } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); return IRQ_HANDLED; } @@ -951,6 +953,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, struct pm2xxx_charger *pm2; int ret = 0; u8 val; + int i; pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); if (!pm2) { @@ -1062,24 +1065,25 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, } /* Register interrupts */ - ret = request_threaded_irq(pm2->pdata->irq_number, NULL, + ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), + NULL, pm2xxx_charger_irq[0].isr, pm2->pdata->irq_type, pm2xxx_charger_irq[0].name, pm2); if (ret != 0) { dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", - pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); + pm2xxx_charger_irq[0].name, + gpio_to_irq(pm2->pdata->gpio_irq_number), ret); goto unregister_pm2xxx_charger; } /* pm interrupt can wake up system */ - ret = enable_irq_wake(pm2->pdata->irq_number); + ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); if (ret) { dev_err(pm2->dev, "failed to set irq wake\n"); goto unregister_pm2xxx_interrupt; } - /*Initialize lock*/ mutex_init(&pm2->lock); /* @@ -1099,16 +1103,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, } set_lpn_pin(pm2); + + /* read interrupt registers */ + for (i = 0; i < PM2XXX_NUM_INT_REG; i++) + pm2xxx_reg_read(pm2, + pm2xxx_interrupt_registers[i], + &val); + ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { - /* - * When boot is due to AC charger plug-in, - * read interrupt registers - */ - pm2xxx_reg_read(pm2, PM2XXX_REG_INT1, &val); - pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); - pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, AB8500_MAIN_CH_DET); @@ -1122,10 +1126,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, free_gpio: gpio_free(pm2->lpn_pin); disable_pm2_irq_wake: - disable_irq_wake(pm2->pdata->irq_number); + disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); unregister_pm2xxx_interrupt: /* disable interrupt */ - free_irq(pm2->pdata->irq_number, pm2); + free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); unregister_pm2xxx_charger: /* unregister power supply */ power_supply_unregister(&pm2->ac_chg.psy); @@ -1148,10 +1152,10 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); /* Disable wake by pm interrupt */ - disable_irq_wake(pm2->pdata->irq_number); + disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); /* Disable interrupts */ - free_irq(pm2->pdata->irq_number, pm2); + free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); /* Delete the work queue */ destroy_workqueue(pm2->charger_wq); @@ -1163,7 +1167,6 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) power_supply_unregister(&pm2->ac_chg.psy); - /*Free GPIO60*/ gpio_free(pm2->lpn_pin); kfree(pm2); -- cgit v1.2.1 From aee2b8468caf3d1eed6e329e828bc09eaa61063a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:28:59 +0000 Subject: pm2301-charger: Add pm_runtime_resume & pm_runtime_suspend To optimize the current consumption we use pm_runtime autosuspend functions which execute the pm_runtime_suspend after a delay of inactivity on the other hand we use pm_runtime_resume every time we receive an interruption to wake up the pm2301. Signed-off-by: M BenZoubeir Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'drivers/power/pm2301_charger.c') 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 @@ #include #include #include +#include #include "pm2301_charger.h" @@ -36,6 +37,7 @@ struct pm2xxx_charger, ac_chg) #define SLEEP_MIN 50 #define SLEEP_MAX 100 +#define PM2XXX_AUTOSUSPEND_DELAY 500 static int pm2xxx_interrupt_registers[] = { PM2XXX_REG_INT1, @@ -493,6 +495,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) struct pm2xxx_interrupts *interrupt = pm2->pm2_int; int i; + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); + do { for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { pm2xxx_reg_read(pm2, @@ -504,6 +509,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) } } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); + pm_runtime_mark_last_busy(pm2->dev); + pm_runtime_put_autosuspend(pm2->dev); + return IRQ_HANDLED; } @@ -946,6 +954,53 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, return 0; } +#ifdef CONFIG_PM +static int pm2xxx_runtime_suspend(struct device *dev) +{ + struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); + struct pm2xxx_charger *pm2; + int ret = 0; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); + if (!pm2) { + dev_err(pm2->dev, "no pm2xxx_charger data supplied\n"); + ret = -EINVAL; + return ret; + } + + clear_lpn_pin(pm2); + + return ret; +} + +static int pm2xxx_runtime_resume(struct device *dev) +{ + struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); + struct pm2xxx_charger *pm2; + int ret = 0; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); + if (!pm2) { + dev_err(pm2->dev, "no pm2xxx_charger data supplied\n"); + ret = -EINVAL; + return ret; + } + + if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0) + set_lpn_pin(pm2); + + return ret; +} + +static const struct dev_pm_ops pm2xxx_pm_ops = { + .runtime_suspend = pm2xxx_runtime_suspend, + .runtime_resume = pm2xxx_runtime_resume, +}; +#define PM2XXX_PM_OPS (&pm2xxx_pm_ops) +#else +#define PM2XXX_PM_OPS NULL +#endif + static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { @@ -1077,6 +1132,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, gpio_to_irq(pm2->pdata->gpio_irq_number), ret); goto unregister_pm2xxx_charger; } + + ret = pm_runtime_set_active(pm2->dev); + if (ret) + dev_err(pm2->dev, "set active Error\n"); + + pm_runtime_enable(pm2->dev); + pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(pm2->dev); + pm_runtime_resume(pm2->dev); + /* pm interrupt can wake up system */ ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); if (ret) { @@ -1148,6 +1213,8 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) { struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); + /* Disable pm_runtime */ + pm_runtime_disable(pm2->dev); /* Disable AC charging */ pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); @@ -1189,6 +1256,7 @@ static struct i2c_driver pm2xxx_charger_driver = { .driver = { .name = "pm2xxx-wall_charger", .owner = THIS_MODULE, + .pm = PM2XXX_PM_OPS, }, .id_table = pm2xxx_id, }; -- cgit v1.2.1 From f70dfdec99877fa716f71633a67d7ba3dfab1c5f Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 10 Oct 2012 14:56:41 +0530 Subject: pm2301-charger: Removed unused code from PM2301 driver Some of the headers and defines accrued over time are no longer in use. Let's take the opportunity to remove a few of them. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index fde5805fdab0..87ddc658413f 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -16,16 +16,12 @@ #include #include #include -#include #include #include #include #include -#include -#include #include #include -#include #include #include #include @@ -1018,7 +1014,6 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, /* get parent data */ pm2->dev = &i2c_client->dev; - pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); pm2->pm2_int = &pm2xxx_int; -- cgit v1.2.1 From a21e22f2f36c65c8453575ffd0cc8267134bb30a Mon Sep 17 00:00:00 2001 From: lme00437 Date: Tue, 13 Nov 2012 14:43:48 +0100 Subject: pm2301-charger: lpn pin used only in C2C boards This patch restricts use of LPN pin to C2C boards to avoid conflict on HSI for GPIO 60 use. Signed-off-by: Benoit GAUTHIER Signed-off-by: Lee Jones Reviewed-by: Mustapha BEN-ZOUBEIR Reviewed-by: Philippe LANGLAIS Tested-by: Benoit GAUTHIER --- drivers/power/pm2301_charger.c | 66 ++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 87ddc658413f..12aeed34bd4f 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -113,17 +113,16 @@ static const struct i2c_device_id pm2xxx_ident[] = { static void set_lpn_pin(struct pm2xxx_charger *pm2) { - gpio_set_value(pm2->lpn_pin, 1); - usleep_range(SLEEP_MIN, SLEEP_MAX); - - return; + if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) { + gpio_set_value(pm2->lpn_pin, 1); + usleep_range(SLEEP_MIN, SLEEP_MAX); + } } static void clear_lpn_pin(struct pm2xxx_charger *pm2) { - gpio_set_value(pm2->lpn_pin, 0); - - return; + if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) + gpio_set_value(pm2->lpn_pin, 0); } static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) @@ -1035,14 +1034,6 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2->bat = pl_data->battery; - /*get lpn GPIO from platform data*/ - if (!pm2->pdata->lpn_gpio) { - dev_err(pm2->dev, "no lpn gpio data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - pm2->lpn_pin = pm2->pdata->lpn_gpio; - if (!i2c_check_functionality(i2c_client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA)) { @@ -1146,23 +1137,28 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, mutex_init(&pm2->lock); - /* - * Charger detection mechanism requires pulling up the LPN pin - * while i2c communication if Charger is not connected - * LPN pin of PM2301 is GPIO60 of AB9540 - */ - ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); - if (ret < 0) { - dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); - goto disable_pm2_irq_wake; - } - ret = gpio_direction_output(pm2->lpn_pin, 0); - if (ret < 0) { - dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); - goto free_gpio; - } + if (gpio_is_valid(pm2->pdata->lpn_gpio)) { + /* get lpn GPIO from platform data */ + pm2->lpn_pin = pm2->pdata->lpn_gpio; - set_lpn_pin(pm2); + /* + * Charger detection mechanism requires pulling up the LPN pin + * while i2c communication if Charger is not connected + * LPN pin of PM2301 is GPIO60 of AB9540 + */ + ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); + + if (ret < 0) { + dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); + goto disable_pm2_irq_wake; + } + ret = gpio_direction_output(pm2->lpn_pin, 0); + if (ret < 0) { + dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); + goto free_gpio; + } + set_lpn_pin(pm2); + } /* read interrupt registers */ for (i = 0; i < PM2XXX_NUM_INT_REG; i++) @@ -1184,7 +1180,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, return 0; free_gpio: - gpio_free(pm2->lpn_pin); + if (gpio_is_valid(pm2->lpn_pin)) + gpio_free(pm2->lpn_pin); disable_pm2_irq_wake: disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); unregister_pm2xxx_interrupt: @@ -1229,7 +1226,8 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) power_supply_unregister(&pm2->ac_chg.psy); - gpio_free(pm2->lpn_pin); + if (gpio_is_valid(pm2->lpn_pin)) + gpio_free(pm2->lpn_pin); kfree(pm2); @@ -1266,7 +1264,7 @@ static void __exit pm2xxx_charger_exit(void) i2c_del_driver(&pm2xxx_charger_driver); } -subsys_initcall_sync(pm2xxx_charger_init); +device_initcall_sync(pm2xxx_charger_init); module_exit(pm2xxx_charger_exit); MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From 0f80ba63187439ef4ad3810ccd97633af9522be8 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Tue, 20 Nov 2012 11:51:56 +0530 Subject: pm2301-charger: Charging LED control for pm2301 The LED Indicator feature allows indicating through a led when the PM2301 battery charging is active. SW shall not disable this LED. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 12aeed34bd4f..ac03f9e247d1 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -706,10 +706,6 @@ static int pm2xxx_charging_init(struct pm2xxx_charger *pm2) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG, PM2XXX_VBAT_LOW_MONITORING_ENA); - /* Disable LED */ - ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, - PM2XXX_LED_SELECT_DIS); - return ret; } -- cgit v1.2.1 From b64f51c4adde8972afac778a63a19a30c6d5f4b0 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 5 Dec 2012 14:14:13 +0530 Subject: pm2301-charger: Wake device on register access When USB Dedicated or Standard host chargers are plugged into the device, chargealg attempts to disable the PM2301 AC charger, However, disabling PM2301 was failing because of it being in runtime suepend mode & LPN pin being low. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ac03f9e247d1..a1fc37eca334 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -128,13 +128,9 @@ static void clear_lpn_pin(struct pm2xxx_charger *pm2) static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) { int ret; - /* - * When AC adaptor is unplugged, the host - * must put LPN high to be able to - * communicate by I2C with PM2301 - * and receive I2C "acknowledge" from PM2301. - */ - mutex_lock(&pm2->lock); + + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, val); @@ -142,7 +138,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); else ret = 0; - mutex_unlock(&pm2->lock); return ret; } @@ -150,13 +145,9 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) { int ret; - /* - * When AC adaptor is unplugged, the host - * must put LPN high to be able to - * communicate by I2C with PM2301 - * and receive I2C "acknowledge" from PM2301. - */ - mutex_lock(&pm2->lock); + + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, &val); @@ -164,7 +155,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); else ret = 0; - mutex_unlock(&pm2->lock); return ret; } -- cgit v1.2.1 From 9b7f50e3ea9a98f518fc4077f8bebc96717acff5 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 5 Dec 2012 16:13:31 +0530 Subject: pm2301-charger: Reference put missing after access Added missing pm_runtime_put_sync in read & write. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Sandeep TRIPATHY Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a1fc37eca334..618c46d25a3b 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -139,6 +139,8 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) else ret = 0; + pm_runtime_put_sync(pm2->dev); + return ret; } @@ -156,6 +158,8 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) else ret = 0; + pm_runtime_put_sync(pm2->dev); + return ret; } -- cgit v1.2.1 From 6b170807cd5cac8dc6353f47a88ccb14bbf76c4f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 13 Apr 2013 13:20:07 +0200 Subject: pm2301-charger: Fix suspend/resume The pm2301-charger driver implements runtime pm and at the same time uses the legacy pm callbacks for suspend and resume. This does not work since the I2C core wont look at the legacy pm callbacks if a driver has the 'pm' field set. This patch fixes it by moving over to dev_pm_ops for suspend/resume as well. Signed-off-by: Lars-Peter Clausen Signed-off-by: Anton Vorontsov --- drivers/power/pm2301_charger.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers/power/pm2301_charger.c') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 618c46d25a3b..f123f3c219c3 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "pm2301_charger.h" @@ -906,8 +907,13 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = { {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, }; -static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) +#ifdef CONFIG_PM + +#ifdef CONFIG_PM_SLEEP + +static int pm2xxx_wall_charger_resume(struct device *dev) { + struct i2c_client *i2c_client = to_i2c_client(dev); struct pm2xxx_charger *pm2; pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); @@ -921,9 +927,9 @@ static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) return 0; } -static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, - pm_message_t state) +static int pm2xxx_wall_charger_suspend(struct device *dev) { + struct i2c_client *i2c_client = to_i2c_client(dev); struct pm2xxx_charger *pm2; pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); @@ -939,7 +945,10 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, return 0; } -#ifdef CONFIG_PM +#endif + +#ifdef CONFIG_PM_RUNTIME + static int pm2xxx_runtime_suspend(struct device *dev) { struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); @@ -977,9 +986,12 @@ static int pm2xxx_runtime_resume(struct device *dev) return ret; } +#endif + static const struct dev_pm_ops pm2xxx_pm_ops = { - .runtime_suspend = pm2xxx_runtime_suspend, - .runtime_resume = pm2xxx_runtime_resume, + SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend, + pm2xxx_wall_charger_resume) + SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL) }; #define PM2XXX_PM_OPS (&pm2xxx_pm_ops) #else @@ -1234,8 +1246,6 @@ MODULE_DEVICE_TABLE(i2c, pm2xxx_id); static struct i2c_driver pm2xxx_charger_driver = { .probe = pm2xxx_wall_charger_probe, .remove = pm2xxx_wall_charger_remove, - .suspend = pm2xxx_wall_charger_suspend, - .resume = pm2xxx_wall_charger_resume, .driver = { .name = "pm2xxx-wall_charger", .owner = THIS_MODULE, -- cgit v1.2.1