diff options
Diffstat (limited to 'drivers/power')
43 files changed, 500 insertions, 316 deletions
diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c index beed5ecf75e1..8bc80b05c63c 100644 --- a/drivers/power/88pm860x_battery.c +++ b/drivers/power/88pm860x_battery.c @@ -901,7 +901,7 @@ static enum power_supply_property pm860x_batt_props[] = { POWER_SUPPLY_PROP_TEMP, }; -static __devinit int pm860x_battery_probe(struct platform_device *pdev) +static int pm860x_battery_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_battery_info *info; @@ -989,7 +989,7 @@ out: return ret; } -static int __devexit pm860x_battery_remove(struct platform_device *pdev) +static int pm860x_battery_remove(struct platform_device *pdev) { struct pm860x_battery_info *info = platform_get_drvdata(pdev); @@ -1033,7 +1033,7 @@ static struct platform_driver pm860x_battery_driver = { .pm = &pm860x_battery_pm_ops, }, .probe = pm860x_battery_probe, - .remove = __devexit_p(pm860x_battery_remove), + .remove = pm860x_battery_remove, }; module_platform_driver(pm860x_battery_driver); diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c index 2dbeb1460901..4b37a5af8deb 100644 --- a/drivers/power/88pm860x_charger.c +++ b/drivers/power/88pm860x_charger.c @@ -645,7 +645,7 @@ static struct pm860x_irq_desc { { "vchg", pm860x_vchg_handler }, }; -static __devinit int pm860x_charger_probe(struct platform_device *pdev) +static int pm860x_charger_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_charger_info *info; @@ -718,7 +718,7 @@ out: return ret; } -static int __devexit pm860x_charger_remove(struct platform_device *pdev) +static int pm860x_charger_remove(struct platform_device *pdev) { struct pm860x_charger_info *info = platform_get_drvdata(pdev); int i; @@ -738,7 +738,7 @@ static struct platform_driver pm860x_charger_driver = { .owner = THIS_MODULE, }, .probe = pm860x_charger_probe, - .remove = __devexit_p(pm860x_charger_remove), + .remove = pm860x_charger_remove, }; module_platform_driver(pm860x_charger_driver); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 263499f8709a..9f45e2f77d53 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -346,6 +346,8 @@ config AB8500_BM help Say Y to include support for AB8500 battery management. +source "drivers/power/reset/Kconfig" + endif # POWER_SUPPLY source "drivers/power/avs/Kconfig" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 070c73d2ef02..b11e0c7ea0f1 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o +obj-$(CONFIG_POWER_RESET) += reset/ diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 158cba5cff53..e1d28039ce7b 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -947,7 +947,7 @@ static int ab8500_btemp_suspend(struct platform_device *pdev, #define ab8500_btemp_resume NULL #endif -static int __devexit ab8500_btemp_remove(struct platform_device *pdev) +static int ab8500_btemp_remove(struct platform_device *pdev) { struct ab8500_btemp *di = platform_get_drvdata(pdev); int i, irq; @@ -973,7 +973,7 @@ static char *supply_interface[] = { "ab8500_fg", }; -static int __devinit ab8500_btemp_probe(struct platform_device *pdev) +static int ab8500_btemp_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct abx500_bm_data *plat = pdev->dev.platform_data; @@ -1109,7 +1109,7 @@ static const struct of_device_id ab8500_btemp_match[] = { static struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, - .remove = __devexit_p(ab8500_btemp_remove), + .remove = ab8500_btemp_remove, .suspend = ab8500_btemp_suspend, .resume = ab8500_btemp_resume, .driver = { diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 2ddface4b2c4..e5755f0ba831 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2587,7 +2587,7 @@ static int ab8500_charger_suspend(struct platform_device *pdev, #define ab8500_charger_resume NULL #endif -static int __devexit ab8500_charger_remove(struct platform_device *pdev) +static int ab8500_charger_remove(struct platform_device *pdev) { struct ab8500_charger *di = platform_get_drvdata(pdev); int i, irq, ret; @@ -2633,7 +2633,7 @@ static char *supply_interface[] = { "ab8500_btemp", }; -static int __devinit ab8500_charger_probe(struct platform_device *pdev) +static int ab8500_charger_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct abx500_bm_data *plat = pdev->dev.platform_data; @@ -2866,7 +2866,7 @@ static const struct of_device_id ab8500_charger_match[] = { static struct platform_driver ab8500_charger_driver = { .probe = ab8500_charger_probe, - .remove = __devexit_p(ab8500_charger_remove), + .remove = ab8500_charger_remove, .suspend = ab8500_charger_suspend, .resume = ab8500_charger_resume, .driver = { diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index df681a80d8a4..3d05c73813c8 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -2410,7 +2410,7 @@ static int ab8500_fg_suspend(struct platform_device *pdev, #define ab8500_fg_resume NULL #endif -static int __devexit ab8500_fg_remove(struct platform_device *pdev) +static int ab8500_fg_remove(struct platform_device *pdev) { int ret = 0; struct ab8500_fg *di = platform_get_drvdata(pdev); @@ -2445,7 +2445,7 @@ static char *supply_interface[] = { "ab8500_usb", }; -static int __devinit ab8500_fg_probe(struct platform_device *pdev) +static int ab8500_fg_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct abx500_bm_data *plat = pdev->dev.platform_data; @@ -2614,7 +2614,7 @@ static const struct of_device_id ab8500_fg_match[] = { static struct platform_driver ab8500_fg_driver = { .probe = ab8500_fg_probe, - .remove = __devexit_p(ab8500_fg_remove), + .remove = ab8500_fg_remove, .suspend = ab8500_fg_suspend, .resume = ab8500_fg_resume, .driver = { diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index a8acfe5b863f..8b69da0ae5af 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -1782,7 +1782,7 @@ static int abx500_chargalg_suspend(struct platform_device *pdev, #define abx500_chargalg_resume NULL #endif -static int __devexit abx500_chargalg_remove(struct platform_device *pdev) +static int abx500_chargalg_remove(struct platform_device *pdev) { struct abx500_chargalg *di = platform_get_drvdata(pdev); @@ -1803,7 +1803,7 @@ static char *supply_interface[] = { "ab8500_fg", }; -static int __devinit abx500_chargalg_probe(struct platform_device *pdev) +static int abx500_chargalg_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct abx500_bm_data *plat = pdev->dev.platform_data; @@ -1911,7 +1911,7 @@ static const struct of_device_id ab8500_chargalg_match[] = { static struct platform_driver abx500_chargalg_driver = { .probe = abx500_chargalg_probe, - .remove = __devexit_p(abx500_chargalg_remove), + .remove = abx500_chargalg_remove, .suspend = abx500_chargalg_suspend, .resume = abx500_chargalg_resume, .driver = { diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index 24768a27e1d8..6b2238bb6a81 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -27,8 +27,6 @@ #include <linux/pm_runtime.h> #include <linux/power/smartreflex.h> -#include <plat/cpu.h> - #define SMARTREFLEX_NAME_LEN 16 #define NVALUE_NAME_LEN 40 #define SR_DISABLE_TIMEOUT 200 @@ -130,24 +128,21 @@ static irqreturn_t sr_interrupt(int irq, void *data) static void sr_set_clk_length(struct omap_sr *sr) { - struct clk *sys_ck; - u32 sys_clk_speed; + struct clk *fck; + u32 fclk_speed; - if (cpu_is_omap34xx()) - sys_ck = clk_get(NULL, "sys_ck"); - else - sys_ck = clk_get(NULL, "sys_clkin_ck"); + fck = clk_get(&sr->pdev->dev, "fck"); - if (IS_ERR(sys_ck)) { - dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n", - __func__); + if (IS_ERR(fck)) { + dev_err(&sr->pdev->dev, "%s: unable to get fck for device %s\n", + __func__, dev_name(&sr->pdev->dev)); return; } - sys_clk_speed = clk_get_rate(sys_ck); - clk_put(sys_ck); + fclk_speed = clk_get_rate(fck); + clk_put(fck); - switch (sys_clk_speed) { + switch (fclk_speed) { case 12000000: sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK; break; @@ -164,34 +159,12 @@ static void sr_set_clk_length(struct omap_sr *sr) sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK; break; default: - dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n", - __func__, sys_clk_speed); + dev_err(&sr->pdev->dev, "%s: Invalid fclk rate: %d\n", + __func__, fclk_speed); break; } } -static void sr_set_regfields(struct omap_sr *sr) -{ - /* - * For time being these values are defined in smartreflex.h - * and populated during init. May be they can be moved to board - * file or pmic specific data structure. In that case these structure - * fields will have to be populated using the pdata or pmic structure. - */ - if (cpu_is_omap34xx() || cpu_is_omap44xx()) { - sr->err_weight = OMAP3430_SR_ERRWEIGHT; - sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; - sr->accum_data = OMAP3430_SR_ACCUMDATA; - if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) { - sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; - sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; - } else { - sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT; - sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT; - } - } -} - static void sr_start_vddautocomp(struct omap_sr *sr) { if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { @@ -924,8 +897,14 @@ static int __init omap_sr_probe(struct platform_device *pdev) sr_info->nvalue_count = pdata->nvalue_count; sr_info->senn_mod = pdata->senn_mod; sr_info->senp_mod = pdata->senp_mod; + sr_info->err_weight = pdata->err_weight; + sr_info->err_maxlimit = pdata->err_maxlimit; + sr_info->accum_data = pdata->accum_data; + sr_info->senn_avgweight = pdata->senn_avgweight; + sr_info->senp_avgweight = pdata->senp_avgweight; sr_info->autocomp_active = false; sr_info->ip_type = pdata->ip_type; + sr_info->base = ioremap(mem->start, resource_size(mem)); if (!sr_info->base) { dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); @@ -937,7 +916,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) sr_info->irq = irq->start; sr_set_clk_length(sr_info); - sr_set_regfields(sr_info); list_add(&sr_info->node, &sr_list); @@ -1026,7 +1004,7 @@ err_free_devinfo: return ret; } -static int __devexit omap_sr_remove(struct platform_device *pdev) +static int omap_sr_remove(struct platform_device *pdev) { struct omap_sr_data *pdata = pdev->dev.platform_data; struct omap_sr *sr_info; @@ -1059,7 +1037,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } -static void __devexit omap_sr_shutdown(struct platform_device *pdev) +static void omap_sr_shutdown(struct platform_device *pdev) { struct omap_sr_data *pdata = pdev->dev.platform_data; struct omap_sr *sr_info; @@ -1083,8 +1061,8 @@ static void __devexit omap_sr_shutdown(struct platform_device *pdev) } static struct platform_driver smartreflex_driver = { - .remove = __devexit_p(omap_sr_remove), - .shutdown = __devexit_p(omap_sr_shutdown), + .remove = omap_sr_remove, + .shutdown = omap_sr_shutdown, .driver = { .name = "smartreflex", }, diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index 41b3328ecfc5..36b34efdafc9 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -934,7 +934,7 @@ static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg, return pdata->read(dev, reg); } -static int __devinit bq27000_battery_probe(struct platform_device *pdev) +static int bq27000_battery_probe(struct platform_device *pdev) { struct bq27x00_device_info *di; struct bq27000_platform_data *pdata = pdev->dev.platform_data; @@ -977,7 +977,7 @@ err_free: return ret; } -static int __devexit bq27000_battery_remove(struct platform_device *pdev) +static int bq27000_battery_remove(struct platform_device *pdev) { struct bq27x00_device_info *di = platform_get_drvdata(pdev); @@ -991,7 +991,7 @@ static int __devexit bq27000_battery_remove(struct platform_device *pdev) static struct platform_driver bq27000_battery_driver = { .probe = bq27000_battery_probe, - .remove = __devexit_p(bq27000_battery_remove), + .remove = bq27000_battery_remove, .driver = { .name = "bq27000-battery", .owner = THIS_MODULE, diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 8a0aca6364c7..8acc3f8d303c 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -239,44 +239,37 @@ static bool is_full_charged(struct charger_manager *cm) int uV; /* If there is no battery, it cannot be charged */ - if (!is_batt_present(cm)) { - val.intval = 0; - goto out; - } + if (!is_batt_present(cm)) + return false; if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) { + val.intval = 0; + /* Not full if capacity of fuel gauge isn't full */ ret = cm->fuel_gauge->get_property(cm->fuel_gauge, POWER_SUPPLY_PROP_CHARGE_FULL, &val); - if (!ret && val.intval > desc->fullbatt_full_capacity) { - val.intval = 1; - goto out; - } + if (!ret && val.intval > desc->fullbatt_full_capacity) + return true; } /* Full, if it's over the fullbatt voltage */ if (desc->fullbatt_uV > 0) { ret = get_batt_uV(cm, &uV); - if (!ret && uV >= desc->fullbatt_uV) { - val.intval = 1; - goto out; - } + if (!ret && uV >= desc->fullbatt_uV) + return true; } /* Full, if the capacity is more than fullbatt_soc */ if (cm->fuel_gauge && desc->fullbatt_soc > 0) { + val.intval = 0; + ret = cm->fuel_gauge->get_property(cm->fuel_gauge, POWER_SUPPLY_PROP_CAPACITY, &val); - if (!ret && val.intval >= desc->fullbatt_soc) { - val.intval = 1; - goto out; - } + if (!ret && val.intval >= desc->fullbatt_soc) + return true; } - val.intval = 0; - -out: - return val.intval ? true : false; + return false; } /** @@ -489,8 +482,9 @@ static void fullbatt_vchk(struct work_struct *work) return; } - diff = desc->fullbatt_uV; - diff -= batt_uV; + diff = desc->fullbatt_uV - batt_uV; + if (diff < 0) + return; dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); @@ -675,15 +669,21 @@ static void _setup_polling(struct work_struct *work) WARN(cm_wq == NULL, "charger-manager: workqueue not initialized" ". try it later. %s\n", __func__); + /* + * Use mod_delayed_work() iff the next polling interval should + * occur before the currently scheduled one. If @cm_monitor_work + * isn't active, the end result is the same, so no need to worry + * about stale @next_polling. + */ _next_polling = jiffies + polling_jiffy; - if (!delayed_work_pending(&cm_monitor_work) || - (delayed_work_pending(&cm_monitor_work) && - time_after(next_polling, _next_polling))) { - next_polling = jiffies + polling_jiffy; + if (time_before(_next_polling, next_polling)) { mod_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy); + next_polling = _next_polling; + } else { + if (queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy)) + next_polling = _next_polling; } - out: mutex_unlock(&cm_list_mtx); } @@ -757,8 +757,7 @@ static void misc_event_handler(struct charger_manager *cm, if (cm_suspended) device_set_wakeup_capable(cm->dev, true); - if (!delayed_work_pending(&cm_monitor_work) && - is_polling_required(cm) && cm->desc->polling_interval_ms) + if (is_polling_required(cm) && cm->desc->polling_interval_ms) schedule_work(&setup_polling); uevent_notify(cm, default_event_names[type]); } @@ -1176,8 +1175,7 @@ static int charger_extcon_notifier(struct notifier_block *self, * when charger cable is attached. */ if (cable->attached && is_polling_required(cable->cm)) { - if (work_pending(&setup_polling)) - cancel_work_sync(&setup_polling); + cancel_work_sync(&setup_polling); schedule_work(&setup_polling); } @@ -1221,6 +1219,55 @@ static int charger_extcon_init(struct charger_manager *cm, return ret; } +/** + * charger_manager_register_extcon - Register extcon device to recevie state + * of charger cable. + * @cm: the Charger Manager representing the battery. + * + * This function support EXTCON(External Connector) subsystem to detect the + * state of charger cables for enabling or disabling charger(regulator) and + * select the charger cable for charging among a number of external cable + * according to policy of H/W board. + */ +static int charger_manager_register_extcon(struct charger_manager *cm) +{ + struct charger_desc *desc = cm->desc; + struct charger_regulator *charger; + int ret = 0; + int i; + int j; + + for (i = 0; i < desc->num_charger_regulators; i++) { + charger = &desc->charger_regulators[i]; + + charger->consumer = regulator_get(cm->dev, + charger->regulator_name); + if (charger->consumer == NULL) { + dev_err(cm->dev, "Cannot find charger(%s)n", + charger->regulator_name); + ret = -EINVAL; + goto err; + } + charger->cm = cm; + + for (j = 0; j < charger->num_cables; j++) { + struct charger_cable *cable = &charger->cables[j]; + + ret = charger_extcon_init(cm, cable); + if (ret < 0) { + dev_err(cm->dev, "Cannot initialize charger(%s)n", + charger->regulator_name); + goto err; + } + cable->charger = charger; + cable->cm = cm; + } + } + +err: + return ret; +} + /* help function of sysfs node to control charger(regulator) */ static ssize_t charger_name_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1280,7 +1327,7 @@ static ssize_t charger_externally_control_store(struct device *dev, for (i = 0; i < desc->num_charger_regulators; i++) { if (&desc->charger_regulators[i] != charger && - !desc->charger_regulators[i].externally_control) { + !desc->charger_regulators[i].externally_control) { /* * At least, one charger is controlled by * charger-manager @@ -1309,13 +1356,107 @@ static ssize_t charger_externally_control_store(struct device *dev, return count; } +/** + * charger_manager_register_sysfs - Register sysfs entry for each charger + * @cm: the Charger Manager representing the battery. + * + * This function add sysfs entry for charger(regulator) to control charger from + * user-space. If some development board use one more chargers for charging + * but only need one charger on specific case which is dependent on user + * scenario or hardware restrictions, the user enter 1 or 0(zero) to '/sys/ + * class/power_supply/battery/charger.[index]/externally_control'. For example, + * if user enter 1 to 'sys/class/power_supply/battery/charger.[index]/ + * externally_control, this charger isn't controlled from charger-manager and + * always stay off state of regulator. + */ +static int charger_manager_register_sysfs(struct charger_manager *cm) +{ + struct charger_desc *desc = cm->desc; + struct charger_regulator *charger; + int chargers_externally_control = 1; + char buf[11]; + char *str; + int ret = 0; + int i; + + /* Create sysfs entry to control charger(regulator) */ + for (i = 0; i < desc->num_charger_regulators; i++) { + charger = &desc->charger_regulators[i]; + + snprintf(buf, 10, "charger.%d", i); + str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); + if (!str) { + dev_err(cm->dev, "Cannot allocate memory: %s\n", + charger->regulator_name); + ret = -ENOMEM; + goto err; + } + strcpy(str, buf); + + charger->attrs[0] = &charger->attr_name.attr; + charger->attrs[1] = &charger->attr_state.attr; + charger->attrs[2] = &charger->attr_externally_control.attr; + charger->attrs[3] = NULL; + charger->attr_g.name = str; + charger->attr_g.attrs = charger->attrs; + + sysfs_attr_init(&charger->attr_name.attr); + charger->attr_name.attr.name = "name"; + charger->attr_name.attr.mode = 0444; + charger->attr_name.show = charger_name_show; + + sysfs_attr_init(&charger->attr_state.attr); + charger->attr_state.attr.name = "state"; + charger->attr_state.attr.mode = 0444; + charger->attr_state.show = charger_state_show; + + sysfs_attr_init(&charger->attr_externally_control.attr); + charger->attr_externally_control.attr.name + = "externally_control"; + charger->attr_externally_control.attr.mode = 0644; + charger->attr_externally_control.show + = charger_externally_control_show; + charger->attr_externally_control.store + = charger_externally_control_store; + + if (!desc->charger_regulators[i].externally_control || + !chargers_externally_control) + chargers_externally_control = 0; + + dev_info(cm->dev, "'%s' regulator's externally_control" + "is %d\n", charger->regulator_name, + charger->externally_control); + + ret = sysfs_create_group(&cm->charger_psy.dev->kobj, + &charger->attr_g); + if (ret < 0) { + dev_err(cm->dev, "Cannot create sysfs entry" + "of %s regulator\n", + charger->regulator_name); + ret = -EINVAL; + goto err; + } + } + + if (chargers_externally_control) { + dev_err(cm->dev, "Cannot register regulator because " + "charger-manager must need at least " + "one charger for charging battery\n"); + + ret = -EINVAL; + goto err; + } + +err: + return ret; +} + static int charger_manager_probe(struct platform_device *pdev) { struct charger_desc *desc = dev_get_platdata(&pdev->dev); struct charger_manager *cm; int ret = 0, i = 0; int j = 0; - int chargers_externally_control = 1; union power_supply_propval val; if (g_desc && !rtc_dev && g_desc->rtc_name) { @@ -1446,11 +1587,10 @@ static int charger_manager_probe(struct platform_device *pdev) memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default)); - if (!desc->psy_name) { + if (!desc->psy_name) strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); - } else { + else strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); - } cm->charger_psy.name = cm->psy_name_buf; /* Allocate for psy properties because they may vary */ @@ -1502,105 +1642,19 @@ static int charger_manager_probe(struct platform_device *pdev) goto err_register; } - for (i = 0 ; i < desc->num_charger_regulators ; i++) { - struct charger_regulator *charger - = &desc->charger_regulators[i]; - char buf[11]; - char *str; - - charger->consumer = regulator_get(&pdev->dev, - charger->regulator_name); - if (charger->consumer == NULL) { - dev_err(&pdev->dev, "Cannot find charger(%s)n", - charger->regulator_name); - ret = -EINVAL; - goto err_chg_get; - } - charger->cm = cm; - - for (j = 0 ; j < charger->num_cables ; j++) { - struct charger_cable *cable = &charger->cables[j]; - - ret = charger_extcon_init(cm, cable); - if (ret < 0) { - dev_err(&pdev->dev, "Cannot find charger(%s)n", - charger->regulator_name); - goto err_extcon; - } - cable->charger = charger; - cable->cm = cm; - } - - /* Create sysfs entry to control charger(regulator) */ - snprintf(buf, 10, "charger.%d", i); - str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); - if (!str) { - for (i--; i >= 0; i--) { - charger = &desc->charger_regulators[i]; - kfree(charger->attr_g.name); - } - ret = -ENOMEM; - - goto err_extcon; - } - strcpy(str, buf); - - charger->attrs[0] = &charger->attr_name.attr; - charger->attrs[1] = &charger->attr_state.attr; - charger->attrs[2] = &charger->attr_externally_control.attr; - charger->attrs[3] = NULL; - charger->attr_g.name = str; - charger->attr_g.attrs = charger->attrs; - - sysfs_attr_init(&charger->attr_name.attr); - charger->attr_name.attr.name = "name"; - charger->attr_name.attr.mode = 0444; - charger->attr_name.show = charger_name_show; - - sysfs_attr_init(&charger->attr_state.attr); - charger->attr_state.attr.name = "state"; - charger->attr_state.attr.mode = 0444; - charger->attr_state.show = charger_state_show; - - sysfs_attr_init(&charger->attr_externally_control.attr); - charger->attr_externally_control.attr.name - = "externally_control"; - charger->attr_externally_control.attr.mode = 0644; - charger->attr_externally_control.show - = charger_externally_control_show; - charger->attr_externally_control.store - = charger_externally_control_store; - - if (!desc->charger_regulators[i].externally_control || - !chargers_externally_control) { - chargers_externally_control = 0; - } - dev_info(&pdev->dev, "'%s' regulator's externally_control" - "is %d\n", charger->regulator_name, - charger->externally_control); - - ret = sysfs_create_group(&cm->charger_psy.dev->kobj, - &charger->attr_g); - if (ret < 0) { - dev_info(&pdev->dev, "Cannot create sysfs entry" - "of %s regulator\n", - charger->regulator_name); - } - } - - if (chargers_externally_control) { - dev_err(&pdev->dev, "Cannot register regulator because " - "charger-manager must need at least " - "one charger for charging battery\n"); - - ret = -EINVAL; - goto err_chg_enable; + /* Register extcon device for charger cable */ + ret = charger_manager_register_extcon(cm); + if (ret < 0) { + dev_err(&pdev->dev, "Cannot initialize extcon device\n"); + goto err_reg_extcon; } - ret = try_charger_enable(cm, true); - if (ret) { - dev_err(&pdev->dev, "Cannot enable charger regulators\n"); - goto err_chg_enable; + /* Register sysfs entry for charger(regulator) */ + ret = charger_manager_register_sysfs(cm); + if (ret < 0) { + dev_err(&pdev->dev, + "Cannot initialize sysfs entry of regulator\n"); + goto err_reg_sysfs; } /* Add to the list */ @@ -1619,27 +1673,28 @@ static int charger_manager_probe(struct platform_device *pdev) return 0; -err_chg_enable: +err_reg_sysfs: for (i = 0; i < desc->num_charger_regulators; i++) { struct charger_regulator *charger; charger = &desc->charger_regulators[i]; sysfs_remove_group(&cm->charger_psy.dev->kobj, &charger->attr_g); + kfree(charger->attr_g.name); } -err_extcon: - for (i = 0 ; i < desc->num_charger_regulators ; i++) { - struct charger_regulator *charger - = &desc->charger_regulators[i]; - for (j = 0 ; j < charger->num_cables ; j++) { +err_reg_extcon: + for (i = 0; i < desc->num_charger_regulators; i++) { + struct charger_regulator *charger; + + charger = &desc->charger_regulators[i]; + for (j = 0; j < charger->num_cables; j++) { struct charger_cable *cable = &charger->cables[j]; extcon_unregister_interest(&cable->extcon_dev); } - } -err_chg_get: - for (i = 0 ; i < desc->num_charger_regulators ; i++) + regulator_put(desc->charger_regulators[i].consumer); + } power_supply_unregister(&cm->charger_psy); err_register: @@ -1655,7 +1710,7 @@ err_alloc: return ret; } -static int __devexit charger_manager_remove(struct platform_device *pdev) +static int charger_manager_remove(struct platform_device *pdev) { struct charger_manager *cm = platform_get_drvdata(pdev); struct charger_desc *desc = cm->desc; @@ -1667,10 +1722,8 @@ static int __devexit charger_manager_remove(struct platform_device *pdev) list_del(&cm->entry); mutex_unlock(&cm_list_mtx); - if (work_pending(&setup_polling)) - cancel_work_sync(&setup_polling); - if (delayed_work_pending(&cm_monitor_work)) - cancel_delayed_work_sync(&cm_monitor_work); + cancel_work_sync(&setup_polling); + cancel_delayed_work_sync(&cm_monitor_work); for (i = 0 ; i < desc->num_charger_regulators ; i++) { struct charger_regulator *charger @@ -1739,8 +1792,7 @@ static int cm_suspend_prepare(struct device *dev) cm_suspended = true; } - if (delayed_work_pending(&cm->fullbatt_vchk_work)) - cancel_delayed_work(&cm->fullbatt_vchk_work); + cancel_delayed_work(&cm->fullbatt_vchk_work); cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm); cm->status_save_batt = is_batt_present(cm); @@ -1812,7 +1864,7 @@ static struct platform_driver charger_manager_driver = { .pm = &charger_manager_pm, }, .probe = charger_manager_probe, - .remove = __devexit_p(charger_manager_remove), + .remove = charger_manager_remove, .id_table = charger_manager_id, }; diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index b19bfe400f8c..c58d0e31bdef 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c @@ -305,7 +305,7 @@ static int collie_bat_resume(struct ucb1x00_dev *dev) #define collie_bat_resume NULL #endif -static int __devinit collie_bat_probe(struct ucb1x00_dev *dev) +static int collie_bat_probe(struct ucb1x00_dev *dev) { int ret; @@ -349,7 +349,7 @@ err_psy_reg_main: return ret; } -static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) +static void collie_bat_remove(struct ucb1x00_dev *dev) { free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); @@ -367,7 +367,7 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) static struct ucb1x00_driver collie_bat_driver = { .add = collie_bat_probe, - .remove = __devexit_p(collie_bat_remove), + .remove = collie_bat_remove, .suspend = collie_bat_suspend, .resume = collie_bat_resume, }; diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c index d9d034d7496f..3c5c2e459d73 100644 --- a/drivers/power/da9052-battery.c +++ b/drivers/power/da9052-battery.c @@ -440,8 +440,10 @@ static int da9052_bat_check_health(struct da9052_battery *bat, int *health) static irqreturn_t da9052_bat_irq(int irq, void *data) { struct da9052_battery *bat = data; + int virq; - irq -= bat->da9052->irq_base; + virq = regmap_irq_get_virq(bat->da9052->irq_data, irq); + irq -= virq; if (irq == DA9052_IRQ_CHGEND) bat->status = POWER_SUPPLY_STATUS_FULL; @@ -567,7 +569,7 @@ static struct power_supply template_battery = { .get_property = da9052_bat_get_property, }; -static const char *const da9052_bat_irqs[] = { +static char *da9052_bat_irqs[] = { "BATT TEMP", "DCIN DET", "DCIN REM", @@ -576,12 +578,20 @@ static const char *const da9052_bat_irqs[] = { "CHG END", }; -static s32 __devinit da9052_bat_probe(struct platform_device *pdev) +static int da9052_bat_irq_bits[] = { + DA9052_IRQ_TBAT, + DA9052_IRQ_DCIN, + DA9052_IRQ_DCINREM, + DA9052_IRQ_VBUS, + DA9052_IRQ_VBUSREM, + DA9052_IRQ_CHGEND, +}; + +static s32 da9052_bat_probe(struct platform_device *pdev) { struct da9052_pdata *pdata; struct da9052_battery *bat; int ret; - int irq; int i; bat = kzalloc(sizeof(struct da9052_battery), GFP_KERNEL); @@ -602,15 +612,14 @@ static s32 __devinit da9052_bat_probe(struct platform_device *pdev) bat->psy.use_for_apm = 1; for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) { - irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]); - ret = request_threaded_irq(bat->da9052->irq_base + irq, - NULL, da9052_bat_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - da9052_bat_irqs[i], bat); + ret = da9052_request_irq(bat->da9052, + da9052_bat_irq_bits[i], da9052_bat_irqs[i], + da9052_bat_irq, bat); + if (ret != 0) { dev_err(bat->da9052->dev, - "DA9052 failed to request %s IRQ %d: %d\n", - da9052_bat_irqs[i], irq, ret); + "DA9052 failed to request %s IRQ: %d\n", + da9052_bat_irqs[i], ret); goto err; } } @@ -623,23 +632,20 @@ static s32 __devinit da9052_bat_probe(struct platform_device *pdev) return 0; err: - while (--i >= 0) { - irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]); - free_irq(bat->da9052->irq_base + irq, bat); - } + while (--i >= 0) + da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); + kfree(bat); return ret; } -static int __devexit da9052_bat_remove(struct platform_device *pdev) +static int da9052_bat_remove(struct platform_device *pdev) { int i; - int irq; struct da9052_battery *bat = platform_get_drvdata(pdev); - for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) { - irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]); - free_irq(bat->da9052->irq_base + irq, bat); - } + for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) + da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); + power_supply_unregister(&bat->psy); kfree(bat); @@ -648,7 +654,7 @@ static int __devexit da9052_bat_remove(struct platform_device *pdev) static struct platform_driver da9052_bat_driver = { .probe = da9052_bat_probe, - .remove = __devexit_p(da9052_bat_remove), + .remove = da9052_bat_remove, .driver = { .name = "da9052-bat", .owner = THIS_MODULE, diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index 74fad941c56c..8b6c4539e7f4 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c @@ -755,7 +755,7 @@ static const struct attribute_group ds2780_attr_group = { .attrs = ds2780_attributes, }; -static int __devinit ds2780_battery_probe(struct platform_device *pdev) +static int ds2780_battery_probe(struct platform_device *pdev) { int ret = 0; struct ds2780_device_info *dev_info; @@ -819,7 +819,7 @@ fail: return ret; } -static int __devexit ds2780_battery_remove(struct platform_device *pdev) +static int ds2780_battery_remove(struct platform_device *pdev) { struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); @@ -837,7 +837,7 @@ static struct platform_driver ds2780_battery_driver = { .name = "ds2780-battery", }, .probe = ds2780_battery_probe, - .remove = __devexit_p(ds2780_battery_remove), + .remove = ds2780_battery_remove, }; module_platform_driver(ds2780_battery_driver); diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c index 22b3c8c93552..0a5acc6fc6f0 100644 --- a/drivers/power/ds2781_battery.c +++ b/drivers/power/ds2781_battery.c @@ -750,7 +750,7 @@ static const struct attribute_group ds2781_attr_group = { .attrs = ds2781_attributes, }; -static int __devinit ds2781_battery_probe(struct platform_device *pdev) +static int ds2781_battery_probe(struct platform_device *pdev) { int ret = 0; struct ds2781_device_info *dev_info; @@ -810,7 +810,7 @@ fail: return ret; } -static int __devexit ds2781_battery_remove(struct platform_device *pdev) +static int ds2781_battery_remove(struct platform_device *pdev) { struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); @@ -827,7 +827,7 @@ static struct platform_driver ds2781_battery_driver = { .name = "ds2781-battery", }, .probe = ds2781_battery_probe, - .remove = __devexit_p(ds2781_battery_remove), + .remove = ds2781_battery_remove, }; module_platform_driver(ds2781_battery_driver); diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index ecbf672a35db..32ce17e235c0 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c @@ -236,7 +236,7 @@ static irqreturn_t gab_charged(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit gab_probe(struct platform_device *pdev) +static int gab_probe(struct platform_device *pdev) { struct gab *adc_bat; struct power_supply *psy; @@ -352,7 +352,7 @@ first_mem_fail: return ret; } -static int __devexit gab_remove(struct platform_device *pdev) +static int gab_remove(struct platform_device *pdev) { int chan; struct gab *adc_bat = platform_get_drvdata(pdev); @@ -414,7 +414,7 @@ static struct platform_driver gab_driver = { .pm = GAB_PM_OPS }, .probe = gab_probe, - .remove = __devexit_p(gab_remove), + .remove = gab_remove, }; module_platform_driver(gab_driver); diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index cb2aa3195687..e3e40a9f3af2 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -68,7 +68,7 @@ static enum power_supply_property gpio_charger_properties[] = { POWER_SUPPLY_PROP_ONLINE, }; -static int __devinit gpio_charger_probe(struct platform_device *pdev) +static int gpio_charger_probe(struct platform_device *pdev) { const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; struct gpio_charger *gpio_charger; @@ -144,7 +144,7 @@ err_free: return ret; } -static int __devexit gpio_charger_remove(struct platform_device *pdev) +static int gpio_charger_remove(struct platform_device *pdev) { struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); @@ -177,7 +177,7 @@ static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, NULL, gpio_charger_resume); static struct platform_driver gpio_charger_driver = { .probe = gpio_charger_probe, - .remove = __devexit_p(gpio_charger_remove), + .remove = gpio_charger_remove, .driver = { .name = "gpio-charger", .owner = THIS_MODULE, diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index d09649706bd3..18d136b443ee 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c @@ -649,7 +649,7 @@ static void pmic_battery_handle_intrpt(struct work_struct *work) * PMIC battery initializes its internal data structue and other * infrastructure components for it to work as expected. */ -static __devinit int probe(int irq, struct device *dev) +static int probe(int irq, struct device *dev) { int retval = 0; struct pmic_power_module_info *pbi; @@ -739,7 +739,7 @@ wqueue_failed: return retval; } -static int __devinit platform_pmic_battery_probe(struct platform_device *pdev) +static int platform_pmic_battery_probe(struct platform_device *pdev) { return probe(pdev->id, &pdev->dev); } @@ -754,7 +754,7 @@ static int __devinit platform_pmic_battery_probe(struct platform_device *pdev) * pmic_battery_probe. */ -static int __devexit platform_pmic_battery_remove(struct platform_device *pdev) +static int platform_pmic_battery_remove(struct platform_device *pdev) { struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev); @@ -776,7 +776,7 @@ static struct platform_driver platform_pmic_battery_driver = { .owner = THIS_MODULE, }, .probe = platform_pmic_battery_probe, - .remove = __devexit_p(platform_pmic_battery_remove), + .remove = platform_pmic_battery_remove, }; module_platform_driver(platform_pmic_battery_driver); diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 122911978da2..176ad59d99f5 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -406,7 +406,7 @@ static inline int isp1704_test_ulpi(struct isp1704_charger *isp) return -ENODEV; } -static int __devinit isp1704_charger_probe(struct platform_device *pdev) +static int isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; @@ -484,7 +484,7 @@ fail0: return ret; } -static int __devexit isp1704_charger_remove(struct platform_device *pdev) +static int isp1704_charger_remove(struct platform_device *pdev) { struct isp1704_charger *isp = platform_get_drvdata(pdev); @@ -502,7 +502,7 @@ static struct platform_driver isp1704_charger_driver = { .name = "isp1704_charger", }, .probe = isp1704_charger_probe, - .remove = __devexit_p(isp1704_charger_remove), + .remove = isp1704_charger_remove, }; module_platform_driver(isp1704_charger_driver); diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index fc7550d4d568..bf914893c6fd 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -237,7 +237,7 @@ static void jz_battery_work(struct work_struct *work) schedule_delayed_work(&jz_battery->work, interval); } -static int __devinit jz_battery_probe(struct platform_device *pdev) +static int jz_battery_probe(struct platform_device *pdev) { int ret = 0; struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data; @@ -353,7 +353,7 @@ err: return ret; } -static int __devexit jz_battery_remove(struct platform_device *pdev) +static int jz_battery_remove(struct platform_device *pdev) { struct jz_battery *jz_battery = platform_get_drvdata(pdev); @@ -404,7 +404,7 @@ static const struct dev_pm_ops jz_battery_pm_ops = { static struct platform_driver jz_battery_driver = { .probe = jz_battery_probe, - .remove = __devexit_p(jz_battery_remove), + .remove = jz_battery_remove, .driver = { .name = "jz4740-battery", .owner = THIS_MODULE, diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c index c628224b7f58..4ee71a90e248 100644 --- a/drivers/power/lp8727_charger.c +++ b/drivers/power/lp8727_charger.c @@ -522,7 +522,7 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) return 0; } -static int __devexit lp8727_remove(struct i2c_client *cl) +static int lp8727_remove(struct i2c_client *cl) { struct lp8727_chg *pchg = i2c_get_clientdata(cl); @@ -542,7 +542,7 @@ static struct i2c_driver lp8727_driver = { .name = "lp8727", }, .probe = lp8727_probe, - .remove = __devexit_p(lp8727_remove), + .remove = lp8727_remove, .id_table = lp8727_ids, }; module_i2c_driver(lp8727_driver); diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c index fb592bfbec6e..22b6407c9ca9 100644 --- a/drivers/power/lp8788-charger.c +++ b/drivers/power/lp8788-charger.c @@ -686,7 +686,7 @@ static const struct attribute_group lp8788_attr_group = { .attrs = lp8788_charger_attr, }; -static __devinit int lp8788_charger_probe(struct platform_device *pdev) +static int lp8788_charger_probe(struct platform_device *pdev) { struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); struct lp8788_charger *pchg; @@ -723,7 +723,7 @@ static __devinit int lp8788_charger_probe(struct platform_device *pdev) return 0; } -static int __devexit lp8788_charger_remove(struct platform_device *pdev) +static int lp8788_charger_remove(struct platform_device *pdev) { struct lp8788_charger *pchg = platform_get_drvdata(pdev); @@ -738,7 +738,7 @@ static int __devexit lp8788_charger_remove(struct platform_device *pdev) static struct platform_driver lp8788_charger_driver = { .probe = lp8788_charger_probe, - .remove = __devexit_p(lp8788_charger_remove), + .remove = lp8788_charger_remove, .driver = { .name = LP8788_DEV_CHARGER, .owner = THIS_MODULE, diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c index 58e67830143c..22cfe9cc4727 100644 --- a/drivers/power/max17040_battery.c +++ b/drivers/power/max17040_battery.c @@ -197,7 +197,7 @@ static enum power_supply_property max17040_battery_props[] = { POWER_SUPPLY_PROP_CAPACITY, }; -static int __devinit max17040_probe(struct i2c_client *client, +static int max17040_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); @@ -238,7 +238,7 @@ static int __devinit max17040_probe(struct i2c_client *client, return 0; } -static int __devexit max17040_remove(struct i2c_client *client) +static int max17040_remove(struct i2c_client *client) { struct max17040_chip *chip = i2c_get_clientdata(client); @@ -285,7 +285,7 @@ static struct i2c_driver max17040_i2c_driver = { .name = "max17040", }, .probe = max17040_probe, - .remove = __devexit_p(max17040_remove), + .remove = max17040_remove, .suspend = max17040_suspend, .resume = max17040_resume, .id_table = max17040_id, diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c index 66b2c7b50914..d664ef58afa7 100644 --- a/drivers/power/max17042_battery.c +++ b/drivers/power/max17042_battery.c @@ -682,7 +682,7 @@ max17042_get_pdata(struct device *dev) } #endif -static int __devinit max17042_probe(struct i2c_client *client, +static int max17042_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); @@ -776,7 +776,7 @@ static int __devinit max17042_probe(struct i2c_client *client, return 0; } -static int __devexit max17042_remove(struct i2c_client *client) +static int max17042_remove(struct i2c_client *client) { struct max17042_chip *chip = i2c_get_clientdata(client); @@ -852,7 +852,7 @@ static struct i2c_driver max17042_i2c_driver = { .pm = MAX17042_PM_OPS, }, .probe = max17042_probe, - .remove = __devexit_p(max17042_remove), + .remove = max17042_remove, .id_table = max17042_id, }; module_i2c_driver(max17042_i2c_driver); diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c index 3e23f43e98af..14e2b96d93b0 100644 --- a/drivers/power/max8903_charger.c +++ b/drivers/power/max8903_charger.c @@ -179,7 +179,7 @@ static irqreturn_t max8903_fault(int irq, void *_data) return IRQ_HANDLED; } -static __devinit int max8903_probe(struct platform_device *pdev) +static int max8903_probe(struct platform_device *pdev) { struct max8903_data *data; struct device *dev = &pdev->dev; @@ -345,7 +345,7 @@ err: return ret; } -static __devexit int max8903_remove(struct platform_device *pdev) +static int max8903_remove(struct platform_device *pdev) { struct max8903_data *data = platform_get_drvdata(pdev); @@ -367,7 +367,7 @@ static __devexit int max8903_remove(struct platform_device *pdev) static struct platform_driver max8903_driver = { .probe = max8903_probe, - .remove = __devexit_p(max8903_remove), + .remove = max8903_remove, .driver = { .name = "max8903-charger", .owner = THIS_MODULE, diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c index b5a3ccb16a14..665cdc76c265 100644 --- a/drivers/power/max8925_power.c +++ b/drivers/power/max8925_power.c @@ -357,7 +357,7 @@ do { \ _irq, ret); \ } while (0) -static __devinit int max8925_init_charger(struct max8925_chip *chip, +static int max8925_init_charger(struct max8925_chip *chip, struct max8925_power_info *info) { int ret; @@ -415,7 +415,7 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip, return 0; } -static __devexit int max8925_deinit_charger(struct max8925_power_info *info) +static int max8925_deinit_charger(struct max8925_power_info *info) { struct max8925_chip *chip = info->chip; int irq; @@ -475,7 +475,7 @@ max8925_power_dt_init(struct platform_device *pdev) } #endif -static __devinit int max8925_power_probe(struct platform_device *pdev) +static int max8925_power_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct max8925_power_pdata *pdata = NULL; @@ -550,7 +550,7 @@ out: return ret; } -static __devexit int max8925_power_remove(struct platform_device *pdev) +static int max8925_power_remove(struct platform_device *pdev) { struct max8925_power_info *info = platform_get_drvdata(pdev); @@ -566,7 +566,7 @@ static __devexit int max8925_power_remove(struct platform_device *pdev) static struct platform_driver max8925_power_driver = { .probe = max8925_power_probe, - .remove = __devexit_p(max8925_power_remove), + .remove = max8925_power_remove, .driver = { .name = "max8925-power", }, diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c index 6e88c5d026b9..e757885b620c 100644 --- a/drivers/power/max8997_charger.c +++ b/drivers/power/max8997_charger.c @@ -86,7 +86,7 @@ static int max8997_battery_get_property(struct power_supply *psy, return 0; } -static __devinit int max8997_battery_probe(struct platform_device *pdev) +static int max8997_battery_probe(struct platform_device *pdev) { int ret = 0; struct charger_data *charger; @@ -167,7 +167,7 @@ err: return ret; } -static int __devexit max8997_battery_remove(struct platform_device *pdev) +static int max8997_battery_remove(struct platform_device *pdev) { struct charger_data *charger = platform_get_drvdata(pdev); @@ -187,7 +187,7 @@ static struct platform_driver max8997_battery_driver = { .owner = THIS_MODULE, }, .probe = max8997_battery_probe, - .remove = __devexit_p(max8997_battery_remove), + .remove = max8997_battery_remove, .id_table = max8997_battery_id, }; diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c index 6dc01c255592..bf677e3daec9 100644 --- a/drivers/power/max8998_charger.c +++ b/drivers/power/max8998_charger.c @@ -75,7 +75,7 @@ static int max8998_battery_get_property(struct power_supply *psy, return 0; } -static __devinit int max8998_battery_probe(struct platform_device *pdev) +static int max8998_battery_probe(struct platform_device *pdev) { struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); @@ -178,7 +178,7 @@ err: return ret; } -static int __devexit max8998_battery_remove(struct platform_device *pdev) +static int max8998_battery_remove(struct platform_device *pdev) { struct max8998_battery_data *max8998 = platform_get_drvdata(pdev); @@ -199,7 +199,7 @@ static struct platform_driver max8998_battery_driver = { .owner = THIS_MODULE, }, .probe = max8998_battery_probe, - .remove = __devexit_p(max8998_battery_remove), + .remove = max8998_battery_remove, .id_table = max8998_battery_id, }; diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index a89a41acf9c5..298c47d111b4 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -598,7 +598,7 @@ static int olpc_battery_suspend(struct platform_device *pdev, return 0; } -static int __devinit olpc_battery_probe(struct platform_device *pdev) +static int olpc_battery_probe(struct platform_device *pdev) { int ret; uint8_t status; @@ -659,7 +659,7 @@ battery_failed: return ret; } -static int __devexit olpc_battery_remove(struct platform_device *pdev) +static int olpc_battery_remove(struct platform_device *pdev) { device_remove_file(olpc_bat.dev, &olpc_bat_error); device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); @@ -681,7 +681,7 @@ static struct platform_driver olpc_battery_driver = { .of_match_table = olpc_battery_ids, }, .probe = olpc_battery_probe, - .remove = __devexit_p(olpc_battery_remove), + .remove = olpc_battery_remove, .suspend = olpc_battery_suspend, }; diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 3d1e9efb6f53..c2122a7ad065 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -366,7 +366,7 @@ static const u8 mbc_irq_handlers[] = { PCF50633_IRQ_LOWBAT, }; -static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) +static int pcf50633_mbc_probe(struct platform_device *pdev) { struct pcf50633_mbc *mbc; int ret; @@ -447,7 +447,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) return 0; } -static int __devexit pcf50633_mbc_remove(struct platform_device *pdev) +static int pcf50633_mbc_remove(struct platform_device *pdev) { struct pcf50633_mbc *mbc = platform_get_drvdata(pdev); int i; @@ -471,7 +471,7 @@ static struct platform_driver pcf50633_mbc_driver = { .name = "pcf50633-mbc", }, .probe = pcf50633_mbc_probe, - .remove = __devexit_p(pcf50633_mbc_remove), + .remove = pcf50633_mbc_remove, }; module_platform_driver(pcf50633_mbc_driver); diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index f984da1066ec..8a7cfb3cc166 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy) for (i = 0; i < psy->num_properties; i++) { if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) { psy->tzd = thermal_zone_device_register(psy->name, 0, 0, - psy, &psy_tzd_ops, 0, 0); + psy, &psy_tzd_ops, NULL, 0, 0); if (IS_ERR(psy->tzd)) return PTR_ERR(psy->tzd); break; diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig new file mode 100644 index 000000000000..6461b489fb09 --- /dev/null +++ b/drivers/power/reset/Kconfig @@ -0,0 +1,15 @@ +menuconfig POWER_RESET + bool "Board level reset or power off" + help + Provides a number of drivers which either reset a complete board + or shut it down, by manipulating the main power supply on the board. + + Say Y here to enable board reset and power off + +config POWER_RESET_GPIO + bool "GPIO power-off driver" + depends on OF_GPIO && POWER_RESET + help + This driver supports turning off your board via a GPIO line. + If your board needs a GPIO high/low to power down, say Y and + create a binding in your devicetree. diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile new file mode 100644 index 000000000000..751488a4a0c5 --- /dev/null +++ b/drivers/power/reset/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c new file mode 100644 index 000000000000..0491e5335d02 --- /dev/null +++ b/drivers/power/reset/gpio-poweroff.c @@ -0,0 +1,129 @@ +/* + * Toggles a GPIO pin to power down a device + * + * Jamie Lentin <jm@lentin.co.uk> + * Andrew Lunn <andrew@lunn.ch> + * + * Copyright (C) 2012 Jamie Lentin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/of_platform.h> +#include <linux/of_gpio.h> +#include <linux/module.h> + +/* + * Hold configuration here, cannot be more than one instance of the driver + * since pm_power_off itself is global. + */ +static int gpio_num = -1; +static int gpio_active_low; + +static void gpio_poweroff_do_poweroff(void) +{ + BUG_ON(gpio_num == -1); + + /* drive it active */ + gpio_direction_output(gpio_num, !gpio_active_low); + mdelay(100); + /* rising edge or drive inactive */ + gpio_set_value(gpio_num, gpio_active_low); + mdelay(100); + /* falling edge */ + gpio_set_value(gpio_num, !gpio_active_low); + + /* give it some time */ + mdelay(3000); + + WARN_ON(1); +} + +static int __devinit gpio_poweroff_probe(struct platform_device *pdev) +{ + enum of_gpio_flags flags; + bool input = false; + int ret; + + /* If a pm_power_off function has already been added, leave it alone */ + if (pm_power_off != NULL) { + pr_err("%s: pm_power_off function already registered", + __func__); + return -EBUSY; + } + + gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); + if (gpio_num < 0) { + pr_err("%s: Could not get GPIO configuration: %d", + __func__, gpio_num); + return -ENODEV; + } + gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; + + if (of_get_property(pdev->dev.of_node, "input", NULL)) + input = true; + + ret = gpio_request(gpio_num, "poweroff-gpio"); + if (ret) { + pr_err("%s: Could not get GPIO %d", __func__, gpio_num); + return ret; + } + if (input) { + if (gpio_direction_input(gpio_num)) { + pr_err("Could not set direction of GPIO %d to input", + gpio_num); + goto err; + } + } else { + if (gpio_direction_output(gpio_num, gpio_active_low)) { + pr_err("Could not set direction of GPIO %d", gpio_num); + goto err; + } + } + + pm_power_off = &gpio_poweroff_do_poweroff; + return 0; + +err: + gpio_free(gpio_num); + return -ENODEV; +} + +static int __devexit gpio_poweroff_remove(struct platform_device *pdev) +{ + if (gpio_num != -1) + gpio_free(gpio_num); + if (pm_power_off == &gpio_poweroff_do_poweroff) + pm_power_off = NULL; + + return 0; +} + +static const struct of_device_id of_gpio_poweroff_match[] = { + { .compatible = "gpio-poweroff", }, + {}, +}; + +static struct platform_driver gpio_poweroff_driver = { + .probe = gpio_poweroff_probe, + .remove = __devexit_p(gpio_poweroff_remove), + .driver = { + .name = "poweroff-gpio", + .owner = THIS_MODULE, + .of_match_table = of_gpio_poweroff_match, + }, +}; + +module_platform_driver(gpio_poweroff_driver); + +MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>"); +MODULE_DESCRIPTION("GPIO poweroff driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:poweroff-gpio"); diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index 8b804a566756..d2ca989dcbdc 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c @@ -286,7 +286,7 @@ static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit s3c_adc_bat_probe(struct platform_device *pdev) +static int s3c_adc_bat_probe(struct platform_device *pdev) { struct s3c_adc_client *client; struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c index 4146596d254b..3960f0b2afe9 100644 --- a/drivers/power/sbs-battery.c +++ b/drivers/power/sbs-battery.c @@ -675,7 +675,7 @@ static struct sbs_platform_data *sbs_of_populate_pdata( } #endif -static int __devinit sbs_probe(struct i2c_client *client, +static int sbs_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct sbs_info *chip; @@ -800,7 +800,7 @@ exit_free_name: return rc; } -static int __devexit sbs_remove(struct i2c_client *client) +static int sbs_remove(struct i2c_client *client) { struct sbs_info *chip = i2c_get_clientdata(client); @@ -853,7 +853,7 @@ MODULE_DEVICE_TABLE(i2c, sbs_id); static struct i2c_driver sbs_battery_driver = { .probe = sbs_probe, - .remove = __devexit_p(sbs_remove), + .remove = sbs_remove, .suspend = sbs_suspend, .resume = sbs_resume, .id_table = sbs_id, diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c index a9707c11fbed..acf84e80fe98 100644 --- a/drivers/power/smb347-charger.c +++ b/drivers/power/smb347-charger.c @@ -1313,7 +1313,7 @@ static struct i2c_driver smb347_driver = { .name = "smb347", }, .probe = smb347_probe, - .remove = __devexit_p(smb347_remove), + .remove = smb347_remove, .id_table = smb347_id, }; diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c index 51199b5ce221..0224de50c540 100644 --- a/drivers/power/tosa_battery.c +++ b/drivers/power/tosa_battery.c @@ -342,7 +342,7 @@ static int tosa_bat_resume(struct platform_device *dev) #define tosa_bat_resume NULL #endif -static int __devinit tosa_bat_probe(struct platform_device *dev) +static int tosa_bat_probe(struct platform_device *dev) { int ret; @@ -409,7 +409,7 @@ err_psy_reg_main: return ret; } -static int __devexit tosa_bat_remove(struct platform_device *dev) +static int tosa_bat_remove(struct platform_device *dev) { free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket); free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); @@ -433,7 +433,7 @@ static struct platform_driver tosa_bat_driver = { .driver.name = "wm97xx-battery", .driver.owner = THIS_MODULE, .probe = tosa_bat_probe, - .remove = __devexit_p(tosa_bat_remove), + .remove = tosa_bat_remove, .suspend = tosa_bat_suspend, .resume = tosa_bat_resume, }; diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 6243e6975126..d9cc169f1424 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c @@ -161,7 +161,7 @@ static enum power_supply_property wm831x_backup_props[] = { * Initialisation *********************************************************************/ -static __devinit int wm831x_backup_probe(struct platform_device *pdev) +static int wm831x_backup_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; @@ -207,7 +207,7 @@ err_kmalloc: return ret; } -static __devexit int wm831x_backup_remove(struct platform_device *pdev) +static int wm831x_backup_remove(struct platform_device *pdev) { struct wm831x_backup *devdata = platform_get_drvdata(pdev); @@ -220,7 +220,7 @@ static __devexit int wm831x_backup_remove(struct platform_device *pdev) static struct platform_driver wm831x_backup_driver = { .probe = wm831x_backup_probe, - .remove = __devexit_p(wm831x_backup_remove), + .remove = wm831x_backup_remove, .driver = { .name = "wm831x-backup", }, diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index fc1ad9551182..3bed2f55cf7d 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -489,7 +489,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data) return IRQ_HANDLED; } -static __devinit int wm831x_power_probe(struct platform_device *pdev) +static int wm831x_power_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; @@ -625,7 +625,7 @@ err_kmalloc: return ret; } -static __devexit int wm831x_power_remove(struct platform_device *pdev) +static int wm831x_power_remove(struct platform_device *pdev) { struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); struct wm831x *wm831x = wm831x_power->wm831x; @@ -654,7 +654,7 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev) static struct platform_driver wm831x_power_driver = { .probe = wm831x_power_probe, - .remove = __devexit_p(wm831x_power_remove), + .remove = wm831x_power_remove, .driver = { .name = "wm831x-power", }, diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c index fae04d384657..b3607e2906d2 100644 --- a/drivers/power/wm8350_power.c +++ b/drivers/power/wm8350_power.c @@ -442,7 +442,7 @@ static void free_charger_irq(struct wm8350 *wm8350) wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350); } -static __devinit int wm8350_power_probe(struct platform_device *pdev) +static int wm8350_power_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_power *power = &wm8350->power; @@ -501,7 +501,7 @@ battery_failed: return ret; } -static __devexit int wm8350_power_remove(struct platform_device *pdev) +static int wm8350_power_remove(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_power *power = &wm8350->power; @@ -516,7 +516,7 @@ static __devexit int wm8350_power_remove(struct platform_device *pdev) static struct platform_driver wm8350_power_driver = { .probe = wm8350_power_probe, - .remove = __devexit_p(wm8350_power_remove), + .remove = wm8350_power_remove, .driver = { .name = "wm8350-power", }, diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index e128a813dc24..58f7348e6c22 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -162,7 +162,7 @@ static const struct dev_pm_ops wm97xx_bat_pm_ops = { }; #endif -static int __devinit wm97xx_bat_probe(struct platform_device *dev) +static int wm97xx_bat_probe(struct platform_device *dev) { int ret = 0; int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ @@ -263,7 +263,7 @@ err: return ret; } -static int __devexit wm97xx_bat_remove(struct platform_device *dev) +static int wm97xx_bat_remove(struct platform_device *dev) { struct wm97xx_pdata *wmdata = dev->dev.platform_data; struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; @@ -287,7 +287,7 @@ static struct platform_driver wm97xx_bat_driver = { #endif }, .probe = wm97xx_bat_probe, - .remove = __devexit_p(wm97xx_bat_remove), + .remove = wm97xx_bat_remove, }; module_platform_driver(wm97xx_bat_driver); diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c index 5757d0d6782f..814d2e31f0c9 100644 --- a/drivers/power/z2_battery.c +++ b/drivers/power/z2_battery.c @@ -180,7 +180,7 @@ static int z2_batt_ps_init(struct z2_charger *charger, int props) return 0; } -static int __devinit z2_batt_probe(struct i2c_client *client, +static int z2_batt_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; @@ -251,7 +251,7 @@ err: return ret; } -static int __devexit z2_batt_remove(struct i2c_client *client) +static int z2_batt_remove(struct i2c_client *client) { struct z2_charger *charger = i2c_get_clientdata(client); struct z2_battery_info *info = charger->info; @@ -313,7 +313,7 @@ static struct i2c_driver z2_batt_driver = { .pm = Z2_BATTERY_PM_OPS }, .probe = z2_batt_probe, - .remove = __devexit_p(z2_batt_remove), + .remove = z2_batt_remove, .id_table = z2_batt_id, }; module_i2c_driver(z2_batt_driver); |