Samsung pinctrl drivers changes for v5.8
Two fixes for S5Pv210 pinctrl driver: setting proper external interrupt wakeup mask and restoring external interrupt mask value after system suspend. -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEE3dJiKD0RGyM7briowTdm5oaLg9cFAl7Dg/EQHGtyemtAa2Vy bmVsLm9yZwAKCRDBN2bmhouD101uEACEj2B5TwtGvcgc0Q4X1TlqyIrqwvgJwZnM J9Z97xAqIxlYT3Z8vyiN5zwRuAbKZSOkaxFh6qJGSQ2Zuxena7t6v0Hkh4CnzHxC 6awhyyovnw6tw1CzFRxjPWc+snXmZ4ika2a1wifiU+KdLpKkjW58bW3uu5QZ/6Vh KdSM7nAQIFdakovfc8QFE17vE7ujnU8g+Zp9I0Mi3eGd+9pPtXO9xKiYCptp+P8A qyHZU/F3CN4V6m0ZTX4CiUdgwTdE4fVcevAWvisQRYaVIQaQ2pgP1MIFfT/fNLvx eooDYKuXO/fwJ71R+PJFrIrt7+VJffTkeZTREMMC4rEbkZFsZLmCWrkrNRuK/Abz VDQR0sc6rmUB0EGIdkf0nsRgvqqol8vYWqIjaYBq0cUi9DBHYmqXq2Z6MBcQyzdK FVs/yPVQ6yMnbuKF7IQninm+WwVaDG43u9vFdEVeKiFJ84KagFsjMzSAcDIN7PNR ezi6lTrWNsKhkdm49IRP4Xsw0+XEopOj/DNxMy/B6ppEBAVXgsS4dUG4W/LZ2sjG E5rWySKoLd/IPbO41y5APMpKgppXDHf24hq8tdL24wN3+u2gUJ5WQdGTqLs0j4Vo zh2cxAIHvP4PUrMlNwcc7/2Ph8Dro39N3i5w31KjN7H41/6m6Y467krVW7OYhlnq h9fbPYBQhA== =9T4z -----END PGP SIGNATURE----- Merge tag 'samsung-pinctrl-5.8' of https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung into devel Samsung pinctrl drivers changes for v5.8 Two fixes for S5Pv210 pinctrl driver: setting proper external interrupt wakeup mask and restoring external interrupt mask value after system suspend.
This commit is contained in:
commit
d04996eac5
|
@ -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)
|
||||
|
@ -265,6 +267,7 @@ struct exynos_eint_gpio_save {
|
|||
u32 eint_con;
|
||||
u32 eint_fltcon0;
|
||||
u32 eint_fltcon1;
|
||||
u32 eint_mask;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -342,6 +345,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 +404,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 +425,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 +444,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 +621,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)
|
||||
|
@ -608,10 +634,13 @@ static void exynos_pinctrl_suspend_bank(
|
|||
+ 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);
|
||||
}
|
||||
|
||||
void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
|
||||
|
@ -626,8 +655,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",
|
||||
|
@ -653,6 +682,9 @@ static void exynos_pinctrl_resume_bank(
|
|||
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);
|
||||
|
@ -660,6 +692,8 @@ static void exynos_pinctrl_resume_bank(
|
|||
+ 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 exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
|
||||
|
|
Loading…
Reference in a new issue