Merge branch 'power-supply-scope' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorAnton Vorontsov <cbouatmailru@gmail.com>
Wed, 4 Jan 2012 05:09:35 +0000 (09:09 +0400)
committerAnton Vorontsov <cbouatmailru@gmail.com>
Wed, 4 Jan 2012 05:09:35 +0000 (09:09 +0400)
1  2 
drivers/power/Kconfig
drivers/power/ds2780_battery.c
drivers/power/max17042_battery.c
drivers/power/max8903_charger.c
drivers/power/max8997_charger.c
drivers/power/max8998_charger.c
drivers/power/power_supply_sysfs.c
include/linux/power_supply.h

diff --combined drivers/power/Kconfig
index ac807c4fda57b3416b6f5769590679fd4b917581,9f88641e67f9255e0219071eb5a702a1289bb066..3bd2ed86fea2e71b5fadacf451a82dade4b68fe6
@@@ -70,6 -70,7 +70,7 @@@ config BATTERY_DS276
  
  config BATTERY_DS2780
        tristate "DS2780 battery driver"
+       depends on HAS_IOMEM
        select W1
        select W1_SLAVE_DS2780
        help
@@@ -225,12 -226,6 +226,12 @@@ config CHARGER_TWL403
        help
          Say Y here to enable support for TWL4030 Battery Charge Interface.
  
 +config CHARGER_LP8727
 +      tristate "National Semiconductor LP8727 charger driver"
 +      depends on I2C
 +      help
 +        Say Y here to enable support for LP8727 Charger Driver.
 +
  config CHARGER_GPIO
        tristate "GPIO charger"
        depends on GPIOLIB
          This driver can be build as a module. If so, the module will be
          called gpio-charger.
  
 +config CHARGER_MANAGER
 +      bool "Battery charger manager for multiple chargers"
 +      depends on REGULATOR && RTC_CLASS
 +      help
 +          Say Y to enable charger-manager support, which allows multiple
 +          chargers attached to a battery and multiple batteries attached to a
 +          system. The charger-manager also can monitor charging status in
 +          runtime and in suspend-to-RAM by waking up the system periodically
 +          with help of suspend_again support.
 +
  config CHARGER_MAX8997
        tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
        depends on MFD_MAX8997 && REGULATOR_MAX8997
index ed25ef5887d47c381812c88bb51d16ae49c8e596,91a783d72360b314094a134d5284a89e751b3ca9..887ec98d8c22063ff85754e6d749ac16f6460652
@@@ -39,6 -39,7 +39,7 @@@ struct ds2780_device_info 
        struct device *dev;
        struct power_supply bat;
        struct device *w1_dev;
+       struct task_struct *mutex_holder;
  };
  
  enum current_types {
@@@ -49,8 -50,8 +50,8 @@@
  static const char model[] = "DS2780";
  static const char manufacturer[] = "Maxim/Dallas";
  
- static inline struct ds2780_device_info *to_ds2780_device_info(
      struct power_supply *psy)
+ static inline struct ds2780_device_info *
to_ds2780_device_info(struct power_supply *psy)
  {
        return container_of(psy, struct ds2780_device_info, bat);
  }
@@@ -60,17 -61,28 +61,28 @@@ static inline struct power_supply *to_p
        return dev_get_drvdata(dev);
  }
  
- static inline int ds2780_read8(struct device *dev, u8 *val, int addr)
+ static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
+       char *buf, int addr, size_t count, int io)
  {
-       return w1_ds2780_io(dev, val, addr, sizeof(u8), 0);
+       if (dev_info->mutex_holder == current)
+               return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io);
+       else
+               return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
+ }
+ static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val,
+       int addr)
+ {
+       return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0);
  }
  
- static int ds2780_read16(struct device *dev, s16 *val, int addr)
+ static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val,
+       int addr)
  {
        int ret;
        u8 raw[2];
  
-       ret = w1_ds2780_io(dev, raw, addr, sizeof(u8) * 2, 0);
+       ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0);
        if (ret < 0)
                return ret;
  
        return 0;
  }
  
- static inline int ds2780_read_block(struct device *dev, u8 *val, int addr,
-       size_t count)
+ static inline int ds2780_read_block(struct ds2780_device_info *dev_info,
+       u8 *val, int addr, size_t count)
  {
-       return w1_ds2780_io(dev, val, addr, count, 0);
+       return ds2780_battery_io(dev_info, val, addr, count, 0);
  }
  
- static inline int ds2780_write(struct device *dev, u8 *val, int addr,
-       size_t count)
+ static inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val,
+       int addr, size_t count)
  {
-       return w1_ds2780_io(dev, val, addr, count, 1);
+       return ds2780_battery_io(dev_info, val, addr, count, 1);
  }
  
  static inline int ds2780_store_eeprom(struct device *dev, int addr)
@@@ -122,7 -134,7 +134,7 @@@ static int ds2780_set_sense_register(st
  {
        int ret;
  
-       ret = ds2780_write(dev_info->w1_dev, &conductance,
+       ret = ds2780_write(dev_info, &conductance,
                                DS2780_RSNSP_REG, sizeof(u8));
        if (ret < 0)
                return ret;
  static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info,
        u16 *rsgain)
  {
-       return ds2780_read16(dev_info->w1_dev, rsgain, DS2780_RSGAIN_MSB_REG);
+       return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG);
  }
  
  /* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
@@@ -144,8 -156,8 +156,8 @@@ static int ds2780_set_rsgain_register(s
        int ret;
        u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
  
-       ret = ds2780_write(dev_info->w1_dev, raw,
-                               DS2780_RSGAIN_MSB_REG, sizeof(u8) * 2);
+       ret = ds2780_write(dev_info, raw,
+                               DS2780_RSGAIN_MSB_REG, sizeof(raw));
        if (ret < 0)
                return ret;
  
@@@ -167,7 -179,7 +179,7 @@@ static int ds2780_get_voltage(struct ds
         * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
         * voltage LSB register
         */
-       ret = ds2780_read16(dev_info->w1_dev, &voltage_raw,
+       ret = ds2780_read16(dev_info, &voltage_raw,
                                DS2780_VOLT_MSB_REG);
        if (ret < 0)
                return ret;
@@@ -196,7 -208,7 +208,7 @@@ static int ds2780_get_temperature(struc
         * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
         * temperature LSB register
         */
-       ret = ds2780_read16(dev_info->w1_dev, &temperature_raw,
+       ret = ds2780_read16(dev_info, &temperature_raw,
                                DS2780_TEMP_MSB_REG);
        if (ret < 0)
                return ret;
@@@ -222,13 -234,13 +234,13 @@@ static int ds2780_get_current(struct ds
         * The units of measurement for current are dependent on the value of
         * the sense resistor.
         */
-       ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
+       ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
        if (ret < 0)
                return ret;
  
        if (sense_res_raw == 0) {
                dev_err(dev_info->dev, "sense resistor value is 0\n");
-               return -ENXIO;
+               return -EINVAL;
        }
        sense_res = 1000 / sense_res_raw;
  
         * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
         * LSB register
         */
-       ret = ds2780_read16(dev_info->w1_dev, &current_raw, reg_msb);
+       ret = ds2780_read16(dev_info, &current_raw, reg_msb);
        if (ret < 0)
                return ret;
  
@@@ -267,7 -279,7 +279,7 @@@ static int ds2780_get_accumulated_curre
         * The units of measurement for accumulated current are dependent on
         * the value of the sense resistor.
         */
-       ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
+       ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
        if (ret < 0)
                return ret;
  
         * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
         * LSB register
         */
-       ret = ds2780_read16(dev_info->w1_dev, &current_raw, DS2780_ACR_MSB_REG);
+       ret = ds2780_read16(dev_info, &current_raw, DS2780_ACR_MSB_REG);
        if (ret < 0)
                return ret;
  
@@@ -299,7 -311,7 +311,7 @@@ static int ds2780_get_capacity(struct d
        int ret;
        u8 raw;
  
-       ret = ds2780_read8(dev_info->w1_dev, &raw, DS2780_RARC_REG);
+       ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG);
        if (ret < 0)
                return ret;
  
@@@ -345,7 -357,7 +357,7 @@@ static int ds2780_get_charge_now(struc
         * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
         * LSB register
         */
-       ret = ds2780_read16(dev_info->w1_dev, &charge_raw, DS2780_RAAC_MSB_REG);
+       ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG);
        if (ret < 0)
                return ret;
  
  static int ds2780_get_control_register(struct ds2780_device_info *dev_info,
        u8 *control_reg)
  {
-       return ds2780_read8(dev_info->w1_dev, control_reg, DS2780_CONTROL_REG);
+       return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG);
  }
  
  static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
  {
        int ret;
  
-       ret = ds2780_write(dev_info->w1_dev, &control_reg,
+       ret = ds2780_write(dev_info, &control_reg,
                                DS2780_CONTROL_REG, sizeof(u8));
        if (ret < 0)
                return ret;
@@@ -503,7 -515,7 +515,7 @@@ static ssize_t ds2780_get_sense_resisto
        struct power_supply *psy = to_power_supply(dev);
        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
  
-       ret = ds2780_read8(dev_info->w1_dev, &sense_resistor, DS2780_RSNSP_REG);
+       ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG);
        if (ret < 0)
                return ret;
  
@@@ -584,7 -596,7 +596,7 @@@ static ssize_t ds2780_get_pio_pin(struc
        struct power_supply *psy = to_power_supply(dev);
        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
  
-       ret = ds2780_read8(dev_info->w1_dev, &sfr, DS2780_SFR_REG);
+       ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG);
        if (ret < 0)
                return ret;
  
@@@ -611,7 -623,7 +623,7 @@@ static ssize_t ds2780_set_pio_pin(struc
                return -EINVAL;
        }
  
-       ret = ds2780_write(dev_info->w1_dev, &new_setting,
+       ret = ds2780_write(dev_info, &new_setting,
                                DS2780_SFR_REG, sizeof(u8));
        if (ret < 0)
                return ret;
@@@ -632,7 -644,7 +644,7 @@@ static ssize_t ds2780_read_param_eeprom
                DS2780_EEPROM_BLOCK1_END -
                DS2780_EEPROM_BLOCK1_START + 1 - off);
  
-       return ds2780_read_block(dev_info->w1_dev, buf,
+       return ds2780_read_block(dev_info, buf,
                                DS2780_EEPROM_BLOCK1_START + off, count);
  }
  
@@@ -650,7 -662,7 +662,7 @@@ static ssize_t ds2780_write_param_eepro
                DS2780_EEPROM_BLOCK1_END -
                DS2780_EEPROM_BLOCK1_START + 1 - off);
  
-       ret = ds2780_write(dev_info->w1_dev, buf,
+       ret = ds2780_write(dev_info, buf,
                                DS2780_EEPROM_BLOCK1_START + off, count);
        if (ret < 0)
                return ret;
@@@ -685,9 -697,8 +697,8 @@@ static ssize_t ds2780_read_user_eeprom_
                DS2780_EEPROM_BLOCK0_END -
                DS2780_EEPROM_BLOCK0_START + 1 - off);
  
-       return ds2780_read_block(dev_info->w1_dev, buf,
+       return ds2780_read_block(dev_info, buf,
                                DS2780_EEPROM_BLOCK0_START + off, count);
  }
  
  static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
                DS2780_EEPROM_BLOCK0_END -
                DS2780_EEPROM_BLOCK0_START + 1 - off);
  
-       ret = ds2780_write(dev_info->w1_dev, buf,
+       ret = ds2780_write(dev_info, buf,
                                DS2780_EEPROM_BLOCK0_START + off, count);
        if (ret < 0)
                return ret;
@@@ -768,6 -779,7 +779,7 @@@ static int __devinit ds2780_battery_pro
        dev_info->bat.properties        = ds2780_battery_props;
        dev_info->bat.num_properties    = ARRAY_SIZE(ds2780_battery_props);
        dev_info->bat.get_property      = ds2780_battery_get_property;
+       dev_info->mutex_holder          = current;
  
        ret = power_supply_register(&pdev->dev, &dev_info->bat);
        if (ret) {
                goto fail_remove_bin_file;
        }
  
+       dev_info->mutex_holder = NULL;
        return 0;
  
  fail_remove_bin_file:
@@@ -816,6 -830,8 +830,8 @@@ static int __devexit ds2780_battery_rem
  {
        struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
  
+       dev_info->mutex_holder = current;
        /* remove attributes */
        sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
  
@@@ -832,7 -848,7 +848,7 @@@ static struct platform_driver ds2780_ba
                .name = "ds2780-battery",
        },
        .probe    = ds2780_battery_probe,
 -      .remove   = ds2780_battery_remove,
 +      .remove   = __devexit_p(ds2780_battery_remove),
  };
  
  static int __init ds2780_battery_init(void)
index 10ffa8c22d36f883d1f9eca2846dcc1f03e6fd2f,9f0183c73076852b213b10ea2832bc7e9d74cd3e..86acee2f988917912919e710d4b62f1592b98397
@@@ -23,6 -23,7 +23,7 @@@
   */
  
  #include <linux/init.h>
+ #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/i2c.h>
  #include <linux/mod_devicetable.h>
@@@ -84,79 -85,55 +85,79 @@@ static int max17042_get_property(struc
  {
        struct max17042_chip *chip = container_of(psy,
                                struct max17042_chip, battery);
 +      int ret;
  
        switch (psp) {
        case POWER_SUPPLY_PROP_PRESENT:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_STATUS);
 -              if (val->intval & MAX17042_STATUS_BattAbsent)
 +              ret = max17042_read_reg(chip->client, MAX17042_STATUS);
 +              if (ret < 0)
 +                      return ret;
 +
 +              if (ret & MAX17042_STATUS_BattAbsent)
                        val->intval = 0;
                else
                        val->intval = 1;
                break;
        case POWER_SUPPLY_PROP_CYCLE_COUNT:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_Cycles);
 +              ret = max17042_read_reg(chip->client, MAX17042_Cycles);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret;
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_MAX:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_MinMaxVolt);
 -              val->intval >>= 8;
 +              ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret >> 8;
                val->intval *= 20000; /* Units of LSB = 20mV */
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_V_empty);
 -              val->intval >>= 7;
 +              ret = max17042_read_reg(chip->client, MAX17042_V_empty);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret >> 7;
                val->intval *= 10000; /* Units of LSB = 10mV */
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
 +              ret = max17042_read_reg(chip->client, MAX17042_VCELL);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret * 625 / 8;
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_AVG:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_AvgVCELL) * 83;
 +              ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret * 625 / 8;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_SOC) / 256;
 +              ret = max17042_read_reg(chip->client, MAX17042_SOC);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret >> 8;
                break;
        case POWER_SUPPLY_PROP_CHARGE_FULL:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_RepSOC);
 -              if ((val->intval / 256) >= MAX17042_BATTERY_FULL)
 +              ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
 +              if (ret < 0)
 +                      return ret;
 +
 +              if ((ret >> 8) >= MAX17042_BATTERY_FULL)
                        val->intval = 1;
 -              else if (val->intval >= 0)
 +              else if (ret >= 0)
                        val->intval = 0;
                break;
        case POWER_SUPPLY_PROP_TEMP:
 -              val->intval = max17042_read_reg(chip->client,
 -                              MAX17042_TEMP);
 +              ret = max17042_read_reg(chip->client, MAX17042_TEMP);
 +              if (ret < 0)
 +                      return ret;
 +
 +              val->intval = ret;
                /* The value is signed. */
                if (val->intval & 0x8000) {
                        val->intval = (0x7fff & ~val->intval) + 1;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
                if (chip->pdata->enable_current_sense) {
 -                      val->intval = max17042_read_reg(chip->client,
 -                                      MAX17042_Current);
 +                      ret = max17042_read_reg(chip->client, MAX17042_Current);
 +                      if (ret < 0)
 +                              return ret;
 +
 +                      val->intval = ret;
                        if (val->intval & 0x8000) {
                                /* Negative */
                                val->intval = ~val->intval & 0x7fff;
                                val->intval++;
                                val->intval *= -1;
                        }
 -                      val->intval >>= 4;
 -                      val->intval *= 1000000 * 25 / chip->pdata->r_sns;
 +                      val->intval *= 1562500 / chip->pdata->r_sns;
                } else {
                        return -EINVAL;
                }
                break;
        case POWER_SUPPLY_PROP_CURRENT_AVG:
                if (chip->pdata->enable_current_sense) {
 -                      val->intval = max17042_read_reg(chip->client,
 -                                      MAX17042_AvgCurrent);
 +                      ret = max17042_read_reg(chip->client,
 +                                              MAX17042_AvgCurrent);
 +                      if (ret < 0)
 +                              return ret;
 +
 +                      val->intval = ret;
                        if (val->intval & 0x8000) {
                                /* Negative */
                                val->intval = ~val->intval & 0x7fff;
@@@ -239,9 -210,6 +240,9 @@@ static int __devinit max17042_probe(str
        if (!chip->pdata->enable_current_sense)
                chip->battery.num_properties -= 2;
  
 +      if (chip->pdata->r_sns == 0)
 +              chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
 +
        ret = power_supply_register(&client->dev, &chip->battery);
        if (ret) {
                dev_err(&client->dev, "failed: power supply register\n");
                max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
                max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
                max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
 -      } else {
 -              if (chip->pdata->r_sns == 0)
 -                      chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
        }
  
        return 0;
index 3c030c9052785875ec014262e185b0b300e401cf,2595145f3bffad80d9cdfba4d50b83df3f41ffa6..f204ad16361adf8daaa8cfd65289e1c6fab2eb9a
@@@ -22,6 -22,7 +22,7 @@@
  
  #include <linux/gpio.h>
  #include <linux/interrupt.h>
+ #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/power_supply.h>
  #include <linux/platform_device.h>
@@@ -388,4 -389,4 +389,4 @@@ module_exit(max8903_exit)
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("MAX8903 Charger Driver");
  MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 -MODULE_ALIAS("max8903-charger");
 +MODULE_ALIAS("platform:max8903-charger");
index 6e88c5d026b93485a942c3102cf27971cd64df1f,a23317d75c5a80e65bec82fdf89bdb1f6499f0a1..23ca65d177059481687e2c9705d5954716154ca2
@@@ -19,6 -19,7 +19,7 @@@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
+ #include <linux/module.h>
  #include <linux/err.h>
  #include <linux/module.h>
  #include <linux/slab.h>
@@@ -97,7 -98,7 +98,7 @@@ static __devinit int max8997_battery_pr
                return -EINVAL;
  
        if (pdata->eoc_mA) {
 -              u8 val = (pdata->eoc_mA - 50) / 10;
 +              int val = (pdata->eoc_mA - 50) / 10;
                if (val < 0)
                        val = 0;
                if (val > 0xf)
@@@ -178,7 -179,6 +179,7 @@@ static int __devexit max8997_battery_re
  
  static const struct platform_device_id max8997_battery_id[] = {
        { "max8997-battery", 0 },
 +      { }
  };
  
  static struct platform_driver max8997_battery_driver = {
index 6f5ffc3e2f03676828b0ce79ab9002e79e35da27,93e3bb47a3a817ac7d1fbf0aa712bb77b0c181fd..0737302af1d202f6803ba633f341340696a3a56e
@@@ -19,6 -19,7 +19,7 @@@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
+ #include <linux/module.h>
  #include <linux/err.h>
  #include <linux/module.h>
  #include <linux/slab.h>
@@@ -153,7 -154,6 +154,7 @@@ static __devinit int max8998_battery_pr
        case 0:
                dev_dbg(max8998->dev,
                        "Full Timeout not set: leave it unchanged.\n");
 +              break;
        default:
                dev_err(max8998->dev, "Invalid Full Timeout value\n");
                ret = -EINVAL;
@@@ -190,7 -190,6 +191,7 @@@ static int __devexit max8998_battery_re
  
  static const struct platform_device_id max8998_battery_id[] = {
        { "max8998-battery", TYPE_MAX8998 },
 +      { }
  };
  
  static struct platform_driver max8998_battery_driver = {
index 939e2e432553dd2744884c3d36a9e99b2915c335,21178ebfe51aacb9d7996dcd6d15299aaa1547fb..5faf7ae9b81f224bb72684d44e1f81be62ac1cad
@@@ -14,6 -14,7 +14,7 @@@
  #include <linux/ctype.h>
  #include <linux/power_supply.h>
  #include <linux/slab.h>
+ #include <linux/stat.h>
  
  #include "power_supply.h"
  
@@@ -42,7 -43,7 +43,7 @@@ static ssize_t power_supply_show_proper
                                          struct device_attribute *attr,
                                          char *buf) {
        static char *type_text[] = {
 -              "Battery", "UPS", "Mains", "USB",
 +              "Unknown", "Battery", "UPS", "Mains", "USB",
                "USB_DCP", "USB_CDP", "USB_ACA"
        };
        static char *status_text[] = {
@@@ -62,6 -63,9 +63,9 @@@
        static char *capacity_level_text[] = {
                "Unknown", "Critical", "Low", "Normal", "High", "Full"
        };
+       static char *scope_text[] = {
+               "Unknown", "System", "Device"
+       };
        ssize_t ret = 0;
        struct power_supply *psy = dev_get_drvdata(dev);
        const ptrdiff_t off = attr - power_supply_attrs;
@@@ -77,8 -81,8 +81,8 @@@
                        dev_dbg(dev, "driver has no data for `%s' property\n",
                                attr->attr.name);
                else if (ret != -ENODEV)
 -                      dev_err(dev, "driver failed to report `%s' property\n",
 -                              attr->attr.name);
 +                      dev_err(dev, "driver failed to report `%s' property: %zd\n",
 +                              attr->attr.name, ret);
                return ret;
        }
  
@@@ -94,6 -98,8 +98,8 @@@
                return sprintf(buf, "%s\n", capacity_level_text[value.intval]);
        else if (off == POWER_SUPPLY_PROP_TYPE)
                return sprintf(buf, "%s\n", type_text[value.intval]);
+       else if (off == POWER_SUPPLY_PROP_SCOPE)
+               return sprintf(buf, "%s\n", scope_text[value.intval]);
        else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
                return sprintf(buf, "%s\n", value.strval);
  
@@@ -166,6 -172,7 +172,7 @@@ static struct device_attribute power_su
        POWER_SUPPLY_ATTR(time_to_full_now),
        POWER_SUPPLY_ATTR(time_to_full_avg),
        POWER_SUPPLY_ATTR(type),
+       POWER_SUPPLY_ATTR(scope),
        /* Properties of type `const char *' */
        POWER_SUPPLY_ATTR(model_name),
        POWER_SUPPLY_ATTR(manufacturer),
index 9c83e04f6a43db8b5fdfd7db002704faec3c9f2c,2e3c8279b3b0e91d288a9437e4b0db3d05e7d547..fa9b962aec124ad0e126d7400d8a92325525d9ff
@@@ -74,6 -74,12 +74,12 @@@ enum 
        POWER_SUPPLY_CAPACITY_LEVEL_FULL,
  };
  
+ enum {
+       POWER_SUPPLY_SCOPE_UNKNOWN = 0,
+       POWER_SUPPLY_SCOPE_SYSTEM,
+       POWER_SUPPLY_SCOPE_DEVICE,
+ };
  enum power_supply_property {
        /* Properties of type `int' */
        POWER_SUPPLY_PROP_STATUS = 0,
        POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
        POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
        POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
+       POWER_SUPPLY_PROP_SCOPE,
        /* Properties of type `const char *' */
        POWER_SUPPLY_PROP_MODEL_NAME,
        POWER_SUPPLY_PROP_MANUFACTURER,
  };
  
  enum power_supply_type {
 -      POWER_SUPPLY_TYPE_BATTERY = 0,
 +      POWER_SUPPLY_TYPE_UNKNOWN = 0,
 +      POWER_SUPPLY_TYPE_BATTERY,
        POWER_SUPPLY_TYPE_UPS,
        POWER_SUPPLY_TYPE_MAINS,
        POWER_SUPPLY_TYPE_USB,          /* Standard Downstream Port */
@@@ -212,6 -218,7 +219,7 @@@ static inline int power_supply_is_syste
  extern int power_supply_register(struct device *parent,
                                 struct power_supply *psy);
  extern void power_supply_unregister(struct power_supply *psy);
+ extern int power_supply_powers(struct power_supply *psy, struct device *dev);
  
  /* For APM emulation, think legacy userspace. */
  extern struct class *power_supply_class;