pinctrl: samsung: Correct setting of eint wakeup mask on s5pv210
Commita8be2af021
("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:a8be2af021
("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>
This commit is contained in:
parent
8f3d9f3542
commit
b577a27991
|
@ -40,6 +40,8 @@ struct exynos_irq_chip {
|
||||||
u32 eint_pend;
|
u32 eint_pend;
|
||||||
u32 eint_wake_mask_value;
|
u32 eint_wake_mask_value;
|
||||||
u32 eint_wake_mask_reg;
|
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)
|
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;
|
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
|
* 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_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||||
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||||
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
|
.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,
|
.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 = {
|
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_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||||
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
|
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
|
||||||
.eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
|
.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 = {
|
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_pend = EXYNOS7_WKUP_EPEND_OFFSET,
|
||||||
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
|
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
|
||||||
.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
|
.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
|
||||||
|
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* list of external wakeup controllers supported */
|
/* list of external wakeup controllers supported */
|
||||||
|
@ -574,27 +620,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
|
||||||
return 0;
|
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(
|
static void exynos_pinctrl_suspend_bank(
|
||||||
struct samsung_pinctrl_drv_data *drvdata,
|
struct samsung_pinctrl_drv_data *drvdata,
|
||||||
struct samsung_pin_bank *bank)
|
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) {
|
else if (bank->eint_type == EINT_TYPE_WKUP) {
|
||||||
if (!irq_chip) {
|
if (!irq_chip) {
|
||||||
irq_chip = bank->irq_chip;
|
irq_chip = bank->irq_chip;
|
||||||
exynos_pinctrl_set_eint_wakeup_mask(drvdata,
|
irq_chip->set_eint_wakeup_mask(drvdata,
|
||||||
irq_chip);
|
irq_chip);
|
||||||
} else if (bank->irq_chip != irq_chip) {
|
} else if (bank->irq_chip != irq_chip) {
|
||||||
dev_warn(drvdata->dev,
|
dev_warn(drvdata->dev,
|
||||||
"More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",
|
"More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",
|
||||||
|
|
Loading…
Reference in New Issue