Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7051d8e6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-v3.19' of git://git.infradead.org/battery-2.6

Pull power supply updates from Sebastian Reichel::
 "Power supply and reset changes for the v3.19 series

   - update power/reset drivers to use kernel restart handler
   - add power off driver for i.mx6
   - add DT support for gpio-charger"

* tag 'for-v3.19' of git://git.infradead.org/battery-2.6:
  power: reset: adjust priority of simple syscon reboot driver
  power: ds2782_battery: Simplify the PM hooks
  power/reset: brcmstb: Register with kernel restart handler
  power/reset: hisi: Register with kernel restart handler
  power/reset: keystone: Register with kernel restart handler
  power/reset: axxia: Register with kernel restart handler
  power/reset: xgene: Register with kernel restart handler
  power/reset: xgene: Use mdelay instead of jiffies based timeout
  power/reset: xgene: Use local variable dev instead of pdev->dev
  power/reset: xgene: Drop devm_kfree
  power/reset: xgene: Return -ENOMEM if out of memory
  power/reset: vexpress: Register with kernel restart handler
  power: reset: imx-snvs-poweroff: add power off driver for i.mx6
  power: gpio-charger: add device tree support
  dt-bindings: document gpio-charger bindings
parents d3255ec4 b81180b3
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
gpio-charger

Required properties :
 - compatible : "gpio-charger"
 - gpios : GPIO indicating the charger presence.
   See GPIO binding in bindings/gpio/gpio.txt .
 - charger-type : power supply type, one of
     unknown
     battery
     ups
     mains
     usb-sdp (USB standard downstream port)
     usb-dcp (USB dedicated charging port)
     usb-cdp (USB charging downstream port)
     usb-aca (USB accessory charger adapter)

Example:

	usb_charger: charger {
		compatible = "gpio-charger";
		charger-type = "usb-sdp";
		gpios = <&gpf0 2 0 0 0>;
	}

	battery {
		power-supplies = <&usb_charger>;
	};
+2 −6
Original line number Diff line number Diff line
@@ -351,13 +351,9 @@ static int ds278x_resume(struct device *dev)
	schedule_delayed_work(&info->bat_work, DS278x_DELAY);
	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume);
#define DS278X_BATTERY_PM_OPS (&ds278x_battery_pm_ops)

#else
#define DS278X_BATTERY_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */

enum ds278x_num_id {
	DS2782 = 0,
@@ -460,7 +456,7 @@ MODULE_DEVICE_TABLE(i2c, ds278x_id);
static struct i2c_driver ds278x_battery_driver = {
	.driver 	= {
		.name	= "ds2782-battery",
		.pm	= DS278X_BATTERY_PM_OPS,
		.pm	= &ds278x_battery_pm_ops,
	},
	.probe		= ds278x_battery_probe,
	.remove		= ds278x_battery_remove,
+70 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>

#include <linux/power/gpio-charger.h>

@@ -69,6 +71,59 @@ static enum power_supply_property gpio_charger_properties[] = {
	POWER_SUPPLY_PROP_ONLINE,
};

static
struct gpio_charger_platform_data *gpio_charger_parse_dt(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct gpio_charger_platform_data *pdata;
	const char *chargetype;
	enum of_gpio_flags flags;
	int ret;

	if (!np)
		return ERR_PTR(-ENOENT);

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	pdata->name = np->name;

	pdata->gpio = of_get_gpio_flags(np, 0, &flags);
	if (pdata->gpio < 0) {
		if (pdata->gpio != -EPROBE_DEFER)
			dev_err(dev, "could not get charger gpio\n");
		return ERR_PTR(pdata->gpio);
	}

	pdata->gpio_active_low = !!(flags & OF_GPIO_ACTIVE_LOW);

	pdata->type = POWER_SUPPLY_TYPE_UNKNOWN;
	ret = of_property_read_string(np, "charger-type", &chargetype);
	if (ret >= 0) {
		if (!strncmp("unknown", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_UNKNOWN;
		else if (!strncmp("battery", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_BATTERY;
		else if (!strncmp("ups", chargetype, 3))
			pdata->type = POWER_SUPPLY_TYPE_UPS;
		else if (!strncmp("mains", chargetype, 5))
			pdata->type = POWER_SUPPLY_TYPE_MAINS;
		else if (!strncmp("usb-sdp", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_USB;
		else if (!strncmp("usb-dcp", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_USB_DCP;
		else if (!strncmp("usb-cdp", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_USB_CDP;
		else if (!strncmp("usb-aca", chargetype, 7))
			pdata->type = POWER_SUPPLY_TYPE_USB_ACA;
		else
			dev_warn(dev, "unknown charger type %s\n", chargetype);
	}

	return pdata;
}

static int gpio_charger_probe(struct platform_device *pdev)
{
	const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
@@ -78,8 +133,13 @@ static int gpio_charger_probe(struct platform_device *pdev)
	int irq;

	if (!pdata) {
		pdata = gpio_charger_parse_dt(&pdev->dev);
		if (IS_ERR(pdata)) {
			ret = PTR_ERR(pdata);
			if (ret != -EPROBE_DEFER)
				dev_err(&pdev->dev, "No platform data\n");
		return -EINVAL;
			return ret;
		}
	}

	if (!gpio_is_valid(pdata->gpio)) {
@@ -103,6 +163,7 @@ static int gpio_charger_probe(struct platform_device *pdev)
	charger->get_property = gpio_charger_get_property;
	charger->supplied_to = pdata->supplied_to;
	charger->num_supplicants = pdata->num_supplicants;
	charger->of_node = pdev->dev.of_node;

	ret = gpio_request(pdata->gpio, dev_name(&pdev->dev));
	if (ret) {
@@ -189,12 +250,19 @@ static int gpio_charger_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops,
		gpio_charger_suspend, gpio_charger_resume);

static const struct of_device_id gpio_charger_match[] = {
	{ .compatible = "gpio-charger" },
	{ }
};
MODULE_DEVICE_TABLE(of, gpio_charger_match);

static struct platform_driver gpio_charger_driver = {
	.probe = gpio_charger_probe,
	.remove = gpio_charger_remove,
	.driver = {
		.name = "gpio-charger",
		.pm = &gpio_charger_pm_ops,
		.of_match_table = gpio_charger_match,
	},
};

+15 −6
Original line number Diff line number Diff line
@@ -19,14 +19,12 @@
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>

#include <asm/system_misc.h>


#define SC_CRIT_WRITE_KEY	0x1000
#define SC_LATCH_ON_RESET	0x1004
#define SC_RESET_CONTROL	0x1008
@@ -39,7 +37,8 @@

static struct regmap *syscon;

static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd)
static int axxia_restart_handler(struct notifier_block *this,
				 unsigned long mode, void *cmd)
{
	/* Access Key (0xab) */
	regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
@@ -50,11 +49,19 @@ static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd)
	/* Assert chip reset */
	regmap_update_bits(syscon, SC_RESET_CONTROL,
			   RSTCTL_RST_CHIP, RSTCTL_RST_CHIP);

	return NOTIFY_DONE;
}

static struct notifier_block axxia_restart_nb = {
	.notifier_call = axxia_restart_handler,
	.priority = 128,
};

static int axxia_reset_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int err;

	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
	if (IS_ERR(syscon)) {
@@ -62,9 +69,11 @@ static int axxia_reset_probe(struct platform_device *pdev)
		return PTR_ERR(syscon);
	}

	arm_pm_restart = do_axxia_restart;
	err = register_restart_handler(&axxia_restart_nb);
	if (err)
		dev_err(dev, "cannot register restart handler (err=%d)\n", err);

	return 0;
	return err;
}

static const struct of_device_id of_axxia_reset_match[] = {
+19 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/notifier.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
@@ -26,8 +27,6 @@
#include <linux/smp.h>
#include <linux/mfd/syscon.h>

#include <asm/system_misc.h>

#define RESET_SOURCE_ENABLE_REG 1
#define SW_MASTER_RESET_REG 2

@@ -35,7 +34,8 @@ static struct regmap *regmap;
static u32 rst_src_en;
static u32 sw_mstr_rst;

static void brcmstb_reboot(enum reboot_mode mode, const char *cmd)
static int brcmstb_restart_handler(struct notifier_block *this,
				   unsigned long mode, void *cmd)
{
	int rc;
	u32 tmp;
@@ -43,31 +43,38 @@ static void brcmstb_reboot(enum reboot_mode mode, const char *cmd)
	rc = regmap_write(regmap, rst_src_en, 1);
	if (rc) {
		pr_err("failed to write rst_src_en (%d)\n", rc);
		return;
		return NOTIFY_DONE;
	}

	rc = regmap_read(regmap, rst_src_en, &tmp);
	if (rc) {
		pr_err("failed to read rst_src_en (%d)\n", rc);
		return;
		return NOTIFY_DONE;
	}

	rc = regmap_write(regmap, sw_mstr_rst, 1);
	if (rc) {
		pr_err("failed to write sw_mstr_rst (%d)\n", rc);
		return;
		return NOTIFY_DONE;
	}

	rc = regmap_read(regmap, sw_mstr_rst, &tmp);
	if (rc) {
		pr_err("failed to read sw_mstr_rst (%d)\n", rc);
		return;
		return NOTIFY_DONE;
	}

	while (1)
		;

	return NOTIFY_DONE;
}

static struct notifier_block brcmstb_restart_nb = {
	.notifier_call = brcmstb_restart_handler,
	.priority = 128,
};

static int brcmstb_reboot_probe(struct platform_device *pdev)
{
	int rc;
@@ -93,9 +100,12 @@ static int brcmstb_reboot_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	arm_pm_restart = brcmstb_reboot;
	rc = register_restart_handler(&brcmstb_restart_nb);
	if (rc)
		dev_err(&pdev->dev,
			"cannot register restart handler (err=%d)\n", rc);

	return 0;
	return rc;
}

static const struct of_device_id of_match[] = {
Loading