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

Commit 3f5faf3a authored by Baolin Wang's avatar Baolin Wang Committed by Sebastian Reichel
Browse files

power: reset: Add Spreadtrum SC27xx PMIC power off support



On Spreadtrum platform, we need power off system through external SC27xx
series PMICs including the SC2720, SC2721, SC2723, SC2730 and SC2731 chips.
Thus this patch adds SC27xx series PMICs power-off support.

Signed-off-by: default avatarBaolin Wang <baolin.wang@linaro.org>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
parent 6ff653e3
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -225,5 +225,14 @@ config SYSCON_REBOOT_MODE
	  register, then the bootloader can read it to take different
	  register, then the bootloader can read it to take different
	  action according to the mode.
	  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
endif
+1 −0
Original line number Original line Diff line number Diff line
@@ -27,3 +27,4 @@ obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o
obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
+66 −0
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018 Spreadtrum Communications Inc.
 * Copyright (C) 2018 Linaro Ltd.
 */

#include <linux/cpu.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/syscore_ops.h>

#define SC27XX_PWR_PD_HW	0xc2c
#define SC27XX_PWR_OFF_EN	BIT(0)

static struct regmap *regmap;

/*
 * On Spreadtrum platform, we need power off system through external SC27xx
 * series PMICs, and it is one similar SPI bus mapped by regmap to access PMIC,
 * which is not fast io access.
 *
 * So before stopping other cores, we need release other cores' resource by
 * taking cpus down to avoid racing regmap or spi mutex lock when poweroff
 * system through PMIC.
 */
void sc27xx_poweroff_shutdown(void)
{
#ifdef CONFIG_PM_SLEEP_SMP
	int cpu = smp_processor_id();

	freeze_secondary_cpus(cpu);
#endif
}

static struct syscore_ops poweroff_syscore_ops = {
	.shutdown = sc27xx_poweroff_shutdown,
};

static void sc27xx_poweroff_do_poweroff(void)
{
	regmap_write(regmap, SC27XX_PWR_PD_HW, SC27XX_PWR_OFF_EN);
}

static int sc27xx_poweroff_probe(struct platform_device *pdev)
{
	if (regmap)
		return -EINVAL;

	regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!regmap)
		return -ENODEV;

	pm_power_off = sc27xx_poweroff_do_poweroff;
	register_syscore_ops(&poweroff_syscore_ops);
	return 0;
}

static struct platform_driver sc27xx_poweroff_driver = {
	.probe = sc27xx_poweroff_probe,
	.driver = {
		.name = "sc27xx-poweroff",
	},
};
builtin_platform_driver(sc27xx_poweroff_driver);