Skip to content

Commit

Permalink
Merge tag 'for-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/sre/linux-power-supply

Pull power supply and reset updates from Sebastian Reichel:

 - Microsemi Ocelot reset support

 - Spreadtrum SC27xx reset support

 - generic gpio charger: lot's of cleanups

 - axp20x fuel gauge: add AXP813 support

 - misc fixes, including one devicetree change for the Nokia N900, that
   has been Acked-by Tony Lindgren

* tag 'for-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (27 commits)
  power: reset: at91-reset: Switch from the pr_*() to the dev_*() logging functions
  power: reset: at91-poweroff: Remove redundant dev_err call in at91_poweroff_probe()
  power: reset: at91-poweroff: Switch from the pr_*() to the dev_*() logging functions
  power: reset: make function sc27xx_poweroff_shutdown static
  power: supply: da9150-fg: remove VLA usage
  ARM: dts: omap3-n900: Add link between battery and charger
  power: supply: bq2415x: add DT referencing support
  power: supply: bq27xxx: support missing supplier device
  max17042: propagate of_node to power supply device
  power: supply: axp288_fuel_gauge: Fix full status reporting
  power: supply: axp288_fuel_gauge: Do not register FG on ECS EF20EA
  power: reset: gpio-poweroff: Support for timeout from device property
  dt-bindings: power: reset: gpio-poweroff: Add 'timeout-ms' property
  power: reset: Add Spreadtrum SC27xx PMIC power off support
  power: supply: axp20x_battery: add support for AXP813
  dt-bindings: power: supply: axp20x: add AXP813 battery DT binding
  power: supply: axp20x_battery: use data struct for variant specific code
  power: supply: gpio-charger: Remove pdata from gpio_charger
  power: supply: gpio-charger: Use GPIOF_ACTIVE_LOW for legacy setup
  power: supply: gpio-charger: Remove redundant dev_err call in probe function
  ...
  • Loading branch information
torvalds committed Apr 3, 2018
2 parents 75dcc7e + fd73a3e commit 3ac684b
Show file tree
Hide file tree
Showing 20 changed files with 500 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ Optional properties:
it to an output when the power-off handler is called. If this optional
property is not specified, the GPIO is initialized as an output in its
inactive state.
- timeout-ms: Time to wait before asserting a WARN_ON(1). If nothing is
specified, 3000 ms is used.

Examples:

gpio-poweroff {
compatible = "gpio-poweroff";
gpios = <&gpio 4 0>;
timeout-ms = <3000>;
};
14 changes: 14 additions & 0 deletions Documentation/devicetree/bindings/power/reset/ocelot-reset.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Microsemi Ocelot reset controller

The DEVCPU_GCB:CHIP_REGS have a SOFT_RST register that can be used to reset the
SoC MIPS core.

Required Properties:
- compatible: "mscc,ocelot-chip-reset"

Example:
reset@1070008 {
compatible = "mscc,ocelot-chip-reset";
reg = <0x1070008 0x4>;
};

Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ Required Properties:
- compatible, one of:
"x-powers,axp209-battery-power-supply"
"x-powers,axp221-battery-power-supply"
"x-powers,axp813-battery-power-supply"

This node is a subnode of the axp20x/axp22x PMIC.
This node is a subnode of its respective PMIC DT node.

The AXP20X and AXP22X can read the battery voltage, charge and discharge
currents of the battery by reading ADC channels from the AXP20X/AXP22X
ADC.
The supported devices can read the battery voltage, charge and discharge
currents of the battery by reading ADC channels from the ADC.

Example:

Expand Down
1 change: 1 addition & 0 deletions arch/arm/boot/dts/omap3-n900.dts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
bq27200: bq27200@55 {
compatible = "ti,bq27200";
reg = <0x55>;
power-supplies = <&bq24150a>;
};

/* Stereo headphone amplifier */
Expand Down
16 changes: 16 additions & 0 deletions drivers/power/reset/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ config POWER_RESET_MSM
help
Power off and restart support for Qualcomm boards.

config POWER_RESET_OCELOT_RESET
bool "Microsemi Ocelot reset driver"
depends on MSCC_OCELOT || COMPILE_TEST
select MFD_SYSCON
help
This driver supports restart for Microsemi Ocelot SoC.

config POWER_RESET_PIIX4_POWEROFF
tristate "Intel PIIX4 power-off driver"
depends on PCI
Expand Down Expand Up @@ -218,5 +225,14 @@ config SYSCON_REBOOT_MODE
register, then the bootloader can read it to take different
action according to the mode.

config POWER_RESET_SC27XX
bool "Spreadtrum SC27xx PMIC power-off driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
help
This driver supports powering off a system through
Spreadtrum SC27xx series PMICs. The SC27xx series
PMICs includes the SC2720, SC2721, SC2723, SC2730
and SC2731 chips.

endif

2 changes: 2 additions & 0 deletions drivers/power/reset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
Expand All @@ -26,3 +27,4 @@ obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o
obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
14 changes: 7 additions & 7 deletions drivers/power/reset/at91-poweroff.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ static void __iomem *at91_shdwc_base;
static struct clk *sclk;
static void __iomem *mpddrc_base;

static void __init at91_wakeup_status(void)
static void __init at91_wakeup_status(struct platform_device *pdev)
{
const char *reason;
u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
char *reason = "unknown";

/* Simple power-on, just bail out */
if (!reg)
Expand All @@ -68,8 +68,10 @@ static void __init at91_wakeup_status(void)
reason = "RTT";
else if (reg & AT91_SHDW_RTCWK)
reason = "RTC";
else
reason = "unknown";

pr_info("AT91: Wake-Up source: %s\n", reason);
dev_info(&pdev->dev, "Wake-Up source: %s\n", reason);
}

static void at91_poweroff(void)
Expand Down Expand Up @@ -157,10 +159,8 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(at91_shdwc_base)) {
dev_err(&pdev->dev, "Could not map reset controller address\n");
if (IS_ERR(at91_shdwc_base))
return PTR_ERR(at91_shdwc_base);
}

sclk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(sclk))
Expand All @@ -172,7 +172,7 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
return ret;
}

at91_wakeup_status();
at91_wakeup_status(pdev);

if (pdev->dev.of_node)
at91_poweroff_dt_set_wakeup_mode(pdev);
Expand Down
4 changes: 2 additions & 2 deletions drivers/power/reset/at91-reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ static int samx7_restart(struct notifier_block *this, unsigned long mode,

static void __init at91_reset_status(struct platform_device *pdev)
{
const char *reason;
u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
char *reason;

switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
case RESET_TYPE_GENERAL:
Expand All @@ -169,7 +169,7 @@ static void __init at91_reset_status(struct platform_device *pdev)
break;
}

pr_info("AT91: Starting after %s\n", reason);
dev_info(&pdev->dev, "Starting after %s\n", reason);
}

static const struct of_device_id at91_ramc_of_match[] = {
Expand Down
30 changes: 17 additions & 13 deletions drivers/power/reset/gemini-poweroff.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
val &= 0x70U;
switch (val) {
case GEMINI_STAT_CIR:
dev_info(gpw->dev, "infrared poweroff\n");
orderly_poweroff(true);
/*
* We do not yet have a driver for the infrared
* controller so it can cause spurious poweroff
* events. Ignore those for now.
*/
dev_info(gpw->dev, "infrared poweroff - ignored\n");
break;
case GEMINI_STAT_RTC:
dev_info(gpw->dev, "RTC poweroff\n");
Expand Down Expand Up @@ -116,7 +120,17 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
return -ENODEV;
}

/* Clear the power management IRQ */
/*
* Enable the power controller. This is crucial on Gemini
* systems: if this is not done, pressing the power button
* will result in unconditional poweroff without any warning.
* This makes the kernel handle the poweroff.
*/
val = readl(gpw->base + GEMINI_PWC_CTRLREG);
val |= GEMINI_CTRL_ENABLE;
writel(val, gpw->base + GEMINI_PWC_CTRLREG);

/* Now that the state machine is active, clear the IRQ */
val = readl(gpw->base + GEMINI_PWC_CTRLREG);
val |= GEMINI_CTRL_IRQ_CLR;
writel(val, gpw->base + GEMINI_PWC_CTRLREG);
Expand All @@ -129,16 +143,6 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
pm_power_off = gemini_poweroff;
gpw_poweroff = gpw;

/*
* Enable the power controller. This is crucial on Gemini
* systems: if this is not done, pressing the power button
* will result in unconditional poweroff without any warning.
* This makes the kernel handle the poweroff.
*/
val = readl(gpw->base + GEMINI_PWC_CTRLREG);
val |= GEMINI_CTRL_ENABLE;
writel(val, gpw->base + GEMINI_PWC_CTRLREG);

dev_info(dev, "Gemini poweroff driver registered\n");

return 0;
Expand Down
8 changes: 6 additions & 2 deletions drivers/power/reset/gpio-poweroff.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include <linux/of_platform.h>
#include <linux/module.h>

#define DEFAULT_TIMEOUT_MS 3000
/*
* Hold configuration here, cannot be more than one instance of the driver
* since pm_power_off itself is global.
*/
static struct gpio_desc *reset_gpio;
static u32 timeout = DEFAULT_TIMEOUT_MS;

static void gpio_poweroff_do_poweroff(void)
{
Expand All @@ -40,7 +42,7 @@ static void gpio_poweroff_do_poweroff(void)
gpiod_set_value(reset_gpio, 1);

/* give it some time */
mdelay(3000);
mdelay(timeout);

WARN_ON(1);
}
Expand All @@ -58,12 +60,14 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
return -EBUSY;
}

input = of_property_read_bool(pdev->dev.of_node, "input");
input = device_property_read_bool(&pdev->dev, "input");
if (input)
flags = GPIOD_IN;
else
flags = GPIOD_OUT_LOW;

device_property_read_u32(&pdev->dev, "timeout-ms", &timeout);

reset_gpio = devm_gpiod_get(&pdev->dev, NULL, flags);
if (IS_ERR(reset_gpio))
return PTR_ERR(reset_gpio);
Expand Down
88 changes: 88 additions & 0 deletions drivers/power/reset/ocelot-reset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Microsemi MIPS SoC reset driver
*
* License: Dual MIT/GPL
* Copyright (c) 2017 Microsemi Corporation
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/notifier.h>
#include <linux/mfd/syscon.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>

struct ocelot_reset_context {
void __iomem *base;
struct regmap *cpu_ctrl;
struct notifier_block restart_handler;
};

#define ICPU_CFG_CPU_SYSTEM_CTRL_RESET 0x20
#define CORE_RST_PROTECT BIT(2)

#define SOFT_CHIP_RST BIT(0)

static int ocelot_restart_handle(struct notifier_block *this,
unsigned long mode, void *cmd)
{
struct ocelot_reset_context *ctx = container_of(this, struct
ocelot_reset_context,
restart_handler);

/* Make sure the core is not protected from reset */
regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_RESET,
CORE_RST_PROTECT, 0);

writel(SOFT_CHIP_RST, ctx->base);

pr_emerg("Unable to restart system\n");
return NOTIFY_DONE;
}

static int ocelot_reset_probe(struct platform_device *pdev)
{
struct ocelot_reset_context *ctx;
struct resource *res;

struct device *dev = &pdev->dev;
int err;

ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ctx->base = devm_ioremap_resource(dev, res);
if (IS_ERR(ctx->base))
return PTR_ERR(ctx->base);

ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible("mscc,ocelot-cpu-syscon");
if (IS_ERR(ctx->cpu_ctrl))
return PTR_ERR(ctx->cpu_ctrl);

ctx->restart_handler.notifier_call = ocelot_restart_handle;
ctx->restart_handler.priority = 192;
err = register_restart_handler(&ctx->restart_handler);
if (err)
dev_err(dev, "can't register restart notifier (err=%d)\n", err);

return err;
}

static const struct of_device_id ocelot_reset_of_match[] = {
{ .compatible = "mscc,ocelot-chip-reset" },
{}
};

static struct platform_driver ocelot_reset_driver = {
.probe = ocelot_reset_probe,
.driver = {
.name = "ocelot-chip-reset",
.of_match_table = ocelot_reset_of_match,
},
};
builtin_platform_driver(ocelot_reset_driver);
Loading

0 comments on commit 3ac684b

Please sign in to comment.