Previously, all the remotes attached to the same receiver would share the
same power_supply. That's not good as the remotes will constantly change
the battery information according to their own state.

To have something generic enough, we introduce struct wacom_battery
which regroups all the information we need for a battery.

This backport works around the split in the battery path at kernel 4.1.

Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com>
Acked-by: Ping Cheng <pi...@wacom.com>
Signed-off-by: Jiri Kosina <jkos...@suse.cz>
[aaron.sko...@wacom.com: Imported into input-wacom repository (59d69bc)]
Signed-off-by: Aaron Armstrong Skomra <aaron.sko...@wacom.com>
[aaron.sko...@wacom.com: Backported from input-wacom repository (89f769c)]
Signed-off-by: Aaron Armstrong Skomra <aaron.sko...@wacom.com>
---
 2.6.38/wacom.h     |  14 +++-
 2.6.38/wacom_sys.c |  91 ++++++++++++++---------
 2.6.38/wacom_wac.c |  55 +++++++-------
 2.6.38/wacom_wac.h |   5 --
 3.17/wacom.h       |  27 +++++--
 3.17/wacom_sys.c   | 214 +++++++++++++++++++++++++++++++++--------------------
 3.17/wacom_wac.c   |  53 ++++++-------
 3.17/wacom_wac.h   |   6 --
 3.7/wacom.h        |  14 +++-
 3.7/wacom_sys.c    | 101 ++++++++++++++++---------
 3.7/wacom_wac.c    |  55 +++++++-------
 3.7/wacom_wac.h    |   5 --
 12 files changed, 385 insertions(+), 255 deletions(-)

diff --git a/2.6.38/wacom.h b/2.6.38/wacom.h
index e501fae..0ccfcc1 100644
--- a/2.6.38/wacom.h
+++ b/2.6.38/wacom.h
@@ -119,6 +119,17 @@ enum wacom_worker {
        WACOM_WORKER_REMOTE,
 };
 
+struct wacom_battery {
+       struct power_supply battery;
+       struct power_supply ac;
+       char bat_name[WACOM_NAME_MAX];
+       char ac_name[WACOM_NAME_MAX];
+       int battery_capacity;
+       int bat_charging;
+       int bat_connected;
+       int ps_connected;
+};
+
 struct wacom_remote {
        spinlock_t remote_lock;
        struct kfifo remote_fifo;
@@ -128,6 +139,7 @@ struct wacom_remote {
                u32 serial;
                struct input_dev *input;
                bool registered;
+               struct wacom_battery battery;
        } remotes[WACOM_MAX_REMOTES];
 };
 
@@ -150,7 +162,7 @@ struct wacom {
                u8 hlv;       /* status led brightness button pressed (1..127) 
*/
                u8 img_lum;   /* OLED matrix display brightness */
        } led;
-       struct power_supply battery;
+       struct wacom_battery battery;
 };
 
 static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
diff --git a/2.6.38/wacom_sys.c b/2.6.38/wacom_sys.c
index b8dbcc4..5683cd8 100644
--- a/2.6.38/wacom_sys.c
+++ b/2.6.38/wacom_sys.c
@@ -1159,12 +1159,13 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
                                      enum power_supply_property psp,
                                      union power_supply_propval *val)
 {
-       struct wacom *wacom = container_of(psy, struct wacom, battery);
+       struct wacom_battery *battery = container_of(psy, struct wacom_battery,
+                                                    battery);
        int ret = 0;
 
        switch (psp) {
                case POWER_SUPPLY_PROP_PRESENT:
-                       val->intval = wacom->wacom_wac.bat_connected;
+                       val->intval = battery->bat_connected;
                        break;
 #ifdef POWER_SUPPLY_PROP_SCOPE
                case POWER_SUPPLY_PROP_SCOPE:
@@ -1172,16 +1173,15 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
                        break;
 #endif
                case POWER_SUPPLY_PROP_CAPACITY:
-                       val->intval =
-                               wacom->wacom_wac.battery_capacity;
+                       val->intval = battery->battery_capacity;
                        break;
                case POWER_SUPPLY_PROP_STATUS:
-                       if (wacom->wacom_wac.bat_charging)
+                       if (battery->bat_charging)
                                val->intval = POWER_SUPPLY_STATUS_CHARGING;
-                       else if (wacom->wacom_wac.battery_capacity == 100 &&
-                                   wacom->wacom_wac.ps_connected)
+                       else if (battery->battery_capacity == 100 &&
+                                   battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_FULL;
-                       else if (wacom->wacom_wac.ps_connected)
+                       else if (battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
                        else
                                val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
@@ -1194,48 +1194,65 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
        return ret;
 }
 
-static int wacom_initialize_battery(struct wacom *wacom)
+static int __wacom_initialize_battery(struct wacom *wacom,
+                                     struct wacom_battery *battery)
 {
        static atomic_t battery_no = ATOMIC_INIT(0);
        static DEFINE_SPINLOCK(ps_lock);
        unsigned long flags;
        int error = 0;
+       unsigned long n;
 
        spin_lock_irqsave(&ps_lock, flags); /* Prevent potential race for the 
"wacom_battery" name */
-       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
-               unsigned long n = atomic_inc_return(&battery_no) - 1;
+       n = atomic_inc_return(&battery_no) - 1;
 
-               if (power_supply_get_by_name("wacom_battery"))
-                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", 
n);
-               else
-                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery");
+       if (power_supply_get_by_name("wacom_battery"))
+               sprintf(battery->bat_name, "wacom_battery_%ld", n);
+       else
+               sprintf(battery->bat_name, "wacom_battery");
 
-               wacom->battery.properties = wacom_battery_props;
-               wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
-               wacom->battery.get_property = wacom_battery_get_property;
-               wacom->battery.name = wacom->wacom_wac.bat_name;
-               wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
-               wacom->battery.use_for_apm = 0;
+       battery->battery.properties = wacom_battery_props;
+       battery->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
+       battery->battery.get_property = wacom_battery_get_property;
+       battery->battery.name = battery->bat_name;
+       battery->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->battery.use_for_apm = 0;
 
-               error = power_supply_register(&wacom->usbdev->dev,
-                                             &wacom->battery);
+       error = power_supply_register(&wacom->usbdev->dev,
+                                     &battery->battery);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
-               if (!error)
-                       power_supply_powers(&wacom->battery,
-                                           &wacom->usbdev->dev);
+       if (!error)
+               power_supply_powers(&battery->battery,
+                                   &wacom->usbdev->dev);
 #endif
-       }
+
        spin_unlock_irqrestore(&ps_lock, flags);
 
        return error;
 }
 
+static int wacom_initialize_battery(struct wacom *wacom)
+{
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY)
+               return __wacom_initialize_battery(wacom, &wacom->battery);
+
+       return 0;
+}
+
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-       if (wacom->battery.dev) {
-               power_supply_unregister(&wacom->battery);
-               wacom->battery.dev = NULL;
+       if (wacom->battery.battery.dev) {
+               power_supply_unregister(&wacom->battery.battery);
+               wacom->battery.battery.dev = NULL;
+       }
+}
+
+static void wacom_destroy_remote_battery(struct wacom_battery *battery)
+{
+       if (battery->battery.dev) {
+               power_supply_unregister(&battery->battery);
+               battery->battery.dev = NULL;
        }
 }
 
@@ -1341,6 +1358,9 @@ static void wacom_remote_destroy_one(struct wacom *wacom, 
unsigned int index)
        if (remote->remotes[index].input)
                input_unregister_device(remote->remotes[index].input);
 
+       if (remote->remotes[index].battery.battery.dev)
+               wacom_destroy_remote_battery(&remote->remotes[index].battery);
+
        for (i = 0; i < WACOM_MAX_REMOTES; i++) {
                if (remote->remotes[i].serial == serial) {
                        remote->remotes[i].serial = 0;
@@ -1402,7 +1422,7 @@ static void wacom_remotes_destroy(void *data)
                return;
 
        for (i = 0; i < WACOM_MAX_REMOTES; i++) {
-               if (wacom->remote->remotes[i].group.name) {
+               if (remote->remotes[i].registered) {
                        wacom_remote_destroy_one(wacom, i);
                }
        }
@@ -1611,6 +1631,11 @@ static int wacom_remote_create_one(struct wacom *wacom, 
u32 serial,
 
        remote->remotes[index].registered = true;
 
+       error = __wacom_initialize_battery(wacom,
+                                          &remote->remotes[index].battery);
+       if (error)
+               goto fail;
+
        devres_close_group(dev, &remote->remotes[index]);
 
        return 0;
@@ -1765,11 +1790,11 @@ void wacom_battery_work(struct work_struct *work)
        struct wacom *wacom = container_of(work, struct wacom, battery_work);
 
        if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-            !wacom->battery.dev) {
+            !wacom->battery.battery.dev) {
                wacom_initialize_battery(wacom);
        }
        else if (!(wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-                wacom->battery.dev) {
+                wacom->battery.battery.dev) {
                wacom_destroy_battery(wacom);
        }
 }
diff --git a/2.6.38/wacom_wac.c b/2.6.38/wacom_wac.c
index 4e246d0..4d14e97 100644
--- a/2.6.38/wacom_wac.c
+++ b/2.6.38/wacom_wac.c
@@ -41,27 +41,36 @@
 static void wacom_report_numbered_buttons(struct input_dev *input_dev,
                                int button_cout, int mask);
 
-static void wacom_notify_battery(struct wacom_wac *wacom_wac,
+static void __wacom_notify_battery(struct wacom_battery *battery,
        int bat_capacity, bool bat_charging, bool bat_connected,
        bool ps_connected)
 {
-       struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
-       bool changed = wacom_wac->battery_capacity != bat_capacity  ||
-                      wacom_wac->bat_charging     != bat_charging  ||
-                      wacom_wac->bat_connected    != bat_connected ||
-                      wacom_wac->ps_connected     != ps_connected;
+       bool changed = battery->battery_capacity != bat_capacity  ||
+                      battery->bat_charging     != bat_charging  ||
+                      battery->bat_connected    != bat_connected ||
+                      battery->ps_connected     != ps_connected;
 
        if (changed) {
-               wacom_wac->battery_capacity = bat_capacity;
-               wacom_wac->bat_charging = bat_charging;
-               wacom_wac->bat_connected = bat_connected;
-               wacom_wac->ps_connected = ps_connected;
+               battery->battery_capacity = bat_capacity;
+               battery->bat_charging = bat_charging;
+               battery->bat_connected = bat_connected;
+               battery->ps_connected = ps_connected;
 
-               if (wacom->battery.dev)
-                       power_supply_changed(&wacom->battery);
+               if (battery->battery.dev)
+                       power_supply_changed(&battery->battery);
        }
 }
 
+static void wacom_notify_battery(struct wacom_wac *wacom_wac,
+       int bat_capacity, bool bat_charging, bool bat_connected,
+       bool ps_connected)
+{
+       struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+
+       __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging,
+                              bat_connected, ps_connected);
+}
+
 static int wacom_penpartner_irq(struct wacom_wac *wacom)
 {
        unsigned char *data = wacom->data;
@@ -701,7 +710,6 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
 {
        unsigned char *data = wacom_wac->data;
        struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
-       struct wacom_features *features = &wacom_wac->features;
        struct wacom_remote *remote = wacom->remote;
        struct input_dev *input;
        int bat_charging, bat_percent, touch_ring_mode;
@@ -778,13 +786,8 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
                        wacom->led.select[i] = touch_ring_mode;
        }
 
-       if (!wacom->battery.dev &&
-           !(features->quirks & WACOM_QUIRK_BATTERY)) {
-               features->quirks |= WACOM_QUIRK_BATTERY;
-               wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
-       }
-
-       wacom_notify_battery(wacom_wac, bat_percent, bat_charging, 1, 
bat_charging);
+       __wacom_notify_battery(&remote->remotes[index].battery, bat_percent,
+               bat_charging, 1, bat_charging);
 
 out:
        spin_unlock_irqrestore(&remote->remote_lock, flags);
@@ -1557,7 +1560,6 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t 
len)
 
 static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
 {
-       struct wacom *w = container_of(wacom, struct wacom, wacom_wac);
        unsigned char *data = wacom->data;
        int connected;
 
@@ -1585,8 +1587,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, 
size_t len)
                        wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
                }
 
-               if (w->battery.dev)
-                       wacom_notify_battery(wacom, battery, charging, 1, 0);
+               wacom_notify_battery(wacom, battery, charging, 1, 0);
 
        } else if (wacom->pid != 0) {
                /* disconnected while previously connected */
@@ -1623,14 +1624,14 @@ static int wacom_status_irq(struct wacom_wac 
*wacom_wac, size_t len)
                wacom_notify_battery(wacom_wac, battery, charging,
                                     battery || charging, 1);
 
-               if (!wacom->battery.dev &&
+               if (!wacom->battery.battery.dev &&
                    !(features->quirks & WACOM_QUIRK_BATTERY)) {
                        features->quirks |= WACOM_QUIRK_BATTERY;
                        wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                }
        }
        else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
-                wacom->battery.dev) {
+                wacom->battery.battery.dev) {
                features->quirks &= ~WACOM_QUIRK_BATTERY;
                wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
@@ -1856,9 +1857,9 @@ void wacom_setup_device_quirks(struct wacom *wacom)
                }
        }
 
-       if (features->type == REMOTE) {
+       if (features->type == REMOTE)
                features->quirks |= WACOM_QUIRK_MONITOR;
-       }
+
 }
 
 static void wacom_abs_set_axis(struct input_dev *input_dev,
diff --git a/2.6.38/wacom_wac.h b/2.6.38/wacom_wac.h
index abe52fb..844ab81 100644
--- a/2.6.38/wacom_wac.h
+++ b/2.6.38/wacom_wac.h
@@ -174,7 +174,6 @@ struct wacom_remote_data {
 
 struct wacom_wac {
        char name[WACOM_NAME_MAX];
-       char bat_name[WACOM_NAME_MAX];
        unsigned char *data;
        int tool[2];
        int id[2];
@@ -184,12 +183,8 @@ struct wacom_wac {
        struct wacom_shared *shared;
        struct input_dev *input;
        int pid;
-       int battery_capacity;
        int num_contacts_left;
        int *slots;
-       int bat_charging;
-       int bat_connected;
-       int ps_connected;
 };
 
 #endif
diff --git a/3.17/wacom.h b/3.17/wacom.h
index c299a83..d3fb8b9 100644
--- a/3.17/wacom.h
+++ b/3.17/wacom.h
@@ -130,6 +130,24 @@ struct wacom_group_leds {
        u8 select; /* status led selector (0..3) */
 };
 
+struct wacom_battery {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+       struct power_supply_desc bat_desc;
+       struct power_supply_desc ac_desc;
+       struct power_supply *battery;
+       struct power_supply *ac;
+#else
+       struct power_supply battery;
+       struct power_supply ac;
+#endif
+       char bat_name[WACOM_NAME_MAX];
+       char ac_name[WACOM_NAME_MAX];
+       int battery_capacity;
+       int bat_charging;
+       int bat_connected;
+       int ps_connected;
+};
+
 struct wacom_remote {
        spinlock_t remote_lock;
        struct kfifo remote_fifo;
@@ -139,6 +157,7 @@ struct wacom_remote {
                u32 serial;
                struct input_dev *input;
                bool registered;
+               struct wacom_battery battery;
        } remotes[WACOM_MAX_REMOTES];
 };
 
@@ -159,13 +178,9 @@ struct wacom {
                u8 img_lum;   /* OLED matrix display brightness */
        } led;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-       struct power_supply *battery;
-       struct power_supply *ac;
-       struct power_supply_desc battery_desc;
-       struct power_supply_desc ac_desc;
+       struct wacom_battery battery;
 #else
-       struct power_supply battery;
-       struct power_supply ac;
+       struct wacom_battery battery;
 #endif
        bool resources;
 };
diff --git a/3.17/wacom_sys.c b/3.17/wacom_sys.c
index efa03fb..793cb72 100644
--- a/3.17/wacom_sys.c
+++ b/3.17/wacom_sys.c
@@ -1118,30 +1118,29 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
                                      union power_supply_propval *val)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-       struct wacom *wacom = power_supply_get_drvdata(psy);
+       struct wacom_battery *battery = power_supply_get_drvdata(psy);
 #else
-       struct wacom *wacom = container_of(psy, struct wacom, battery);
+       struct wacom_battery *battery = container_of(psy, struct wacom_battery, 
battery);
 #endif
        int ret = 0;
 
        switch (psp) {
                case POWER_SUPPLY_PROP_PRESENT:
-                       val->intval = wacom->wacom_wac.bat_connected;
+                       val->intval = battery->bat_connected;
                        break;
                case POWER_SUPPLY_PROP_SCOPE:
                        val->intval = POWER_SUPPLY_SCOPE_DEVICE;
                        break;
                case POWER_SUPPLY_PROP_CAPACITY:
-                       val->intval =
-                               wacom->wacom_wac.battery_capacity;
+                       val->intval = battery->battery_capacity;
                        break;
                case POWER_SUPPLY_PROP_STATUS:
-                       if (wacom->wacom_wac.bat_charging)
+                       if (battery->bat_charging)
                                val->intval = POWER_SUPPLY_STATUS_CHARGING;
-                       else if (wacom->wacom_wac.battery_capacity == 100 &&
-                                   wacom->wacom_wac.ps_connected)
+                       else if (battery->battery_capacity == 100 &&
+                                   battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_FULL;
-                       else if (wacom->wacom_wac.ps_connected)
+                       else if (battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
                        else
                                val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
@@ -1159,9 +1158,9 @@ static int wacom_ac_get_property(struct power_supply *psy,
                                union power_supply_propval *val)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-       struct wacom *wacom = power_supply_get_drvdata(psy);
+       struct wacom_battery *battery = power_supply_get_drvdata(psy);
 #else
-       struct wacom *wacom = container_of(psy, struct wacom, ac);
+       struct wacom_battery *battery = container_of(psy, struct wacom_battery, 
battery);
 #endif
        int ret = 0;
 
@@ -1169,7 +1168,7 @@ static int wacom_ac_get_property(struct power_supply *psy,
        case POWER_SUPPLY_PROP_PRESENT:
                /* fall through */
        case POWER_SUPPLY_PROP_ONLINE:
-               val->intval = wacom->wacom_wac.ps_connected;
+               val->intval = battery->ps_connected;
                break;
        case POWER_SUPPLY_PROP_SCOPE:
                val->intval = POWER_SUPPLY_SCOPE_DEVICE;
@@ -1181,101 +1180,132 @@ static int wacom_ac_get_property(struct power_supply 
*psy,
        return ret;
 }
 
-static int wacom_initialize_battery(struct wacom *wacom)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+static int __wacom_initialize_battery(struct wacom *wacom,
+                                     struct wacom_battery *battery)
 {
        static atomic_t battery_no = ATOMIC_INIT(0);
        struct device *dev = &wacom->hdev->dev;
        int error;
        unsigned long n;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-       struct power_supply_config psy_cfg = { .drv_data = wacom, };
-       struct power_supply_desc *bat_desc = 
&WACOM_POWERSUPPLY_DESC(wacom->battery);
 
-       if (!devres_open_group(dev, bat_desc, GFP_KERNEL))
-               return -ENOMEM;
-#endif
+       n = atomic_inc_return(&battery_no) - 1;
 
-       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
-               n = atomic_inc_return(&battery_no) - 1;
-
-               WACOM_POWERSUPPLY_DESC(wacom->battery).properties = 
wacom_battery_props;
-               WACOM_POWERSUPPLY_DESC(wacom->battery).num_properties = 
ARRAY_SIZE(wacom_battery_props);
-               WACOM_POWERSUPPLY_DESC(wacom->battery).get_property = 
wacom_battery_get_property;
-               sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n);
-               WACOM_POWERSUPPLY_DESC(wacom->battery).name = 
wacom->wacom_wac.bat_name;
-               WACOM_POWERSUPPLY_DESC(wacom->battery).type = 
POWER_SUPPLY_TYPE_BATTERY;
-               WACOM_POWERSUPPLY_DESC(wacom->battery).use_for_apm = 0;
-
-               WACOM_POWERSUPPLY_DESC(wacom->ac).properties = wacom_ac_props;
-               WACOM_POWERSUPPLY_DESC(wacom->ac).num_properties = 
ARRAY_SIZE(wacom_ac_props);
-               WACOM_POWERSUPPLY_DESC(wacom->ac).get_property = 
wacom_ac_get_property;
-               sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n);
-               WACOM_POWERSUPPLY_DESC(wacom->ac).name = 
wacom->wacom_wac.ac_name;
-               WACOM_POWERSUPPLY_DESC(wacom->battery).type = 
POWER_SUPPLY_TYPE_MAINS;
-               WACOM_POWERSUPPLY_DESC(wacom->battery).use_for_apm = 0;
+       battery->battery.properties = wacom_battery_props;
+       battery->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
+       battery->battery.get_property = wacom_battery_get_property;
+       sprintf(wacom->battery.bat_name, "wacom_battery_%ld", n);
+       battery->battery.name = wacom->battery.bat_name;
+       battery->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->battery.use_for_apm = 0;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-               wacom->battery = devm_power_supply_register(dev,
-                                                          
&WACOM_POWERSUPPLY_DESC(wacom->battery),
-                                                          &psy_cfg);
-               if (IS_ERR(wacom->battery)) {
-                       error = PTR_ERR(wacom->battery);
-                       goto err;
-               }
-#else
-               error = power_supply_register(dev,
-                                             &wacom->battery);
+       battery->ac.properties = wacom_ac_props;
+       battery->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
+       battery->ac.get_property = wacom_ac_get_property;
+       sprintf(wacom->battery.ac_name, "wacom_ac_%ld", n);
+       battery->ac.name = wacom->battery.ac_name;
+       battery->ac.type = POWER_SUPPLY_TYPE_MAINS;
+       battery->ac.use_for_apm = 0;
 
-               if (error)
-                       return error;
-#endif
+       error = power_supply_register(dev, &battery->battery);
+
+       if (error)
+               return error;
 
-               power_supply_powers(WACOM_POWERSUPPLY_REF(wacom->battery), dev);
+       power_supply_powers(WACOM_POWERSUPPLY_REF(battery->battery), dev);
+
+       error = power_supply_register(dev, &battery->ac);
+
+       if (error) {
+               power_supply_unregister(&battery->battery);
+               return error;
+       }
+
+       power_supply_powers(WACOM_POWERSUPPLY_REF(battery->ac), dev);
+
+       return 0;
+}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-               wacom->ac = devm_power_supply_register(dev,
-                                                      
&WACOM_POWERSUPPLY_DESC(wacom->battery),
-                                                      &psy_cfg);
-               if (IS_ERR(wacom->ac)) {
-                       error = PTR_ERR(wacom->ac);
-                       goto err;
-               }
 #else
-               error = power_supply_register(dev, &wacom->ac);
+static int __wacom_initialize_battery(struct wacom *wacom,
+                                     struct wacom_battery *battery)
+{
+       static atomic_t battery_no = ATOMIC_INIT(0);
+       struct device *dev = &wacom->hdev->dev;
+       struct power_supply_config psy_cfg = { .drv_data = battery, };
+       struct power_supply *ps_bat, *ps_ac;
+       struct power_supply_desc *bat_desc = &battery->bat_desc;
+       struct power_supply_desc *ac_desc = &battery->ac_desc;
+       unsigned long n;
+       int error;
 
-               if (error) {
-                       power_supply_unregister(&wacom->battery);
-                       return error;
-               }
-#endif
-               power_supply_powers(WACOM_POWERSUPPLY_REF(wacom->ac), dev);
+       if (!devres_open_group(dev, bat_desc, GFP_KERNEL))
+               return -ENOMEM;
+
+       n = atomic_inc_return(&battery_no) - 1;
+
+       bat_desc->properties = wacom_battery_props;
+       bat_desc->num_properties = ARRAY_SIZE(wacom_battery_props);
+       bat_desc->get_property = wacom_battery_get_property;
+       sprintf(battery->bat_name, "wacom_battery_%ld", n);
+       bat_desc->name = battery->bat_name;
+       bat_desc->type = POWER_SUPPLY_TYPE_BATTERY;
+       bat_desc->use_for_apm = 0;
+
+       ac_desc->properties = wacom_ac_props;
+       ac_desc->num_properties = ARRAY_SIZE(wacom_ac_props);
+       ac_desc->get_property = wacom_ac_get_property;
+       sprintf(battery->ac_name, "wacom_ac_%ld", n);
+       ac_desc->name = battery->ac_name;
+       ac_desc->type = POWER_SUPPLY_TYPE_MAINS;
+       ac_desc->use_for_apm = 0;
+
+       ps_bat = devm_power_supply_register(dev, bat_desc, &psy_cfg);
+       if (IS_ERR(ps_bat)) {
+               error = PTR_ERR(ps_bat);
+               goto err;
        }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-       devres_close_group(dev, bat_desc);
-#endif
+       ps_ac = devm_power_supply_register(dev, ac_desc, &psy_cfg);
+       if (IS_ERR(ps_ac)) {
+               error = PTR_ERR(ps_ac);
+               goto err;
+       }
+
+       power_supply_powers(ps_bat, &wacom->hdev->dev);
+       power_supply_powers(ps_ac, &wacom->hdev->dev);
 
+       battery->battery = ps_bat;
+       battery->ac = ps_ac;
+
+       devres_close_group(dev, bat_desc);
        return 0;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
 err:
        devres_release_group(dev, bat_desc);
        return error;
+}
 #endif
+
+static int wacom_initialize_battery(struct wacom *wacom)
+{
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY)
+                return __wacom_initialize_battery(wacom, &wacom->battery);
+
+       return 0;
 }
 
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-       if (WACOM_POWERSUPPLY_DEVICE(wacom->battery)) {
-
+       if (WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery)) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
-               devres_release_group(&wacom->hdev->dev, 
WACOM_POWERSUPPLY_DEVICE(wacom->battery));
+               devres_release_group(&wacom->hdev->dev, wacom->battery.battery);
 #else
-               power_supply_unregister(WACOM_POWERSUPPLY_REF(wacom->battery));
-               power_supply_unregister(WACOM_POWERSUPPLY_REF(wacom->ac));
+               power_supply_unregister(&wacom->battery.battery);
+               power_supply_unregister(&wacom->battery.ac);
 #endif
-               WACOM_POWERSUPPLY_DEVICE(wacom->battery) = NULL;
-               WACOM_POWERSUPPLY_DEVICE(wacom->ac) = NULL;
+               WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery) = NULL;
+               WACOM_POWERSUPPLY_DEVICE(wacom->battery.ac) = NULL;
        }
 }
 
@@ -1439,9 +1469,28 @@ static void wacom_remotes_destroy(void *data)
        struct wacom *wacom = data;
        struct wacom_remote *remote = wacom->remote;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+       int i;
+       unsigned long flags;
+#endif
+
        if (!remote)
                return;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+       for (i = 0; i < WACOM_MAX_REMOTES; i++) {
+               if (remote->remotes[i].registered) {
+                       spin_lock_irqsave(&remote->remote_lock, flags);
+                       remote->remotes[i].registered = false;
+                       spin_unlock_irqrestore(&remote->remote_lock, flags);
+
+                       if 
(WACOM_POWERSUPPLY_DEVICE(remote->remotes[i].battery.battery)) {
+                               
power_supply_unregister(&remote->remotes[i].battery.battery);
+                               
power_supply_unregister(&remote->remotes[i].battery.ac);
+                       }
+               }
+       }
+#endif
        kobject_put(remote->remote_dir);
        kfifo_free(&remote->remote_fifo);
        wacom->remote = NULL;
@@ -1645,11 +1694,11 @@ void wacom_battery_work(struct work_struct *work)
        struct wacom *wacom = container_of(work, struct wacom, battery_work);
 
        if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-            !WACOM_POWERSUPPLY_DEVICE(wacom->battery)) {
+            !WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery)) {
                wacom_initialize_battery(wacom);
        }
        else if (!(wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-                WACOM_POWERSUPPLY_DEVICE(wacom->battery)) {
+                WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery)) {
                wacom_destroy_battery(wacom);
        }
 }
@@ -2047,6 +2096,11 @@ static int wacom_remote_create_one(struct wacom *wacom, 
u32 serial,
        if (error)
                goto fail;
 
+       error = __wacom_initialize_battery(wacom,
+                                          &remote->remotes[index].battery);
+       if (error)
+                goto fail;
+
        remote->remotes[index].registered = true;
 
        devres_close_group(dev, &remote->remotes[index]);
diff --git a/3.17/wacom_wac.c b/3.17/wacom_wac.c
index 4cfd4dd..b2f3d6b 100644
--- a/3.17/wacom_wac.c
+++ b/3.17/wacom_wac.c
@@ -52,25 +52,34 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 
70, 100, 100 };
  */
 static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
 
+static void __wacom_notify_battery(struct wacom_battery *battery,
+                                  int bat_capacity, bool bat_charging,
+                                  bool bat_connected, bool ps_connected)
+{
+       bool changed = battery->battery_capacity != bat_capacity  ||
+                        battery->bat_charging     != bat_charging  ||
+                        battery->bat_connected    != bat_connected ||
+                        battery->ps_connected     != ps_connected;
+
+       if (changed) {
+                battery->battery_capacity = bat_capacity;
+                battery->bat_charging = bat_charging;
+                battery->bat_connected = bat_connected;
+                battery->ps_connected = ps_connected;
+
+                if (WACOM_POWERSUPPLY_DEVICE(battery->battery))
+                         
power_supply_changed(WACOM_POWERSUPPLY_REF(battery->battery));
+       }
+}
+
 static void wacom_notify_battery(struct wacom_wac *wacom_wac,
        int bat_capacity, bool bat_charging, bool bat_connected,
        bool ps_connected)
 {
        struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
-       bool changed = wacom_wac->battery_capacity != bat_capacity  ||
-                      wacom_wac->bat_charging     != bat_charging  ||
-                      wacom_wac->bat_connected    != bat_connected ||
-                      wacom_wac->ps_connected     != ps_connected;
 
-       if (changed) {
-               wacom_wac->battery_capacity = bat_capacity;
-               wacom_wac->bat_charging = bat_charging;
-               wacom_wac->bat_connected = bat_connected;
-               wacom_wac->ps_connected = ps_connected;
-
-               if (WACOM_POWERSUPPLY_DEVICE(wacom->battery))
-                       
power_supply_changed(WACOM_POWERSUPPLY_REF(wacom->battery));
-       }
+       __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging,
+                              bat_connected, ps_connected);
 }
 
 static int wacom_penpartner_irq(struct wacom_wac *wacom)
@@ -760,7 +769,6 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
        struct input_dev *input;
        struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
        struct wacom_remote *remote = wacom->remote;
-       struct wacom_features *features = &wacom_wac->features;
        int bat_charging, bat_percent, touch_ring_mode;
        __u32 serial;
        int i, index = -1;
@@ -835,14 +843,9 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
                        wacom->led.groups[i].select = touch_ring_mode;
        }
 
-       if (!WACOM_POWERSUPPLY_DEVICE(wacom->battery) &&
-           !(features->quirks & WACOM_QUIRK_BATTERY)) {
-               features->quirks |= WACOM_QUIRK_BATTERY;
-               wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
-       }
+       __wacom_notify_battery(&remote->remotes[index].battery, bat_percent,
+                              bat_charging, 1, bat_charging);
 
-       wacom_notify_battery(wacom_wac, bat_percent, bat_charging, 1,
-                            bat_charging);
 
 out:
        spin_unlock_irqrestore(&remote->remote_lock, flags);
@@ -2139,7 +2142,6 @@ static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, 
size_t len)
 
 static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
 {
-       struct wacom *w = container_of(wacom, struct wacom, wacom_wac);
        unsigned char *data = wacom->data;
        int connected;
 
@@ -2167,8 +2169,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, 
size_t len)
                        wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
                }
 
-               if (WACOM_POWERSUPPLY_DEVICE(w->battery))
-                       wacom_notify_battery(wacom, battery, charging, 1, 0);
+               wacom_notify_battery(wacom, battery, charging, 1, 0);
 
        } else if (wacom->pid != 0) {
                /* disconnected while previously connected */
@@ -2205,14 +2206,14 @@ static int wacom_status_irq(struct wacom_wac 
*wacom_wac, size_t len)
                wacom_notify_battery(wacom_wac, battery, charging,
                                     battery || charging, 1);
 
-               if (!WACOM_POWERSUPPLY_DEVICE(wacom->battery) &&
+               if (!WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery) &&
                    !(features->quirks & WACOM_QUIRK_BATTERY)) {
                        features->quirks |= WACOM_QUIRK_BATTERY;
                        wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                }
        }
        else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
-                WACOM_POWERSUPPLY_DEVICE(wacom->battery)) {
+                WACOM_POWERSUPPLY_DEVICE(wacom->battery.battery)) {
                features->quirks &= ~WACOM_QUIRK_BATTERY;
                wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
diff --git a/3.17/wacom_wac.h b/3.17/wacom_wac.h
index b3c1a09..84e94ce 100644
--- a/3.17/wacom_wac.h
+++ b/3.17/wacom_wac.h
@@ -229,8 +229,6 @@ struct wacom_wac {
        char pen_name[WACOM_NAME_MAX];
        char touch_name[WACOM_NAME_MAX];
        char pad_name[WACOM_NAME_MAX];
-       char bat_name[WACOM_NAME_MAX];
-       char ac_name[WACOM_NAME_MAX];
        unsigned char data[WACOM_PKGLEN_MAX];
        int tool[2];
        int id[2];
@@ -242,11 +240,7 @@ struct wacom_wac {
        struct input_dev *touch_input;
        struct input_dev *pad_input;
        int pid;
-       int battery_capacity;
        int num_contacts_left;
-       int bat_charging;
-       int bat_connected;
-       int ps_connected;
        u8 bt_features;
        u8 bt_high_speed;
        int mode_report;
diff --git a/3.7/wacom.h b/3.7/wacom.h
index 1183cbb..c6fc12c 100644
--- a/3.7/wacom.h
+++ b/3.7/wacom.h
@@ -115,6 +115,17 @@ enum wacom_worker {
        WACOM_WORKER_REMOTE,
 };
 
+struct wacom_battery {
+       struct power_supply battery;
+       struct power_supply ac;
+       char bat_name[WACOM_NAME_MAX];
+       char ac_name[WACOM_NAME_MAX];
+       int battery_capacity;
+       int bat_charging;
+       int bat_connected;
+       int ps_connected;
+};
+
 struct wacom_remote {
        spinlock_t remote_lock;
        struct kfifo remote_fifo;
@@ -124,6 +135,7 @@ struct wacom_remote {
                u32 serial;
                struct input_dev *input;
                bool registered;
+               struct wacom_battery battery;
        } remotes[WACOM_MAX_REMOTES];
 };
 
@@ -146,7 +158,7 @@ struct wacom {
                u8 hlv;       /* status led brightness button pressed (1..127) 
*/
                u8 img_lum;   /* OLED matrix display brightness */
        } led;
-       struct power_supply battery;
+       struct wacom_battery battery;
 };
 
 static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c
index 3801468..0094ff5 100644
--- a/3.7/wacom_sys.c
+++ b/3.7/wacom_sys.c
@@ -1156,27 +1156,28 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
                                      enum power_supply_property psp,
                                      union power_supply_propval *val)
 {
-       struct wacom *wacom = container_of(psy, struct wacom, battery);
+       struct wacom_battery *battery = container_of(psy, struct wacom_battery,
+                                                    battery);
+
        int ret = 0;
 
        switch (psp) {
                case POWER_SUPPLY_PROP_PRESENT:
-                       val->intval = wacom->wacom_wac.bat_connected;
+                       val->intval = battery->bat_connected;
                        break;
                case POWER_SUPPLY_PROP_SCOPE:
                        val->intval = POWER_SUPPLY_SCOPE_DEVICE;
                        break;
                case POWER_SUPPLY_PROP_CAPACITY:
-                       val->intval =
-                               wacom->wacom_wac.battery_capacity;
+                       val->intval = battery->battery_capacity;
                        break;
                case POWER_SUPPLY_PROP_STATUS:
-                       if (wacom->wacom_wac.bat_charging)
+                       if (battery->bat_charging)
                                val->intval = POWER_SUPPLY_STATUS_CHARGING;
-                       else if (wacom->wacom_wac.battery_capacity == 100 &&
-                                   wacom->wacom_wac.ps_connected)
+                       else if (battery->battery_capacity == 100 &&
+                                   battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_FULL;
-                       else if (wacom->wacom_wac.ps_connected)
+                       else if (battery->ps_connected)
                                val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
                        else
                                val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
@@ -1189,46 +1190,64 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
        return ret;
 }
 
-static int wacom_initialize_battery(struct wacom *wacom)
+static int __wacom_initialize_battery(struct wacom *wacom,
+                                     struct wacom_battery *battery)
 {
        static atomic_t battery_no = ATOMIC_INIT(0);
        static DEFINE_SPINLOCK(ps_lock);
        unsigned long flags;
        int error = 0;
+       unsigned long n;
 
        spin_lock_irqsave(&ps_lock, flags); /* Prevent potential race for the 
"wacom_battery" name */
-       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
-               unsigned long n = atomic_inc_return(&battery_no) - 1;
-
-               if (power_supply_get_by_name("wacom_battery"))
-                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", 
n);
-               else
-                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery");
-
-               wacom->battery.properties = wacom_battery_props;
-               wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
-               wacom->battery.get_property = wacom_battery_get_property;
-               wacom->battery.name = wacom->wacom_wac.bat_name;
-               wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
-               wacom->battery.use_for_apm = 0;
-
-               error = power_supply_register(&wacom->usbdev->dev,
-                                             &wacom->battery);
-
-               if (!error)
-                       power_supply_powers(&wacom->battery,
-                                           &wacom->usbdev->dev);
-       }
+
+       n = atomic_inc_return(&battery_no) - 1;
+
+       if (power_supply_get_by_name("wacom_battery"))
+               sprintf(battery->bat_name, "wacom_battery_%ld", n);
+       else
+               sprintf(battery->bat_name, "wacom_battery");
+
+       battery->battery.properties = wacom_battery_props;
+       battery->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
+       battery->battery.get_property = wacom_battery_get_property;
+       battery->battery.name = battery->bat_name;
+       battery->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->battery.use_for_apm = 0;
+
+       error = power_supply_register(&wacom->usbdev->dev,
+                                     &battery->battery);
+
+       if (!error)
+               power_supply_powers(&battery->battery,
+                                   &wacom->usbdev->dev);
+
        spin_unlock_irqrestore(&ps_lock, flags);
 
        return error;
 }
 
+static int wacom_initialize_battery(struct wacom *wacom)
+{
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY)
+                return __wacom_initialize_battery(wacom, &wacom->battery);
+
+       return 0;
+}
+
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-       if (wacom->battery.dev) {
-               power_supply_unregister(&wacom->battery);
-               wacom->battery.dev = NULL;
+       if (wacom->battery.battery.dev) {
+               power_supply_unregister(&wacom->battery.battery);
+               wacom->battery.battery.dev = NULL;
+       }
+}
+
+static void wacom_destroy_remote_battery(struct wacom_battery *battery)
+{
+       if (battery->battery.dev) {
+               power_supply_unregister(&battery->battery);
+               battery->battery.dev = NULL;
        }
 }
 
@@ -1333,6 +1352,9 @@ static void wacom_remote_destroy_one(struct wacom *wacom, 
unsigned int index)
        if (remote->remotes[index].input)
                input_unregister_device(remote->remotes[index].input);
 
+       if (remote->remotes[index].battery.battery.dev)
+               wacom_destroy_remote_battery(&remote->remotes[index].battery);
+
        for (i = 0; i < WACOM_MAX_REMOTES; i++) {
                if (remote->remotes[i].serial == serial) {
                        remote->remotes[i].serial = 0;
@@ -1392,7 +1414,7 @@ static void wacom_remotes_destroy(struct wacom *wacom)
                return;
 
        for (i = 0; i < WACOM_MAX_REMOTES; i++) {
-               if (wacom->remote->remotes[i].group.name) {
+               if (remote->remotes[i].registered) {
                        wacom_remote_destroy_one(wacom, i);
                }
        }
@@ -1600,6 +1622,11 @@ static int wacom_remote_create_one(struct wacom *wacom, 
u32 serial,
 
        remote->remotes[index].registered = true;
 
+       error = __wacom_initialize_battery(wacom,
+                                          &remote->remotes[index].battery);
+       if (error)
+               goto fail;
+
        devres_close_group(dev, &remote->remotes[index]);
 
        return 0;
@@ -1758,11 +1785,11 @@ void wacom_battery_work(struct work_struct *work)
        struct wacom *wacom = container_of(work, struct wacom, battery_work);
 
        if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-            !wacom->battery.dev) {
+            !wacom->battery.battery.dev) {
                wacom_initialize_battery(wacom);
        }
        else if (!(wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
-                wacom->battery.dev) {
+                wacom->battery.battery.dev) {
                wacom_destroy_battery(wacom);
        }
 }
diff --git a/3.7/wacom_wac.c b/3.7/wacom_wac.c
index 252e871..ed8cedb 100644
--- a/3.7/wacom_wac.c
+++ b/3.7/wacom_wac.c
@@ -41,27 +41,36 @@
 static void wacom_report_numbered_buttons(struct input_dev *input_dev,
                                int button_cout, int mask);
 
-static void wacom_notify_battery(struct wacom_wac *wacom_wac,
+static void __wacom_notify_battery(struct wacom_battery *battery,
        int bat_capacity, bool bat_charging, bool bat_connected,
        bool ps_connected)
 {
-       struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
-       bool changed = wacom_wac->battery_capacity != bat_capacity  ||
-                      wacom_wac->bat_charging     != bat_charging  ||
-                      wacom_wac->bat_connected    != bat_connected ||
-                      wacom_wac->ps_connected     != ps_connected;
+       bool changed = battery->battery_capacity != bat_capacity  ||
+                      battery->bat_charging     != bat_charging  ||
+                      battery->bat_connected    != bat_connected ||
+                      battery->ps_connected     != ps_connected;
 
        if (changed) {
-               wacom_wac->battery_capacity = bat_capacity;
-               wacom_wac->bat_charging = bat_charging;
-               wacom_wac->bat_connected = bat_connected;
-               wacom_wac->ps_connected = ps_connected;
+               battery->battery_capacity = bat_capacity;
+               battery->bat_charging = bat_charging;
+               battery->bat_connected = bat_connected;
+               battery->ps_connected = ps_connected;
 
-               if (wacom->battery.dev)
-                       power_supply_changed(&wacom->battery);
+               if (battery->battery.dev)
+                       power_supply_changed(&battery->battery);
        }
 }
 
+static void wacom_notify_battery(struct wacom_wac *wacom_wac,
+       int bat_capacity, bool bat_charging, bool bat_connected,
+       bool ps_connected)
+{
+       struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+
+       __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging,
+                              bat_connected, ps_connected);
+}
+
 static int wacom_penpartner_irq(struct wacom_wac *wacom)
 {
        unsigned char *data = wacom->data;
@@ -701,7 +710,6 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
 {
        unsigned char *data = wacom_wac->data;
        struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
-       struct wacom_features *features = &wacom_wac->features;
        struct wacom_remote *remote = wacom->remote;
        struct input_dev *input;
        int bat_charging, bat_percent, touch_ring_mode;
@@ -778,14 +786,8 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, 
size_t len)
                        wacom->led.select[i] = touch_ring_mode;
        }
 
-       if (!wacom->battery.dev &&
-           !(features->quirks & WACOM_QUIRK_BATTERY)) {
-               features->quirks |= WACOM_QUIRK_BATTERY;
-               wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
-       }
-
-       wacom_notify_battery(wacom_wac, bat_percent, bat_charging, 1,
-                            bat_charging);
+       __wacom_notify_battery(&remote->remotes[index].battery, bat_percent,
+                              bat_charging, 1, bat_charging);
 
 out:
        spin_unlock_irqrestore(&remote->remote_lock, flags);
@@ -1537,7 +1539,6 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t 
len)
 
 static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
 {
-       struct wacom *w = container_of(wacom, struct wacom, wacom_wac);
        unsigned char *data = wacom->data;
        int connected;
 
@@ -1565,8 +1566,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, 
size_t len)
                        wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
                }
 
-               if (w->battery.dev)
-                       wacom_notify_battery(wacom, battery, charging, 1, 0);
+               wacom_notify_battery(wacom, battery, charging, 1, 0);
 
        } else if (wacom->pid != 0) {
                /* disconnected while previously connected */
@@ -1603,14 +1603,14 @@ static int wacom_status_irq(struct wacom_wac 
*wacom_wac, size_t len)
                wacom_notify_battery(wacom_wac, battery, charging,
                                     battery || charging, 1);
 
-               if (!wacom->battery.dev &&
+               if (!wacom->battery.battery.dev &&
                    !(features->quirks & WACOM_QUIRK_BATTERY)) {
                        features->quirks |= WACOM_QUIRK_BATTERY;
                        wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                }
        }
        else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
-                wacom->battery.dev) {
+                wacom->battery.battery.dev) {
                features->quirks &= ~WACOM_QUIRK_BATTERY;
                wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
                wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
@@ -1835,9 +1835,8 @@ void wacom_setup_device_quirks(struct wacom *wacom)
                }
        }
 
-       if (features->type == REMOTE) {
+       if (features->type == REMOTE)
                features->quirks |= WACOM_QUIRK_MONITOR;
-       }
 }
 
 static void wacom_abs_set_axis(struct input_dev *input_dev,
diff --git a/3.7/wacom_wac.h b/3.7/wacom_wac.h
index 7e12b8b..25a9ac5 100644
--- a/3.7/wacom_wac.h
+++ b/3.7/wacom_wac.h
@@ -174,7 +174,6 @@ struct wacom_remote_data {
 
 struct wacom_wac {
        char name[WACOM_NAME_MAX];
-       char bat_name[WACOM_NAME_MAX];
        unsigned char *data;
        int tool[2];
        int id[2];
@@ -184,11 +183,7 @@ struct wacom_wac {
        struct wacom_shared *shared;
        struct input_dev *input;
        int pid;
-       int battery_capacity;
        int num_contacts_left;
-       int bat_charging;
-       int bat_connected;
-       int ps_connected;
 };
 
 #endif
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to