Skip to content

Commit a30692b

Browse files
petegriffinkrzk
authored andcommitted
pinctrl: samsung: Add filter selection support for alive bank on gs101
Newer Exynos based SoCs have a filter selection bitfield in the filter configuration registers on alive bank pins. This allows the selection of a digital or analog delay filter for each pin. Add support for selecting and enabling the filter. On suspend we set the analog filter to all pins in the bank (as the digital filter relies on a clock). On resume the digital filter is reapplied to all pins in the bank. The digital filter is working via a clock and has an adjustable filter delay flt_width bitfield, whereas the analog filter uses a fixed delay. The filter determines to what extent signal fluctuations received through the pad are considered glitches. The code path can be exercised using echo mem > /sys/power/state And then wake the device using a eint gpio Reviewed-by: André Draszik <[email protected]> Signed-off-by: Peter Griffin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Krzysztof Kozlowski <[email protected]>
1 parent bdbe0a0 commit a30692b

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

drivers/pinctrl/samsung/pinctrl-exynos.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,37 @@ struct exynos_eint_gpio_save {
370370
u32 eint_mask;
371371
};
372372

373+
static void exynos_eint_update_flt_reg(void __iomem *reg, int cnt, int con)
374+
{
375+
unsigned int val, shift;
376+
int i;
377+
378+
val = readl(reg);
379+
for (i = 0; i < cnt; i++) {
380+
shift = i * EXYNOS_FLTCON_LEN;
381+
val &= ~(EXYNOS_FLTCON_DIGITAL << shift);
382+
val |= con << shift;
383+
}
384+
writel(val, reg);
385+
}
386+
387+
/*
388+
* Set the desired filter (digital or analog delay) and enable it to
389+
* every pin in the bank. Note the filter selection bitfield is only
390+
* found on alive banks. The filter determines to what extent signal
391+
* fluctuations received through the pad are considered glitches.
392+
*/
393+
static void exynos_eint_set_filter(struct samsung_pin_bank *bank, int filter)
394+
{
395+
unsigned int off = EXYNOS_GPIO_EFLTCON_OFFSET + bank->eint_fltcon_offset;
396+
void __iomem *reg = bank->drvdata->virt_base + off;
397+
unsigned int con = EXYNOS_FLTCON_EN | filter;
398+
399+
for (int n = 0; n < bank->nr_pins; n += 4)
400+
exynos_eint_update_flt_reg(reg + n,
401+
min(bank->nr_pins - n, 4), con);
402+
}
403+
373404
/*
374405
* exynos_eint_gpio_init() - setup handling of external gpio interrupts.
375406
* @d: driver data of samsung pinctrl driver.
@@ -832,6 +863,7 @@ void gs101_pinctrl_suspend(struct samsung_pin_bank *bank)
832863
bank->name, save->eint_mask);
833864
} else if (bank->eint_type == EINT_TYPE_WKUP) {
834865
exynos_set_wakeup(bank);
866+
exynos_eint_set_filter(bank, EXYNOS_FLTCON_ANALOG);
835867
}
836868
}
837869

@@ -887,6 +919,8 @@ void gs101_pinctrl_resume(struct samsung_pin_bank *bank)
887919
writel(save->eint_fltcon1, eint_fltcfg0 + 4);
888920
writel(save->eint_mask, regs + bank->irq_chip->eint_mask
889921
+ bank->eint_offset);
922+
} else if (bank->eint_type == EINT_TYPE_WKUP) {
923+
exynos_eint_set_filter(bank, EXYNOS_FLTCON_DIGITAL);
890924
}
891925
}
892926

drivers/pinctrl/samsung/pinctrl-exynos.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@
5252
#define EXYNOS_EINT_MAX_PER_BANK 8
5353
#define EXYNOS_EINT_NR_WKUP_EINT
5454

55+
/*
56+
* EINT filter configuration register (on alive banks) has
57+
* the following layout.
58+
*
59+
* BitfieldName[PinNum][Bit:Bit]
60+
* FLT_EN[3][31] FLT_SEL[3][30] FLT_WIDTH[3][29:24]
61+
* FLT_EN[2][23] FLT_SEL[2][22] FLT_WIDTH[2][21:16]
62+
* FLT_EN[1][15] FLT_SEL[1][14] FLT_WIDTH[1][13:8]
63+
* FLT_EN[0][7] FLT_SEL[0][6] FLT_WIDTH[0][5:0]
64+
*
65+
* FLT_EN 0x0 = Disable, 0x1=Enable
66+
* FLT_SEL 0x0 = Analog delay filter, 0x1 Digital filter (clock count)
67+
* FLT_WIDTH Filtering width. Valid when FLT_SEL is 0x1
68+
*/
69+
70+
#define EXYNOS_FLTCON_EN BIT(7)
71+
#define EXYNOS_FLTCON_DIGITAL BIT(6)
72+
#define EXYNOS_FLTCON_ANALOG (0 << 6)
73+
#define EXYNOS_FLTCON_LEN 8
74+
5575
#define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \
5676
{ \
5777
.type = &bank_type_off, \

0 commit comments

Comments
 (0)