--- /dev/null
+diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
+index 46db966..6a6224e 100644
+--- a/drivers/power/bq27x00_battery.c
++++ b/drivers/power/bq27x00_battery.c
+@@ -29,12 +29,15 @@
+ #include <linux/jiffies.h>
+ #include <linux/workqueue.h>
+ #include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
+ #include <linux/platform_device.h>
+ #include <linux/power_supply.h>
+ #include <linux/idr.h>
+ #include <linux/i2c.h>
+ #include <linux/slab.h>
+ #include <asm/unaligned.h>
++#include <asm/uaccess.h>
+
+ #include <linux/power/bq27x00_battery.h>
+
+@@ -89,8 +92,34 @@ struct bq27x00_reg_cache {
+ int flags;
+ };
+
++#define BQ27X00_READ_REG _IO(MISC_MAJOR, 0)
++
++/**
++ * struct bq27x00_reg_parms - User data for ioctl call BQ27X00_READ_REG
++ * @reg: Battery register
++ * @single: 1 if register is 8bit, 0 if 16bit
++ * @ret: value of register reg
++ * Ioctl call BQ27X00_READ_REG can be used to read battery register.
++ * If bq27x00_battery is loaded, it is not possible to use i2c-get
++ * to get status of battery registers, so this ioctl can be used.
++ */
++struct bq27x00_reg_parms {
++ int reg;
++ int single;
++ int ret;
++};
++
++struct bq27x00_reg_device {
++ struct miscdevice miscdev;
++ struct bq27x00_device_info *di;
++ struct bq27x00_reg_device *next, *prev;
++};
++
++static struct bq27x00_reg_device *bq27x00_reg_devices = NULL;
++
+ struct bq27x00_device_info {
+ struct device *dev;
++ struct bq27x00_reg_device *regdev;
+ int id;
+ enum bq27x00_chip chip;
+
+@@ -141,6 +153,109 @@ static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
+ return di->bus.read(di, reg, single);
+ }
+
++/* Code for register device access */
++
++static long bq27x00_battery_reg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++{
++ int ret;
++ int minor = iminor(filp->f_dentry->d_inode);
++ struct bq27x00_reg_parms param;
++ struct bq27x00_reg_device *regdev = bq27x00_reg_devices;
++
++ while (regdev) {
++ if (regdev->miscdev.minor == minor)
++ break;
++ regdev = regdev->next;
++ }
++
++ if (!regdev)
++ return -ENXIO;
++
++ if (cmd != BQ27X00_READ_REG)
++ return -EINVAL;
++
++ ret = copy_from_user(¶m, (void __user *)arg, sizeof(param));
++ if (ret != 0)
++ return -EACCES;
++
++ param.ret = bq27x00_read(regdev->di, param.reg, param.single);
++
++ ret = copy_to_user((void __user *)arg, ¶m, sizeof(param));
++ if (ret != 0)
++ return -EACCES;
++
++ return 0;
++}
++
++static int bq27x00_battery_reg_open(struct inode *inode, struct file *file)
++{
++ if (!try_module_get(THIS_MODULE))
++ return -EPERM;
++
++ return 0;
++}
++
++static int bq27x00_battery_reg_release(struct inode *inode, struct file *file)
++{
++ module_put(THIS_MODULE);
++ return 0;
++}
++
++static struct file_operations bq27x00_reg_fileops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = bq27x00_battery_reg_ioctl,
++ .open = bq27x00_battery_reg_open,
++ .release = bq27x00_battery_reg_release,
++};
++
++static int bq27x00_battery_reg_init(struct bq27x00_device_info *di)
++{
++ struct bq27x00_reg_device *regdev;
++ int ret;
++
++ regdev = kzalloc(sizeof *regdev, GFP_KERNEL);
++ if (!regdev)
++ return -ENOMEM;
++
++ regdev->miscdev.minor = MISC_DYNAMIC_MINOR;
++ regdev->miscdev.name = di->bat.name;
++ regdev->miscdev.fops = &bq27x00_reg_fileops;
++ regdev->di = di;
++
++ ret = misc_register(®dev->miscdev);
++ if (ret != 0) {
++ kfree(regdev);
++ return ret;
++ }
++
++ di->regdev = regdev;
++
++ if (bq27x00_reg_devices)
++ bq27x00_reg_devices->prev = regdev;
++
++ regdev->prev = NULL;
++ regdev->next = bq27x00_reg_devices;
++ bq27x00_reg_devices = regdev;
++
++ return 0;
++}
++
++static void bq27x00_battery_reg_exit(struct bq27x00_device_info *di)
++{
++ misc_deregister(&di->regdev->miscdev);
++
++ if (di->regdev->next)
++ di->regdev->next->prev = di->regdev->prev;
++
++ if (di->regdev->prev)
++ di->regdev->prev->next = di->regdev->next;
++
++ if (di->regdev == bq27x00_reg_devices)
++ bq27x00_reg_devices = NULL;
++
++ kfree(di->regdev);
++}
++
+ /*
+ * Return the battery Relative State-of-Charge
+ * Or < 0 if something fails.
+@@ -839,6 +839,9 @@ static int bq27x00_battery_probe(struct
+
+ i2c_set_clientdata(client, di);
+
++ if (bq27x00_battery_reg_init(di))
++ di->regdev = NULL;
++
+ return 0;
+
+ batt_failed_3:
+@@ -859,6 +862,9 @@ static int bq27x00_battery_remove(struct
+
+ bq27x00_powersupply_unregister(di);
+
++ if (di->regdev)
++ bq27x00_battery_reg_exit(di);
++
+ kfree(di->bat.name);
+
+ mutex_lock(&battery_mutex);
+@@ -829,6 +944,9 @@ static int __devinit bq27000_battery_probe(struct platform_device *pdev)
+ if (ret)
+ goto err_free;
+
++ if (bq27x00_battery_reg_init(di))
++ di->regdev = NULL;
++
+ return 0;
+
+ err_free:
+@@ -844,6 +962,9 @@ static int __devexit bq27000_battery_remove(struct platform_device *pdev)
+
+ bq27x00_powersupply_unregister(di);
+
++ if (di->regdev)
++ bq27x00_battery_reg_exit(di);
++
+ platform_set_drvdata(pdev, NULL);
+ kfree(di);
+