0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/device.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/irqdomain.h>
0019 #include <linux/irq.h>
0020 #include <linux/irqchip/chained_irq.h>
0021 #include <linux/of.h>
0022 #include <linux/of_irq.h>
0023 #include <linux/slab.h>
0024 #include <linux/spinlock.h>
0025 #include <linux/regmap.h>
0026 #include <linux/err.h>
0027 #include <linux/soc/samsung/exynos-pmu.h>
0028 #include <linux/soc/samsung/exynos-regs-pmu.h>
0029
0030 #include "pinctrl-samsung.h"
0031 #include "pinctrl-exynos.h"
0032
0033 struct exynos_irq_chip {
0034 struct irq_chip chip;
0035
0036 u32 eint_con;
0037 u32 eint_mask;
0038 u32 eint_pend;
0039 u32 *eint_wake_mask_value;
0040 u32 eint_wake_mask_reg;
0041 void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata,
0042 struct exynos_irq_chip *irq_chip);
0043 };
0044
0045 static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
0046 {
0047 return container_of(chip, struct exynos_irq_chip, chip);
0048 }
0049
0050 static void exynos_irq_mask(struct irq_data *irqd)
0051 {
0052 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
0053 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
0054 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0055 unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
0056 unsigned int mask;
0057 unsigned long flags;
0058
0059 raw_spin_lock_irqsave(&bank->slock, flags);
0060
0061 mask = readl(bank->eint_base + reg_mask);
0062 mask |= 1 << irqd->hwirq;
0063 writel(mask, bank->eint_base + reg_mask);
0064
0065 raw_spin_unlock_irqrestore(&bank->slock, flags);
0066 }
0067
0068 static void exynos_irq_ack(struct irq_data *irqd)
0069 {
0070 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
0071 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
0072 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0073 unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
0074
0075 writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
0076 }
0077
0078 static void exynos_irq_unmask(struct irq_data *irqd)
0079 {
0080 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
0081 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
0082 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0083 unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
0084 unsigned int mask;
0085 unsigned long flags;
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
0096 exynos_irq_ack(irqd);
0097
0098 raw_spin_lock_irqsave(&bank->slock, flags);
0099
0100 mask = readl(bank->eint_base + reg_mask);
0101 mask &= ~(1 << irqd->hwirq);
0102 writel(mask, bank->eint_base + reg_mask);
0103
0104 raw_spin_unlock_irqrestore(&bank->slock, flags);
0105 }
0106
0107 static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
0108 {
0109 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
0110 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
0111 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0112 unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
0113 unsigned int con, trig_type;
0114 unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
0115
0116 switch (type) {
0117 case IRQ_TYPE_EDGE_RISING:
0118 trig_type = EXYNOS_EINT_EDGE_RISING;
0119 break;
0120 case IRQ_TYPE_EDGE_FALLING:
0121 trig_type = EXYNOS_EINT_EDGE_FALLING;
0122 break;
0123 case IRQ_TYPE_EDGE_BOTH:
0124 trig_type = EXYNOS_EINT_EDGE_BOTH;
0125 break;
0126 case IRQ_TYPE_LEVEL_HIGH:
0127 trig_type = EXYNOS_EINT_LEVEL_HIGH;
0128 break;
0129 case IRQ_TYPE_LEVEL_LOW:
0130 trig_type = EXYNOS_EINT_LEVEL_LOW;
0131 break;
0132 default:
0133 pr_err("unsupported external interrupt type\n");
0134 return -EINVAL;
0135 }
0136
0137 if (type & IRQ_TYPE_EDGE_BOTH)
0138 irq_set_handler_locked(irqd, handle_edge_irq);
0139 else
0140 irq_set_handler_locked(irqd, handle_level_irq);
0141
0142 con = readl(bank->eint_base + reg_con);
0143 con &= ~(EXYNOS_EINT_CON_MASK << shift);
0144 con |= trig_type << shift;
0145 writel(con, bank->eint_base + reg_con);
0146
0147 return 0;
0148 }
0149
0150 static int exynos_irq_request_resources(struct irq_data *irqd)
0151 {
0152 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0153 const struct samsung_pin_bank_type *bank_type = bank->type;
0154 unsigned long reg_con, flags;
0155 unsigned int shift, mask, con;
0156 int ret;
0157
0158 ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq);
0159 if (ret) {
0160 dev_err(bank->gpio_chip.parent,
0161 "unable to lock pin %s-%lu IRQ\n",
0162 bank->name, irqd->hwirq);
0163 return ret;
0164 }
0165
0166 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
0167 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
0168 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
0169
0170 raw_spin_lock_irqsave(&bank->slock, flags);
0171
0172 con = readl(bank->pctl_base + reg_con);
0173 con &= ~(mask << shift);
0174 con |= EXYNOS_PIN_CON_FUNC_EINT << shift;
0175 writel(con, bank->pctl_base + reg_con);
0176
0177 raw_spin_unlock_irqrestore(&bank->slock, flags);
0178
0179 return 0;
0180 }
0181
0182 static void exynos_irq_release_resources(struct irq_data *irqd)
0183 {
0184 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0185 const struct samsung_pin_bank_type *bank_type = bank->type;
0186 unsigned long reg_con, flags;
0187 unsigned int shift, mask, con;
0188
0189 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
0190 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
0191 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
0192
0193 raw_spin_lock_irqsave(&bank->slock, flags);
0194
0195 con = readl(bank->pctl_base + reg_con);
0196 con &= ~(mask << shift);
0197 con |= PIN_CON_FUNC_INPUT << shift;
0198 writel(con, bank->pctl_base + reg_con);
0199
0200 raw_spin_unlock_irqrestore(&bank->slock, flags);
0201
0202 gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq);
0203 }
0204
0205
0206
0207
0208 static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = {
0209 .chip = {
0210 .name = "exynos_gpio_irq_chip",
0211 .irq_unmask = exynos_irq_unmask,
0212 .irq_mask = exynos_irq_mask,
0213 .irq_ack = exynos_irq_ack,
0214 .irq_set_type = exynos_irq_set_type,
0215 .irq_request_resources = exynos_irq_request_resources,
0216 .irq_release_resources = exynos_irq_release_resources,
0217 },
0218 .eint_con = EXYNOS_GPIO_ECON_OFFSET,
0219 .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
0220 .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
0221
0222 };
0223
0224 static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq,
0225 irq_hw_number_t hw)
0226 {
0227 struct samsung_pin_bank *b = h->host_data;
0228
0229 irq_set_chip_data(virq, b);
0230 irq_set_chip_and_handler(virq, &b->irq_chip->chip,
0231 handle_level_irq);
0232 return 0;
0233 }
0234
0235
0236
0237
0238 static const struct irq_domain_ops exynos_eint_irqd_ops = {
0239 .map = exynos_eint_irq_map,
0240 .xlate = irq_domain_xlate_twocell,
0241 };
0242
0243 static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
0244 {
0245 struct samsung_pinctrl_drv_data *d = data;
0246 struct samsung_pin_bank *bank = d->pin_banks;
0247 unsigned int svc, group, pin;
0248 int ret;
0249
0250 svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
0251 group = EXYNOS_SVC_GROUP(svc);
0252 pin = svc & EXYNOS_SVC_NUM_MASK;
0253
0254 if (!group)
0255 return IRQ_HANDLED;
0256 bank += (group - 1);
0257
0258 ret = generic_handle_domain_irq(bank->irq_domain, pin);
0259 if (ret)
0260 return IRQ_NONE;
0261
0262 return IRQ_HANDLED;
0263 }
0264
0265 struct exynos_eint_gpio_save {
0266 u32 eint_con;
0267 u32 eint_fltcon0;
0268 u32 eint_fltcon1;
0269 u32 eint_mask;
0270 };
0271
0272
0273
0274
0275
0276 __init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
0277 {
0278 struct samsung_pin_bank *bank;
0279 struct device *dev = d->dev;
0280 int ret;
0281 int i;
0282
0283 if (!d->irq) {
0284 dev_err(dev, "irq number not available\n");
0285 return -EINVAL;
0286 }
0287
0288 ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
0289 0, dev_name(dev), d);
0290 if (ret) {
0291 dev_err(dev, "irq request failed\n");
0292 return -ENXIO;
0293 }
0294
0295 bank = d->pin_banks;
0296 for (i = 0; i < d->nr_banks; ++i, ++bank) {
0297 if (bank->eint_type != EINT_TYPE_GPIO)
0298 continue;
0299
0300 bank->irq_chip = devm_kmemdup(dev, &exynos_gpio_irq_chip,
0301 sizeof(*bank->irq_chip), GFP_KERNEL);
0302 if (!bank->irq_chip) {
0303 ret = -ENOMEM;
0304 goto err_domains;
0305 }
0306 bank->irq_chip->chip.name = bank->name;
0307
0308 bank->irq_domain = irq_domain_create_linear(bank->fwnode,
0309 bank->nr_pins, &exynos_eint_irqd_ops, bank);
0310 if (!bank->irq_domain) {
0311 dev_err(dev, "gpio irq domain add failed\n");
0312 ret = -ENXIO;
0313 goto err_domains;
0314 }
0315
0316 bank->soc_priv = devm_kzalloc(d->dev,
0317 sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
0318 if (!bank->soc_priv) {
0319 irq_domain_remove(bank->irq_domain);
0320 ret = -ENOMEM;
0321 goto err_domains;
0322 }
0323
0324 }
0325
0326 return 0;
0327
0328 err_domains:
0329 for (--i, --bank; i >= 0; --i, --bank) {
0330 if (bank->eint_type != EINT_TYPE_GPIO)
0331 continue;
0332 irq_domain_remove(bank->irq_domain);
0333 }
0334
0335 return ret;
0336 }
0337
0338 static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
0339 {
0340 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
0341 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
0342 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
0343 unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
0344
0345 pr_info("wake %s for irq %u (%s-%lu)\n", on ? "enabled" : "disabled",
0346 irqd->irq, bank->name, irqd->hwirq);
0347
0348 if (!on)
0349 *our_chip->eint_wake_mask_value |= bit;
0350 else
0351 *our_chip->eint_wake_mask_value &= ~bit;
0352
0353 return 0;
0354 }
0355
0356 static void
0357 exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
0358 struct exynos_irq_chip *irq_chip)
0359 {
0360 struct regmap *pmu_regs;
0361
0362 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
0363 dev_warn(drvdata->dev,
0364 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
0365 return;
0366 }
0367
0368 pmu_regs = drvdata->retention_ctrl->priv;
0369 dev_info(drvdata->dev,
0370 "Setting external wakeup interrupt mask: 0x%x\n",
0371 *irq_chip->eint_wake_mask_value);
0372
0373 regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
0374 *irq_chip->eint_wake_mask_value);
0375 }
0376
0377 static void
0378 s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
0379 struct exynos_irq_chip *irq_chip)
0380
0381 {
0382 void __iomem *clk_base;
0383
0384 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
0385 dev_warn(drvdata->dev,
0386 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
0387 return;
0388 }
0389
0390
0391 clk_base = (void __iomem *) drvdata->retention_ctrl->priv;
0392
0393 __raw_writel(*irq_chip->eint_wake_mask_value,
0394 clk_base + irq_chip->eint_wake_mask_reg);
0395 }
0396
0397 static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED;
0398
0399
0400
0401 static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
0402 .chip = {
0403 .name = "s5pv210_wkup_irq_chip",
0404 .irq_unmask = exynos_irq_unmask,
0405 .irq_mask = exynos_irq_mask,
0406 .irq_ack = exynos_irq_ack,
0407 .irq_set_type = exynos_irq_set_type,
0408 .irq_set_wake = exynos_wkup_irq_set_wake,
0409 .irq_request_resources = exynos_irq_request_resources,
0410 .irq_release_resources = exynos_irq_release_resources,
0411 },
0412 .eint_con = EXYNOS_WKUP_ECON_OFFSET,
0413 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
0414 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
0415 .eint_wake_mask_value = &eint_wake_mask_value,
0416
0417 .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK,
0418 .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask,
0419 };
0420
0421 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
0422 .chip = {
0423 .name = "exynos4210_wkup_irq_chip",
0424 .irq_unmask = exynos_irq_unmask,
0425 .irq_mask = exynos_irq_mask,
0426 .irq_ack = exynos_irq_ack,
0427 .irq_set_type = exynos_irq_set_type,
0428 .irq_set_wake = exynos_wkup_irq_set_wake,
0429 .irq_request_resources = exynos_irq_request_resources,
0430 .irq_release_resources = exynos_irq_release_resources,
0431 },
0432 .eint_con = EXYNOS_WKUP_ECON_OFFSET,
0433 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
0434 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
0435 .eint_wake_mask_value = &eint_wake_mask_value,
0436 .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
0437 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
0438 };
0439
0440 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
0441 .chip = {
0442 .name = "exynos7_wkup_irq_chip",
0443 .irq_unmask = exynos_irq_unmask,
0444 .irq_mask = exynos_irq_mask,
0445 .irq_ack = exynos_irq_ack,
0446 .irq_set_type = exynos_irq_set_type,
0447 .irq_set_wake = exynos_wkup_irq_set_wake,
0448 .irq_request_resources = exynos_irq_request_resources,
0449 .irq_release_resources = exynos_irq_release_resources,
0450 },
0451 .eint_con = EXYNOS7_WKUP_ECON_OFFSET,
0452 .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET,
0453 .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
0454 .eint_wake_mask_value = &eint_wake_mask_value,
0455 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
0456 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
0457 };
0458
0459
0460 static const struct of_device_id exynos_wkup_irq_ids[] = {
0461 { .compatible = "samsung,s5pv210-wakeup-eint",
0462 .data = &s5pv210_wkup_irq_chip },
0463 { .compatible = "samsung,exynos4210-wakeup-eint",
0464 .data = &exynos4210_wkup_irq_chip },
0465 { .compatible = "samsung,exynos7-wakeup-eint",
0466 .data = &exynos7_wkup_irq_chip },
0467 { .compatible = "samsung,exynos850-wakeup-eint",
0468 .data = &exynos7_wkup_irq_chip },
0469 { .compatible = "samsung,exynosautov9-wakeup-eint",
0470 .data = &exynos7_wkup_irq_chip },
0471 { }
0472 };
0473
0474
0475 static void exynos_irq_eint0_15(struct irq_desc *desc)
0476 {
0477 struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc);
0478 struct samsung_pin_bank *bank = eintd->bank;
0479 struct irq_chip *chip = irq_desc_get_chip(desc);
0480
0481 chained_irq_enter(chip, desc);
0482
0483 generic_handle_domain_irq(bank->irq_domain, eintd->irq);
0484
0485 chained_irq_exit(chip, desc);
0486 }
0487
0488 static inline void exynos_irq_demux_eint(unsigned int pend,
0489 struct irq_domain *domain)
0490 {
0491 unsigned int irq;
0492
0493 while (pend) {
0494 irq = fls(pend) - 1;
0495 generic_handle_domain_irq(domain, irq);
0496 pend &= ~(1 << irq);
0497 }
0498 }
0499
0500
0501 static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
0502 {
0503 struct irq_chip *chip = irq_desc_get_chip(desc);
0504 struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
0505 unsigned int pend;
0506 unsigned int mask;
0507 int i;
0508
0509 chained_irq_enter(chip, desc);
0510
0511 for (i = 0; i < eintd->nr_banks; ++i) {
0512 struct samsung_pin_bank *b = eintd->banks[i];
0513 pend = readl(b->eint_base + b->irq_chip->eint_pend
0514 + b->eint_offset);
0515 mask = readl(b->eint_base + b->irq_chip->eint_mask
0516 + b->eint_offset);
0517 exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
0518 }
0519
0520 chained_irq_exit(chip, desc);
0521 }
0522
0523
0524
0525
0526
0527 __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
0528 {
0529 struct device *dev = d->dev;
0530 struct device_node *wkup_np = NULL;
0531 struct device_node *np;
0532 struct samsung_pin_bank *bank;
0533 struct exynos_weint_data *weint_data;
0534 struct exynos_muxed_weint_data *muxed_data;
0535 const struct exynos_irq_chip *irq_chip;
0536 unsigned int muxed_banks = 0;
0537 unsigned int i;
0538 int idx, irq;
0539
0540 for_each_child_of_node(dev->of_node, np) {
0541 const struct of_device_id *match;
0542
0543 match = of_match_node(exynos_wkup_irq_ids, np);
0544 if (match) {
0545 irq_chip = match->data;
0546 wkup_np = np;
0547 break;
0548 }
0549 }
0550 if (!wkup_np)
0551 return -ENODEV;
0552
0553 bank = d->pin_banks;
0554 for (i = 0; i < d->nr_banks; ++i, ++bank) {
0555 if (bank->eint_type != EINT_TYPE_WKUP)
0556 continue;
0557
0558 bank->irq_chip = devm_kmemdup(dev, irq_chip, sizeof(*irq_chip),
0559 GFP_KERNEL);
0560 if (!bank->irq_chip) {
0561 of_node_put(wkup_np);
0562 return -ENOMEM;
0563 }
0564 bank->irq_chip->chip.name = bank->name;
0565
0566 bank->irq_domain = irq_domain_create_linear(bank->fwnode,
0567 bank->nr_pins, &exynos_eint_irqd_ops, bank);
0568 if (!bank->irq_domain) {
0569 dev_err(dev, "wkup irq domain add failed\n");
0570 of_node_put(wkup_np);
0571 return -ENXIO;
0572 }
0573
0574 if (!fwnode_property_present(bank->fwnode, "interrupts")) {
0575 bank->eint_type = EINT_TYPE_WKUP_MUX;
0576 ++muxed_banks;
0577 continue;
0578 }
0579
0580 weint_data = devm_kcalloc(dev,
0581 bank->nr_pins, sizeof(*weint_data),
0582 GFP_KERNEL);
0583 if (!weint_data) {
0584 of_node_put(wkup_np);
0585 return -ENOMEM;
0586 }
0587
0588 for (idx = 0; idx < bank->nr_pins; ++idx) {
0589 irq = irq_of_parse_and_map(to_of_node(bank->fwnode), idx);
0590 if (!irq) {
0591 dev_err(dev, "irq number for eint-%s-%d not found\n",
0592 bank->name, idx);
0593 continue;
0594 }
0595 weint_data[idx].irq = idx;
0596 weint_data[idx].bank = bank;
0597 irq_set_chained_handler_and_data(irq,
0598 exynos_irq_eint0_15,
0599 &weint_data[idx]);
0600 }
0601 }
0602
0603 if (!muxed_banks) {
0604 of_node_put(wkup_np);
0605 return 0;
0606 }
0607
0608 irq = irq_of_parse_and_map(wkup_np, 0);
0609 of_node_put(wkup_np);
0610 if (!irq) {
0611 dev_err(dev, "irq number for muxed EINTs not found\n");
0612 return 0;
0613 }
0614
0615 muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
0616 + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
0617 if (!muxed_data)
0618 return -ENOMEM;
0619
0620 irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
0621 muxed_data);
0622
0623 bank = d->pin_banks;
0624 idx = 0;
0625 for (i = 0; i < d->nr_banks; ++i, ++bank) {
0626 if (bank->eint_type != EINT_TYPE_WKUP_MUX)
0627 continue;
0628
0629 muxed_data->banks[idx++] = bank;
0630 }
0631 muxed_data->nr_banks = muxed_banks;
0632
0633 return 0;
0634 }
0635
0636 static void exynos_pinctrl_suspend_bank(
0637 struct samsung_pinctrl_drv_data *drvdata,
0638 struct samsung_pin_bank *bank)
0639 {
0640 struct exynos_eint_gpio_save *save = bank->soc_priv;
0641 void __iomem *regs = bank->eint_base;
0642
0643 save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
0644 + bank->eint_offset);
0645 save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
0646 + 2 * bank->eint_offset);
0647 save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
0648 + 2 * bank->eint_offset + 4);
0649 save->eint_mask = readl(regs + bank->irq_chip->eint_mask
0650 + bank->eint_offset);
0651
0652 pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
0653 pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
0654 pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
0655 pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
0656 }
0657
0658 void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
0659 {
0660 struct samsung_pin_bank *bank = drvdata->pin_banks;
0661 struct exynos_irq_chip *irq_chip = NULL;
0662 int i;
0663
0664 for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
0665 if (bank->eint_type == EINT_TYPE_GPIO)
0666 exynos_pinctrl_suspend_bank(drvdata, bank);
0667 else if (bank->eint_type == EINT_TYPE_WKUP) {
0668 if (!irq_chip) {
0669 irq_chip = bank->irq_chip;
0670 irq_chip->set_eint_wakeup_mask(drvdata,
0671 irq_chip);
0672 }
0673 }
0674 }
0675 }
0676
0677 static void exynos_pinctrl_resume_bank(
0678 struct samsung_pinctrl_drv_data *drvdata,
0679 struct samsung_pin_bank *bank)
0680 {
0681 struct exynos_eint_gpio_save *save = bank->soc_priv;
0682 void __iomem *regs = bank->eint_base;
0683
0684 pr_debug("%s: con %#010x => %#010x\n", bank->name,
0685 readl(regs + EXYNOS_GPIO_ECON_OFFSET
0686 + bank->eint_offset), save->eint_con);
0687 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
0688 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
0689 + 2 * bank->eint_offset), save->eint_fltcon0);
0690 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
0691 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
0692 + 2 * bank->eint_offset + 4), save->eint_fltcon1);
0693 pr_debug("%s: mask %#010x => %#010x\n", bank->name,
0694 readl(regs + bank->irq_chip->eint_mask
0695 + bank->eint_offset), save->eint_mask);
0696
0697 writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
0698 + bank->eint_offset);
0699 writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
0700 + 2 * bank->eint_offset);
0701 writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
0702 + 2 * bank->eint_offset + 4);
0703 writel(save->eint_mask, regs + bank->irq_chip->eint_mask
0704 + bank->eint_offset);
0705 }
0706
0707 void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
0708 {
0709 struct samsung_pin_bank *bank = drvdata->pin_banks;
0710 int i;
0711
0712 for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
0713 if (bank->eint_type == EINT_TYPE_GPIO)
0714 exynos_pinctrl_resume_bank(drvdata, bank);
0715 }
0716
0717 static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
0718 {
0719 if (drvdata->retention_ctrl->refcnt)
0720 atomic_inc(drvdata->retention_ctrl->refcnt);
0721 }
0722
0723 static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
0724 {
0725 struct samsung_retention_ctrl *ctrl = drvdata->retention_ctrl;
0726 struct regmap *pmu_regs = ctrl->priv;
0727 int i;
0728
0729 if (ctrl->refcnt && !atomic_dec_and_test(ctrl->refcnt))
0730 return;
0731
0732 for (i = 0; i < ctrl->nr_regs; i++)
0733 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
0734 }
0735
0736 struct samsung_retention_ctrl *
0737 exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
0738 const struct samsung_retention_data *data)
0739 {
0740 struct samsung_retention_ctrl *ctrl;
0741 struct regmap *pmu_regs;
0742 int i;
0743
0744 ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
0745 if (!ctrl)
0746 return ERR_PTR(-ENOMEM);
0747
0748 pmu_regs = exynos_get_pmu_regmap();
0749 if (IS_ERR(pmu_regs))
0750 return ERR_CAST(pmu_regs);
0751
0752 ctrl->priv = pmu_regs;
0753 ctrl->regs = data->regs;
0754 ctrl->nr_regs = data->nr_regs;
0755 ctrl->value = data->value;
0756 ctrl->refcnt = data->refcnt;
0757 ctrl->enable = exynos_retention_enable;
0758 ctrl->disable = exynos_retention_disable;
0759
0760
0761 for (i = 0; i < ctrl->nr_regs; i++)
0762 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
0763
0764 return ctrl;
0765 }