summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos-arm64.c52
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c294
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.h28
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c21
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.h8
5 files changed, 252 insertions, 151 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index dd07720e32cc..9fd894729a7b 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -1419,8 +1419,8 @@ static const struct samsung_pin_ctrl exynosautov920_pin_ctrl[] = {
.pin_banks = exynosautov920_pin_banks0,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
.retention_data = &exynosautov920_retention_data,
}, {
/* pin-controller instance 1 AUD data */
@@ -1431,43 +1431,43 @@ static const struct samsung_pin_ctrl exynosautov920_pin_ctrl[] = {
.pin_banks = exynosautov920_pin_banks2,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
}, {
/* pin-controller instance 3 HSI1 data */
.pin_banks = exynosautov920_pin_banks3,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
}, {
/* pin-controller instance 4 HSI2 data */
.pin_banks = exynosautov920_pin_banks4,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
}, {
/* pin-controller instance 5 HSI2UFS data */
.pin_banks = exynosautov920_pin_banks5,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
}, {
/* pin-controller instance 6 PERIC0 data */
.pin_banks = exynosautov920_pin_banks6,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
}, {
/* pin-controller instance 7 PERIC1 data */
.pin_banks = exynosautov920_pin_banks7,
.nr_banks = ARRAY_SIZE(exynosautov920_pin_banks7),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = exynosautov920_pinctrl_suspend,
+ .resume = exynosautov920_pinctrl_resume,
},
};
@@ -1762,15 +1762,15 @@ static const struct samsung_pin_ctrl gs101_pin_ctrl[] __initconst = {
.pin_banks = gs101_pin_alive,
.nr_banks = ARRAY_SIZE(gs101_pin_alive),
.eint_wkup_init = exynos_eint_wkup_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
}, {
/* pin banks of gs101 pin-controller (FAR_ALIVE) */
.pin_banks = gs101_pin_far_alive,
.nr_banks = ARRAY_SIZE(gs101_pin_far_alive),
.eint_wkup_init = exynos_eint_wkup_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
}, {
/* pin banks of gs101 pin-controller (GSACORE) */
.pin_banks = gs101_pin_gsacore,
@@ -1784,29 +1784,29 @@ static const struct samsung_pin_ctrl gs101_pin_ctrl[] __initconst = {
.pin_banks = gs101_pin_peric0,
.nr_banks = ARRAY_SIZE(gs101_pin_peric0),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
}, {
/* pin banks of gs101 pin-controller (PERIC1) */
.pin_banks = gs101_pin_peric1,
.nr_banks = ARRAY_SIZE(gs101_pin_peric1),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
}, {
/* pin banks of gs101 pin-controller (HSI1) */
.pin_banks = gs101_pin_hsi1,
.nr_banks = ARRAY_SIZE(gs101_pin_hsi1),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
}, {
/* pin banks of gs101 pin-controller (HSI2) */
.pin_banks = gs101_pin_hsi2,
.nr_banks = ARRAY_SIZE(gs101_pin_hsi2),
.eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
+ .suspend = gs101_pinctrl_suspend,
+ .resume = gs101_pinctrl_resume,
},
};
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 42093bae8bb7..f3e1c11abe55 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -370,6 +370,37 @@ struct exynos_eint_gpio_save {
u32 eint_mask;
};
+static void exynos_eint_update_flt_reg(void __iomem *reg, int cnt, int con)
+{
+ unsigned int val, shift;
+ int i;
+
+ val = readl(reg);
+ for (i = 0; i < cnt; i++) {
+ shift = i * EXYNOS_FLTCON_LEN;
+ val &= ~(EXYNOS_FLTCON_DIGITAL << shift);
+ val |= con << shift;
+ }
+ writel(val, reg);
+}
+
+/*
+ * Set the desired filter (digital or analog delay) and enable it to
+ * every pin in the bank. Note the filter selection bitfield is only
+ * found on alive banks. The filter determines to what extent signal
+ * fluctuations received through the pad are considered glitches.
+ */
+static void exynos_eint_set_filter(struct samsung_pin_bank *bank, int filter)
+{
+ unsigned int off = EXYNOS_GPIO_EFLTCON_OFFSET + bank->eint_fltcon_offset;
+ void __iomem *reg = bank->drvdata->virt_base + off;
+ unsigned int con = EXYNOS_FLTCON_EN | filter;
+
+ for (int n = 0; n < bank->nr_pins; n += 4)
+ exynos_eint_update_flt_reg(reg + n,
+ min(bank->nr_pins - n, 4), con);
+}
+
/*
* exynos_eint_gpio_init() - setup handling of external gpio interrupts.
* @d: driver data of samsung pinctrl driver.
@@ -762,153 +793,190 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return 0;
}
-static void exynos_pinctrl_suspend_bank(
- struct samsung_pinctrl_drv_data *drvdata,
- struct samsung_pin_bank *bank)
+static void exynos_set_wakeup(struct samsung_pin_bank *bank)
{
- struct exynos_eint_gpio_save *save = bank->soc_priv;
- const void __iomem *regs = bank->eint_base;
+ struct exynos_irq_chip *irq_chip;
- if (clk_enable(bank->drvdata->pclk)) {
- dev_err(bank->gpio_chip.parent,
- "unable to enable clock for saving state\n");
- return;
+ if (bank->irq_chip) {
+ irq_chip = bank->irq_chip;
+ irq_chip->set_eint_wakeup_mask(bank->drvdata, irq_chip);
}
-
- save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
- + bank->eint_offset);
- save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset);
- save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset + 4);
- save->eint_mask = readl(regs + bank->irq_chip->eint_mask
- + bank->eint_offset);
-
- clk_disable(bank->drvdata->pclk);
-
- pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
- pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
- pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
- pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
}
-static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drvdata,
- struct samsung_pin_bank *bank)
+void exynos_pinctrl_suspend(struct samsung_pin_bank *bank)
{
struct exynos_eint_gpio_save *save = bank->soc_priv;
const void __iomem *regs = bank->eint_base;
- if (clk_enable(bank->drvdata->pclk)) {
- dev_err(bank->gpio_chip.parent,
- "unable to enable clock for saving state\n");
- return;
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset);
+ save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset);
+ save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset + 4);
+ save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
+
+ pr_debug("%s: save con %#010x\n",
+ bank->name, save->eint_con);
+ pr_debug("%s: save fltcon0 %#010x\n",
+ bank->name, save->eint_fltcon0);
+ pr_debug("%s: save fltcon1 %#010x\n",
+ bank->name, save->eint_fltcon1);
+ pr_debug("%s: save mask %#010x\n",
+ bank->name, save->eint_mask);
+ } else if (bank->eint_type == EINT_TYPE_WKUP) {
+ exynos_set_wakeup(bank);
}
-
- save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
- save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
-
- clk_disable(bank->drvdata->pclk);
-
- pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
- pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
}
-void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
+void gs101_pinctrl_suspend(struct samsung_pin_bank *bank)
{
- struct samsung_pin_bank *bank = drvdata->pin_banks;
- struct exynos_irq_chip *irq_chip = NULL;
- int i;
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ const void __iomem *regs = bank->eint_base;
- for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
- if (bank->eint_type == EINT_TYPE_GPIO) {
- if (bank->eint_con_offset)
- exynosauto_pinctrl_suspend_bank(drvdata, bank);
- else
- exynos_pinctrl_suspend_bank(drvdata, bank);
- }
- else if (bank->eint_type == EINT_TYPE_WKUP) {
- if (!irq_chip) {
- irq_chip = bank->irq_chip;
- irq_chip->set_eint_wakeup_mask(drvdata,
- irq_chip);
- }
- }
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset);
+
+ save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + bank->eint_fltcon_offset);
+
+ /* fltcon1 register only exists for pins 4-7 */
+ if (bank->nr_pins > 4)
+ save->eint_fltcon1 = readl(regs +
+ EXYNOS_GPIO_EFLTCON_OFFSET
+ + bank->eint_fltcon_offset + 4);
+
+ save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
+
+ pr_debug("%s: save con %#010x\n",
+ bank->name, save->eint_con);
+ pr_debug("%s: save fltcon0 %#010x\n",
+ bank->name, save->eint_fltcon0);
+ if (bank->nr_pins > 4)
+ pr_debug("%s: save fltcon1 %#010x\n",
+ bank->name, save->eint_fltcon1);
+ pr_debug("%s: save mask %#010x\n",
+ bank->name, save->eint_mask);
+ } else if (bank->eint_type == EINT_TYPE_WKUP) {
+ exynos_set_wakeup(bank);
+ exynos_eint_set_filter(bank, EXYNOS_FLTCON_ANALOG);
}
}
-static void exynos_pinctrl_resume_bank(
- struct samsung_pinctrl_drv_data *drvdata,
- struct samsung_pin_bank *bank)
+void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank)
{
struct exynos_eint_gpio_save *save = bank->soc_priv;
- void __iomem *regs = bank->eint_base;
+ const void __iomem *regs = bank->eint_base;
- if (clk_enable(bank->drvdata->pclk)) {
- dev_err(bank->gpio_chip.parent,
- "unable to enable clock for restoring state\n");
- return;
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ save->eint_con = readl(regs + bank->pctl_offset +
+ bank->eint_con_offset);
+ save->eint_mask = readl(regs + bank->pctl_offset +
+ bank->eint_mask_offset);
+ pr_debug("%s: save con %#010x\n",
+ bank->name, save->eint_con);
+ pr_debug("%s: save mask %#010x\n",
+ bank->name, save->eint_mask);
+ } else if (bank->eint_type == EINT_TYPE_WKUP) {
+ exynos_set_wakeup(bank);
}
+}
- pr_debug("%s: con %#010x => %#010x\n", bank->name,
- readl(regs + EXYNOS_GPIO_ECON_OFFSET
- + bank->eint_offset), save->eint_con);
- pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
- readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset), save->eint_fltcon0);
- pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
- readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset + 4), save->eint_fltcon1);
- pr_debug("%s: mask %#010x => %#010x\n", bank->name,
- readl(regs + bank->irq_chip->eint_mask
- + bank->eint_offset), save->eint_mask);
-
- writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
- + bank->eint_offset);
- writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset);
- writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
- + 2 * bank->eint_offset + 4);
- writel(save->eint_mask, regs + bank->irq_chip->eint_mask
- + bank->eint_offset);
+void gs101_pinctrl_resume(struct samsung_pin_bank *bank)
+{
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
- clk_disable(bank->drvdata->pclk);
+ void __iomem *regs = bank->eint_base;
+ void __iomem *eint_fltcfg0 = regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + bank->eint_fltcon_offset;
+
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ pr_debug("%s: con %#010x => %#010x\n", bank->name,
+ readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset), save->eint_con);
+
+ pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
+ readl(eint_fltcfg0), save->eint_fltcon0);
+
+ /* fltcon1 register only exists for pins 4-7 */
+ if (bank->nr_pins > 4)
+ pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+ readl(eint_fltcfg0 + 4), save->eint_fltcon1);
+
+ pr_debug("%s: mask %#010x => %#010x\n", bank->name,
+ readl(regs + bank->irq_chip->eint_mask
+ + bank->eint_offset), save->eint_mask);
+
+ writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset);
+ writel(save->eint_fltcon0, eint_fltcfg0);
+
+ if (bank->nr_pins > 4)
+ writel(save->eint_fltcon1, eint_fltcfg0 + 4);
+ writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
+ } else if (bank->eint_type == EINT_TYPE_WKUP) {
+ exynos_eint_set_filter(bank, EXYNOS_FLTCON_DIGITAL);
+ }
}
-static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
- struct samsung_pin_bank *bank)
+void exynos_pinctrl_resume(struct samsung_pin_bank *bank)
{
struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = bank->eint_base;
- if (clk_enable(bank->drvdata->pclk)) {
- dev_err(bank->gpio_chip.parent,
- "unable to enable clock for restoring state\n");
- return;
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ pr_debug("%s: con %#010x => %#010x\n", bank->name,
+ readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset), save->eint_con);
+ pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
+ readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset), save->eint_fltcon0);
+ pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+ readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset + 4),
+ save->eint_fltcon1);
+ pr_debug("%s: mask %#010x => %#010x\n", bank->name,
+ readl(regs + bank->irq_chip->eint_mask
+ + bank->eint_offset), save->eint_mask);
+
+ writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset);
+ writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset);
+ writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ + 2 * bank->eint_offset + 4);
+ writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
}
-
- pr_debug("%s: con %#010x => %#010x\n", bank->name,
- readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
- pr_debug("%s: mask %#010x => %#010x\n", bank->name,
- readl(regs + bank->pctl_offset + bank->eint_mask_offset), save->eint_mask);
-
- writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
- writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
-
- clk_disable(bank->drvdata->pclk);
}
-void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
+void exynosautov920_pinctrl_resume(struct samsung_pin_bank *bank)
{
- struct samsung_pin_bank *bank = drvdata->pin_banks;
- int i;
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ void __iomem *regs = bank->eint_base;
- for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
- if (bank->eint_type == EINT_TYPE_GPIO) {
- if (bank->eint_con_offset)
- exynosauto_pinctrl_resume_bank(drvdata, bank);
- else
- exynos_pinctrl_resume_bank(drvdata, bank);
- }
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+ /* exynosautov920 has eint_con_offset for all but one bank */
+ if (!bank->eint_con_offset)
+ exynos_pinctrl_resume(bank);
+
+ pr_debug("%s: con %#010x => %#010x\n", bank->name,
+ readl(regs + bank->pctl_offset + bank->eint_con_offset),
+ save->eint_con);
+ pr_debug("%s: mask %#010x => %#010x\n", bank->name,
+ readl(regs + bank->pctl_offset +
+ bank->eint_mask_offset), save->eint_mask);
+
+ writel(save->eint_con,
+ regs + bank->pctl_offset + bank->eint_con_offset);
+ writel(save->eint_mask,
+ regs + bank->pctl_offset + bank->eint_mask_offset);
+ }
}
static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index b483270ddc53..362dc533186f 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
@@ -52,6 +52,26 @@
#define EXYNOS_EINT_MAX_PER_BANK 8
#define EXYNOS_EINT_NR_WKUP_EINT
+/*
+ * EINT filter configuration register (on alive banks) has
+ * the following layout.
+ *
+ * BitfieldName[PinNum][Bit:Bit]
+ * FLT_EN[3][31] FLT_SEL[3][30] FLT_WIDTH[3][29:24]
+ * FLT_EN[2][23] FLT_SEL[2][22] FLT_WIDTH[2][21:16]
+ * FLT_EN[1][15] FLT_SEL[1][14] FLT_WIDTH[1][13:8]
+ * FLT_EN[0][7] FLT_SEL[0][6] FLT_WIDTH[0][5:0]
+ *
+ * FLT_EN 0x0 = Disable, 0x1=Enable
+ * FLT_SEL 0x0 = Analog delay filter, 0x1 Digital filter (clock count)
+ * FLT_WIDTH Filtering width. Valid when FLT_SEL is 0x1
+ */
+
+#define EXYNOS_FLTCON_EN BIT(7)
+#define EXYNOS_FLTCON_DIGITAL BIT(6)
+#define EXYNOS_FLTCON_ANALOG (0 << 6)
+#define EXYNOS_FLTCON_LEN 8
+
#define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \
{ \
.type = &bank_type_off, \
@@ -240,8 +260,12 @@ struct exynos_muxed_weint_data {
int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d);
int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d);
-void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata);
-void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata);
+void exynosautov920_pinctrl_resume(struct samsung_pin_bank *bank);
+void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank);
+void exynos_pinctrl_suspend(struct samsung_pin_bank *bank);
+void exynos_pinctrl_resume(struct samsung_pin_bank *bank);
+void gs101_pinctrl_suspend(struct samsung_pin_bank *bank);
+void gs101_pinctrl_resume(struct samsung_pin_bank *bank);
struct samsung_retention_ctrl *
exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
const struct samsung_retention_data *data);
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index f5d617e70706..fe1ac82b9d79 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1338,6 +1338,7 @@ err_put_banks:
static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
{
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
+ struct samsung_pin_bank *bank;
int i;
i = clk_enable(drvdata->pclk);
@@ -1348,7 +1349,7 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
}
for (i = 0; i < drvdata->nr_banks; i++) {
- struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
+ bank = &drvdata->pin_banks[i];
const void __iomem *reg = bank->pctl_base + bank->pctl_offset;
const u8 *offs = bank->type->reg_offset;
const u8 *widths = bank->type->fld_width;
@@ -1376,10 +1377,14 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
}
}
+ for (i = 0; i < drvdata->nr_banks; i++) {
+ bank = &drvdata->pin_banks[i];
+ if (drvdata->suspend)
+ drvdata->suspend(bank);
+ }
+
clk_disable(drvdata->pclk);
- if (drvdata->suspend)
- drvdata->suspend(drvdata);
if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable)
drvdata->retention_ctrl->enable(drvdata);
@@ -1397,6 +1402,7 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
{
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
+ struct samsung_pin_bank *bank;
int ret;
int i;
@@ -1411,11 +1417,14 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
return ret;
}
- if (drvdata->resume)
- drvdata->resume(drvdata);
+ for (i = 0; i < drvdata->nr_banks; i++) {
+ bank = &drvdata->pin_banks[i];
+ if (drvdata->resume)
+ drvdata->resume(bank);
+ }
for (i = 0; i < drvdata->nr_banks; i++) {
- struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
+ bank = &drvdata->pin_banks[i];
void __iomem *reg = bank->pctl_base + bank->pctl_offset;
const u8 *offs = bank->type->reg_offset;
const u8 *widths = bank->type->fld_width;
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 3cf758df7d69..fcc57c244d16 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -285,8 +285,8 @@ struct samsung_pin_ctrl {
int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
void (*pud_value_init)(struct samsung_pinctrl_drv_data *drvdata);
- void (*suspend)(struct samsung_pinctrl_drv_data *);
- void (*resume)(struct samsung_pinctrl_drv_data *);
+ void (*suspend)(struct samsung_pin_bank *bank);
+ void (*resume)(struct samsung_pin_bank *bank);
};
/**
@@ -335,8 +335,8 @@ struct samsung_pinctrl_drv_data {
struct samsung_retention_ctrl *retention_ctrl;
- void (*suspend)(struct samsung_pinctrl_drv_data *);
- void (*resume)(struct samsung_pinctrl_drv_data *);
+ void (*suspend)(struct samsung_pin_bank *bank);
+ void (*resume)(struct samsung_pin_bank *bank);
};
/**