summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/battery.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman2015-05-01 20:41:00 +0200
committerGreg Kroah-Hartman2015-05-05 11:09:56 +0200
commita549be518623e0948213bdacd338183bba033229 (patch)
tree74d862bc5039923b46f3244b9c449999442d79b3 /drivers/staging/greybus/battery.c
parentgreybus: Move id-field before bundle-field in CPort Descriptor. (diff)
downloadkernel-qcow2-linux-a549be518623e0948213bdacd338183bba033229.tar.gz
kernel-qcow2-linux-a549be518623e0948213bdacd338183bba033229.tar.xz
kernel-qcow2-linux-a549be518623e0948213bdacd338183bba033229.zip
greybus: battery: update for 4.1 power supply api changes
The 4.1-rc1 kernel changed the power supply apis such that the structures are now owned by the power supply core, and not the individual drivers. This broke the greybus battery driver, so update it to support both the old and the new apis. The API changes were such that I can't "hide" them in kernel_ver.h, but rather the driver itself needs to have ugly #ifdefs in it. I tried to keep it to a minimum, making a sub-function for initializing the power supply device that is implemented differently for different kernel versions. When this is submitted upstream, or if we ever move our AP development to 4.1 or greater, the support for older kernels can be removed. Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/staging/greybus/battery.c')
-rw-r--r--drivers/staging/greybus/battery.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/drivers/staging/greybus/battery.c b/drivers/staging/greybus/battery.c
index b968d149741e..eb688c9e821a 100644
--- a/drivers/staging/greybus/battery.c
+++ b/drivers/staging/greybus/battery.c
@@ -7,6 +7,7 @@
* Released under the GPLv2 only.
*/
+#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -14,7 +15,19 @@
#include "greybus.h"
struct gb_battery {
+ /*
+ * The power supply api changed in 4.1, so handle both the old
+ * and new apis in the same driver for now, until this is merged
+ * upstream, when all of these version checks can be removed.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
struct power_supply bat;
+#define to_gb_battery(x) container_of(x, struct gb_battery, bat)
+#else
+ struct power_supply *bat;
+ struct power_supply_desc desc;
+#define to_gb_battery(x) power_supply_get_drvdata(x)
+#endif
// FIXME
// we will want to keep the battery stats in here as we will be getting
// updates from the SVC "on the fly" so we don't have to always go ask
@@ -24,7 +37,6 @@ struct gb_battery {
u8 version_minor;
};
-#define to_gb_battery(x) container_of(x, struct gb_battery, bat)
/* Version of the Greybus battery protocol we support */
#define GB_BATTERY_VERSION_MAJOR 0x00
@@ -283,10 +295,56 @@ static enum power_supply_property battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
};
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
+static int init_and_register(struct gb_connection *connection,
+ struct gb_battery *gb)
+{
+ int retval;
+
+ // FIXME - get a better (i.e. unique) name
+ // FIXME - anything else needs to be set?
+ gb->bat.name = "gb_battery";
+ gb->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ gb->bat.properties = battery_props;
+ gb->bat.num_properties = ARRAY_SIZE(battery_props);
+ gb->bat.get_property = get_property;
+
+ retval = power_supply_register(&connection->bundle->intf->dev,
+ &gb->bat);
+ if (retval)
+ kfree(gb);
+ return retval;
+}
+#else
+static int init_and_register(struct gb_connection *connection,
+ struct gb_battery *gb)
+{
+ struct power_supply_config cfg = {};
+ int retval = 0;
+
+ cfg.drv_data = gb;
+
+ // FIXME - get a better (i.e. unique) name
+ // FIXME - anything else needs to be set?
+ gb->desc.name = "gb_battery";
+ gb->desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ gb->desc.properties = battery_props;
+ gb->desc.num_properties = ARRAY_SIZE(battery_props);
+ gb->desc.get_property = get_property;
+
+ gb->bat = power_supply_register(&connection->bundle->intf->dev,
+ &gb->desc, &cfg);
+ if (IS_ERR(gb->bat)) {
+ retval = PTR_ERR(gb->bat);
+ kfree(gb);
+ }
+ return retval;
+}
+#endif
+
static int gb_battery_connection_init(struct gb_connection *connection)
{
struct gb_battery *gb;
- struct power_supply *b;
int retval;
gb = kzalloc(sizeof(*gb), GFP_KERNEL);
@@ -303,29 +361,18 @@ static int gb_battery_connection_init(struct gb_connection *connection)
return retval;
}
- b = &gb->bat;
- // FIXME - get a better (i.e. unique) name
- // FIXME - anything else needs to be set?
- b->name = "gb_battery";
- b->type = POWER_SUPPLY_TYPE_BATTERY,
- b->properties = battery_props,
- b->num_properties = ARRAY_SIZE(battery_props),
- b->get_property = get_property,
-
- retval = power_supply_register(&connection->bundle->intf->dev, b);
- if (retval) {
- kfree(gb);
- return retval;
- }
-
- return 0;
+ return init_and_register(connection, gb);
}
static void gb_battery_connection_exit(struct gb_connection *connection)
{
struct gb_battery *gb = connection->private;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
power_supply_unregister(&gb->bat);
+#else
+ power_supply_unregister(gb->bat);
+#endif
kfree(gb);
}