Skip to content

Commit e2f3cf1

Browse files
atorguelinusw
authored andcommitted
pinctrl: stm32: add suspend/resume management
During power sequence, GPIO hardware registers could be lost if the power supply is switched off. Each device using pinctrl API is in charge of managing pins during suspend/resume sequences. But for pins used as gpio or irq stm32 pinctrl driver has to save the hardware configuration. Signed-off-by: Alexandre Torgue <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent b672a87 commit e2f3cf1

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

drivers/pinctrl/stm32/pinctrl-stm32.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@
4444
#define STM32_GPIO_AFRL 0x20
4545
#define STM32_GPIO_AFRH 0x24
4646

47+
/* custom bitfield to backup pin status */
48+
#define STM32_GPIO_BKP_MODE_SHIFT 0
49+
#define STM32_GPIO_BKP_MODE_MASK GENMASK(1, 0)
50+
#define STM32_GPIO_BKP_ALT_SHIFT 2
51+
#define STM32_GPIO_BKP_ALT_MASK GENMASK(5, 2)
52+
#define STM32_GPIO_BKP_SPEED_SHIFT 6
53+
#define STM32_GPIO_BKP_SPEED_MASK GENMASK(7, 6)
54+
#define STM32_GPIO_BKP_PUPD_SHIFT 8
55+
#define STM32_GPIO_BKP_PUPD_MASK GENMASK(9, 8)
56+
#define STM32_GPIO_BKP_TYPE 10
57+
#define STM32_GPIO_BKP_VAL 11
58+
4759
#define STM32_GPIO_PINS_PER_BANK 16
4860
#define STM32_GPIO_IRQ_LINE 16
4961

@@ -79,6 +91,7 @@ struct stm32_gpio_bank {
7991
struct irq_domain *domain;
8092
u32 bank_nr;
8193
u32 bank_ioport_nr;
94+
u32 pin_backup[STM32_GPIO_PINS_PER_BANK];
8295
};
8396

8497
struct stm32_pinctrl {
@@ -133,11 +146,50 @@ static inline u32 stm32_gpio_get_alt(u32 function)
133146
return 0;
134147
}
135148

149+
static void stm32_gpio_backup_value(struct stm32_gpio_bank *bank,
150+
u32 offset, u32 value)
151+
{
152+
bank->pin_backup[offset] &= ~BIT(STM32_GPIO_BKP_VAL);
153+
bank->pin_backup[offset] |= value << STM32_GPIO_BKP_VAL;
154+
}
155+
156+
static void stm32_gpio_backup_mode(struct stm32_gpio_bank *bank, u32 offset,
157+
u32 mode, u32 alt)
158+
{
159+
bank->pin_backup[offset] &= ~(STM32_GPIO_BKP_MODE_MASK |
160+
STM32_GPIO_BKP_ALT_MASK);
161+
bank->pin_backup[offset] |= mode << STM32_GPIO_BKP_MODE_SHIFT;
162+
bank->pin_backup[offset] |= alt << STM32_GPIO_BKP_ALT_SHIFT;
163+
}
164+
165+
static void stm32_gpio_backup_driving(struct stm32_gpio_bank *bank, u32 offset,
166+
u32 drive)
167+
{
168+
bank->pin_backup[offset] &= ~BIT(STM32_GPIO_BKP_TYPE);
169+
bank->pin_backup[offset] |= drive << STM32_GPIO_BKP_TYPE;
170+
}
171+
172+
static void stm32_gpio_backup_speed(struct stm32_gpio_bank *bank, u32 offset,
173+
u32 speed)
174+
{
175+
bank->pin_backup[offset] &= ~STM32_GPIO_BKP_SPEED_MASK;
176+
bank->pin_backup[offset] |= speed << STM32_GPIO_BKP_SPEED_SHIFT;
177+
}
178+
179+
static void stm32_gpio_backup_bias(struct stm32_gpio_bank *bank, u32 offset,
180+
u32 bias)
181+
{
182+
bank->pin_backup[offset] &= ~STM32_GPIO_BKP_PUPD_MASK;
183+
bank->pin_backup[offset] |= bias << STM32_GPIO_BKP_PUPD_SHIFT;
184+
}
185+
136186
/* GPIO functions */
137187

138188
static inline void __stm32_gpio_set(struct stm32_gpio_bank *bank,
139189
unsigned offset, int value)
140190
{
191+
stm32_gpio_backup_value(bank, offset, value);
192+
141193
if (!value)
142194
offset += STM32_GPIO_PINS_PER_BANK;
143195

@@ -620,6 +672,8 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank,
620672
if (pctl->hwlock)
621673
hwspin_unlock(pctl->hwlock);
622674

675+
stm32_gpio_backup_mode(bank, pin, mode, alt);
676+
623677
unlock:
624678
spin_unlock_irqrestore(&bank->lock, flags);
625679
clk_disable(bank->clk);
@@ -732,6 +786,8 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank,
732786
if (pctl->hwlock)
733787
hwspin_unlock(pctl->hwlock);
734788

789+
stm32_gpio_backup_driving(bank, offset, drive);
790+
735791
unlock:
736792
spin_unlock_irqrestore(&bank->lock, flags);
737793
clk_disable(bank->clk);
@@ -784,6 +840,8 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank,
784840
if (pctl->hwlock)
785841
hwspin_unlock(pctl->hwlock);
786842

843+
stm32_gpio_backup_speed(bank, offset, speed);
844+
787845
unlock:
788846
spin_unlock_irqrestore(&bank->lock, flags);
789847
clk_disable(bank->clk);
@@ -836,6 +894,8 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank,
836894
if (pctl->hwlock)
837895
hwspin_unlock(pctl->hwlock);
838896

897+
stm32_gpio_backup_bias(bank, offset, bias);
898+
839899
unlock:
840900
spin_unlock_irqrestore(&bank->lock, flags);
841901
clk_disable(bank->clk);
@@ -1369,3 +1429,75 @@ int stm32_pctl_probe(struct platform_device *pdev)
13691429

13701430
return 0;
13711431
}
1432+
1433+
static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
1434+
struct stm32_pinctrl *pctl, u32 pin)
1435+
{
1436+
const struct pin_desc *desc = pin_desc_get(pctl->pctl_dev, pin);
1437+
u32 val, alt, mode, offset = stm32_gpio_pin(pin);
1438+
struct pinctrl_gpio_range *range;
1439+
struct stm32_gpio_bank *bank;
1440+
bool pin_is_irq;
1441+
int ret;
1442+
1443+
range = pinctrl_find_gpio_range_from_pin(pctl->pctl_dev, pin);
1444+
if (!range)
1445+
return 0;
1446+
1447+
pin_is_irq = gpiochip_line_is_irq(range->gc, offset);
1448+
1449+
if (!desc || (!pin_is_irq && !desc->gpio_owner))
1450+
return 0;
1451+
1452+
bank = gpiochip_get_data(range->gc);
1453+
1454+
alt = bank->pin_backup[offset] & STM32_GPIO_BKP_ALT_MASK;
1455+
alt >>= STM32_GPIO_BKP_ALT_SHIFT;
1456+
mode = bank->pin_backup[offset] & STM32_GPIO_BKP_MODE_MASK;
1457+
mode >>= STM32_GPIO_BKP_MODE_SHIFT;
1458+
1459+
ret = stm32_pmx_set_mode(bank, offset, mode, alt);
1460+
if (ret)
1461+
return ret;
1462+
1463+
if (mode == 1) {
1464+
val = bank->pin_backup[offset] & BIT(STM32_GPIO_BKP_VAL);
1465+
val = val >> STM32_GPIO_BKP_VAL;
1466+
__stm32_gpio_set(bank, offset, val);
1467+
}
1468+
1469+
val = bank->pin_backup[offset] & BIT(STM32_GPIO_BKP_TYPE);
1470+
val >>= STM32_GPIO_BKP_TYPE;
1471+
ret = stm32_pconf_set_driving(bank, offset, val);
1472+
if (ret)
1473+
return ret;
1474+
1475+
val = bank->pin_backup[offset] & STM32_GPIO_BKP_SPEED_MASK;
1476+
val >>= STM32_GPIO_BKP_SPEED_SHIFT;
1477+
ret = stm32_pconf_set_speed(bank, offset, val);
1478+
if (ret)
1479+
return ret;
1480+
1481+
val = bank->pin_backup[offset] & STM32_GPIO_BKP_PUPD_MASK;
1482+
val >>= STM32_GPIO_BKP_PUPD_SHIFT;
1483+
ret = stm32_pconf_set_bias(bank, offset, val);
1484+
if (ret)
1485+
return ret;
1486+
1487+
if (pin_is_irq)
1488+
regmap_field_write(pctl->irqmux[offset], bank->bank_ioport_nr);
1489+
1490+
return 0;
1491+
}
1492+
1493+
int __maybe_unused stm32_pinctrl_resume(struct device *dev)
1494+
{
1495+
struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
1496+
struct stm32_pinctrl_group *g = pctl->groups;
1497+
int i;
1498+
1499+
for (i = g->pin; i < g->pin + pctl->ngroups; i++)
1500+
stm32_pinctrl_restore_gpio_regs(pctl, i);
1501+
1502+
return 0;
1503+
}

drivers/pinctrl/stm32/pinctrl-stm32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,7 @@ struct stm32_gpio_bank;
6565
int stm32_pctl_probe(struct platform_device *pdev);
6666
void stm32_pmx_get_mode(struct stm32_gpio_bank *bank,
6767
int pin, u32 *mode, u32 *alt);
68+
int stm32_pinctrl_resume(struct device *dev);
69+
6870
#endif /* __PINCTRL_STM32_H */
6971

0 commit comments

Comments
 (0)