Skip to content

Commit a10c9c7

Browse files
committed
Merge tag 'for-v5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset changes from Sebastian Reichel: "Core: - Nothing Drivers: - at91-reset: cleanups, proper handling for sam9x60 - sc27xx, charger-manager: allow building as module - sc27xx: add support to read current charge capacity - axp288: more quirks for weird hardware - misc fixes" * tag 'for-v5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (26 commits) power: reset: sc27xx: Allow the SC27XX poweroff driver building into a module power: reset: sc27xx: Change to use cpu_down() power: reset: sc27xx: Power off the external subsystems' connection power: twl4030: Use scnprintf() for avoiding potential buffer overflow power: supply: bq27xxx_battery: Silence deferred-probe error power: reset: at91-reset: handle nrst async for sam9x60 power: reset: at91-reset: get rid of at91_reset_data power: reset: at91-reset: keep only one reset function power: reset: at91-reset: make at91sam9g45_restart() generic power: reset: at91-reset: introduce ramc_lpr to struct at91_reset power: reset: at91-reset: use r4 as tmp argument power: reset: at91-reset: introduce args member in at91_reset_data power: reset: at91-reset: introduce struct at91_reset_data power: reset: at91-reset: devm_kzalloc() for at91_reset data structure power: reset: at91-reset: pass rstc base address to at91_reset_status() power: reset: at91-reset: convert reset in pointer to struct at91_reset power: reset: at91-reset: add notifier block to struct at91_reset power: reset: at91-reset: add sclk to struct at91_reset power: reset: at91-reset: add ramc_base[] to struct at91_reset power: reset: at91-reset: introduce struct at91_reset ...
2 parents c48b072 + f78c55e commit a10c9c7

File tree

12 files changed

+211
-126
lines changed

12 files changed

+211
-126
lines changed

drivers/power/reset/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ config SYSCON_REBOOT_MODE
248248
action according to the mode.
249249

250250
config POWER_RESET_SC27XX
251-
bool "Spreadtrum SC27xx PMIC power-off driver"
251+
tristate "Spreadtrum SC27xx PMIC power-off driver"
252252
depends on MFD_SC27XX_PMIC || COMPILE_TEST
253253
help
254254
This driver supports powering off a system through

drivers/power/reset/at91-reset.c

Lines changed: 94 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
3737
#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
38+
#define AT91_RSTC_URSTASYNC BIT(2) /* User Reset Asynchronous Control */
3839
#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
3940
#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
4041

@@ -49,105 +50,63 @@ enum reset_type {
4950
RESET_TYPE_ULP2 = 8,
5051
};
5152

52-
static void __iomem *at91_ramc_base[2], *at91_rstc_base;
53-
static struct clk *sclk;
53+
struct at91_reset {
54+
void __iomem *rstc_base;
55+
void __iomem *ramc_base[2];
56+
struct clk *sclk;
57+
struct notifier_block nb;
58+
u32 args;
59+
u32 ramc_lpr;
60+
};
5461

5562
/*
5663
* unless the SDRAM is cleanly shutdown before we hit the
5764
* reset register it can be left driving the data bus and
5865
* killing the chance of a subsequent boot from NAND
5966
*/
60-
static int at91sam9260_restart(struct notifier_block *this, unsigned long mode,
61-
void *cmd)
67+
static int at91_reset(struct notifier_block *this, unsigned long mode,
68+
void *cmd)
6269
{
63-
asm volatile(
64-
/* Align to cache lines */
65-
".balign 32\n\t"
66-
67-
/* Disable SDRAM accesses */
68-
"str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t"
69-
70-
/* Power down SDRAM */
71-
"str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t"
72-
73-
/* Reset CPU */
74-
"str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t"
75-
76-
"b .\n\t"
77-
:
78-
: "r" (at91_ramc_base[0]),
79-
"r" (at91_rstc_base),
80-
"r" (1),
81-
"r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN),
82-
"r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST));
70+
struct at91_reset *reset = container_of(this, struct at91_reset, nb);
8371

84-
return NOTIFY_DONE;
85-
}
86-
87-
static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode,
88-
void *cmd)
89-
{
9072
asm volatile(
91-
/*
92-
* Test wether we have a second RAM controller to care
93-
* about.
94-
*
95-
* First, test that we can dereference the virtual address.
96-
*/
97-
"cmp %1, #0\n\t"
98-
"beq 1f\n\t"
99-
100-
/* Then, test that the RAM controller is enabled */
101-
"ldr r0, [%1]\n\t"
102-
"cmp r0, #0\n\t"
103-
10473
/* Align to cache lines */
10574
".balign 32\n\t"
10675

10776
/* Disable SDRAM0 accesses */
108-
"1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
77+
" tst %0, #0\n\t"
78+
" beq 1f\n\t"
79+
" str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
10980
/* Power down SDRAM0 */
110-
" str %4, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
81+
" str %4, [%0, %6]\n\t"
11182
/* Disable SDRAM1 accesses */
83+
"1: tst %1, #0\n\t"
84+
" beq 2f\n\t"
11285
" strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
11386
/* Power down SDRAM1 */
114-
" strne %4, [%1, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
87+
" strne %4, [%1, %6]\n\t"
11588
/* Reset CPU */
116-
" str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
89+
"2: str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
11790

11891
" b .\n\t"
11992
:
120-
: "r" (at91_ramc_base[0]),
121-
"r" (at91_ramc_base[1]),
122-
"r" (at91_rstc_base),
93+
: "r" (reset->ramc_base[0]),
94+
"r" (reset->ramc_base[1]),
95+
"r" (reset->rstc_base),
12396
"r" (1),
12497
"r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
125-
"r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)
126-
: "r0");
127-
128-
return NOTIFY_DONE;
129-
}
130-
131-
static int sama5d3_restart(struct notifier_block *this, unsigned long mode,
132-
void *cmd)
133-
{
134-
writel(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST,
135-
at91_rstc_base);
98+
"r" (reset->args),
99+
"r" (reset->ramc_lpr)
100+
: "r4");
136101

137102
return NOTIFY_DONE;
138103
}
139104

140-
static int samx7_restart(struct notifier_block *this, unsigned long mode,
141-
void *cmd)
142-
{
143-
writel(AT91_RSTC_KEY | AT91_RSTC_PROCRST, at91_rstc_base);
144-
return NOTIFY_DONE;
145-
}
146-
147-
static void __init at91_reset_status(struct platform_device *pdev)
105+
static void __init at91_reset_status(struct platform_device *pdev,
106+
void __iomem *base)
148107
{
149108
const char *reason;
150-
u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
109+
u32 reg = readl(base + AT91_RSTC_SR);
151110

152111
switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
153112
case RESET_TYPE_GENERAL:
@@ -183,42 +142,68 @@ static void __init at91_reset_status(struct platform_device *pdev)
183142
}
184143

185144
static const struct of_device_id at91_ramc_of_match[] = {
186-
{ .compatible = "atmel,at91sam9260-sdramc", },
187-
{ .compatible = "atmel,at91sam9g45-ddramc", },
145+
{
146+
.compatible = "atmel,at91sam9260-sdramc",
147+
.data = (void *)AT91_SDRAMC_LPR,
148+
},
149+
{
150+
.compatible = "atmel,at91sam9g45-ddramc",
151+
.data = (void *)AT91_DDRSDRC_LPR,
152+
},
188153
{ /* sentinel */ }
189154
};
190155

191156
static const struct of_device_id at91_reset_of_match[] = {
192-
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart },
193-
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
194-
{ .compatible = "atmel,sama5d3-rstc", .data = sama5d3_restart },
195-
{ .compatible = "atmel,samx7-rstc", .data = samx7_restart },
196-
{ .compatible = "microchip,sam9x60-rstc", .data = samx7_restart },
157+
{
158+
.compatible = "atmel,at91sam9260-rstc",
159+
.data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
160+
AT91_RSTC_PROCRST),
161+
},
162+
{
163+
.compatible = "atmel,at91sam9g45-rstc",
164+
.data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
165+
AT91_RSTC_PROCRST)
166+
},
167+
{
168+
.compatible = "atmel,sama5d3-rstc",
169+
.data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
170+
AT91_RSTC_PROCRST)
171+
},
172+
{
173+
.compatible = "atmel,samx7-rstc",
174+
.data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
175+
},
176+
{
177+
.compatible = "microchip,sam9x60-rstc",
178+
.data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
179+
},
197180
{ /* sentinel */ }
198181
};
199182
MODULE_DEVICE_TABLE(of, at91_reset_of_match);
200183

201-
static struct notifier_block at91_restart_nb = {
202-
.priority = 192,
203-
};
204-
205184
static int __init at91_reset_probe(struct platform_device *pdev)
206185
{
207186
const struct of_device_id *match;
187+
struct at91_reset *reset;
208188
struct device_node *np;
209189
int ret, idx = 0;
210190

211-
at91_rstc_base = of_iomap(pdev->dev.of_node, 0);
212-
if (!at91_rstc_base) {
191+
reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
192+
if (!reset)
193+
return -ENOMEM;
194+
195+
reset->rstc_base = of_iomap(pdev->dev.of_node, 0);
196+
if (!reset->rstc_base) {
213197
dev_err(&pdev->dev, "Could not map reset controller address\n");
214198
return -ENODEV;
215199
}
216200

217201
if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) {
218202
/* we need to shutdown the ddr controller, so get ramc base */
219-
for_each_matching_node(np, at91_ramc_of_match) {
220-
at91_ramc_base[idx] = of_iomap(np, 0);
221-
if (!at91_ramc_base[idx]) {
203+
for_each_matching_node_and_match(np, at91_ramc_of_match, &match) {
204+
reset->ramc_lpr = (u32)match->data;
205+
reset->ramc_base[idx] = of_iomap(np, 0);
206+
if (!reset->ramc_base[idx]) {
222207
dev_err(&pdev->dev, "Could not map ram controller address\n");
223208
of_node_put(np);
224209
return -ENODEV;
@@ -228,33 +213,46 @@ static int __init at91_reset_probe(struct platform_device *pdev)
228213
}
229214

230215
match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
231-
at91_restart_nb.notifier_call = match->data;
216+
reset->nb.notifier_call = at91_reset;
217+
reset->nb.priority = 192;
218+
reset->args = (u32)match->data;
232219

233-
sclk = devm_clk_get(&pdev->dev, NULL);
234-
if (IS_ERR(sclk))
235-
return PTR_ERR(sclk);
220+
reset->sclk = devm_clk_get(&pdev->dev, NULL);
221+
if (IS_ERR(reset->sclk))
222+
return PTR_ERR(reset->sclk);
236223

237-
ret = clk_prepare_enable(sclk);
224+
ret = clk_prepare_enable(reset->sclk);
238225
if (ret) {
239226
dev_err(&pdev->dev, "Could not enable slow clock\n");
240227
return ret;
241228
}
242229

243-
ret = register_restart_handler(&at91_restart_nb);
230+
platform_set_drvdata(pdev, reset);
231+
232+
if (of_device_is_compatible(pdev->dev.of_node, "microchip,sam9x60-rstc")) {
233+
u32 val = readl(reset->rstc_base + AT91_RSTC_MR);
234+
235+
writel(AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val,
236+
reset->rstc_base + AT91_RSTC_MR);
237+
}
238+
239+
ret = register_restart_handler(&reset->nb);
244240
if (ret) {
245-
clk_disable_unprepare(sclk);
241+
clk_disable_unprepare(reset->sclk);
246242
return ret;
247243
}
248244

249-
at91_reset_status(pdev);
245+
at91_reset_status(pdev, reset->rstc_base);
250246

251247
return 0;
252248
}
253249

254250
static int __exit at91_reset_remove(struct platform_device *pdev)
255251
{
256-
unregister_restart_handler(&at91_restart_nb);
257-
clk_disable_unprepare(sclk);
252+
struct at91_reset *reset = platform_get_drvdata(pdev);
253+
254+
unregister_restart_handler(&reset->nb);
255+
clk_disable_unprepare(reset->sclk);
258256

259257
return 0;
260258
}

drivers/power/reset/sc27xx-poweroff.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
#include <linux/cpu.h>
88
#include <linux/kernel.h>
9+
#include <linux/module.h>
910
#include <linux/platform_device.h>
1011
#include <linux/pm.h>
1112
#include <linux/regmap.h>
1213
#include <linux/syscore_ops.h>
1314

1415
#define SC27XX_PWR_PD_HW 0xc2c
1516
#define SC27XX_PWR_OFF_EN BIT(0)
17+
#define SC27XX_SLP_CTRL 0xdf0
18+
#define SC27XX_LDO_XTL_EN BIT(3)
1619

1720
static struct regmap *regmap;
1821

@@ -27,10 +30,13 @@ static struct regmap *regmap;
2730
*/
2831
static void sc27xx_poweroff_shutdown(void)
2932
{
30-
#ifdef CONFIG_PM_SLEEP_SMP
31-
int cpu = smp_processor_id();
33+
#ifdef CONFIG_HOTPLUG_CPU
34+
int cpu;
3235

33-
freeze_secondary_cpus(cpu);
36+
for_each_online_cpu(cpu) {
37+
if (cpu != smp_processor_id())
38+
remove_cpu(cpu);
39+
}
3440
#endif
3541
}
3642

@@ -40,6 +46,9 @@ static struct syscore_ops poweroff_syscore_ops = {
4046

4147
static void sc27xx_poweroff_do_poweroff(void)
4248
{
49+
/* Disable the external subsys connection's power firstly */
50+
regmap_write(regmap, SC27XX_SLP_CTRL, SC27XX_LDO_XTL_EN);
51+
4352
regmap_write(regmap, SC27XX_PWR_PD_HW, SC27XX_PWR_OFF_EN);
4453
}
4554

@@ -63,4 +72,8 @@ static struct platform_driver sc27xx_poweroff_driver = {
6372
.name = "sc27xx-poweroff",
6473
},
6574
};
66-
builtin_platform_driver(sc27xx_poweroff_driver);
75+
module_platform_driver(sc27xx_poweroff_driver);
76+
77+
MODULE_DESCRIPTION("Power off driver for SC27XX PMIC Device");
78+
MODULE_AUTHOR("Baolin Wang <[email protected]>");
79+
MODULE_LICENSE("GPL v2");

drivers/power/supply/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ config CHARGER_GPIO
480480
called gpio-charger.
481481

482482
config CHARGER_MANAGER
483-
bool "Battery charger manager for multiple chargers"
483+
tristate "Battery charger manager for multiple chargers"
484484
depends on REGULATOR
485485
select EXTCON
486486
help

0 commit comments

Comments
 (0)