pinctrl: samsung: Correct setting of eint wakeup mask on s5pv210
authorJonathan Bakker <xc-racer2@live.ca>
Sat, 4 Apr 2020 17:08:49 +0000 (10:08 -0700)
committerKrzysztof Kozlowski <krzk@kernel.org>
Mon, 13 Apr 2020 10:10:30 +0000 (12:10 +0200)
Commit a8be2af0218c ("pinctrl: samsung: Write external wakeup interrupt
mask") started writing the eint wakeup mask from the pinctrl driver.
Unfortunately, it made the assumption that the private retention data
was always a regmap while in the case of s5pv210 it is a raw pointer
to the clock base (as the eint wakeup mask not in the PMU as with newer
Exynos platforms).

Fixes: a8be2af0218c ("pinctrl: samsung: Write external wakeup interrupt mask")
Cc: <stable@vger.kernel.org>
Signed-off-by: Jonathan Bakker <xc-racer2@live.ca>
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
drivers/pinctrl/samsung/pinctrl-exynos.c

index 0599f51..5126a5a 100644 (file)
@@ -40,6 +40,8 @@ struct exynos_irq_chip {
        u32 eint_pend;
        u32 eint_wake_mask_value;
        u32 eint_wake_mask_reg;
+       void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata,
+                                    struct exynos_irq_chip *irq_chip);
 };
 
 static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
@@ -342,6 +344,47 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
        return 0;
 }
 
+static void
+exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
+                                   struct exynos_irq_chip *irq_chip)
+{
+       struct regmap *pmu_regs;
+
+       if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
+               dev_warn(drvdata->dev,
+                        "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
+               return;
+       }
+
+       pmu_regs = drvdata->retention_ctrl->priv;
+       dev_info(drvdata->dev,
+                "Setting external wakeup interrupt mask: 0x%x\n",
+                irq_chip->eint_wake_mask_value);
+
+       regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
+                    irq_chip->eint_wake_mask_value);
+}
+
+static void
+s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
+                                   struct exynos_irq_chip *irq_chip)
+
+{
+       void __iomem *clk_base;
+
+       if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
+               dev_warn(drvdata->dev,
+                        "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
+               return;
+       }
+
+
+       clk_base = (void __iomem *) drvdata->retention_ctrl->priv;
+
+       __raw_writel(irq_chip->eint_wake_mask_value,
+                    clk_base + irq_chip->eint_wake_mask_reg);
+}
+
 /*
  * irq_chip for wakeup interrupts
  */
@@ -360,8 +403,9 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
        .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
        .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
        .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
-       /* Only difference with exynos4210_wkup_irq_chip: */
+       /* Only differences with exynos4210_wkup_irq_chip: */
        .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK,
+       .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask,
 };
 
 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
@@ -380,6 +424,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
        .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
        .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
        .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
+       .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
 };
 
 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
@@ -398,6 +443,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
        .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
        .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
        .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
+       .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
 };
 
 /* list of external wakeup controllers supported */
@@ -574,27 +620,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
        return 0;
 }
 
-static void
-exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
-                                   struct exynos_irq_chip *irq_chip)
-{
-       struct regmap *pmu_regs;
-
-       if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
-               dev_warn(drvdata->dev,
-                        "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
-               return;
-       }
-
-       pmu_regs = drvdata->retention_ctrl->priv;
-       dev_info(drvdata->dev,
-                "Setting external wakeup interrupt mask: 0x%x\n",
-                irq_chip->eint_wake_mask_value);
-
-       regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
-                    irq_chip->eint_wake_mask_value);
-}
-
 static void exynos_pinctrl_suspend_bank(
                                struct samsung_pinctrl_drv_data *drvdata,
                                struct samsung_pin_bank *bank)
@@ -626,8 +651,8 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
                else if (bank->eint_type == EINT_TYPE_WKUP) {
                        if (!irq_chip) {
                                irq_chip = bank->irq_chip;
-                               exynos_pinctrl_set_eint_wakeup_mask(drvdata,
-                                                                   irq_chip);
+                               irq_chip->set_eint_wakeup_mask(drvdata,
+                                                              irq_chip);
                        } else if (bank->irq_chip != irq_chip) {
                                dev_warn(drvdata->dev,
                                         "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",