linux/drivers/power/charger-manager.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
   3 * MyungJoo Ham <myungjoo.ham@samsung.com>
   4 *
   5 * This driver enables to monitor battery health and control charger
   6 * during suspend-to-mem.
   7 * Charger manager depends on other devices. register this later than
   8 * the depending devices.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13**/
  14
  15#include <linux/io.h>
  16#include <linux/module.h>
  17#include <linux/irq.h>
  18#include <linux/interrupt.h>
  19#include <linux/rtc.h>
  20#include <linux/slab.h>
  21#include <linux/workqueue.h>
  22#include <linux/platform_device.h>
  23#include <linux/power/charger-manager.h>
  24#include <linux/regulator/consumer.h>
  25
  26static const char * const default_event_names[] = {
  27        [CM_EVENT_UNKNOWN] = "Unknown",
  28        [CM_EVENT_BATT_FULL] = "Battery Full",
  29        [CM_EVENT_BATT_IN] = "Battery Inserted",
  30        [CM_EVENT_BATT_OUT] = "Battery Pulled Out",
  31        [CM_EVENT_EXT_PWR_IN_OUT] = "External Power Attach/Detach",
  32        [CM_EVENT_CHG_START_STOP] = "Charging Start/Stop",
  33        [CM_EVENT_OTHERS] = "Other battery events"
  34};
  35
  36/*
  37 * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for
  38 * delayed works so that we can run delayed works with CM_JIFFIES_SMALL
  39 * without any delays.
  40 */
  41#define CM_JIFFIES_SMALL        (2)
  42
  43/* If y is valid (> 0) and smaller than x, do x = y */
  44#define CM_MIN_VALID(x, y)      x = (((y > 0) && ((x) > (y))) ? (y) : (x))
  45
  46/*
  47 * Regard CM_RTC_SMALL (sec) is small enough to ignore error in invoking
  48 * rtc alarm. It should be 2 or larger
  49 */
  50#define CM_RTC_SMALL            (2)
  51
  52#define UEVENT_BUF_SIZE         32
  53
  54static LIST_HEAD(cm_list);
  55static DEFINE_MUTEX(cm_list_mtx);
  56
  57/* About in-suspend (suspend-again) monitoring */
  58static struct rtc_device *rtc_dev;
  59/*
  60 * Backup RTC alarm
  61 * Save the wakeup alarm before entering suspend-to-RAM
  62 */
  63static struct rtc_wkalrm rtc_wkalarm_save;
  64/* Backup RTC alarm time in terms of seconds since 01-01-1970 00:00:00 */
  65static unsigned long rtc_wkalarm_save_time;
  66static bool cm_suspended;
  67static bool cm_rtc_set;
  68static unsigned long cm_suspend_duration_ms;
  69
  70/* About normal (not suspended) monitoring */
  71static unsigned long polling_jiffy = ULONG_MAX; /* ULONG_MAX: no polling */
  72static unsigned long next_polling; /* Next appointed polling time */
  73static struct workqueue_struct *cm_wq; /* init at driver add */
  74static struct delayed_work cm_monitor_work; /* init at driver add */
  75
  76/* Global charger-manager description */
  77static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
  78
  79/**
  80 * is_batt_present - See if the battery presents in place.
  81 * @cm: the Charger Manager representing the battery.
  82 */
  83static bool is_batt_present(struct charger_manager *cm)
  84{
  85        union power_supply_propval val;
  86        bool present = false;
  87        int i, ret;
  88
  89        switch (cm->desc->battery_present) {
  90        case CM_BATTERY_PRESENT:
  91                present = true;
  92                break;
  93        case CM_NO_BATTERY:
  94                break;
  95        case CM_FUEL_GAUGE:
  96                ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  97                                POWER_SUPPLY_PROP_PRESENT, &val);
  98                if (ret == 0 && val.intval)
  99                        present = true;
 100                break;
 101        case CM_CHARGER_STAT:
 102                for (i = 0; cm->charger_stat[i]; i++) {
 103                        ret = cm->charger_stat[i]->get_property(
 104                                        cm->charger_stat[i],
 105                                        POWER_SUPPLY_PROP_PRESENT, &val);
 106                        if (ret == 0 && val.intval) {
 107                                present = true;
 108                                break;
 109                        }
 110                }
 111                break;
 112        }
 113
 114        return present;
 115}
 116
 117/**
 118 * is_ext_pwr_online - See if an external power source is attached to charge
 119 * @cm: the Charger Manager representing the battery.
 120 *
 121 * Returns true if at least one of the chargers of the battery has an external
 122 * power source attached to charge the battery regardless of whether it is
 123 * actually charging or not.
 124 */
 125static bool is_ext_pwr_online(struct charger_manager *cm)
 126{
 127        union power_supply_propval val;
 128        bool online = false;
 129        int i, ret;
 130
 131        /* If at least one of them has one, it's yes. */
 132        for (i = 0; cm->charger_stat[i]; i++) {
 133                ret = cm->charger_stat[i]->get_property(
 134                                cm->charger_stat[i],
 135                                POWER_SUPPLY_PROP_ONLINE, &val);
 136                if (ret == 0 && val.intval) {
 137                        online = true;
 138                        break;
 139                }
 140        }
 141
 142        return online;
 143}
 144
 145/**
 146 * get_batt_uV - Get the voltage level of the battery
 147 * @cm: the Charger Manager representing the battery.
 148 * @uV: the voltage level returned.
 149 *
 150 * Returns 0 if there is no error.
 151 * Returns a negative value on error.
 152 */
 153static int get_batt_uV(struct charger_manager *cm, int *uV)
 154{
 155        union power_supply_propval val;
 156        int ret;
 157
 158        if (!cm->fuel_gauge)
 159                return -ENODEV;
 160
 161        ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
 162                                POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
 163        if (ret)
 164                return ret;
 165
 166        *uV = val.intval;
 167        return 0;
 168}
 169
 170/**
 171 * is_charging - Returns true if the battery is being charged.
 172 * @cm: the Charger Manager representing the battery.
 173 */
 174static bool is_charging(struct charger_manager *cm)
 175{
 176        int i, ret;
 177        bool charging = false;
 178        union power_supply_propval val;
 179
 180        /* If there is no battery, it cannot be charged */
 181        if (!is_batt_present(cm))
 182                return false;
 183
 184        /* If at least one of the charger is charging, return yes */
 185        for (i = 0; cm->charger_stat[i]; i++) {
 186                /* 1. The charger sholuld not be DISABLED */
 187                if (cm->emergency_stop)
 188                        continue;
 189                if (!cm->charger_enabled)
 190                        continue;
 191
 192                /* 2. The charger should be online (ext-power) */
 193                ret = cm->charger_stat[i]->get_property(
 194                                cm->charger_stat[i],
 195                                POWER_SUPPLY_PROP_ONLINE, &val);
 196                if (ret) {
 197                        dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n",
 198                                        cm->desc->psy_charger_stat[i]);
 199                        continue;
 200                }
 201                if (val.intval == 0)
 202                        continue;
 203
 204                /*
 205                 * 3. The charger should not be FULL, DISCHARGING,
 206                 * or NOT_CHARGING.
 207                 */
 208                ret = cm->charger_stat[i]->get_property(
 209                                cm->charger_stat[i],
 210                                POWER_SUPPLY_PROP_STATUS, &val);
 211                if (ret) {
 212                        dev_warn(cm->dev, "Cannot read STATUS value from %s.\n",
 213                                        cm->desc->psy_charger_stat[i]);
 214                        continue;
 215                }
 216                if (val.intval == POWER_SUPPLY_STATUS_FULL ||
 217                                val.intval == POWER_SUPPLY_STATUS_DISCHARGING ||
 218                                val.intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
 219                        continue;
 220
 221                /* Then, this is charging. */
 222                charging = true;
 223                break;
 224        }
 225
 226        return charging;
 227}
 228
 229/**
 230 * is_polling_required - Return true if need to continue polling for this CM.
 231 * @cm: the Charger Manager representing the battery.
 232 */
 233static bool is_polling_required(struct charger_manager *cm)
 234{
 235        switch (cm->desc->polling_mode) {
 236        case CM_POLL_DISABLE:
 237                return false;
 238        case CM_POLL_ALWAYS:
 239                return true;
 240        case CM_POLL_EXTERNAL_POWER_ONLY:
 241                return is_ext_pwr_online(cm);
 242        case CM_POLL_CHARGING_ONLY:
 243                return is_charging(cm);
 244        default:
 245                dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
 246                        cm->desc->polling_mode);
 247        }
 248
 249        return false;
 250}
 251
 252/**
 253 * try_charger_enable - Enable/Disable chargers altogether
 254 * @cm: the Charger Manager representing the battery.
 255 * @enable: true: enable / false: disable
 256 *
 257 * Note that Charger Manager keeps the charger enabled regardless whether
 258 * the charger is charging or not (because battery is full or no external
 259 * power source exists) except when CM needs to disable chargers forcibly
 260 * bacause of emergency causes; when the battery is overheated or too cold.
 261 */
 262static int try_charger_enable(struct charger_manager *cm, bool enable)
 263{
 264        int err = 0, i;
 265        struct charger_desc *desc = cm->desc;
 266
 267        /* Ignore if it's redundent command */
 268        if (enable == cm->charger_enabled)
 269                return 0;
 270
 271        if (enable) {
 272                if (cm->emergency_stop)
 273                        return -EAGAIN;
 274                for (i = 0 ; i < desc->num_charger_regulators ; i++)
 275                        regulator_enable(desc->charger_regulators[i].consumer);
 276        } else {
 277                /*
 278                 * Abnormal battery state - Stop charging forcibly,
 279                 * even if charger was enabled at the other places
 280                 */
 281                for (i = 0; i < desc->num_charger_regulators; i++) {
 282                        if (regulator_is_enabled(
 283                                    desc->charger_regulators[i].consumer)) {
 284                                regulator_force_disable(
 285                                        desc->charger_regulators[i].consumer);
 286                                dev_warn(cm->dev,
 287                                        "Disable regulator(%s) forcibly.\n",
 288                                        desc->charger_regulators[i].regulator_name);
 289                        }
 290                }
 291        }
 292
 293        if (!err)
 294                cm->charger_enabled = enable;
 295
 296        return err;
 297}
 298
 299/**
 300 * try_charger_restart - Restart charging.
 301 * @cm: the Charger Manager representing the battery.
 302 *
 303 * Restart charging by turning off and on the charger.
 304 */
 305static int try_charger_restart(struct charger_manager *cm)
 306{
 307        int err;
 308
 309        if (cm->emergency_stop)
 310                return -EAGAIN;
 311
 312        err = try_charger_enable(cm, false);
 313        if (err)
 314                return err;
 315
 316        return try_charger_enable(cm, true);
 317}
 318
 319/**
 320 * uevent_notify - Let users know something has changed.
 321 * @cm: the Charger Manager representing the battery.
 322 * @event: the event string.
 323 *
 324 * If @event is null, it implies that uevent_notify is called
 325 * by resume function. When called in the resume function, cm_suspended
 326 * should be already reset to false in order to let uevent_notify
 327 * notify the recent event during the suspend to users. While
 328 * suspended, uevent_notify does not notify users, but tracks
 329 * events so that uevent_notify can notify users later after resumed.
 330 */
 331static void uevent_notify(struct charger_manager *cm, const char *event)
 332{
 333        static char env_str[UEVENT_BUF_SIZE + 1] = "";
 334        static char env_str_save[UEVENT_BUF_SIZE + 1] = "";
 335
 336        if (cm_suspended) {
 337                /* Nothing in suspended-event buffer */
 338                if (env_str_save[0] == 0) {
 339                        if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
 340                                return; /* status not changed */
 341                        strncpy(env_str_save, event, UEVENT_BUF_SIZE);
 342                        return;
 343                }
 344
 345                if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
 346                        return; /* Duplicated. */
 347                strncpy(env_str_save, event, UEVENT_BUF_SIZE);
 348                return;
 349        }
 350
 351        if (event == NULL) {
 352                /* No messages pending */
 353                if (!env_str_save[0])
 354                        return;
 355
 356                strncpy(env_str, env_str_save, UEVENT_BUF_SIZE);
 357                kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
 358                env_str_save[0] = 0;
 359
 360                return;
 361        }
 362
 363        /* status not changed */
 364        if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
 365                return;
 366
 367        /* save the status and notify the update */
 368        strncpy(env_str, event, UEVENT_BUF_SIZE);
 369        kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
 370
 371        dev_info(cm->dev, event);
 372}
 373
 374/**
 375 * fullbatt_vchk - Check voltage drop some times after "FULL" event.
 376 * @work: the work_struct appointing the function
 377 *
 378 * If a user has designated "fullbatt_vchkdrop_ms/uV" values with
 379 * charger_desc, Charger Manager checks voltage drop after the battery
 380 * "FULL" event. It checks whether the voltage has dropped more than
 381 * fullbatt_vchkdrop_uV by calling this function after fullbatt_vchkrop_ms.
 382 */
 383static void fullbatt_vchk(struct work_struct *work)
 384{
 385        struct delayed_work *dwork = to_delayed_work(work);
 386        struct charger_manager *cm = container_of(dwork,
 387                        struct charger_manager, fullbatt_vchk_work);
 388        struct charger_desc *desc = cm->desc;
 389        int batt_uV, err, diff;
 390
 391        /* remove the appointment for fullbatt_vchk */
 392        cm->fullbatt_vchk_jiffies_at = 0;
 393
 394        if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
 395                return;
 396
 397        err = get_batt_uV(cm, &batt_uV);
 398        if (err) {
 399                dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err);
 400                return;
 401        }
 402
 403        diff = cm->fullbatt_vchk_uV;
 404        diff -= batt_uV;
 405
 406        dev_dbg(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
 407
 408        if (diff > desc->fullbatt_vchkdrop_uV) {
 409                try_charger_restart(cm);
 410                uevent_notify(cm, "Recharge");
 411        }
 412}
 413
 414/**
 415 * _cm_monitor - Monitor the temperature and return true for exceptions.
 416 * @cm: the Charger Manager representing the battery.
 417 *
 418 * Returns true if there is an event to notify for the battery.
 419 * (True if the status of "emergency_stop" changes)
 420 */
 421static bool _cm_monitor(struct charger_manager *cm)
 422{
 423        struct charger_desc *desc = cm->desc;
 424        int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
 425
 426        dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
 427                cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
 428
 429        /* It has been stopped or charging already */
 430        if (!!temp == !!cm->emergency_stop)
 431                return false;
 432
 433        if (temp) {
 434                cm->emergency_stop = temp;
 435                if (!try_charger_enable(cm, false)) {
 436                        if (temp > 0)
 437                                uevent_notify(cm, "OVERHEAT");
 438                        else
 439                                uevent_notify(cm, "COLD");
 440                }
 441        } else {
 442                cm->emergency_stop = 0;
 443                if (!try_charger_enable(cm, true))
 444                        uevent_notify(cm, "CHARGING");
 445        }
 446
 447        return true;
 448}
 449
 450/**
 451 * cm_monitor - Monitor every battery.
 452 *
 453 * Returns true if there is an event to notify from any of the batteries.
 454 * (True if the status of "emergency_stop" changes)
 455 */
 456static bool cm_monitor(void)
 457{
 458        bool stop = false;
 459        struct charger_manager *cm;
 460
 461        mutex_lock(&cm_list_mtx);
 462
 463        list_for_each_entry(cm, &cm_list, entry) {
 464                if (_cm_monitor(cm))
 465                        stop = true;
 466        }
 467
 468        mutex_unlock(&cm_list_mtx);
 469
 470        return stop;
 471}
 472
 473/**
 474 * _setup_polling - Setup the next instance of polling.
 475 * @work: work_struct of the function _setup_polling.
 476 */
 477static void _setup_polling(struct work_struct *work)
 478{
 479        unsigned long min = ULONG_MAX;
 480        struct charger_manager *cm;
 481        bool keep_polling = false;
 482        unsigned long _next_polling;
 483
 484        mutex_lock(&cm_list_mtx);
 485
 486        list_for_each_entry(cm, &cm_list, entry) {
 487                if (is_polling_required(cm) && cm->desc->polling_interval_ms) {
 488                        keep_polling = true;
 489
 490                        if (min > cm->desc->polling_interval_ms)
 491                                min = cm->desc->polling_interval_ms;
 492                }
 493        }
 494
 495        polling_jiffy = msecs_to_jiffies(min);
 496        if (polling_jiffy <= CM_JIFFIES_SMALL)
 497                polling_jiffy = CM_JIFFIES_SMALL + 1;
 498
 499        if (!keep_polling)
 500                polling_jiffy = ULONG_MAX;
 501        if (polling_jiffy == ULONG_MAX)
 502                goto out;
 503
 504        WARN(cm_wq == NULL, "charger-manager: workqueue not initialized"
 505                            ". try it later. %s\n", __func__);
 506
 507        _next_polling = jiffies + polling_jiffy;
 508
 509        if (!delayed_work_pending(&cm_monitor_work) ||
 510            (delayed_work_pending(&cm_monitor_work) &&
 511             time_after(next_polling, _next_polling))) {
 512                cancel_delayed_work_sync(&cm_monitor_work);
 513                next_polling = jiffies + polling_jiffy;
 514                queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy);
 515        }
 516
 517out:
 518        mutex_unlock(&cm_list_mtx);
 519}
 520static DECLARE_WORK(setup_polling, _setup_polling);
 521
 522/**
 523 * cm_monitor_poller - The Monitor / Poller.
 524 * @work: work_struct of the function cm_monitor_poller
 525 *
 526 * During non-suspended state, cm_monitor_poller is used to poll and monitor
 527 * the batteries.
 528 */
 529static void cm_monitor_poller(struct work_struct *work)
 530{
 531        cm_monitor();
 532        schedule_work(&setup_polling);
 533}
 534
 535/**
 536 * fullbatt_handler - Event handler for CM_EVENT_BATT_FULL
 537 * @cm: the Charger Manager representing the battery.
 538 */
 539static void fullbatt_handler(struct charger_manager *cm)
 540{
 541        struct charger_desc *desc = cm->desc;
 542
 543        if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
 544                goto out;
 545
 546        if (cm_suspended)
 547                device_set_wakeup_capable(cm->dev, true);
 548
 549        if (delayed_work_pending(&cm->fullbatt_vchk_work))
 550                cancel_delayed_work(&cm->fullbatt_vchk_work);
 551        queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
 552                           msecs_to_jiffies(desc->fullbatt_vchkdrop_ms));
 553        cm->fullbatt_vchk_jiffies_at = jiffies + msecs_to_jiffies(
 554                                       desc->fullbatt_vchkdrop_ms);
 555
 556        if (cm->fullbatt_vchk_jiffies_at == 0)
 557                cm->fullbatt_vchk_jiffies_at = 1;
 558
 559out:
 560        dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
 561        uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
 562}
 563
 564/**
 565 * battout_handler - Event handler for CM_EVENT_BATT_OUT
 566 * @cm: the Charger Manager representing the battery.
 567 */
 568static void battout_handler(struct charger_manager *cm)
 569{
 570        if (cm_suspended)
 571                device_set_wakeup_capable(cm->dev, true);
 572
 573        if (!is_batt_present(cm)) {
 574                dev_emerg(cm->dev, "Battery Pulled Out!\n");
 575                uevent_notify(cm, default_event_names[CM_EVENT_BATT_OUT]);
 576        } else {
 577                uevent_notify(cm, "Battery Reinserted?");
 578        }
 579}
 580
 581/**
 582 * misc_event_handler - Handler for other evnets
 583 * @cm: the Charger Manager representing the battery.
 584 * @type: the Charger Manager representing the battery.
 585 */
 586static void misc_event_handler(struct charger_manager *cm,
 587                        enum cm_event_types type)
 588{
 589        if (cm_suspended)
 590                device_set_wakeup_capable(cm->dev, true);
 591
 592        if (!delayed_work_pending(&cm_monitor_work) &&
 593            is_polling_required(cm) && cm->desc->polling_interval_ms)
 594                schedule_work(&setup_polling);
 595        uevent_notify(cm, default_event_names[type]);
 596}
 597
 598static int charger_get_property(struct power_supply *psy,
 599                enum power_supply_property psp,
 600                union power_supply_propval *val)
 601{
 602        struct charger_manager *cm = container_of(psy,
 603                        struct charger_manager, charger_psy);
 604        struct charger_desc *desc = cm->desc;
 605        int ret = 0;
 606        int uV;
 607
 608        switch (psp) {
 609        case POWER_SUPPLY_PROP_STATUS:
 610                if (is_charging(cm))
 611                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
 612                else if (is_ext_pwr_online(cm))
 613                        val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
 614                else
 615                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 616                break;
 617        case POWER_SUPPLY_PROP_HEALTH:
 618                if (cm->emergency_stop > 0)
 619                        val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
 620                else if (cm->emergency_stop < 0)
 621                        val->intval = POWER_SUPPLY_HEALTH_COLD;
 622                else
 623                        val->intval = POWER_SUPPLY_HEALTH_GOOD;
 624                break;
 625        case POWER_SUPPLY_PROP_PRESENT:
 626                if (is_batt_present(cm))
 627                        val->intval = 1;
 628                else
 629                        val->intval = 0;
 630                break;
 631        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 632                ret = get_batt_uV(cm, &val->intval);
 633                break;
 634        case POWER_SUPPLY_PROP_CURRENT_NOW:
 635                ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
 636                                POWER_SUPPLY_PROP_CURRENT_NOW, val);
 637                break;
 638        case POWER_SUPPLY_PROP_TEMP:
 639                /* in thenth of centigrade */
 640                if (cm->last_temp_mC == INT_MIN)
 641                        desc->temperature_out_of_range(&cm->last_temp_mC);
 642                val->intval = cm->last_temp_mC / 100;
 643                if (!desc->measure_battery_temp)
 644                        ret = -ENODEV;
 645                break;
 646        case POWER_SUPPLY_PROP_TEMP_AMBIENT:
 647                /* in thenth of centigrade */
 648                if (cm->last_temp_mC == INT_MIN)
 649                        desc->temperature_out_of_range(&cm->last_temp_mC);
 650                val->intval = cm->last_temp_mC / 100;
 651                if (desc->measure_battery_temp)
 652                        ret = -ENODEV;
 653                break;
 654        case POWER_SUPPLY_PROP_CAPACITY:
 655                if (!cm->fuel_gauge) {
 656                        ret = -ENODEV;
 657                        break;
 658                }
 659
 660                if (!is_batt_present(cm)) {
 661                        /* There is no battery. Assume 100% */
 662                        val->intval = 100;
 663                        break;
 664                }
 665
 666                ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
 667                                        POWER_SUPPLY_PROP_CAPACITY, val);
 668                if (ret)
 669                        break;
 670
 671                if (val->intval > 100) {
 672                        val->intval = 100;
 673                        break;
 674                }
 675                if (val->intval < 0)
 676                        val->intval = 0;
 677
 678                /* Do not adjust SOC when charging: voltage is overrated */
 679                if (is_charging(cm))
 680                        break;
 681
 682                /*
 683                 * If the capacity value is inconsistent, calibrate it base on
 684                 * the battery voltage values and the thresholds given as desc
 685                 */
 686                ret = get_batt_uV(cm, &uV);
 687                if (ret) {
 688                        /* Voltage information not available. No calibration */
 689                        ret = 0;
 690                        break;
 691                }
 692
 693                if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
 694                    !is_charging(cm)) {
 695                        val->intval = 100;
 696                        break;
 697                }
 698
 699                break;
 700        case POWER_SUPPLY_PROP_ONLINE:
 701                if (is_ext_pwr_online(cm))
 702                        val->intval = 1;
 703                else
 704                        val->intval = 0;
 705                break;
 706        case POWER_SUPPLY_PROP_CHARGE_FULL:
 707                if (cm->fuel_gauge) {
 708                        if (cm->fuel_gauge->get_property(cm->fuel_gauge,
 709                            POWER_SUPPLY_PROP_CHARGE_FULL, val) == 0)
 710                                break;
 711                }
 712
 713                if (is_ext_pwr_online(cm)) {
 714                        /* Not full if it's charging. */
 715                        if (is_charging(cm)) {
 716                                val->intval = 0;
 717                                break;
 718                        }
 719                        /*
 720                         * Full if it's powered but not charging andi
 721                         * not forced stop by emergency
 722                         */
 723                        if (!cm->emergency_stop) {
 724                                val->intval = 1;
 725                                break;
 726                        }
 727                }
 728
 729                /* Full if it's over the fullbatt voltage */
 730                ret = get_batt_uV(cm, &uV);
 731                if (!ret && desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
 732                    !is_charging(cm)) {
 733                        val->intval = 1;
 734                        break;
 735                }
 736
 737                /* Full if the cap is 100 */
 738                if (cm->fuel_gauge) {
 739                        ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
 740                                        POWER_SUPPLY_PROP_CAPACITY, val);
 741                        if (!ret && val->intval >= 100 && !is_charging(cm)) {
 742                                val->intval = 1;
 743                                break;
 744                        }
 745                }
 746
 747                val->intval = 0;
 748                ret = 0;
 749                break;
 750        case POWER_SUPPLY_PROP_CHARGE_NOW:
 751                if (is_charging(cm)) {
 752                        ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
 753                                                POWER_SUPPLY_PROP_CHARGE_NOW,
 754                                                val);
 755                        if (ret) {
 756                                val->intval = 1;
 757                                ret = 0;
 758                        } else {
 759                                /* If CHARGE_NOW is supplied, use it */
 760                                val->intval = (val->intval > 0) ?
 761                                                val->intval : 1;
 762                        }
 763                } else {
 764                        val->intval = 0;
 765                }
 766                break;
 767        default:
 768                return -EINVAL;
 769        }
 770        return ret;
 771}
 772
 773#define NUM_CHARGER_PSY_OPTIONAL        (4)
 774static enum power_supply_property default_charger_props[] = {
 775        /* Guaranteed to provide */
 776        POWER_SUPPLY_PROP_STATUS,
 777        POWER_SUPPLY_PROP_HEALTH,
 778        POWER_SUPPLY_PROP_PRESENT,
 779        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 780        POWER_SUPPLY_PROP_CAPACITY,
 781        POWER_SUPPLY_PROP_ONLINE,
 782        POWER_SUPPLY_PROP_CHARGE_FULL,
 783        /*
 784         * Optional properties are:
 785         * POWER_SUPPLY_PROP_CHARGE_NOW,
 786         * POWER_SUPPLY_PROP_CURRENT_NOW,
 787         * POWER_SUPPLY_PROP_TEMP, and
 788         * POWER_SUPPLY_PROP_TEMP_AMBIENT,
 789         */
 790};
 791
 792static struct power_supply psy_default = {
 793        .name = "battery",
 794        .type = POWER_SUPPLY_TYPE_BATTERY,
 795        .properties = default_charger_props,
 796        .num_properties = ARRAY_SIZE(default_charger_props),
 797        .get_property = charger_get_property,
 798};
 799
 800/**
 801 * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
 802 *                  for suspend_again.
 803 *
 804 * Returns true if the alarm is set for Charger Manager to use.
 805 * Returns false if
 806 *      cm_setup_timer fails to set an alarm,
 807 *      cm_setup_timer does not need to set an alarm for Charger Manager,
 808 *      or an alarm previously configured is to be used.
 809 */
 810static bool cm_setup_timer(void)
 811{
 812        struct charger_manager *cm;
 813        unsigned int wakeup_ms = UINT_MAX;
 814        bool ret = false;
 815
 816        mutex_lock(&cm_list_mtx);
 817
 818        list_for_each_entry(cm, &cm_list, entry) {
 819                unsigned int fbchk_ms = 0;
 820
 821                /* fullbatt_vchk is required. setup timer for that */
 822                if (cm->fullbatt_vchk_jiffies_at) {
 823                        fbchk_ms = jiffies_to_msecs(cm->fullbatt_vchk_jiffies_at
 824                                                    - jiffies);
 825                        if (time_is_before_eq_jiffies(
 826                                cm->fullbatt_vchk_jiffies_at) ||
 827                                msecs_to_jiffies(fbchk_ms) < CM_JIFFIES_SMALL) {
 828                                fullbatt_vchk(&cm->fullbatt_vchk_work.work);
 829                                fbchk_ms = 0;
 830                        }
 831                }
 832                CM_MIN_VALID(wakeup_ms, fbchk_ms);
 833
 834                /* Skip if polling is not required for this CM */
 835                if (!is_polling_required(cm) && !cm->emergency_stop)
 836                        continue;
 837                if (cm->desc->polling_interval_ms == 0)
 838                        continue;
 839                CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms);
 840        }
 841
 842        mutex_unlock(&cm_list_mtx);
 843
 844        if (wakeup_ms < UINT_MAX && wakeup_ms > 0) {
 845                pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms);
 846                if (rtc_dev) {
 847                        struct rtc_wkalrm tmp;
 848                        unsigned long time, now;
 849                        unsigned long add = DIV_ROUND_UP(wakeup_ms, 1000);
 850
 851                        /*
 852                         * Set alarm with the polling interval (wakeup_ms)
 853                         * except when rtc_wkalarm_save comes first.
 854                         * However, the alarm time should be NOW +
 855                         * CM_RTC_SMALL or later.
 856                         */
 857                        tmp.enabled = 1;
 858                        rtc_read_time(rtc_dev, &tmp.time);
 859                        rtc_tm_to_time(&tmp.time, &now);
 860                        if (add < CM_RTC_SMALL)
 861                                add = CM_RTC_SMALL;
 862                        time = now + add;
 863
 864                        ret = true;
 865
 866                        if (rtc_wkalarm_save.enabled &&
 867                            rtc_wkalarm_save_time &&
 868                            rtc_wkalarm_save_time < time) {
 869                                if (rtc_wkalarm_save_time < now + CM_RTC_SMALL)
 870                                        time = now + CM_RTC_SMALL;
 871                                else
 872                                        time = rtc_wkalarm_save_time;
 873
 874                                /* The timer is not appointed by CM */
 875                                ret = false;
 876                        }
 877
 878                        pr_info("Waking up after %lu secs.\n",
 879                                        time - now);
 880
 881                        rtc_time_to_tm(time, &tmp.time);
 882                        rtc_set_alarm(rtc_dev, &tmp);
 883                        cm_suspend_duration_ms += wakeup_ms;
 884                        return ret;
 885                }
 886        }
 887
 888        if (rtc_dev)
 889                rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
 890        return false;
 891}
 892
 893static void _cm_fbchk_in_suspend(struct charger_manager *cm)
 894{
 895        unsigned long jiffy_now = jiffies;
 896
 897        if (!cm->fullbatt_vchk_jiffies_at)
 898                return;
 899
 900        if (g_desc && g_desc->assume_timer_stops_in_suspend)
 901                jiffy_now += msecs_to_jiffies(cm_suspend_duration_ms);
 902
 903        /* Execute now if it's going to be executed not too long after */
 904        jiffy_now += CM_JIFFIES_SMALL;
 905
 906        if (time_after_eq(jiffy_now, cm->fullbatt_vchk_jiffies_at))
 907                fullbatt_vchk(&cm->fullbatt_vchk_work.work);
 908}
 909
 910/**
 911 * cm_suspend_again - Determine whether suspend again or not
 912 *
 913 * Returns true if the system should be suspended again
 914 * Returns false if the system should be woken up
 915 */
 916bool cm_suspend_again(void)
 917{
 918        struct charger_manager *cm;
 919        bool ret = false;
 920
 921        if (!g_desc || !g_desc->rtc_only_wakeup || !g_desc->rtc_only_wakeup() ||
 922            !cm_rtc_set)
 923                return false;
 924
 925        if (cm_monitor())
 926                goto out;
 927
 928        ret = true;
 929        mutex_lock(&cm_list_mtx);
 930        list_for_each_entry(cm, &cm_list, entry) {
 931                _cm_fbchk_in_suspend(cm);
 932
 933                if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
 934                    cm->status_save_batt != is_batt_present(cm)) {
 935                        ret = false;
 936                        break;
 937                }
 938        }
 939        mutex_unlock(&cm_list_mtx);
 940
 941        cm_rtc_set = cm_setup_timer();
 942out:
 943        /* It's about the time when the non-CM appointed timer goes off */
 944        if (rtc_wkalarm_save.enabled) {
 945                unsigned long now;
 946                struct rtc_time tmp;
 947
 948                rtc_read_time(rtc_dev, &tmp);
 949                rtc_tm_to_time(&tmp, &now);
 950
 951                if (rtc_wkalarm_save_time &&
 952                    now + CM_RTC_SMALL >= rtc_wkalarm_save_time)
 953                        return false;
 954        }
 955        return ret;
 956}
 957EXPORT_SYMBOL_GPL(cm_suspend_again);
 958
 959/**
 960 * setup_charger_manager - initialize charger_global_desc data
 961 * @gd: pointer to instance of charger_global_desc
 962 */
 963int setup_charger_manager(struct charger_global_desc *gd)
 964{
 965        if (!gd)
 966                return -EINVAL;
 967
 968        if (rtc_dev)
 969                rtc_class_close(rtc_dev);
 970        rtc_dev = NULL;
 971        g_desc = NULL;
 972
 973        if (!gd->rtc_only_wakeup) {
 974                pr_err("The callback rtc_only_wakeup is not given.\n");
 975                return -EINVAL;
 976        }
 977
 978        if (gd->rtc_name) {
 979                rtc_dev = rtc_class_open(gd->rtc_name);
 980                if (IS_ERR_OR_NULL(rtc_dev)) {
 981                        rtc_dev = NULL;
 982                        /* Retry at probe. RTC may be not registered yet */
 983                }
 984        } else {
 985                pr_warn("No wakeup timer is given for charger manager."
 986                        "In-suspend monitoring won't work.\n");
 987        }
 988
 989        g_desc = gd;
 990        return 0;
 991}
 992EXPORT_SYMBOL_GPL(setup_charger_manager);
 993
 994/**
 995 * charger_extcon_work - enable/diable charger according to the state
 996 *                      of charger cable
 997 *
 998 * @work: work_struct of the function charger_extcon_work.
 999 */
1000static void charger_extcon_work(struct work_struct *work)
1001{
1002        struct charger_cable *cable =
1003                        container_of(work, struct charger_cable, wq);
1004        int ret;
1005
1006        if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) {
1007                ret = regulator_set_current_limit(cable->charger->consumer,
1008                                        cable->min_uA, cable->max_uA);
1009                if (ret < 0) {
1010                        pr_err("Cannot set current limit of %s (%s)\n",
1011                                cable->charger->regulator_name, cable->name);
1012                        return;
1013                }
1014
1015                pr_info("Set current limit of %s : %duA ~ %duA\n",
1016                                        cable->charger->regulator_name,
1017                                        cable->min_uA, cable->max_uA);
1018        }
1019
1020        try_charger_enable(cable->cm, cable->attached);
1021}
1022
1023/**
1024 * charger_extcon_notifier - receive the state of charger cable
1025 *                      when registered cable is attached or detached.
1026 *
1027 * @self: the notifier block of the charger_extcon_notifier.
1028 * @event: the cable state.
1029 * @ptr: the data pointer of notifier block.
1030 */
1031static int charger_extcon_notifier(struct notifier_block *self,
1032                        unsigned long event, void *ptr)
1033{
1034        struct charger_cable *cable =
1035                container_of(self, struct charger_cable, nb);
1036
1037        cable->attached = event;
1038        schedule_work(&cable->wq);
1039
1040        return NOTIFY_DONE;
1041}
1042
1043/**
1044 * charger_extcon_init - register external connector to use it
1045 *                      as the charger cable
1046 *
1047 * @cm: the Charger Manager representing the battery.
1048 * @cable: the Charger cable representing the external connector.
1049 */
1050static int charger_extcon_init(struct charger_manager *cm,
1051                struct charger_cable *cable)
1052{
1053        int ret = 0;
1054
1055        /*
1056         * Charger manager use Extcon framework to identify
1057         * the charger cable among various external connector
1058         * cable (e.g., TA, USB, MHL, Dock).
1059         */
1060        INIT_WORK(&cable->wq, charger_extcon_work);
1061        cable->nb.notifier_call = charger_extcon_notifier;
1062        ret = extcon_register_interest(&cable->extcon_dev,
1063                        cable->extcon_name, cable->name, &cable->nb);
1064        if (ret < 0) {
1065                pr_info("Cannot register extcon_dev for %s(cable: %s).\n",
1066                                cable->extcon_name,
1067                                cable->name);
1068                ret = -EINVAL;
1069        }
1070
1071        return ret;
1072}
1073
1074static int charger_manager_probe(struct platform_device *pdev)
1075{
1076        struct charger_desc *desc = dev_get_platdata(&pdev->dev);
1077        struct charger_manager *cm;
1078        int ret = 0, i = 0;
1079        int j = 0;
1080        union power_supply_propval val;
1081
1082        if (g_desc && !rtc_dev && g_desc->rtc_name) {
1083                rtc_dev = rtc_class_open(g_desc->rtc_name);
1084                if (IS_ERR_OR_NULL(rtc_dev)) {
1085                        rtc_dev = NULL;
1086                        dev_err(&pdev->dev, "Cannot get RTC %s.\n",
1087                                g_desc->rtc_name);
1088                        ret = -ENODEV;
1089                        goto err_alloc;
1090                }
1091        }
1092
1093        if (!desc) {
1094                dev_err(&pdev->dev, "No platform data (desc) found.\n");
1095                ret = -ENODEV;
1096                goto err_alloc;
1097        }
1098
1099        cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
1100        if (!cm) {
1101                dev_err(&pdev->dev, "Cannot allocate memory.\n");
1102                ret = -ENOMEM;
1103                goto err_alloc;
1104        }
1105
1106        /* Basic Values. Unspecified are Null or 0 */
1107        cm->dev = &pdev->dev;
1108        cm->desc = kzalloc(sizeof(struct charger_desc), GFP_KERNEL);
1109        if (!cm->desc) {
1110                dev_err(&pdev->dev, "Cannot allocate memory.\n");
1111                ret = -ENOMEM;
1112                goto err_alloc_desc;
1113        }
1114        memcpy(cm->desc, desc, sizeof(struct charger_desc));
1115        cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
1116
1117        /*
1118         * The following two do not need to be errors.
1119         * Users may intentionally ignore those two features.
1120         */
1121        if (desc->fullbatt_uV == 0) {
1122                dev_info(&pdev->dev, "Ignoring full-battery voltage threshold"
1123                                        " as it is not supplied.");
1124        }
1125        if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) {
1126                dev_info(&pdev->dev, "Disabling full-battery voltage drop "
1127                                "checking mechanism as it is not supplied.");
1128                desc->fullbatt_vchkdrop_ms = 0;
1129                desc->fullbatt_vchkdrop_uV = 0;
1130        }
1131
1132        if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
1133                ret = -EINVAL;
1134                dev_err(&pdev->dev, "charger_regulators undefined.\n");
1135                goto err_no_charger;
1136        }
1137
1138        if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
1139                dev_err(&pdev->dev, "No power supply defined.\n");
1140                ret = -EINVAL;
1141                goto err_no_charger_stat;
1142        }
1143
1144        /* Counting index only */
1145        while (desc->psy_charger_stat[i])
1146                i++;
1147
1148        cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1),
1149                                   GFP_KERNEL);
1150        if (!cm->charger_stat) {
1151                ret = -ENOMEM;
1152                goto err_no_charger_stat;
1153        }
1154
1155        for (i = 0; desc->psy_charger_stat[i]; i++) {
1156                cm->charger_stat[i] = power_supply_get_by_name(
1157                                        desc->psy_charger_stat[i]);
1158                if (!cm->charger_stat[i]) {
1159                        dev_err(&pdev->dev, "Cannot find power supply "
1160                                        "\"%s\"\n",
1161                                        desc->psy_charger_stat[i]);
1162                        ret = -ENODEV;
1163                        goto err_chg_stat;
1164                }
1165        }
1166
1167        cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
1168        if (!cm->fuel_gauge) {
1169                dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
1170                                desc->psy_fuel_gauge);
1171                ret = -ENODEV;
1172                goto err_chg_stat;
1173        }
1174
1175        if (desc->polling_interval_ms == 0 ||
1176            msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
1177                dev_err(&pdev->dev, "polling_interval_ms is too small\n");
1178                ret = -EINVAL;
1179                goto err_chg_stat;
1180        }
1181
1182        if (!desc->temperature_out_of_range) {
1183                dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
1184                ret = -EINVAL;
1185                goto err_chg_stat;
1186        }
1187
1188        platform_set_drvdata(pdev, cm);
1189
1190        memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default));
1191
1192        if (!desc->psy_name) {
1193                strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX);
1194        } else {
1195                strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
1196        }
1197        cm->charger_psy.name = cm->psy_name_buf;
1198
1199        /* Allocate for psy properties because they may vary */
1200        cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property)
1201                                * (ARRAY_SIZE(default_charger_props) +
1202                                NUM_CHARGER_PSY_OPTIONAL),
1203                                GFP_KERNEL);
1204        if (!cm->charger_psy.properties) {
1205                dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
1206                ret = -ENOMEM;
1207                goto err_chg_stat;
1208        }
1209        memcpy(cm->charger_psy.properties, default_charger_props,
1210                sizeof(enum power_supply_property) *
1211                ARRAY_SIZE(default_charger_props));
1212        cm->charger_psy.num_properties = psy_default.num_properties;
1213
1214        /* Find which optional psy-properties are available */
1215        if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
1216                                          POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
1217                cm->charger_psy.properties[cm->charger_psy.num_properties] =
1218                                POWER_SUPPLY_PROP_CHARGE_NOW;
1219                cm->charger_psy.num_properties++;
1220        }
1221        if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
1222                                          POWER_SUPPLY_PROP_CURRENT_NOW,
1223                                          &val)) {
1224                cm->charger_psy.properties[cm->charger_psy.num_properties] =
1225                                POWER_SUPPLY_PROP_CURRENT_NOW;
1226                cm->charger_psy.num_properties++;
1227        }
1228
1229        if (desc->measure_battery_temp) {
1230                cm->charger_psy.properties[cm->charger_psy.num_properties] =
1231                                POWER_SUPPLY_PROP_TEMP;
1232                cm->charger_psy.num_properties++;
1233        } else {
1234                cm->charger_psy.properties[cm->charger_psy.num_properties] =
1235                                POWER_SUPPLY_PROP_TEMP_AMBIENT;
1236                cm->charger_psy.num_properties++;
1237        }
1238
1239        INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
1240
1241        ret = power_supply_register(NULL, &cm->charger_psy);
1242        if (ret) {
1243                dev_err(&pdev->dev, "Cannot register charger-manager with"
1244                                " name \"%s\".\n", cm->charger_psy.name);
1245                goto err_register;
1246        }
1247
1248        for (i = 0 ; i < desc->num_charger_regulators ; i++) {
1249                struct charger_regulator *charger
1250                                        = &desc->charger_regulators[i];
1251
1252                charger->consumer = regulator_get(&pdev->dev,
1253                                        charger->regulator_name);
1254                if (charger->consumer == NULL) {
1255                        dev_err(&pdev->dev, "Cannot find charger(%s)n",
1256                                                charger->regulator_name);
1257                        ret = -EINVAL;
1258                        goto err_chg_get;
1259                }
1260
1261                for (j = 0 ; j < charger->num_cables ; j++) {
1262                        struct charger_cable *cable = &charger->cables[j];
1263
1264                        ret = charger_extcon_init(cm, cable);
1265                        if (ret < 0) {
1266                                dev_err(&pdev->dev, "Cannot find charger(%s)n",
1267                                                charger->regulator_name);
1268                                goto err_extcon;
1269                        }
1270                        cable->charger = charger;
1271                        cable->cm = cm;
1272                }
1273        }
1274
1275        ret = try_charger_enable(cm, true);
1276        if (ret) {
1277                dev_err(&pdev->dev, "Cannot enable charger regulators\n");
1278                goto err_chg_enable;
1279        }
1280
1281        /* Add to the list */
1282        mutex_lock(&cm_list_mtx);
1283        list_add(&cm->entry, &cm_list);
1284        mutex_unlock(&cm_list_mtx);
1285
1286        /*
1287         * Charger-manager is capable of waking up the systme from sleep
1288         * when event is happend through cm_notify_event()
1289         */
1290        device_init_wakeup(&pdev->dev, true);
1291        device_set_wakeup_capable(&pdev->dev, false);
1292
1293        schedule_work(&setup_polling);
1294
1295        return 0;
1296
1297err_chg_enable:
1298err_extcon:
1299        for (i = 0 ; i < desc->num_charger_regulators ; i++) {
1300                struct charger_regulator *charger
1301                                = &desc->charger_regulators[i];
1302                for (j = 0 ; j < charger->num_cables ; j++) {
1303                        struct charger_cable *cable = &charger->cables[j];
1304                        extcon_unregister_interest(&cable->extcon_dev);
1305                }
1306        }
1307err_chg_get:
1308        for (i = 0 ; i < desc->num_charger_regulators ; i++)
1309                regulator_put(desc->charger_regulators[i].consumer);
1310
1311        power_supply_unregister(&cm->charger_psy);
1312err_register:
1313        kfree(cm->charger_psy.properties);
1314err_chg_stat:
1315        kfree(cm->charger_stat);
1316err_no_charger_stat:
1317err_no_charger:
1318        kfree(cm->desc);
1319err_alloc_desc:
1320        kfree(cm);
1321err_alloc:
1322        return ret;
1323}
1324
1325static int __devexit charger_manager_remove(struct platform_device *pdev)
1326{
1327        struct charger_manager *cm = platform_get_drvdata(pdev);
1328        struct charger_desc *desc = cm->desc;
1329        int i = 0;
1330        int j = 0;
1331
1332        /* Remove from the list */
1333        mutex_lock(&cm_list_mtx);
1334        list_del(&cm->entry);
1335        mutex_unlock(&cm_list_mtx);
1336
1337        if (work_pending(&setup_polling))
1338                cancel_work_sync(&setup_polling);
1339        if (delayed_work_pending(&cm_monitor_work))
1340                cancel_delayed_work_sync(&cm_monitor_work);
1341
1342        for (i = 0 ; i < desc->num_charger_regulators ; i++) {
1343                struct charger_regulator *charger
1344                                = &desc->charger_regulators[i];
1345                for (j = 0 ; j < charger->num_cables ; j++) {
1346                        struct charger_cable *cable = &charger->cables[j];
1347                        extcon_unregister_interest(&cable->extcon_dev);
1348                }
1349        }
1350
1351        for (i = 0 ; i < desc->num_charger_regulators ; i++)
1352                regulator_put(desc->charger_regulators[i].consumer);
1353
1354        power_supply_unregister(&cm->charger_psy);
1355
1356        try_charger_enable(cm, false);
1357
1358        kfree(cm->charger_psy.properties);
1359        kfree(cm->charger_stat);
1360        kfree(cm->desc);
1361        kfree(cm);
1362
1363        return 0;
1364}
1365
1366static const struct platform_device_id charger_manager_id[] = {
1367        { "charger-manager", 0 },
1368        { },
1369};
1370MODULE_DEVICE_TABLE(platform, charger_manager_id);
1371
1372static int cm_suspend_noirq(struct device *dev)
1373{
1374        int ret = 0;
1375
1376        if (device_may_wakeup(dev)) {
1377                device_set_wakeup_capable(dev, false);
1378                ret = -EAGAIN;
1379        }
1380
1381        return ret;
1382}
1383
1384static int cm_suspend_prepare(struct device *dev)
1385{
1386        struct charger_manager *cm = dev_get_drvdata(dev);
1387
1388        if (!cm_suspended) {
1389                if (rtc_dev) {
1390                        struct rtc_time tmp;
1391                        unsigned long now;
1392
1393                        rtc_read_alarm(rtc_dev, &rtc_wkalarm_save);
1394                        rtc_read_time(rtc_dev, &tmp);
1395
1396                        if (rtc_wkalarm_save.enabled) {
1397                                rtc_tm_to_time(&rtc_wkalarm_save.time,
1398                                               &rtc_wkalarm_save_time);
1399                                rtc_tm_to_time(&tmp, &now);
1400                                if (now > rtc_wkalarm_save_time)
1401                                        rtc_wkalarm_save_time = 0;
1402                        } else {
1403                                rtc_wkalarm_save_time = 0;
1404                        }
1405                }
1406                cm_suspended = true;
1407        }
1408
1409        if (delayed_work_pending(&cm->fullbatt_vchk_work))
1410                cancel_delayed_work(&cm->fullbatt_vchk_work);
1411        cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
1412        cm->status_save_batt = is_batt_present(cm);
1413
1414        if (!cm_rtc_set) {
1415                cm_suspend_duration_ms = 0;
1416                cm_rtc_set = cm_setup_timer();
1417        }
1418
1419        return 0;
1420}
1421
1422static void cm_suspend_complete(struct device *dev)
1423{
1424        struct charger_manager *cm = dev_get_drvdata(dev);
1425
1426        if (cm_suspended) {
1427                if (rtc_dev) {
1428                        struct rtc_wkalrm tmp;
1429
1430                        rtc_read_alarm(rtc_dev, &tmp);
1431                        rtc_wkalarm_save.pending = tmp.pending;
1432                        rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
1433                }
1434                cm_suspended = false;
1435                cm_rtc_set = false;
1436        }
1437
1438        /* Re-enqueue delayed work (fullbatt_vchk_work) */
1439        if (cm->fullbatt_vchk_jiffies_at) {
1440                unsigned long delay = 0;
1441                unsigned long now = jiffies + CM_JIFFIES_SMALL;
1442
1443                if (time_after_eq(now, cm->fullbatt_vchk_jiffies_at)) {
1444                        delay = (unsigned long)((long)now
1445                                - (long)(cm->fullbatt_vchk_jiffies_at));
1446                        delay = jiffies_to_msecs(delay);
1447                } else {
1448                        delay = 0;
1449                }
1450
1451                /*
1452                 * Account for cm_suspend_duration_ms if
1453                 * assume_timer_stops_in_suspend is active
1454                 */
1455                if (g_desc && g_desc->assume_timer_stops_in_suspend) {
1456                        if (delay > cm_suspend_duration_ms)
1457                                delay -= cm_suspend_duration_ms;
1458                        else
1459                                delay = 0;
1460                }
1461
1462                queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
1463                                   msecs_to_jiffies(delay));
1464        }
1465        device_set_wakeup_capable(cm->dev, false);
1466        uevent_notify(cm, NULL);
1467}
1468
1469static const struct dev_pm_ops charger_manager_pm = {
1470        .prepare        = cm_suspend_prepare,
1471        .suspend_noirq  = cm_suspend_noirq,
1472        .complete       = cm_suspend_complete,
1473};
1474
1475static struct platform_driver charger_manager_driver = {
1476        .driver = {
1477                .name = "charger-manager",
1478                .owner = THIS_MODULE,
1479                .pm = &charger_manager_pm,
1480        },
1481        .probe = charger_manager_probe,
1482        .remove = __devexit_p(charger_manager_remove),
1483        .id_table = charger_manager_id,
1484};
1485
1486static int __init charger_manager_init(void)
1487{
1488        cm_wq = create_freezable_workqueue("charger_manager");
1489        INIT_DELAYED_WORK(&cm_monitor_work, cm_monitor_poller);
1490
1491        return platform_driver_register(&charger_manager_driver);
1492}
1493late_initcall(charger_manager_init);
1494
1495static void __exit charger_manager_cleanup(void)
1496{
1497        destroy_workqueue(cm_wq);
1498        cm_wq = NULL;
1499
1500        platform_driver_unregister(&charger_manager_driver);
1501}
1502module_exit(charger_manager_cleanup);
1503
1504/**
1505 * find_power_supply - find the associated power_supply of charger
1506 * @cm: the Charger Manager representing the battery
1507 * @psy: pointer to instance of charger's power_supply
1508 */
1509static bool find_power_supply(struct charger_manager *cm,
1510                        struct power_supply *psy)
1511{
1512        int i;
1513        bool found = false;
1514
1515        for (i = 0; cm->charger_stat[i]; i++) {
1516                if (psy == cm->charger_stat[i]) {
1517                        found = true;
1518                        break;
1519                }
1520        }
1521
1522        return found;
1523}
1524
1525/**
1526 * cm_notify_event - charger driver notify Charger Manager of charger event
1527 * @psy: pointer to instance of charger's power_supply
1528 * @type: type of charger event
1529 * @msg: optional message passed to uevent_notify fuction
1530 */
1531void cm_notify_event(struct power_supply *psy, enum cm_event_types type,
1532                     char *msg)
1533{
1534        struct charger_manager *cm;
1535        bool found_power_supply = false;
1536
1537        if (psy == NULL)
1538                return;
1539
1540        mutex_lock(&cm_list_mtx);
1541        list_for_each_entry(cm, &cm_list, entry) {
1542                found_power_supply = find_power_supply(cm, psy);
1543                if (found_power_supply)
1544                        break;
1545        }
1546        mutex_unlock(&cm_list_mtx);
1547
1548        if (!found_power_supply)
1549                return;
1550
1551        switch (type) {
1552        case CM_EVENT_BATT_FULL:
1553                fullbatt_handler(cm);
1554                break;
1555        case CM_EVENT_BATT_OUT:
1556                battout_handler(cm);
1557                break;
1558        case CM_EVENT_BATT_IN:
1559        case CM_EVENT_EXT_PWR_IN_OUT ... CM_EVENT_CHG_START_STOP:
1560                misc_event_handler(cm, type);
1561                break;
1562        case CM_EVENT_UNKNOWN:
1563        case CM_EVENT_OTHERS:
1564                uevent_notify(cm, msg ? msg : default_event_names[type]);
1565                break;
1566        default:
1567                dev_err(cm->dev, "%s type not specified.\n", __func__);
1568                break;
1569        }
1570}
1571EXPORT_SYMBOL_GPL(cm_notify_event);
1572
1573MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1574MODULE_DESCRIPTION("Charger Manager");
1575MODULE_LICENSE("GPL");
1576
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.