linux/drivers/power/supply/charger-manager.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
   4 * MyungJoo Ham <myungjoo.ham@samsung.com>
   5 *
   6 * This driver enables to monitor battery health and control charger
   7 * during suspend-to-mem.
   8 * Charger manager depends on other devices. Register this later than
   9 * the depending devices.
  10 *
  11**/
  12
  13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  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#include <linux/sysfs.h>
  26#include <linux/of.h>
  27#include <linux/thermal.h>
  28
  29/*
  30 * Default temperature threshold for charging.
  31 * Every temperature units are in tenth of centigrade.
  32 */
  33#define CM_DEFAULT_RECHARGE_TEMP_DIFF   50
  34#define CM_DEFAULT_CHARGE_TEMP_MAX      500
  35
  36static const char * const default_event_names[] = {
  37        [CM_EVENT_UNKNOWN] = "Unknown",
  38        [CM_EVENT_BATT_FULL] = "Battery Full",
  39        [CM_EVENT_BATT_IN] = "Battery Inserted",
  40        [CM_EVENT_BATT_OUT] = "Battery Pulled Out",
  41        [CM_EVENT_BATT_OVERHEAT] = "Battery Overheat",
  42        [CM_EVENT_BATT_COLD] = "Battery Cold",
  43        [CM_EVENT_EXT_PWR_IN_OUT] = "External Power Attach/Detach",
  44        [CM_EVENT_CHG_START_STOP] = "Charging Start/Stop",
  45        [CM_EVENT_OTHERS] = "Other battery events"
  46};
  47
  48/*
  49 * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for
  50 * delayed works so that we can run delayed works with CM_JIFFIES_SMALL
  51 * without any delays.
  52 */
  53#define CM_JIFFIES_SMALL        (2)
  54
  55/* If y is valid (> 0) and smaller than x, do x = y */
  56#define CM_MIN_VALID(x, y)      x = (((y > 0) && ((x) > (y))) ? (y) : (x))
  57
  58/*
  59 * Regard CM_RTC_SMALL (sec) is small enough to ignore error in invoking
  60 * rtc alarm. It should be 2 or larger
  61 */
  62#define CM_RTC_SMALL            (2)
  63
  64#define UEVENT_BUF_SIZE         32
  65
  66static LIST_HEAD(cm_list);
  67static DEFINE_MUTEX(cm_list_mtx);
  68
  69/* About in-suspend (suspend-again) monitoring */
  70static struct alarm *cm_timer;
  71
  72static bool cm_suspended;
  73static bool cm_timer_set;
  74static unsigned long cm_suspend_duration_ms;
  75
  76/* About normal (not suspended) monitoring */
  77static unsigned long polling_jiffy = ULONG_MAX; /* ULONG_MAX: no polling */
  78static unsigned long next_polling; /* Next appointed polling time */
  79static struct workqueue_struct *cm_wq; /* init at driver add */
  80static struct delayed_work cm_monitor_work; /* init at driver add */
  81
  82/**
  83 * is_batt_present - See if the battery presents in place.
  84 * @cm: the Charger Manager representing the battery.
  85 */
  86static bool is_batt_present(struct charger_manager *cm)
  87{
  88        union power_supply_propval val;
  89        struct power_supply *psy;
  90        bool present = false;
  91        int i, ret;
  92
  93        switch (cm->desc->battery_present) {
  94        case CM_BATTERY_PRESENT:
  95                present = true;
  96                break;
  97        case CM_NO_BATTERY:
  98                break;
  99        case CM_FUEL_GAUGE:
 100                psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 101                if (!psy)
 102                        break;
 103
 104                ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT,
 105                                &val);
 106                if (ret == 0 && val.intval)
 107                        present = true;
 108                power_supply_put(psy);
 109                break;
 110        case CM_CHARGER_STAT:
 111                for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
 112                        psy = power_supply_get_by_name(
 113                                        cm->desc->psy_charger_stat[i]);
 114                        if (!psy) {
 115                                dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
 116                                        cm->desc->psy_charger_stat[i]);
 117                                continue;
 118                        }
 119
 120                        ret = power_supply_get_property(psy,
 121                                POWER_SUPPLY_PROP_PRESENT, &val);
 122                        power_supply_put(psy);
 123                        if (ret == 0 && val.intval) {
 124                                present = true;
 125                                break;
 126                        }
 127                }
 128                break;
 129        }
 130
 131        return present;
 132}
 133
 134/**
 135 * is_ext_pwr_online - See if an external power source is attached to charge
 136 * @cm: the Charger Manager representing the battery.
 137 *
 138 * Returns true if at least one of the chargers of the battery has an external
 139 * power source attached to charge the battery regardless of whether it is
 140 * actually charging or not.
 141 */
 142static bool is_ext_pwr_online(struct charger_manager *cm)
 143{
 144        union power_supply_propval val;
 145        struct power_supply *psy;
 146        bool online = false;
 147        int i, ret;
 148
 149        /* If at least one of them has one, it's yes. */
 150        for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
 151                psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
 152                if (!psy) {
 153                        dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
 154                                        cm->desc->psy_charger_stat[i]);
 155                        continue;
 156                }
 157
 158                ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE,
 159                                &val);
 160                power_supply_put(psy);
 161                if (ret == 0 && val.intval) {
 162                        online = true;
 163                        break;
 164                }
 165        }
 166
 167        return online;
 168}
 169
 170/**
 171 * get_batt_uV - Get the voltage level of the battery
 172 * @cm: the Charger Manager representing the battery.
 173 * @uV: the voltage level returned.
 174 *
 175 * Returns 0 if there is no error.
 176 * Returns a negative value on error.
 177 */
 178static int get_batt_uV(struct charger_manager *cm, int *uV)
 179{
 180        union power_supply_propval val;
 181        struct power_supply *fuel_gauge;
 182        int ret;
 183
 184        fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 185        if (!fuel_gauge)
 186                return -ENODEV;
 187
 188        ret = power_supply_get_property(fuel_gauge,
 189                                POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
 190        power_supply_put(fuel_gauge);
 191        if (ret)
 192                return ret;
 193
 194        *uV = val.intval;
 195        return 0;
 196}
 197
 198/**
 199 * is_charging - Returns true if the battery is being charged.
 200 * @cm: the Charger Manager representing the battery.
 201 */
 202static bool is_charging(struct charger_manager *cm)
 203{
 204        int i, ret;
 205        bool charging = false;
 206        struct power_supply *psy;
 207        union power_supply_propval val;
 208
 209        /* If there is no battery, it cannot be charged */
 210        if (!is_batt_present(cm))
 211                return false;
 212
 213        /* If at least one of the charger is charging, return yes */
 214        for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
 215                /* 1. The charger sholuld not be DISABLED */
 216                if (cm->emergency_stop)
 217                        continue;
 218                if (!cm->charger_enabled)
 219                        continue;
 220
 221                psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
 222                if (!psy) {
 223                        dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
 224                                        cm->desc->psy_charger_stat[i]);
 225                        continue;
 226                }
 227
 228                /* 2. The charger should be online (ext-power) */
 229                ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE,
 230                                &val);
 231                if (ret) {
 232                        dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
 233                                 cm->desc->psy_charger_stat[i]);
 234                        power_supply_put(psy);
 235                        continue;
 236                }
 237                if (val.intval == 0) {
 238                        power_supply_put(psy);
 239                        continue;
 240                }
 241
 242                /*
 243                 * 3. The charger should not be FULL, DISCHARGING,
 244                 * or NOT_CHARGING.
 245                 */
 246                ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS,
 247                                &val);
 248                power_supply_put(psy);
 249                if (ret) {
 250                        dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
 251                                 cm->desc->psy_charger_stat[i]);
 252                        continue;
 253                }
 254                if (val.intval == POWER_SUPPLY_STATUS_FULL ||
 255                                val.intval == POWER_SUPPLY_STATUS_DISCHARGING ||
 256                                val.intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
 257                        continue;
 258
 259                /* Then, this is charging. */
 260                charging = true;
 261                break;
 262        }
 263
 264        return charging;
 265}
 266
 267/**
 268 * is_full_charged - Returns true if the battery is fully charged.
 269 * @cm: the Charger Manager representing the battery.
 270 */
 271static bool is_full_charged(struct charger_manager *cm)
 272{
 273        struct charger_desc *desc = cm->desc;
 274        union power_supply_propval val;
 275        struct power_supply *fuel_gauge;
 276        bool is_full = false;
 277        int ret = 0;
 278        int uV;
 279
 280        /* If there is no battery, it cannot be charged */
 281        if (!is_batt_present(cm))
 282                return false;
 283
 284        fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 285        if (!fuel_gauge)
 286                return false;
 287
 288        if (desc->fullbatt_full_capacity > 0) {
 289                val.intval = 0;
 290
 291                /* Not full if capacity of fuel gauge isn't full */
 292                ret = power_supply_get_property(fuel_gauge,
 293                                POWER_SUPPLY_PROP_CHARGE_FULL, &val);
 294                if (!ret && val.intval > desc->fullbatt_full_capacity) {
 295                        is_full = true;
 296                        goto out;
 297                }
 298        }
 299
 300        /* Full, if it's over the fullbatt voltage */
 301        if (desc->fullbatt_uV > 0) {
 302                ret = get_batt_uV(cm, &uV);
 303                if (!ret && uV >= desc->fullbatt_uV) {
 304                        is_full = true;
 305                        goto out;
 306                }
 307        }
 308
 309        /* Full, if the capacity is more than fullbatt_soc */
 310        if (desc->fullbatt_soc > 0) {
 311                val.intval = 0;
 312
 313                ret = power_supply_get_property(fuel_gauge,
 314                                POWER_SUPPLY_PROP_CAPACITY, &val);
 315                if (!ret && val.intval >= desc->fullbatt_soc) {
 316                        is_full = true;
 317                        goto out;
 318                }
 319        }
 320
 321out:
 322        power_supply_put(fuel_gauge);
 323        return is_full;
 324}
 325
 326/**
 327 * is_polling_required - Return true if need to continue polling for this CM.
 328 * @cm: the Charger Manager representing the battery.
 329 */
 330static bool is_polling_required(struct charger_manager *cm)
 331{
 332        switch (cm->desc->polling_mode) {
 333        case CM_POLL_DISABLE:
 334                return false;
 335        case CM_POLL_ALWAYS:
 336                return true;
 337        case CM_POLL_EXTERNAL_POWER_ONLY:
 338                return is_ext_pwr_online(cm);
 339        case CM_POLL_CHARGING_ONLY:
 340                return is_charging(cm);
 341        default:
 342                dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
 343                         cm->desc->polling_mode);
 344        }
 345
 346        return false;
 347}
 348
 349/**
 350 * try_charger_enable - Enable/Disable chargers altogether
 351 * @cm: the Charger Manager representing the battery.
 352 * @enable: true: enable / false: disable
 353 *
 354 * Note that Charger Manager keeps the charger enabled regardless whether
 355 * the charger is charging or not (because battery is full or no external
 356 * power source exists) except when CM needs to disable chargers forcibly
 357 * because of emergency causes; when the battery is overheated or too cold.
 358 */
 359static int try_charger_enable(struct charger_manager *cm, bool enable)
 360{
 361        int err = 0, i;
 362        struct charger_desc *desc = cm->desc;
 363
 364        /* Ignore if it's redundant command */
 365        if (enable == cm->charger_enabled)
 366                return 0;
 367
 368        if (enable) {
 369                if (cm->emergency_stop)
 370                        return -EAGAIN;
 371
 372                /*
 373                 * Save start time of charging to limit
 374                 * maximum possible charging time.
 375                 */
 376                cm->charging_start_time = ktime_to_ms(ktime_get());
 377                cm->charging_end_time = 0;
 378
 379                for (i = 0 ; i < desc->num_charger_regulators ; i++) {
 380                        if (desc->charger_regulators[i].externally_control)
 381                                continue;
 382
 383                        err = regulator_enable(desc->charger_regulators[i].consumer);
 384                        if (err < 0) {
 385                                dev_warn(cm->dev, "Cannot enable %s regulator\n",
 386                                         desc->charger_regulators[i].regulator_name);
 387                        }
 388                }
 389        } else {
 390                /*
 391                 * Save end time of charging to maintain fully charged state
 392                 * of battery after full-batt.
 393                 */
 394                cm->charging_start_time = 0;
 395                cm->charging_end_time = ktime_to_ms(ktime_get());
 396
 397                for (i = 0 ; i < desc->num_charger_regulators ; i++) {
 398                        if (desc->charger_regulators[i].externally_control)
 399                                continue;
 400
 401                        err = regulator_disable(desc->charger_regulators[i].consumer);
 402                        if (err < 0) {
 403                                dev_warn(cm->dev, "Cannot disable %s regulator\n",
 404                                         desc->charger_regulators[i].regulator_name);
 405                        }
 406                }
 407
 408                /*
 409                 * Abnormal battery state - Stop charging forcibly,
 410                 * even if charger was enabled at the other places
 411                 */
 412                for (i = 0; i < desc->num_charger_regulators; i++) {
 413                        if (regulator_is_enabled(
 414                                    desc->charger_regulators[i].consumer)) {
 415                                regulator_force_disable(
 416                                        desc->charger_regulators[i].consumer);
 417                                dev_warn(cm->dev, "Disable regulator(%s) forcibly\n",
 418                                         desc->charger_regulators[i].regulator_name);
 419                        }
 420                }
 421        }
 422
 423        if (!err)
 424                cm->charger_enabled = enable;
 425
 426        return err;
 427}
 428
 429/**
 430 * try_charger_restart - Restart charging.
 431 * @cm: the Charger Manager representing the battery.
 432 *
 433 * Restart charging by turning off and on the charger.
 434 */
 435static int try_charger_restart(struct charger_manager *cm)
 436{
 437        int err;
 438
 439        if (cm->emergency_stop)
 440                return -EAGAIN;
 441
 442        err = try_charger_enable(cm, false);
 443        if (err)
 444                return err;
 445
 446        return try_charger_enable(cm, true);
 447}
 448
 449/**
 450 * uevent_notify - Let users know something has changed.
 451 * @cm: the Charger Manager representing the battery.
 452 * @event: the event string.
 453 *
 454 * If @event is null, it implies that uevent_notify is called
 455 * by resume function. When called in the resume function, cm_suspended
 456 * should be already reset to false in order to let uevent_notify
 457 * notify the recent event during the suspend to users. While
 458 * suspended, uevent_notify does not notify users, but tracks
 459 * events so that uevent_notify can notify users later after resumed.
 460 */
 461static void uevent_notify(struct charger_manager *cm, const char *event)
 462{
 463        static char env_str[UEVENT_BUF_SIZE + 1] = "";
 464        static char env_str_save[UEVENT_BUF_SIZE + 1] = "";
 465
 466        if (cm_suspended) {
 467                /* Nothing in suspended-event buffer */
 468                if (env_str_save[0] == 0) {
 469                        if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
 470                                return; /* status not changed */
 471                        strncpy(env_str_save, event, UEVENT_BUF_SIZE);
 472                        return;
 473                }
 474
 475                if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
 476                        return; /* Duplicated. */
 477                strncpy(env_str_save, event, UEVENT_BUF_SIZE);
 478                return;
 479        }
 480
 481        if (event == NULL) {
 482                /* No messages pending */
 483                if (!env_str_save[0])
 484                        return;
 485
 486                strncpy(env_str, env_str_save, UEVENT_BUF_SIZE);
 487                kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
 488                env_str_save[0] = 0;
 489
 490                return;
 491        }
 492
 493        /* status not changed */
 494        if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
 495                return;
 496
 497        /* save the status and notify the update */
 498        strncpy(env_str, event, UEVENT_BUF_SIZE);
 499        kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
 500
 501        dev_info(cm->dev, "%s\n", event);
 502}
 503
 504/**
 505 * fullbatt_vchk - Check voltage drop some times after "FULL" event.
 506 * @work: the work_struct appointing the function
 507 *
 508 * If a user has designated "fullbatt_vchkdrop_ms/uV" values with
 509 * charger_desc, Charger Manager checks voltage drop after the battery
 510 * "FULL" event. It checks whether the voltage has dropped more than
 511 * fullbatt_vchkdrop_uV by calling this function after fullbatt_vchkrop_ms.
 512 */
 513static void fullbatt_vchk(struct work_struct *work)
 514{
 515        struct delayed_work *dwork = to_delayed_work(work);
 516        struct charger_manager *cm = container_of(dwork,
 517                        struct charger_manager, fullbatt_vchk_work);
 518        struct charger_desc *desc = cm->desc;
 519        int batt_uV, err, diff;
 520
 521        /* remove the appointment for fullbatt_vchk */
 522        cm->fullbatt_vchk_jiffies_at = 0;
 523
 524        if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
 525                return;
 526
 527        err = get_batt_uV(cm, &batt_uV);
 528        if (err) {
 529                dev_err(cm->dev, "%s: get_batt_uV error(%d)\n", __func__, err);
 530                return;
 531        }
 532
 533        diff = desc->fullbatt_uV - batt_uV;
 534        if (diff < 0)
 535                return;
 536
 537        dev_info(cm->dev, "VBATT dropped %duV after full-batt\n", diff);
 538
 539        if (diff > desc->fullbatt_vchkdrop_uV) {
 540                try_charger_restart(cm);
 541                uevent_notify(cm, "Recharging");
 542        }
 543}
 544
 545/**
 546 * check_charging_duration - Monitor charging/discharging duration
 547 * @cm: the Charger Manager representing the battery.
 548 *
 549 * If whole charging duration exceed 'charging_max_duration_ms',
 550 * cm stop charging to prevent overcharge/overheat. If discharging
 551 * duration exceed 'discharging _max_duration_ms', charger cable is
 552 * attached, after full-batt, cm start charging to maintain fully
 553 * charged state for battery.
 554 */
 555static int check_charging_duration(struct charger_manager *cm)
 556{
 557        struct charger_desc *desc = cm->desc;
 558        u64 curr = ktime_to_ms(ktime_get());
 559        u64 duration;
 560        int ret = false;
 561
 562        if (!desc->charging_max_duration_ms &&
 563                        !desc->discharging_max_duration_ms)
 564                return ret;
 565
 566        if (cm->charger_enabled) {
 567                duration = curr - cm->charging_start_time;
 568
 569                if (duration > desc->charging_max_duration_ms) {
 570                        dev_info(cm->dev, "Charging duration exceed %ums\n",
 571                                 desc->charging_max_duration_ms);
 572                        uevent_notify(cm, "Discharging");
 573                        try_charger_enable(cm, false);
 574                        ret = true;
 575                }
 576        } else if (is_ext_pwr_online(cm) && !cm->charger_enabled) {
 577                duration = curr - cm->charging_end_time;
 578
 579                if (duration > desc->discharging_max_duration_ms &&
 580                                is_ext_pwr_online(cm)) {
 581                        dev_info(cm->dev, "Discharging duration exceed %ums\n",
 582                                 desc->discharging_max_duration_ms);
 583                        uevent_notify(cm, "Recharging");
 584                        try_charger_enable(cm, true);
 585                        ret = true;
 586                }
 587        }
 588
 589        return ret;
 590}
 591
 592static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
 593                                        int *temp)
 594{
 595        struct power_supply *fuel_gauge;
 596        int ret;
 597
 598        fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 599        if (!fuel_gauge)
 600                return -ENODEV;
 601
 602        ret = power_supply_get_property(fuel_gauge,
 603                                POWER_SUPPLY_PROP_TEMP,
 604                                (union power_supply_propval *)temp);
 605        power_supply_put(fuel_gauge);
 606
 607        return ret;
 608}
 609
 610static int cm_get_battery_temperature(struct charger_manager *cm,
 611                                        int *temp)
 612{
 613        int ret;
 614
 615        if (!cm->desc->measure_battery_temp)
 616                return -ENODEV;
 617
 618#ifdef CONFIG_THERMAL
 619        if (cm->tzd_batt) {
 620                ret = thermal_zone_get_temp(cm->tzd_batt, temp);
 621                if (!ret)
 622                        /* Calibrate temperature unit */
 623                        *temp /= 100;
 624        } else
 625#endif
 626        {
 627                /* if-else continued from CONFIG_THERMAL */
 628                ret = cm_get_battery_temperature_by_psy(cm, temp);
 629        }
 630
 631        return ret;
 632}
 633
 634static int cm_check_thermal_status(struct charger_manager *cm)
 635{
 636        struct charger_desc *desc = cm->desc;
 637        int temp, upper_limit, lower_limit;
 638        int ret = 0;
 639
 640        ret = cm_get_battery_temperature(cm, &temp);
 641        if (ret) {
 642                /* FIXME:
 643                 * No information of battery temperature might
 644                 * occur hazardous result. We have to handle it
 645                 * depending on battery type.
 646                 */
 647                dev_err(cm->dev, "Failed to get battery temperature\n");
 648                return 0;
 649        }
 650
 651        upper_limit = desc->temp_max;
 652        lower_limit = desc->temp_min;
 653
 654        if (cm->emergency_stop) {
 655                upper_limit -= desc->temp_diff;
 656                lower_limit += desc->temp_diff;
 657        }
 658
 659        if (temp > upper_limit)
 660                ret = CM_EVENT_BATT_OVERHEAT;
 661        else if (temp < lower_limit)
 662                ret = CM_EVENT_BATT_COLD;
 663
 664        return ret;
 665}
 666
 667/**
 668 * _cm_monitor - Monitor the temperature and return true for exceptions.
 669 * @cm: the Charger Manager representing the battery.
 670 *
 671 * Returns true if there is an event to notify for the battery.
 672 * (True if the status of "emergency_stop" changes)
 673 */
 674static bool _cm_monitor(struct charger_manager *cm)
 675{
 676        int temp_alrt;
 677
 678        temp_alrt = cm_check_thermal_status(cm);
 679
 680        /* It has been stopped already */
 681        if (temp_alrt && cm->emergency_stop)
 682                return false;
 683
 684        /*
 685         * Check temperature whether overheat or cold.
 686         * If temperature is out of range normal state, stop charging.
 687         */
 688        if (temp_alrt) {
 689                cm->emergency_stop = temp_alrt;
 690                if (!try_charger_enable(cm, false))
 691                        uevent_notify(cm, default_event_names[temp_alrt]);
 692
 693        /*
 694         * Check whole charging duration and discharging duration
 695         * after full-batt.
 696         */
 697        } else if (!cm->emergency_stop && check_charging_duration(cm)) {
 698                dev_dbg(cm->dev,
 699                        "Charging/Discharging duration is out of range\n");
 700        /*
 701         * Check dropped voltage of battery. If battery voltage is more
 702         * dropped than fullbatt_vchkdrop_uV after fully charged state,
 703         * charger-manager have to recharge battery.
 704         */
 705        } else if (!cm->emergency_stop && is_ext_pwr_online(cm) &&
 706                        !cm->charger_enabled) {
 707                fullbatt_vchk(&cm->fullbatt_vchk_work.work);
 708
 709        /*
 710         * Check whether fully charged state to protect overcharge
 711         * if charger-manager is charging for battery.
 712         */
 713        } else if (!cm->emergency_stop && is_full_charged(cm) &&
 714                        cm->charger_enabled) {
 715                dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n");
 716                uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
 717
 718                try_charger_enable(cm, false);
 719
 720                fullbatt_vchk(&cm->fullbatt_vchk_work.work);
 721        } else {
 722                cm->emergency_stop = 0;
 723                if (is_ext_pwr_online(cm)) {
 724                        if (!try_charger_enable(cm, true))
 725                                uevent_notify(cm, "CHARGING");
 726                }
 727        }
 728
 729        return true;
 730}
 731
 732/**
 733 * cm_monitor - Monitor every battery.
 734 *
 735 * Returns true if there is an event to notify from any of the batteries.
 736 * (True if the status of "emergency_stop" changes)
 737 */
 738static bool cm_monitor(void)
 739{
 740        bool stop = false;
 741        struct charger_manager *cm;
 742
 743        mutex_lock(&cm_list_mtx);
 744
 745        list_for_each_entry(cm, &cm_list, entry) {
 746                if (_cm_monitor(cm))
 747                        stop = true;
 748        }
 749
 750        mutex_unlock(&cm_list_mtx);
 751
 752        return stop;
 753}
 754
 755/**
 756 * _setup_polling - Setup the next instance of polling.
 757 * @work: work_struct of the function _setup_polling.
 758 */
 759static void _setup_polling(struct work_struct *work)
 760{
 761        unsigned long min = ULONG_MAX;
 762        struct charger_manager *cm;
 763        bool keep_polling = false;
 764        unsigned long _next_polling;
 765
 766        mutex_lock(&cm_list_mtx);
 767
 768        list_for_each_entry(cm, &cm_list, entry) {
 769                if (is_polling_required(cm) && cm->desc->polling_interval_ms) {
 770                        keep_polling = true;
 771
 772                        if (min > cm->desc->polling_interval_ms)
 773                                min = cm->desc->polling_interval_ms;
 774                }
 775        }
 776
 777        polling_jiffy = msecs_to_jiffies(min);
 778        if (polling_jiffy <= CM_JIFFIES_SMALL)
 779                polling_jiffy = CM_JIFFIES_SMALL + 1;
 780
 781        if (!keep_polling)
 782                polling_jiffy = ULONG_MAX;
 783        if (polling_jiffy == ULONG_MAX)
 784                goto out;
 785
 786        WARN(cm_wq == NULL, "charger-manager: workqueue not initialized"
 787                            ". try it later. %s\n", __func__);
 788
 789        /*
 790         * Use mod_delayed_work() iff the next polling interval should
 791         * occur before the currently scheduled one.  If @cm_monitor_work
 792         * isn't active, the end result is the same, so no need to worry
 793         * about stale @next_polling.
 794         */
 795        _next_polling = jiffies + polling_jiffy;
 796
 797        if (time_before(_next_polling, next_polling)) {
 798                mod_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy);
 799                next_polling = _next_polling;
 800        } else {
 801                if (queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy))
 802                        next_polling = _next_polling;
 803        }
 804out:
 805        mutex_unlock(&cm_list_mtx);
 806}
 807static DECLARE_WORK(setup_polling, _setup_polling);
 808
 809/**
 810 * cm_monitor_poller - The Monitor / Poller.
 811 * @work: work_struct of the function cm_monitor_poller
 812 *
 813 * During non-suspended state, cm_monitor_poller is used to poll and monitor
 814 * the batteries.
 815 */
 816static void cm_monitor_poller(struct work_struct *work)
 817{
 818        cm_monitor();
 819        schedule_work(&setup_polling);
 820}
 821
 822/**
 823 * fullbatt_handler - Event handler for CM_EVENT_BATT_FULL
 824 * @cm: the Charger Manager representing the battery.
 825 */
 826static void fullbatt_handler(struct charger_manager *cm)
 827{
 828        struct charger_desc *desc = cm->desc;
 829
 830        if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
 831                goto out;
 832
 833        if (cm_suspended)
 834                device_set_wakeup_capable(cm->dev, true);
 835
 836        mod_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
 837                         msecs_to_jiffies(desc->fullbatt_vchkdrop_ms));
 838        cm->fullbatt_vchk_jiffies_at = jiffies + msecs_to_jiffies(
 839                                       desc->fullbatt_vchkdrop_ms);
 840
 841        if (cm->fullbatt_vchk_jiffies_at == 0)
 842                cm->fullbatt_vchk_jiffies_at = 1;
 843
 844out:
 845        dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n");
 846        uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
 847}
 848
 849/**
 850 * battout_handler - Event handler for CM_EVENT_BATT_OUT
 851 * @cm: the Charger Manager representing the battery.
 852 */
 853static void battout_handler(struct charger_manager *cm)
 854{
 855        if (cm_suspended)
 856                device_set_wakeup_capable(cm->dev, true);
 857
 858        if (!is_batt_present(cm)) {
 859                dev_emerg(cm->dev, "Battery Pulled Out!\n");
 860                uevent_notify(cm, default_event_names[CM_EVENT_BATT_OUT]);
 861        } else {
 862                uevent_notify(cm, "Battery Reinserted?");
 863        }
 864}
 865
 866/**
 867 * misc_event_handler - Handler for other events
 868 * @cm: the Charger Manager representing the battery.
 869 * @type: the Charger Manager representing the battery.
 870 */
 871static void misc_event_handler(struct charger_manager *cm,
 872                        enum cm_event_types type)
 873{
 874        if (cm_suspended)
 875                device_set_wakeup_capable(cm->dev, true);
 876
 877        if (is_polling_required(cm) && cm->desc->polling_interval_ms)
 878                schedule_work(&setup_polling);
 879        uevent_notify(cm, default_event_names[type]);
 880}
 881
 882static int charger_get_property(struct power_supply *psy,
 883                enum power_supply_property psp,
 884                union power_supply_propval *val)
 885{
 886        struct charger_manager *cm = power_supply_get_drvdata(psy);
 887        struct charger_desc *desc = cm->desc;
 888        struct power_supply *fuel_gauge = NULL;
 889        int ret = 0;
 890        int uV;
 891
 892        switch (psp) {
 893        case POWER_SUPPLY_PROP_STATUS:
 894                if (is_charging(cm))
 895                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
 896                else if (is_ext_pwr_online(cm))
 897                        val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
 898                else
 899                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 900                break;
 901        case POWER_SUPPLY_PROP_HEALTH:
 902                if (cm->emergency_stop > 0)
 903                        val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
 904                else if (cm->emergency_stop < 0)
 905                        val->intval = POWER_SUPPLY_HEALTH_COLD;
 906                else
 907                        val->intval = POWER_SUPPLY_HEALTH_GOOD;
 908                break;
 909        case POWER_SUPPLY_PROP_PRESENT:
 910                if (is_batt_present(cm))
 911                        val->intval = 1;
 912                else
 913                        val->intval = 0;
 914                break;
 915        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 916                ret = get_batt_uV(cm, &val->intval);
 917                break;
 918        case POWER_SUPPLY_PROP_CURRENT_NOW:
 919                fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 920                if (!fuel_gauge) {
 921                        ret = -ENODEV;
 922                        break;
 923                }
 924                ret = power_supply_get_property(fuel_gauge,
 925                                POWER_SUPPLY_PROP_CURRENT_NOW, val);
 926                break;
 927        case POWER_SUPPLY_PROP_TEMP:
 928        case POWER_SUPPLY_PROP_TEMP_AMBIENT:
 929                return cm_get_battery_temperature(cm, &val->intval);
 930        case POWER_SUPPLY_PROP_CAPACITY:
 931                if (!is_batt_present(cm)) {
 932                        /* There is no battery. Assume 100% */
 933                        val->intval = 100;
 934                        break;
 935                }
 936
 937                fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
 938                if (!fuel_gauge) {
 939                        ret = -ENODEV;
 940                        break;
 941                }
 942
 943                ret = power_supply_get_property(fuel_gauge,
 944                                        POWER_SUPPLY_PROP_CAPACITY, val);
 945                if (ret)
 946                        break;
 947
 948                if (val->intval > 100) {
 949                        val->intval = 100;
 950                        break;
 951                }
 952                if (val->intval < 0)
 953                        val->intval = 0;
 954
 955                /* Do not adjust SOC when charging: voltage is overrated */
 956                if (is_charging(cm))
 957                        break;
 958
 959                /*
 960                 * If the capacity value is inconsistent, calibrate it base on
 961                 * the battery voltage values and the thresholds given as desc
 962                 */
 963                ret = get_batt_uV(cm, &uV);
 964                if (ret) {
 965                        /* Voltage information not available. No calibration */
 966                        ret = 0;
 967                        break;
 968                }
 969
 970                if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
 971                    !is_charging(cm)) {
 972                        val->intval = 100;
 973                        break;
 974                }
 975
 976                break;
 977        case POWER_SUPPLY_PROP_ONLINE:
 978                if (is_ext_pwr_online(cm))
 979                        val->intval = 1;
 980                else
 981                        val->intval = 0;
 982                break;
 983        case POWER_SUPPLY_PROP_CHARGE_FULL:
 984                if (is_full_charged(cm))
 985                        val->intval = 1;
 986                else
 987                        val->intval = 0;
 988                ret = 0;
 989                break;
 990        case POWER_SUPPLY_PROP_CHARGE_NOW:
 991                if (is_charging(cm)) {
 992                        fuel_gauge = power_supply_get_by_name(
 993                                        cm->desc->psy_fuel_gauge);
 994                        if (!fuel_gauge) {
 995                                ret = -ENODEV;
 996                                break;
 997                        }
 998
 999                        ret = power_supply_get_property(fuel_gauge,
1000                                                POWER_SUPPLY_PROP_CHARGE_NOW,
1001                                                val);
1002                        if (ret) {
1003                                val->intval = 1;
1004                                ret = 0;
1005                        } else {
1006                                /* If CHARGE_NOW is supplied, use it */
1007                                val->intval = (val->intval > 0) ?
1008                                                val->intval : 1;
1009                        }
1010                } else {
1011                        val->intval = 0;
1012                }
1013                break;
1014        default:
1015                return -EINVAL;
1016        }
1017        if (fuel_gauge)
1018                power_supply_put(fuel_gauge);
1019        return ret;
1020}
1021
1022#define NUM_CHARGER_PSY_OPTIONAL        (4)
1023static enum power_supply_property default_charger_props[] = {
1024        /* Guaranteed to provide */
1025        POWER_SUPPLY_PROP_STATUS,
1026        POWER_SUPPLY_PROP_HEALTH,
1027        POWER_SUPPLY_PROP_PRESENT,
1028        POWER_SUPPLY_PROP_VOLTAGE_NOW,
1029        POWER_SUPPLY_PROP_CAPACITY,
1030        POWER_SUPPLY_PROP_ONLINE,
1031        POWER_SUPPLY_PROP_CHARGE_FULL,
1032        /*
1033         * Optional properties are:
1034         * POWER_SUPPLY_PROP_CHARGE_NOW,
1035         * POWER_SUPPLY_PROP_CURRENT_NOW,
1036         * POWER_SUPPLY_PROP_TEMP, and
1037         * POWER_SUPPLY_PROP_TEMP_AMBIENT,
1038         */
1039};
1040
1041static const struct power_supply_desc psy_default = {
1042        .name = "battery",
1043        .type = POWER_SUPPLY_TYPE_BATTERY,
1044        .properties = default_charger_props,
1045        .num_properties = ARRAY_SIZE(default_charger_props),
1046        .get_property = charger_get_property,
1047        .no_thermal = true,
1048};
1049
1050/**
1051 * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
1052 *                  for suspend_again.
1053 *
1054 * Returns true if the alarm is set for Charger Manager to use.
1055 * Returns false if
1056 *      cm_setup_timer fails to set an alarm,
1057 *      cm_setup_timer does not need to set an alarm for Charger Manager,
1058 *      or an alarm previously configured is to be used.
1059 */
1060static bool cm_setup_timer(void)
1061{
1062        struct charger_manager *cm;
1063        unsigned int wakeup_ms = UINT_MAX;
1064        int timer_req = 0;
1065
1066        if (time_after(next_polling, jiffies))
1067                CM_MIN_VALID(wakeup_ms,
1068                        jiffies_to_msecs(next_polling - jiffies));
1069
1070        mutex_lock(&cm_list_mtx);
1071        list_for_each_entry(cm, &cm_list, entry) {
1072                unsigned int fbchk_ms = 0;
1073
1074                /* fullbatt_vchk is required. setup timer for that */
1075                if (cm->fullbatt_vchk_jiffies_at) {
1076                        fbchk_ms = jiffies_to_msecs(cm->fullbatt_vchk_jiffies_at
1077                                                    - jiffies);
1078                        if (time_is_before_eq_jiffies(
1079                                cm->fullbatt_vchk_jiffies_at) ||
1080                                msecs_to_jiffies(fbchk_ms) < CM_JIFFIES_SMALL) {
1081                                fullbatt_vchk(&cm->fullbatt_vchk_work.work);
1082                                fbchk_ms = 0;
1083                        }
1084                }
1085                CM_MIN_VALID(wakeup_ms, fbchk_ms);
1086
1087                /* Skip if polling is not required for this CM */
1088                if (!is_polling_required(cm) && !cm->emergency_stop)
1089                        continue;
1090                timer_req++;
1091                if (cm->desc->polling_interval_ms == 0)
1092                        continue;
1093                CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms);
1094        }
1095        mutex_unlock(&cm_list_mtx);
1096
1097        if (timer_req && cm_timer) {
1098                ktime_t now, add;
1099
1100                /*
1101                 * Set alarm with the polling interval (wakeup_ms)
1102                 * The alarm time should be NOW + CM_RTC_SMALL or later.
1103                 */
1104                if (wakeup_ms == UINT_MAX ||
1105                        wakeup_ms < CM_RTC_SMALL * MSEC_PER_SEC)
1106                        wakeup_ms = 2 * CM_RTC_SMALL * MSEC_PER_SEC;
1107
1108                pr_info("Charger Manager wakeup timer: %u ms\n", wakeup_ms);
1109
1110                now = ktime_get_boottime();
1111                add = ktime_set(wakeup_ms / MSEC_PER_SEC,
1112                                (wakeup_ms % MSEC_PER_SEC) * NSEC_PER_MSEC);
1113                alarm_start(cm_timer, ktime_add(now, add));
1114
1115                cm_suspend_duration_ms = wakeup_ms;
1116
1117                return true;
1118        }
1119        return false;
1120}
1121
1122/**
1123 * charger_extcon_work - enable/diable charger according to the state
1124 *                      of charger cable
1125 *
1126 * @work: work_struct of the function charger_extcon_work.
1127 */
1128static void charger_extcon_work(struct work_struct *work)
1129{
1130        struct charger_cable *cable =
1131                        container_of(work, struct charger_cable, wq);
1132        int ret;
1133
1134        if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) {
1135                ret = regulator_set_current_limit(cable->charger->consumer,
1136                                        cable->min_uA, cable->max_uA);
1137                if (ret < 0) {
1138                        pr_err("Cannot set current limit of %s (%s)\n",
1139                               cable->charger->regulator_name, cable->name);
1140                        return;
1141                }
1142
1143                pr_info("Set current limit of %s : %duA ~ %duA\n",
1144                        cable->charger->regulator_name,
1145                        cable->min_uA, cable->max_uA);
1146        }
1147
1148        try_charger_enable(cable->cm, cable->attached);
1149}
1150
1151/**
1152 * charger_extcon_notifier - receive the state of charger cable
1153 *                      when registered cable is attached or detached.
1154 *
1155 * @self: the notifier block of the charger_extcon_notifier.
1156 * @event: the cable state.
1157 * @ptr: the data pointer of notifier block.
1158 */
1159static int charger_extcon_notifier(struct notifier_block *self,
1160                        unsigned long event, void *ptr)
1161{
1162        struct charger_cable *cable =
1163                container_of(self, struct charger_cable, nb);
1164
1165        /*
1166         * The newly state of charger cable.
1167         * If cable is attached, cable->attached is true.
1168         */
1169        cable->attached = event;
1170
1171        /*
1172         * Setup monitoring to check battery state
1173         * when charger cable is attached.
1174         */
1175        if (cable->attached && is_polling_required(cable->cm)) {
1176                cancel_work_sync(&setup_polling);
1177                schedule_work(&setup_polling);
1178        }
1179
1180        /*
1181         * Setup work for controlling charger(regulator)
1182         * according to charger cable.
1183         */
1184        schedule_work(&cable->wq);
1185
1186        return NOTIFY_DONE;
1187}
1188
1189/**
1190 * charger_extcon_init - register external connector to use it
1191 *                      as the charger cable
1192 *
1193 * @cm: the Charger Manager representing the battery.
1194 * @cable: the Charger cable representing the external connector.
1195 */
1196static int charger_extcon_init(struct charger_manager *cm,
1197                struct charger_cable *cable)
1198{
1199        int ret;
1200
1201        /*
1202         * Charger manager use Extcon framework to identify
1203         * the charger cable among various external connector
1204         * cable (e.g., TA, USB, MHL, Dock).
1205         */
1206        INIT_WORK(&cable->wq, charger_extcon_work);
1207        cable->nb.notifier_call = charger_extcon_notifier;
1208        ret = extcon_register_interest(&cable->extcon_dev,
1209                        cable->extcon_name, cable->name, &cable->nb);
1210        if (ret < 0) {
1211                pr_info("Cannot register extcon_dev for %s(cable: %s)\n",
1212                        cable->extcon_name, cable->name);
1213        }
1214
1215        return ret;
1216}
1217
1218/**
1219 * charger_manager_register_extcon - Register extcon device to receive state
1220 *                                   of charger cable.
1221 * @cm: the Charger Manager representing the battery.
1222 *
1223 * This function support EXTCON(External Connector) subsystem to detect the
1224 * state of charger cables for enabling or disabling charger(regulator) and
1225 * select the charger cable for charging among a number of external cable
1226 * according to policy of H/W board.
1227 */
1228static int charger_manager_register_extcon(struct charger_manager *cm)
1229{
1230        struct charger_desc *desc = cm->desc;
1231        struct charger_regulator *charger;
1232        int ret;
1233        int i;
1234        int j;
1235
1236        for (i = 0; i < desc->num_charger_regulators; i++) {
1237                charger = &desc->charger_regulators[i];
1238
1239                charger->consumer = regulator_get(cm->dev,
1240                                        charger->regulator_name);
1241                if (IS_ERR(charger->consumer)) {
1242                        dev_err(cm->dev, "Cannot find charger(%s)\n",
1243                                charger->regulator_name);
1244                        return PTR_ERR(charger->consumer);
1245                }
1246                charger->cm = cm;
1247
1248                for (j = 0; j < charger->num_cables; j++) {
1249                        struct charger_cable *cable = &charger->cables[j];
1250
1251                        ret = charger_extcon_init(cm, cable);
1252                        if (ret < 0) {
1253                                dev_err(cm->dev, "Cannot initialize charger(%s)\n",
1254                                        charger->regulator_name);
1255                                return ret;
1256                        }
1257                        cable->charger = charger;
1258                        cable->cm = cm;
1259                }
1260        }
1261
1262        return 0;
1263}
1264
1265/* help function of sysfs node to control charger(regulator) */
1266static ssize_t charger_name_show(struct device *dev,
1267                                struct device_attribute *attr, char *buf)
1268{
1269        struct charger_regulator *charger
1270                = container_of(attr, struct charger_regulator, attr_name);
1271
1272        return sprintf(buf, "%s\n", charger->regulator_name);
1273}
1274
1275static ssize_t charger_state_show(struct device *dev,
1276                                struct device_attribute *attr, char *buf)
1277{
1278        struct charger_regulator *charger
1279                = container_of(attr, struct charger_regulator, attr_state);
1280        int state = 0;
1281
1282        if (!charger->externally_control)
1283                state = regulator_is_enabled(charger->consumer);
1284
1285        return sprintf(buf, "%s\n", state ? "enabled" : "disabled");
1286}
1287
1288static ssize_t charger_externally_control_show(struct device *dev,
1289                                struct device_attribute *attr, char *buf)
1290{
1291        struct charger_regulator *charger = container_of(attr,
1292                        struct charger_regulator, attr_externally_control);
1293
1294        return sprintf(buf, "%d\n", charger->externally_control);
1295}
1296
1297static ssize_t charger_externally_control_store(struct device *dev,
1298                                struct device_attribute *attr, const char *buf,
1299                                size_t count)
1300{
1301        struct charger_regulator *charger
1302                = container_of(attr, struct charger_regulator,
1303                                        attr_externally_control);
1304        struct charger_manager *cm = charger->cm;
1305        struct charger_desc *desc = cm->desc;
1306        int i;
1307        int ret;
1308        int externally_control;
1309        int chargers_externally_control = 1;
1310
1311        ret = sscanf(buf, "%d", &externally_control);
1312        if (ret == 0) {
1313                ret = -EINVAL;
1314                return ret;
1315        }
1316
1317        if (!externally_control) {
1318                charger->externally_control = 0;
1319                return count;
1320        }
1321
1322        for (i = 0; i < desc->num_charger_regulators; i++) {
1323                if (&desc->charger_regulators[i] != charger &&
1324                        !desc->charger_regulators[i].externally_control) {
1325                        /*
1326                         * At least, one charger is controlled by
1327                         * charger-manager
1328                         */
1329                        chargers_externally_control = 0;
1330                        break;
1331                }
1332        }
1333
1334        if (!chargers_externally_control) {
1335                if (cm->charger_enabled) {
1336                        try_charger_enable(charger->cm, false);
1337                        charger->externally_control = externally_control;
1338                        try_charger_enable(charger->cm, true);
1339                } else {
1340                        charger->externally_control = externally_control;
1341                }
1342        } else {
1343                dev_warn(cm->dev,
1344                         "'%s' regulator should be controlled in charger-manager because charger-manager must need at least one charger for charging\n",
1345                         charger->regulator_name);
1346        }
1347
1348        return count;
1349}
1350
1351/**
1352 * charger_manager_prepare_sysfs - Prepare sysfs entry for each charger
1353 * @cm: the Charger Manager representing the battery.
1354 *
1355 * This function add sysfs entry for charger(regulator) to control charger from
1356 * user-space. If some development board use one more chargers for charging
1357 * but only need one charger on specific case which is dependent on user
1358 * scenario or hardware restrictions, the user enter 1 or 0(zero) to '/sys/
1359 * class/power_supply/battery/charger.[index]/externally_control'. For example,
1360 * if user enter 1 to 'sys/class/power_supply/battery/charger.[index]/
1361 * externally_control, this charger isn't controlled from charger-manager and
1362 * always stay off state of regulator.
1363 */
1364static int charger_manager_prepare_sysfs(struct charger_manager *cm)
1365{
1366        struct charger_desc *desc = cm->desc;
1367        struct charger_regulator *charger;
1368        int chargers_externally_control = 1;
1369        char *name;
1370        int i;
1371
1372        /* Create sysfs entry to control charger(regulator) */
1373        for (i = 0; i < desc->num_charger_regulators; i++) {
1374                charger = &desc->charger_regulators[i];
1375
1376                name = devm_kasprintf(cm->dev, GFP_KERNEL, "charger.%d", i);
1377                if (!name)
1378                        return -ENOMEM;
1379
1380                charger->attrs[0] = &charger->attr_name.attr;
1381                charger->attrs[1] = &charger->attr_state.attr;
1382                charger->attrs[2] = &charger->attr_externally_control.attr;
1383                charger->attrs[3] = NULL;
1384
1385                charger->attr_grp.name = name;
1386                charger->attr_grp.attrs = charger->attrs;
1387                desc->sysfs_groups[i] = &charger->attr_grp;
1388
1389                sysfs_attr_init(&charger->attr_name.attr);
1390                charger->attr_name.attr.name = "name";
1391                charger->attr_name.attr.mode = 0444;
1392                charger->attr_name.show = charger_name_show;
1393
1394                sysfs_attr_init(&charger->attr_state.attr);
1395                charger->attr_state.attr.name = "state";
1396                charger->attr_state.attr.mode = 0444;
1397                charger->attr_state.show = charger_state_show;
1398
1399                sysfs_attr_init(&charger->attr_externally_control.attr);
1400                charger->attr_externally_control.attr.name
1401                                = "externally_control";
1402                charger->attr_externally_control.attr.mode = 0644;
1403                charger->attr_externally_control.show
1404                                = charger_externally_control_show;
1405                charger->attr_externally_control.store
1406                                = charger_externally_control_store;
1407
1408                if (!desc->charger_regulators[i].externally_control ||
1409                                !chargers_externally_control)
1410                        chargers_externally_control = 0;
1411
1412                dev_info(cm->dev, "'%s' regulator's externally_control is %d\n",
1413                         charger->regulator_name, charger->externally_control);
1414        }
1415
1416        if (chargers_externally_control) {
1417                dev_err(cm->dev, "Cannot register regulator because charger-manager must need at least one charger for charging battery\n");
1418                return -EINVAL;
1419        }
1420
1421        return 0;
1422}
1423
1424static int cm_init_thermal_data(struct charger_manager *cm,
1425                struct power_supply *fuel_gauge)
1426{
1427        struct charger_desc *desc = cm->desc;
1428        union power_supply_propval val;
1429        int ret;
1430
1431        /* Verify whether fuel gauge provides battery temperature */
1432        ret = power_supply_get_property(fuel_gauge,
1433                                        POWER_SUPPLY_PROP_TEMP, &val);
1434
1435        if (!ret) {
1436                cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
1437                                POWER_SUPPLY_PROP_TEMP;
1438                cm->charger_psy_desc.num_properties++;
1439                cm->desc->measure_battery_temp = true;
1440        }
1441#ifdef CONFIG_THERMAL
1442        if (ret && desc->thermal_zone) {
1443                cm->tzd_batt =
1444                        thermal_zone_get_zone_by_name(desc->thermal_zone);
1445                if (IS_ERR(cm->tzd_batt))
1446                        return PTR_ERR(cm->tzd_batt);
1447
1448                /* Use external thermometer */
1449                cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
1450                                POWER_SUPPLY_PROP_TEMP_AMBIENT;
1451                cm->charger_psy_desc.num_properties++;
1452                cm->desc->measure_battery_temp = true;
1453                ret = 0;
1454        }
1455#endif
1456        if (cm->desc->measure_battery_temp) {
1457                /* NOTICE : Default allowable minimum charge temperature is 0 */
1458                if (!desc->temp_max)
1459                        desc->temp_max = CM_DEFAULT_CHARGE_TEMP_MAX;
1460                if (!desc->temp_diff)
1461                        desc->temp_diff = CM_DEFAULT_RECHARGE_TEMP_DIFF;
1462        }
1463
1464        return ret;
1465}
1466
1467static const struct of_device_id charger_manager_match[] = {
1468        {
1469                .compatible = "charger-manager",
1470        },
1471        {},
1472};
1473
1474static struct charger_desc *of_cm_parse_desc(struct device *dev)
1475{
1476        struct charger_desc *desc;
1477        struct device_node *np = dev->of_node;
1478        u32 poll_mode = CM_POLL_DISABLE;
1479        u32 battery_stat = CM_NO_BATTERY;
1480        int num_chgs = 0;
1481
1482        desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
1483        if (!desc)
1484                return ERR_PTR(-ENOMEM);
1485
1486        of_property_read_string(np, "cm-name", &desc->psy_name);
1487
1488        of_property_read_u32(np, "cm-poll-mode", &poll_mode);
1489        desc->polling_mode = poll_mode;
1490
1491        of_property_read_u32(np, "cm-poll-interval",
1492                                &desc->polling_interval_ms);
1493
1494        of_property_read_u32(np, "cm-fullbatt-vchkdrop-ms",
1495                                        &desc->fullbatt_vchkdrop_ms);
1496        of_property_read_u32(np, "cm-fullbatt-vchkdrop-volt",
1497                                        &desc->fullbatt_vchkdrop_uV);
1498        of_property_read_u32(np, "cm-fullbatt-voltage", &desc->fullbatt_uV);
1499        of_property_read_u32(np, "cm-fullbatt-soc", &desc->fullbatt_soc);
1500        of_property_read_u32(np, "cm-fullbatt-capacity",
1501                                        &desc->fullbatt_full_capacity);
1502
1503        of_property_read_u32(np, "cm-battery-stat", &battery_stat);
1504        desc->battery_present = battery_stat;
1505
1506        /* chargers */
1507        of_property_read_u32(np, "cm-num-chargers", &num_chgs);
1508        if (num_chgs) {
1509                int i;
1510
1511                /* Allocate empty bin at the tail of array */
1512                desc->psy_charger_stat = devm_kcalloc(dev,
1513                                                      num_chgs + 1,
1514                                                      sizeof(char *),
1515                                                      GFP_KERNEL);
1516                if (!desc->psy_charger_stat)
1517                        return ERR_PTR(-ENOMEM);
1518
1519                for (i = 0; i < num_chgs; i++)
1520                        of_property_read_string_index(np, "cm-chargers",
1521                                                      i, &desc->psy_charger_stat[i]);
1522        }
1523
1524        of_property_read_string(np, "cm-fuel-gauge", &desc->psy_fuel_gauge);
1525
1526        of_property_read_string(np, "cm-thermal-zone", &desc->thermal_zone);
1527
1528        of_property_read_u32(np, "cm-battery-cold", &desc->temp_min);
1529        if (of_get_property(np, "cm-battery-cold-in-minus", NULL))
1530                desc->temp_min *= -1;
1531        of_property_read_u32(np, "cm-battery-hot", &desc->temp_max);
1532        of_property_read_u32(np, "cm-battery-temp-diff", &desc->temp_diff);
1533
1534        of_property_read_u32(np, "cm-charging-max",
1535                                &desc->charging_max_duration_ms);
1536        of_property_read_u32(np, "cm-discharging-max",
1537                                &desc->discharging_max_duration_ms);
1538
1539        /* battery charger regulators */
1540        desc->num_charger_regulators = of_get_child_count(np);
1541        if (desc->num_charger_regulators) {
1542                struct charger_regulator *chg_regs;
1543                struct device_node *child;
1544
1545                chg_regs = devm_kcalloc(dev,
1546                                        desc->num_charger_regulators,
1547                                        sizeof(*chg_regs),
1548                                        GFP_KERNEL);
1549                if (!chg_regs)
1550                        return ERR_PTR(-ENOMEM);
1551
1552                desc->charger_regulators = chg_regs;
1553
1554                desc->sysfs_groups = devm_kcalloc(dev,
1555                                        desc->num_charger_regulators + 1,
1556                                        sizeof(*desc->sysfs_groups),
1557                                        GFP_KERNEL);
1558                if (!desc->sysfs_groups)
1559                        return ERR_PTR(-ENOMEM);
1560
1561                for_each_child_of_node(np, child) {
1562                        struct charger_cable *cables;
1563                        struct device_node *_child;
1564
1565                        of_property_read_string(child, "cm-regulator-name",
1566                                        &chg_regs->regulator_name);
1567
1568                        /* charger cables */
1569                        chg_regs->num_cables = of_get_child_count(child);
1570                        if (chg_regs->num_cables) {
1571                                cables = devm_kcalloc(dev,
1572                                                      chg_regs->num_cables,
1573                                                      sizeof(*cables),
1574                                                      GFP_KERNEL);
1575                                if (!cables) {
1576                                        of_node_put(child);
1577                                        return ERR_PTR(-ENOMEM);
1578                                }
1579
1580                                chg_regs->cables = cables;
1581
1582                                for_each_child_of_node(child, _child) {
1583                                        of_property_read_string(_child,
1584                                        "cm-cable-name", &cables->name);
1585                                        of_property_read_string(_child,
1586                                        "cm-cable-extcon",
1587                                        &cables->extcon_name);
1588                                        of_property_read_u32(_child,
1589                                        "cm-cable-min",
1590                                        &cables->min_uA);
1591                                        of_property_read_u32(_child,
1592                                        "cm-cable-max",
1593                                        &cables->max_uA);
1594                                        cables++;
1595                                }
1596                        }
1597                        chg_regs++;
1598                }
1599        }
1600        return desc;
1601}
1602
1603static inline struct charger_desc *cm_get_drv_data(struct platform_device *pdev)
1604{
1605        if (pdev->dev.of_node)
1606                return of_cm_parse_desc(&pdev->dev);
1607        return dev_get_platdata(&pdev->dev);
1608}
1609
1610static enum alarmtimer_restart cm_timer_func(struct alarm *alarm, ktime_t now)
1611{
1612        cm_timer_set = false;
1613        return ALARMTIMER_NORESTART;
1614}
1615
1616static int charger_manager_probe(struct platform_device *pdev)
1617{
1618        struct charger_desc *desc = cm_get_drv_data(pdev);
1619        struct charger_manager *cm;
1620        int ret, i = 0;
1621        int j = 0;
1622        union power_supply_propval val;
1623        struct power_supply *fuel_gauge;
1624        struct power_supply_config psy_cfg = {};
1625
1626        if (IS_ERR(desc)) {
1627                dev_err(&pdev->dev, "No platform data (desc) found\n");
1628                return PTR_ERR(desc);
1629        }
1630
1631        cm = devm_kzalloc(&pdev->dev, sizeof(*cm), GFP_KERNEL);
1632        if (!cm)
1633                return -ENOMEM;
1634
1635        /* Basic Values. Unspecified are Null or 0 */
1636        cm->dev = &pdev->dev;
1637        cm->desc = desc;
1638        psy_cfg.drv_data = cm;
1639
1640        /* Initialize alarm timer */
1641        if (alarmtimer_get_rtcdev()) {
1642                cm_timer = devm_kzalloc(cm->dev, sizeof(*cm_timer), GFP_KERNEL);
1643                if (!cm_timer)
1644                        return -ENOMEM;
1645                alarm_init(cm_timer, ALARM_BOOTTIME, cm_timer_func);
1646        }
1647
1648        /*
1649         * Some of the following do not need to be errors.
1650         * Users may intentionally ignore those features.
1651         */
1652        if (desc->fullbatt_uV == 0) {
1653                dev_info(&pdev->dev, "Ignoring full-battery voltage threshold as it is not supplied\n");
1654        }
1655        if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) {
1656                dev_info(&pdev->dev, "Disabling full-battery voltage drop checking mechanism as it is not supplied\n");
1657                desc->fullbatt_vchkdrop_ms = 0;
1658                desc->fullbatt_vchkdrop_uV = 0;
1659        }
1660        if (desc->fullbatt_soc == 0) {
1661                dev_info(&pdev->dev, "Ignoring full-battery soc(state of charge) threshold as it is not supplied\n");
1662        }
1663        if (desc->fullbatt_full_capacity == 0) {
1664                dev_info(&pdev->dev, "Ignoring full-battery full capacity threshold as it is not supplied\n");
1665        }
1666
1667        if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
1668                dev_err(&pdev->dev, "charger_regulators undefined\n");
1669                return -EINVAL;
1670        }
1671
1672        if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
1673                dev_err(&pdev->dev, "No power supply defined\n");
1674                return -EINVAL;
1675        }
1676
1677        if (!desc->psy_fuel_gauge) {
1678                dev_err(&pdev->dev, "No fuel gauge power supply defined\n");
1679                return -EINVAL;
1680        }
1681
1682        /* Check if charger's supplies are present at probe */
1683        for (i = 0; desc->psy_charger_stat[i]; i++) {
1684                struct power_supply *psy;
1685
1686                psy = power_supply_get_by_name(desc->psy_charger_stat[i]);
1687                if (!psy) {
1688                        dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
1689                                desc->psy_charger_stat[i]);
1690                        return -ENODEV;
1691                }
1692                power_supply_put(psy);
1693        }
1694
1695        if (cm->desc->polling_mode != CM_POLL_DISABLE &&
1696            (desc->polling_interval_ms == 0 ||
1697             msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL)) {
1698                dev_err(&pdev->dev, "polling_interval_ms is too small\n");
1699                return -EINVAL;
1700        }
1701
1702        if (!desc->charging_max_duration_ms ||
1703                        !desc->discharging_max_duration_ms) {
1704                dev_info(&pdev->dev, "Cannot limit charging duration checking mechanism to prevent overcharge/overheat and control discharging duration\n");
1705                desc->charging_max_duration_ms = 0;
1706                desc->discharging_max_duration_ms = 0;
1707        }
1708
1709        platform_set_drvdata(pdev, cm);
1710
1711        memcpy(&cm->charger_psy_desc, &psy_default, sizeof(psy_default));
1712
1713        if (!desc->psy_name)
1714                strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX);
1715        else
1716                strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
1717        cm->charger_psy_desc.name = cm->psy_name_buf;
1718
1719        /* Allocate for psy properties because they may vary */
1720        cm->charger_psy_desc.properties =
1721                devm_kcalloc(&pdev->dev,
1722                             ARRAY_SIZE(default_charger_props) +
1723                                NUM_CHARGER_PSY_OPTIONAL,
1724                             sizeof(enum power_supply_property), GFP_KERNEL);
1725        if (!cm->charger_psy_desc.properties)
1726                return -ENOMEM;
1727
1728        memcpy(cm->charger_psy_desc.properties, default_charger_props,
1729                sizeof(enum power_supply_property) *
1730                ARRAY_SIZE(default_charger_props));
1731        cm->charger_psy_desc.num_properties = psy_default.num_properties;
1732
1733        /* Find which optional psy-properties are available */
1734        fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
1735        if (!fuel_gauge) {
1736                dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
1737                        desc->psy_fuel_gauge);
1738                return -ENODEV;
1739        }
1740        if (!power_supply_get_property(fuel_gauge,
1741                                          POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
1742                cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
1743                                POWER_SUPPLY_PROP_CHARGE_NOW;
1744                cm->charger_psy_desc.num_properties++;
1745        }
1746        if (!power_supply_get_property(fuel_gauge,
1747                                          POWER_SUPPLY_PROP_CURRENT_NOW,
1748                                          &val)) {
1749                cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
1750                                POWER_SUPPLY_PROP_CURRENT_NOW;
1751                cm->charger_psy_desc.num_properties++;
1752        }
1753
1754        ret = cm_init_thermal_data(cm, fuel_gauge);
1755        if (ret) {
1756                dev_err(&pdev->dev, "Failed to initialize thermal data\n");
1757                cm->desc->measure_battery_temp = false;
1758        }
1759        power_supply_put(fuel_gauge);
1760
1761        INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
1762
1763        /* Register sysfs entry for charger(regulator) */
1764        ret = charger_manager_prepare_sysfs(cm);
1765        if (ret < 0) {
1766                dev_err(&pdev->dev,
1767                        "Cannot prepare sysfs entry of regulators\n");
1768                return ret;
1769        }
1770        psy_cfg.attr_grp = desc->sysfs_groups;
1771
1772        cm->charger_psy = power_supply_register(&pdev->dev,
1773                                                &cm->charger_psy_desc,
1774                                                &psy_cfg);
1775        if (IS_ERR(cm->charger_psy)) {
1776                dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n",
1777                        cm->charger_psy_desc.name);
1778                return PTR_ERR(cm->charger_psy);
1779        }
1780
1781        /* Register extcon device for charger cable */
1782        ret = charger_manager_register_extcon(cm);
1783        if (ret < 0) {
1784                dev_err(&pdev->dev, "Cannot initialize extcon device\n");
1785                goto err_reg_extcon;
1786        }
1787
1788        /* Add to the list */
1789        mutex_lock(&cm_list_mtx);
1790        list_add(&cm->entry, &cm_list);
1791        mutex_unlock(&cm_list_mtx);
1792
1793        /*
1794         * Charger-manager is capable of waking up the systme from sleep
1795         * when event is happened through cm_notify_event()
1796         */
1797        device_init_wakeup(&pdev->dev, true);
1798        device_set_wakeup_capable(&pdev->dev, false);
1799
1800        /*
1801         * Charger-manager have to check the charging state right after
1802         * initialization of charger-manager and then update current charging
1803         * state.
1804         */
1805        cm_monitor();
1806
1807        schedule_work(&setup_polling);
1808
1809        return 0;
1810
1811err_reg_extcon:
1812        for (i = 0; i < desc->num_charger_regulators; i++) {
1813                struct charger_regulator *charger;
1814
1815                charger = &desc->charger_regulators[i];
1816                for (j = 0; j < charger->num_cables; j++) {
1817                        struct charger_cable *cable = &charger->cables[j];
1818                        /* Remove notifier block if only edev exists */
1819                        if (cable->extcon_dev.edev)
1820                                extcon_unregister_interest(&cable->extcon_dev);
1821                }
1822
1823                regulator_put(desc->charger_regulators[i].consumer);
1824        }
1825
1826        power_supply_unregister(cm->charger_psy);
1827
1828        return ret;
1829}
1830
1831static int charger_manager_remove(struct platform_device *pdev)
1832{
1833        struct charger_manager *cm = platform_get_drvdata(pdev);
1834        struct charger_desc *desc = cm->desc;
1835        int i = 0;
1836        int j = 0;
1837
1838        /* Remove from the list */
1839        mutex_lock(&cm_list_mtx);
1840        list_del(&cm->entry);
1841        mutex_unlock(&cm_list_mtx);
1842
1843        cancel_work_sync(&setup_polling);
1844        cancel_delayed_work_sync(&cm_monitor_work);
1845
1846        for (i = 0 ; i < desc->num_charger_regulators ; i++) {
1847                struct charger_regulator *charger
1848                                = &desc->charger_regulators[i];
1849                for (j = 0 ; j < charger->num_cables ; j++) {
1850                        struct charger_cable *cable = &charger->cables[j];
1851                        extcon_unregister_interest(&cable->extcon_dev);
1852                }
1853        }
1854
1855        for (i = 0 ; i < desc->num_charger_regulators ; i++)
1856                regulator_put(desc->charger_regulators[i].consumer);
1857
1858        power_supply_unregister(cm->charger_psy);
1859
1860        try_charger_enable(cm, false);
1861
1862        return 0;
1863}
1864
1865static const struct platform_device_id charger_manager_id[] = {
1866        { "charger-manager", 0 },
1867        { },
1868};
1869MODULE_DEVICE_TABLE(platform, charger_manager_id);
1870
1871static int cm_suspend_noirq(struct device *dev)
1872{
1873        if (device_may_wakeup(dev)) {
1874                device_set_wakeup_capable(dev, false);
1875                return -EAGAIN;
1876        }
1877
1878        return 0;
1879}
1880
1881static bool cm_need_to_awake(void)
1882{
1883        struct charger_manager *cm;
1884
1885        if (cm_timer)
1886                return false;
1887
1888        mutex_lock(&cm_list_mtx);
1889        list_for_each_entry(cm, &cm_list, entry) {
1890                if (is_charging(cm)) {
1891                        mutex_unlock(&cm_list_mtx);
1892                        return true;
1893                }
1894        }
1895        mutex_unlock(&cm_list_mtx);
1896
1897        return false;
1898}
1899
1900static int cm_suspend_prepare(struct device *dev)
1901{
1902        struct charger_manager *cm = dev_get_drvdata(dev);
1903
1904        if (cm_need_to_awake())
1905                return -EBUSY;
1906
1907        if (!cm_suspended)
1908                cm_suspended = true;
1909
1910        cm_timer_set = cm_setup_timer();
1911
1912        if (cm_timer_set) {
1913                cancel_work_sync(&setup_polling);
1914                cancel_delayed_work_sync(&cm_monitor_work);
1915                cancel_delayed_work(&cm->fullbatt_vchk_work);
1916        }
1917
1918        return 0;
1919}
1920
1921static void cm_suspend_complete(struct device *dev)
1922{
1923        struct charger_manager *cm = dev_get_drvdata(dev);
1924
1925        if (cm_suspended)
1926                cm_suspended = false;
1927
1928        if (cm_timer_set) {
1929                ktime_t remain;
1930
1931                alarm_cancel(cm_timer);
1932                cm_timer_set = false;
1933                remain = alarm_expires_remaining(cm_timer);
1934                cm_suspend_duration_ms -= ktime_to_ms(remain);
1935                schedule_work(&setup_polling);
1936        }
1937
1938        _cm_monitor(cm);
1939
1940        /* Re-enqueue delayed work (fullbatt_vchk_work) */
1941        if (cm->fullbatt_vchk_jiffies_at) {
1942                unsigned long delay = 0;
1943                unsigned long now = jiffies + CM_JIFFIES_SMALL;
1944
1945                if (time_after_eq(now, cm->fullbatt_vchk_jiffies_at)) {
1946                        delay = (unsigned long)((long)now
1947                                - (long)(cm->fullbatt_vchk_jiffies_at));
1948                        delay = jiffies_to_msecs(delay);
1949                } else {
1950                        delay = 0;
1951                }
1952
1953                /*
1954                 * Account for cm_suspend_duration_ms with assuming that
1955                 * timer stops in suspend.
1956                 */
1957                if (delay > cm_suspend_duration_ms)
1958                        delay -= cm_suspend_duration_ms;
1959                else
1960                        delay = 0;
1961
1962                queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
1963                                   msecs_to_jiffies(delay));
1964        }
1965        device_set_wakeup_capable(cm->dev, false);
1966}
1967
1968static const struct dev_pm_ops charger_manager_pm = {
1969        .prepare        = cm_suspend_prepare,
1970        .suspend_noirq  = cm_suspend_noirq,
1971        .complete       = cm_suspend_complete,
1972};
1973
1974static struct platform_driver charger_manager_driver = {
1975        .driver = {
1976                .name = "charger-manager",
1977                .pm = &charger_manager_pm,
1978                .of_match_table = charger_manager_match,
1979        },
1980        .probe = charger_manager_probe,
1981        .remove = charger_manager_remove,
1982        .id_table = charger_manager_id,
1983};
1984
1985static int __init charger_manager_init(void)
1986{
1987        cm_wq = create_freezable_workqueue("charger_manager");
1988        if (unlikely(!cm_wq))
1989                return -ENOMEM;
1990
1991        INIT_DELAYED_WORK(&cm_monitor_work, cm_monitor_poller);
1992
1993        return platform_driver_register(&charger_manager_driver);
1994}
1995late_initcall(charger_manager_init);
1996
1997static void __exit charger_manager_cleanup(void)
1998{
1999        destroy_workqueue(cm_wq);
2000        cm_wq = NULL;
2001
2002        platform_driver_unregister(&charger_manager_driver);
2003}
2004module_exit(charger_manager_cleanup);
2005
2006/**
2007 * cm_notify_event - charger driver notify Charger Manager of charger event
2008 * @psy: pointer to instance of charger's power_supply
2009 * @type: type of charger event
2010 * @msg: optional message passed to uevent_notify function
2011 */
2012void cm_notify_event(struct power_supply *psy, enum cm_event_types type,
2013                     char *msg)
2014{
2015        struct charger_manager *cm;
2016        bool found_power_supply = false;
2017
2018        if (psy == NULL)
2019                return;
2020
2021        mutex_lock(&cm_list_mtx);
2022        list_for_each_entry(cm, &cm_list, entry) {
2023                if (match_string(cm->desc->psy_charger_stat, -1,
2024                                 psy->desc->name) >= 0) {
2025                        found_power_supply = true;
2026                        break;
2027                }
2028        }
2029        mutex_unlock(&cm_list_mtx);
2030
2031        if (!found_power_supply)
2032                return;
2033
2034        switch (type) {
2035        case CM_EVENT_BATT_FULL:
2036                fullbatt_handler(cm);
2037                break;
2038        case CM_EVENT_BATT_OUT:
2039                battout_handler(cm);
2040                break;
2041        case CM_EVENT_BATT_IN:
2042        case CM_EVENT_EXT_PWR_IN_OUT ... CM_EVENT_CHG_START_STOP:
2043                misc_event_handler(cm, type);
2044                break;
2045        case CM_EVENT_UNKNOWN:
2046        case CM_EVENT_OTHERS:
2047                uevent_notify(cm, msg ? msg : default_event_names[type]);
2048                break;
2049        default:
2050                dev_err(cm->dev, "%s: type not specified\n", __func__);
2051                break;
2052        }
2053}
2054EXPORT_SYMBOL_GPL(cm_notify_event);
2055
2056MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
2057MODULE_DESCRIPTION("Charger Manager");
2058MODULE_LICENSE("GPL");
2059