Lines Matching +full:ctrl +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2003-2005 Nokia Corporation
9 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
27 #include <linux/platform_data/gpio-omap.h>
36 u32 ctrl; member
84 #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
112 bank->context.oe = omap_gpio_rmw(bank->base + bank->regs->direction, in omap_set_gpio_direction()
121 void __iomem *reg = bank->base; in omap_set_gpio_dataout_reg()
125 reg += bank->regs->set_dataout; in omap_set_gpio_dataout_reg()
126 bank->context.dataout |= l; in omap_set_gpio_dataout_reg()
128 reg += bank->regs->clr_dataout; in omap_set_gpio_dataout_reg()
129 bank->context.dataout &= ~l; in omap_set_gpio_dataout_reg()
139 bank->context.dataout = omap_gpio_rmw(bank->base + bank->regs->dataout, in omap_set_gpio_dataout_mask()
145 if (bank->dbck_enable_mask && !bank->dbck_enabled) { in omap_gpio_dbck_enable()
146 clk_enable(bank->dbck); in omap_gpio_dbck_enable()
147 bank->dbck_enabled = true; in omap_gpio_dbck_enable()
149 writel_relaxed(bank->dbck_enable_mask, in omap_gpio_dbck_enable()
150 bank->base + bank->regs->debounce_en); in omap_gpio_dbck_enable()
156 if (bank->dbck_enable_mask && bank->dbck_enabled) { in omap_gpio_dbck_disable()
162 writel_relaxed(0, bank->base + bank->regs->debounce_en); in omap_gpio_dbck_disable()
164 clk_disable(bank->dbck); in omap_gpio_dbck_disable()
165 bank->dbck_enabled = false; in omap_gpio_dbck_disable()
170 * omap2_set_gpio_debounce - low level gpio debounce time
188 if (!bank->dbck_flag) in omap2_set_gpio_debounce()
189 return -ENOTSUPP; in omap2_set_gpio_debounce()
192 debounce = DIV_ROUND_UP(debounce, 31) - 1; in omap2_set_gpio_debounce()
194 return -EINVAL; in omap2_set_gpio_debounce()
199 clk_enable(bank->dbck); in omap2_set_gpio_debounce()
200 writel_relaxed(debounce, bank->base + bank->regs->debounce); in omap2_set_gpio_debounce()
202 val = omap_gpio_rmw(bank->base + bank->regs->debounce_en, l, enable); in omap2_set_gpio_debounce()
203 bank->dbck_enable_mask = val; in omap2_set_gpio_debounce()
205 clk_disable(bank->dbck); in omap2_set_gpio_debounce()
215 if (bank->dbck_enable_mask) { in omap2_set_gpio_debounce()
216 bank->context.debounce = debounce; in omap2_set_gpio_debounce()
217 bank->context.debounce_en = val; in omap2_set_gpio_debounce()
224 * omap_clear_gpio_debounce - clear debounce settings for a gpio
237 if (!bank->dbck_flag) in omap_clear_gpio_debounce()
240 if (!(bank->dbck_enable_mask & gpio_bit)) in omap_clear_gpio_debounce()
243 bank->dbck_enable_mask &= ~gpio_bit; in omap_clear_gpio_debounce()
244 bank->context.debounce_en &= ~gpio_bit; in omap_clear_gpio_debounce()
245 writel_relaxed(bank->context.debounce_en, in omap_clear_gpio_debounce()
246 bank->base + bank->regs->debounce_en); in omap_clear_gpio_debounce()
248 if (!bank->dbck_enable_mask) { in omap_clear_gpio_debounce()
249 bank->context.debounce = 0; in omap_clear_gpio_debounce()
250 writel_relaxed(bank->context.debounce, bank->base + in omap_clear_gpio_debounce()
251 bank->regs->debounce); in omap_clear_gpio_debounce()
252 clk_disable(bank->dbck); in omap_clear_gpio_debounce()
253 bank->dbck_enabled = false; in omap_clear_gpio_debounce()
258 * Off mode wake-up capable GPIOs in bank(s) that are in the wakeup domain.
259 * See TRM section for GPIO for "Wake-Up Generation" for the list of GPIOs
260 * in wakeup domain. If bank->non_wakeup_gpios is not configured, assume none
265 u32 no_wake = bank->non_wakeup_gpios; in omap_gpio_is_off_wakeup_capable()
276 void __iomem *base = bank->base; in omap_set_gpio_trigger()
279 omap_gpio_rmw(base + bank->regs->leveldetect0, gpio_bit, in omap_set_gpio_trigger()
281 omap_gpio_rmw(base + bank->regs->leveldetect1, gpio_bit, in omap_set_gpio_trigger()
289 omap_gpio_rmw(base + bank->regs->risingdetect, gpio_bit, in omap_set_gpio_trigger()
291 omap_gpio_rmw(base + bank->regs->fallingdetect, gpio_bit, in omap_set_gpio_trigger()
294 bank->context.leveldetect0 = in omap_set_gpio_trigger()
295 readl_relaxed(bank->base + bank->regs->leveldetect0); in omap_set_gpio_trigger()
296 bank->context.leveldetect1 = in omap_set_gpio_trigger()
297 readl_relaxed(bank->base + bank->regs->leveldetect1); in omap_set_gpio_trigger()
298 bank->context.risingdetect = in omap_set_gpio_trigger()
299 readl_relaxed(bank->base + bank->regs->risingdetect); in omap_set_gpio_trigger()
300 bank->context.fallingdetect = in omap_set_gpio_trigger()
301 readl_relaxed(bank->base + bank->regs->fallingdetect); in omap_set_gpio_trigger()
303 bank->level_mask = bank->context.leveldetect0 | in omap_set_gpio_trigger()
304 bank->context.leveldetect1; in omap_set_gpio_trigger()
307 if (!bank->regs->irqctrl && !omap_gpio_is_off_wakeup_capable(bank, gpio)) { in omap_set_gpio_trigger()
312 * Applies for omap2 non-wakeup gpio and all omap3 gpios in omap_set_gpio_trigger()
315 bank->enabled_non_wakeup_gpios |= gpio_bit; in omap_set_gpio_trigger()
317 bank->enabled_non_wakeup_gpios &= ~gpio_bit; in omap_set_gpio_trigger()
327 if (IS_ENABLED(CONFIG_ARCH_OMAP1) && bank->regs->irqctrl) { in omap_toggle_gpio_edge_triggering()
328 void __iomem *reg = bank->base + bank->regs->irqctrl; in omap_toggle_gpio_edge_triggering()
337 void __iomem *reg = bank->base; in omap_set_gpio_triggering()
340 if (bank->regs->leveldetect0 && bank->regs->wkup_en) { in omap_set_gpio_triggering()
342 } else if (bank->regs->irqctrl) { in omap_set_gpio_triggering()
343 reg += bank->regs->irqctrl; in omap_set_gpio_triggering()
347 bank->toggle_mask |= BIT(gpio); in omap_set_gpio_triggering()
353 return -EINVAL; in omap_set_gpio_triggering()
356 } else if (bank->regs->edgectrl1) { in omap_set_gpio_triggering()
358 reg += bank->regs->edgectrl2; in omap_set_gpio_triggering()
360 reg += bank->regs->edgectrl1; in omap_set_gpio_triggering()
376 if (bank->regs->pinctrl) { in omap_enable_gpio_module()
377 void __iomem *reg = bank->base + bank->regs->pinctrl; in omap_enable_gpio_module()
383 if (bank->regs->ctrl && !BANK_USED(bank)) { in omap_enable_gpio_module()
384 void __iomem *reg = bank->base + bank->regs->ctrl; in omap_enable_gpio_module()
385 u32 ctrl; in omap_enable_gpio_module() local
387 ctrl = readl_relaxed(reg); in omap_enable_gpio_module()
389 ctrl &= ~GPIO_MOD_CTRL_BIT; in omap_enable_gpio_module()
390 writel_relaxed(ctrl, reg); in omap_enable_gpio_module()
391 bank->context.ctrl = ctrl; in omap_enable_gpio_module()
397 if (bank->regs->ctrl && !BANK_USED(bank)) { in omap_disable_gpio_module()
398 void __iomem *reg = bank->base + bank->regs->ctrl; in omap_disable_gpio_module()
399 u32 ctrl; in omap_disable_gpio_module() local
401 ctrl = readl_relaxed(reg); in omap_disable_gpio_module()
403 ctrl |= GPIO_MOD_CTRL_BIT; in omap_disable_gpio_module()
404 writel_relaxed(ctrl, reg); in omap_disable_gpio_module()
405 bank->context.ctrl = ctrl; in omap_disable_gpio_module()
411 void __iomem *reg = bank->base + bank->regs->direction; in omap_gpio_is_input()
418 if (!LINE_USED(bank->mod_usage, offset)) { in omap_gpio_init_irq()
422 bank->irq_usage |= BIT(offset); in omap_gpio_init_irq()
430 unsigned offset = d->hwirq; in omap_gpio_irq_type()
433 return -EINVAL; in omap_gpio_irq_type()
435 if (!bank->regs->leveldetect0 && in omap_gpio_irq_type()
437 return -EINVAL; in omap_gpio_irq_type()
439 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_type()
442 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
447 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
448 retval = -EINVAL; in omap_gpio_irq_type()
451 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
472 void __iomem *reg = bank->base; in omap_clear_gpio_irqbank()
474 reg += bank->regs->irqstatus; in omap_clear_gpio_irqbank()
478 if (bank->regs->irqstatus2) { in omap_clear_gpio_irqbank()
479 reg = bank->base + bank->regs->irqstatus2; in omap_clear_gpio_irqbank()
495 void __iomem *reg = bank->base; in omap_get_gpio_irqbank_mask()
497 u32 mask = (BIT(bank->width)) - 1; in omap_get_gpio_irqbank_mask()
499 reg += bank->regs->irqenable; in omap_get_gpio_irqbank_mask()
501 if (bank->regs->irqenable_inv) in omap_get_gpio_irqbank_mask()
510 void __iomem *reg = bank->base; in omap_set_gpio_irqenable()
513 if (bank->regs->set_irqenable && bank->regs->clr_irqenable) { in omap_set_gpio_irqenable()
515 reg += bank->regs->set_irqenable; in omap_set_gpio_irqenable()
516 bank->context.irqenable1 |= gpio_mask; in omap_set_gpio_irqenable()
518 reg += bank->regs->clr_irqenable; in omap_set_gpio_irqenable()
519 bank->context.irqenable1 &= ~gpio_mask; in omap_set_gpio_irqenable()
523 bank->context.irqenable1 = in omap_set_gpio_irqenable()
524 omap_gpio_rmw(reg + bank->regs->irqenable, gpio_mask, in omap_set_gpio_irqenable()
525 enable ^ bank->regs->irqenable_inv); in omap_set_gpio_irqenable()
532 * enabled for the GPIOs which support this feature. in omap_set_gpio_irqenable()
534 if (bank->regs->wkup_en && in omap_set_gpio_irqenable()
535 (bank->regs->edgectrl1 || !(bank->non_wakeup_gpios & gpio_mask))) { in omap_set_gpio_irqenable()
536 bank->context.wake_en = in omap_set_gpio_irqenable()
537 omap_gpio_rmw(bank->base + bank->regs->wkup_en, in omap_set_gpio_irqenable()
547 return irq_set_irq_wake(bank->irq, enable); in omap_gpio_wake_enable()
553 * Then we need to mask-read-clear-unmask the triggered GPIO lines
568 isr_reg = bank->base + bank->regs->irqstatus; in omap_gpio_irq_handler()
572 if (WARN_ONCE(!pm_runtime_active(bank->chip.parent), in omap_gpio_irq_handler()
577 raw_spin_lock_irqsave(&bank->lock, lock_flags); in omap_gpio_irq_handler()
587 edge = isr & ~bank->level_mask; in omap_gpio_irq_handler()
591 raw_spin_unlock_irqrestore(&bank->lock, lock_flags); in omap_gpio_irq_handler()
600 raw_spin_lock_irqsave(&bank->lock, lock_flags); in omap_gpio_irq_handler()
608 if (bank->toggle_mask & (BIT(bit))) in omap_gpio_irq_handler()
611 raw_spin_unlock_irqrestore(&bank->lock, lock_flags); in omap_gpio_irq_handler()
613 raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); in omap_gpio_irq_handler()
615 generic_handle_domain_irq(bank->chip.irq.domain, bit); in omap_gpio_irq_handler()
617 raw_spin_unlock_irqrestore(&bank->wa_lock, in omap_gpio_irq_handler()
629 unsigned offset = d->hwirq; in omap_gpio_irq_startup()
631 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_startup()
633 if (!LINE_USED(bank->mod_usage, offset)) in omap_gpio_irq_startup()
636 bank->irq_usage |= BIT(offset); in omap_gpio_irq_startup()
638 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_startup()
648 unsigned offset = d->hwirq; in omap_gpio_irq_shutdown()
650 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_shutdown()
651 bank->irq_usage &= ~(BIT(offset)); in omap_gpio_irq_shutdown()
655 if (!LINE_USED(bank->mod_usage, offset)) in omap_gpio_irq_shutdown()
658 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_shutdown()
665 pm_runtime_get_sync(bank->chip.parent); in omap_gpio_irq_bus_lock()
672 pm_runtime_put(bank->chip.parent); in gpio_irq_bus_sync_unlock()
678 unsigned offset = d->hwirq; in omap_gpio_mask_irq()
681 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_mask_irq()
684 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_mask_irq()
685 gpiochip_disable_irq(&bank->chip, offset); in omap_gpio_mask_irq()
691 unsigned offset = d->hwirq; in omap_gpio_unmask_irq()
695 gpiochip_enable_irq(&bank->chip, offset); in omap_gpio_unmask_irq()
696 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_unmask_irq()
700 * For level-triggered GPIOs, clearing must be done after the source in omap_gpio_unmask_irq()
704 if (bank->regs->leveldetect0 && bank->regs->wkup_en && in omap_gpio_unmask_irq()
711 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_unmask_irq()
718 seq_printf(p, dev_name(bank->dev)); in omap_gpio_irq_print_chip()
748 /*---------------------------------------------------------------------*/
753 void __iomem *mask_reg = bank->base + in omap_mpuio_suspend_noirq()
754 OMAP_MPUIO_GPIO_MASKIT / bank->stride; in omap_mpuio_suspend_noirq()
757 raw_spin_lock_irqsave(&bank->lock, flags); in omap_mpuio_suspend_noirq()
758 writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg); in omap_mpuio_suspend_noirq()
759 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_mpuio_suspend_noirq()
767 void __iomem *mask_reg = bank->base + in omap_mpuio_resume_noirq()
768 OMAP_MPUIO_GPIO_MASKIT / bank->stride; in omap_mpuio_resume_noirq()
771 raw_spin_lock_irqsave(&bank->lock, flags); in omap_mpuio_resume_noirq()
772 writel_relaxed(bank->context.wake_en, mask_reg); in omap_mpuio_resume_noirq()
773 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_mpuio_resume_noirq()
793 .id = -1,
808 /*---------------------------------------------------------------------*/
815 pm_runtime_get_sync(chip->parent); in omap_gpio_request()
817 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_request()
819 bank->mod_usage |= BIT(offset); in omap_gpio_request()
820 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_request()
830 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_free()
831 bank->mod_usage &= ~(BIT(offset)); in omap_gpio_free()
832 if (!LINE_USED(bank->irq_usage, offset)) { in omap_gpio_free()
837 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_free()
839 pm_runtime_put(chip->parent); in omap_gpio_free()
846 if (readl_relaxed(bank->base + bank->regs->direction) & BIT(offset)) in omap_gpio_get_direction()
858 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_input()
860 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_input()
870 reg = bank->base + bank->regs->datain; in omap_gpio_get()
872 reg = bank->base + bank->regs->dataout; in omap_gpio_get()
883 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_output()
884 bank->set_dataout(bank, offset, value); in omap_gpio_output()
886 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_output()
894 void __iomem *base = bank->base; in omap_gpio_get_multiple()
897 direction = readl_relaxed(base + bank->regs->direction); in omap_gpio_get_multiple()
901 val |= readl_relaxed(base + bank->regs->datain) & m; in omap_gpio_get_multiple()
905 val |= readl_relaxed(base + bank->regs->dataout) & m; in omap_gpio_get_multiple()
921 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_debounce()
923 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_debounce()
926 dev_info(chip->parent, in omap_gpio_debounce()
937 int ret = -ENOTSUPP; in omap_gpio_set_config()
962 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_set()
963 bank->set_dataout(bank, offset, value); in omap_gpio_set()
964 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_set()
971 void __iomem *reg = bank->base + bank->regs->dataout; in omap_gpio_set_multiple()
975 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_set_multiple()
978 bank->context.dataout = l; in omap_gpio_set_multiple()
979 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_set_multiple()
982 /*---------------------------------------------------------------------*/
989 if (called || bank->regs->revision == USHRT_MAX) in omap_gpio_show_rev()
992 rev = readw_relaxed(bank->base + bank->regs->revision); in omap_gpio_show_rev()
1001 void __iomem *base = bank->base; in omap_gpio_mod_init()
1004 if (bank->width == 16) in omap_gpio_mod_init()
1007 if (bank->is_mpuio) { in omap_gpio_mod_init()
1008 writel_relaxed(l, bank->base + bank->regs->irqenable); in omap_gpio_mod_init()
1012 omap_gpio_rmw(base + bank->regs->irqenable, l, in omap_gpio_mod_init()
1013 bank->regs->irqenable_inv); in omap_gpio_mod_init()
1014 omap_gpio_rmw(base + bank->regs->irqstatus, l, in omap_gpio_mod_init()
1015 !bank->regs->irqenable_inv); in omap_gpio_mod_init()
1016 if (bank->regs->debounce_en) in omap_gpio_mod_init()
1017 writel_relaxed(0, base + bank->regs->debounce_en); in omap_gpio_mod_init()
1020 bank->context.oe = readl_relaxed(bank->base + bank->regs->direction); in omap_gpio_mod_init()
1022 if (bank->regs->ctrl) in omap_gpio_mod_init()
1023 writel_relaxed(0, base + bank->regs->ctrl); in omap_gpio_mod_init()
1034 * REVISIT eventually switch from OMAP-specific gpio structs in omap_gpio_chip_init()
1037 bank->chip.request = omap_gpio_request; in omap_gpio_chip_init()
1038 bank->chip.free = omap_gpio_free; in omap_gpio_chip_init()
1039 bank->chip.get_direction = omap_gpio_get_direction; in omap_gpio_chip_init()
1040 bank->chip.direction_input = omap_gpio_input; in omap_gpio_chip_init()
1041 bank->chip.get = omap_gpio_get; in omap_gpio_chip_init()
1042 bank->chip.get_multiple = omap_gpio_get_multiple; in omap_gpio_chip_init()
1043 bank->chip.direction_output = omap_gpio_output; in omap_gpio_chip_init()
1044 bank->chip.set_config = omap_gpio_set_config; in omap_gpio_chip_init()
1045 bank->chip.set = omap_gpio_set; in omap_gpio_chip_init()
1046 bank->chip.set_multiple = omap_gpio_set_multiple; in omap_gpio_chip_init()
1047 if (bank->is_mpuio) { in omap_gpio_chip_init()
1048 bank->chip.label = "mpuio"; in omap_gpio_chip_init()
1049 if (bank->regs->wkup_en) in omap_gpio_chip_init()
1050 bank->chip.parent = &omap_mpuio_device.dev; in omap_gpio_chip_init()
1052 label = devm_kasprintf(bank->chip.parent, GFP_KERNEL, "gpio-%d-%d", in omap_gpio_chip_init()
1053 gpio, gpio + bank->width - 1); in omap_gpio_chip_init()
1055 return -ENOMEM; in omap_gpio_chip_init()
1056 bank->chip.label = label; in omap_gpio_chip_init()
1058 bank->chip.base = -1; in omap_gpio_chip_init()
1059 bank->chip.ngpio = bank->width; in omap_gpio_chip_init()
1061 irq = &bank->chip.irq; in omap_gpio_chip_init()
1063 if (bank->is_mpuio && !bank->regs->wkup_en) in omap_gpio_chip_init()
1067 irq->handler = handle_bad_irq; in omap_gpio_chip_init()
1068 irq->default_type = IRQ_TYPE_NONE; in omap_gpio_chip_init()
1069 irq->num_parents = 1; in omap_gpio_chip_init()
1070 irq->parents = &bank->irq; in omap_gpio_chip_init()
1072 ret = gpiochip_add_data(&bank->chip, bank); in omap_gpio_chip_init()
1074 return dev_err_probe(bank->chip.parent, ret, "Could not register gpio chip\n"); in omap_gpio_chip_init()
1076 irq_domain_set_pm_device(bank->chip.irq.domain, pm_dev); in omap_gpio_chip_init()
1077 ret = devm_request_irq(bank->chip.parent, bank->irq, in omap_gpio_chip_init()
1079 0, dev_name(bank->chip.parent), bank); in omap_gpio_chip_init()
1081 gpiochip_remove(&bank->chip); in omap_gpio_chip_init()
1083 if (!bank->is_mpuio) in omap_gpio_chip_init()
1084 gpio += bank->width; in omap_gpio_chip_init()
1091 const struct omap_gpio_reg_offs *regs = p->regs; in omap_gpio_init_context()
1092 void __iomem *base = p->base; in omap_gpio_init_context()
1094 p->context.sysconfig = readl_relaxed(base + regs->sysconfig); in omap_gpio_init_context()
1095 p->context.ctrl = readl_relaxed(base + regs->ctrl); in omap_gpio_init_context()
1096 p->context.oe = readl_relaxed(base + regs->direction); in omap_gpio_init_context()
1097 p->context.wake_en = readl_relaxed(base + regs->wkup_en); in omap_gpio_init_context()
1098 p->context.leveldetect0 = readl_relaxed(base + regs->leveldetect0); in omap_gpio_init_context()
1099 p->context.leveldetect1 = readl_relaxed(base + regs->leveldetect1); in omap_gpio_init_context()
1100 p->context.risingdetect = readl_relaxed(base + regs->risingdetect); in omap_gpio_init_context()
1101 p->context.fallingdetect = readl_relaxed(base + regs->fallingdetect); in omap_gpio_init_context()
1102 p->context.irqenable1 = readl_relaxed(base + regs->irqenable); in omap_gpio_init_context()
1103 p->context.irqenable2 = readl_relaxed(base + regs->irqenable2); in omap_gpio_init_context()
1104 p->context.dataout = readl_relaxed(base + regs->dataout); in omap_gpio_init_context()
1106 p->context_valid = true; in omap_gpio_init_context()
1111 const struct omap_gpio_reg_offs *regs = bank->regs; in omap_gpio_restore_context()
1112 void __iomem *base = bank->base; in omap_gpio_restore_context()
1114 writel_relaxed(bank->context.sysconfig, base + regs->sysconfig); in omap_gpio_restore_context()
1115 writel_relaxed(bank->context.wake_en, base + regs->wkup_en); in omap_gpio_restore_context()
1116 writel_relaxed(bank->context.ctrl, base + regs->ctrl); in omap_gpio_restore_context()
1117 writel_relaxed(bank->context.leveldetect0, base + regs->leveldetect0); in omap_gpio_restore_context()
1118 writel_relaxed(bank->context.leveldetect1, base + regs->leveldetect1); in omap_gpio_restore_context()
1119 writel_relaxed(bank->context.risingdetect, base + regs->risingdetect); in omap_gpio_restore_context()
1120 writel_relaxed(bank->context.fallingdetect, base + regs->fallingdetect); in omap_gpio_restore_context()
1121 writel_relaxed(bank->context.dataout, base + regs->dataout); in omap_gpio_restore_context()
1122 writel_relaxed(bank->context.oe, base + regs->direction); in omap_gpio_restore_context()
1124 if (bank->dbck_enable_mask) { in omap_gpio_restore_context()
1125 writel_relaxed(bank->context.debounce, base + regs->debounce); in omap_gpio_restore_context()
1126 writel_relaxed(bank->context.debounce_en, in omap_gpio_restore_context()
1127 base + regs->debounce_en); in omap_gpio_restore_context()
1130 writel_relaxed(bank->context.irqenable1, base + regs->irqenable); in omap_gpio_restore_context()
1131 writel_relaxed(bank->context.irqenable2, base + regs->irqenable2); in omap_gpio_restore_context()
1136 struct device *dev = bank->chip.parent; in omap_gpio_idle()
1137 void __iomem *base = bank->base; in omap_gpio_idle()
1140 bank->saved_datain = readl_relaxed(base + bank->regs->datain); in omap_gpio_idle()
1143 if (bank->loses_context) in omap_gpio_idle()
1144 bank->context.sysconfig = readl_relaxed(base + bank->regs->sysconfig); in omap_gpio_idle()
1146 if (!bank->enabled_non_wakeup_gpios) in omap_gpio_idle()
1150 mask = bank->enabled_non_wakeup_gpios & bank->context.fallingdetect; in omap_gpio_idle()
1151 mask &= ~bank->context.risingdetect; in omap_gpio_idle()
1152 bank->saved_datain |= mask; in omap_gpio_idle()
1155 mask = bank->enabled_non_wakeup_gpios & bank->context.risingdetect; in omap_gpio_idle()
1156 mask &= ~bank->context.fallingdetect; in omap_gpio_idle()
1157 bank->saved_datain &= ~mask; in omap_gpio_idle()
1164 * non-wakeup GPIOs. Otherwise spurious IRQs will be in omap_gpio_idle()
1167 if (!bank->loses_context && bank->enabled_non_wakeup_gpios) { in omap_gpio_idle()
1168 nowake = bank->enabled_non_wakeup_gpios; in omap_gpio_idle()
1169 omap_gpio_rmw(base + bank->regs->fallingdetect, nowake, ~nowake); in omap_gpio_idle()
1170 omap_gpio_rmw(base + bank->regs->risingdetect, nowake, ~nowake); in omap_gpio_idle()
1174 if (bank->get_context_loss_count) in omap_gpio_idle()
1175 bank->context_loss_count = in omap_gpio_idle()
1176 bank->get_context_loss_count(dev); in omap_gpio_idle()
1183 struct device *dev = bank->chip.parent; in omap_gpio_unidle()
1192 if (bank->loses_context && !bank->context_valid) { in omap_gpio_unidle()
1195 if (bank->get_context_loss_count) in omap_gpio_unidle()
1196 bank->context_loss_count = in omap_gpio_unidle()
1197 bank->get_context_loss_count(dev); in omap_gpio_unidle()
1202 if (bank->loses_context) { in omap_gpio_unidle()
1203 if (!bank->get_context_loss_count) { in omap_gpio_unidle()
1206 c = bank->get_context_loss_count(dev); in omap_gpio_unidle()
1207 if (c != bank->context_loss_count) { in omap_gpio_unidle()
1215 writel_relaxed(bank->context.fallingdetect, in omap_gpio_unidle()
1216 bank->base + bank->regs->fallingdetect); in omap_gpio_unidle()
1217 writel_relaxed(bank->context.risingdetect, in omap_gpio_unidle()
1218 bank->base + bank->regs->risingdetect); in omap_gpio_unidle()
1221 l = readl_relaxed(bank->base + bank->regs->datain); in omap_gpio_unidle()
1224 * Check if any of the non-wakeup interrupt GPIOs have changed in omap_gpio_unidle()
1229 l ^= bank->saved_datain; in omap_gpio_unidle()
1230 l &= bank->enabled_non_wakeup_gpios; in omap_gpio_unidle()
1236 gen0 = l & bank->context.fallingdetect; in omap_gpio_unidle()
1237 gen0 &= bank->saved_datain; in omap_gpio_unidle()
1239 gen1 = l & bank->context.risingdetect; in omap_gpio_unidle()
1240 gen1 &= ~(bank->saved_datain); in omap_gpio_unidle()
1243 gen = l & (~(bank->context.fallingdetect) & in omap_gpio_unidle()
1244 ~(bank->context.risingdetect)); in omap_gpio_unidle()
1251 old0 = readl_relaxed(bank->base + bank->regs->leveldetect0); in omap_gpio_unidle()
1252 old1 = readl_relaxed(bank->base + bank->regs->leveldetect1); in omap_gpio_unidle()
1254 if (!bank->regs->irqstatus_raw0) { in omap_gpio_unidle()
1255 writel_relaxed(old0 | gen, bank->base + in omap_gpio_unidle()
1256 bank->regs->leveldetect0); in omap_gpio_unidle()
1257 writel_relaxed(old1 | gen, bank->base + in omap_gpio_unidle()
1258 bank->regs->leveldetect1); in omap_gpio_unidle()
1261 if (bank->regs->irqstatus_raw0) { in omap_gpio_unidle()
1262 writel_relaxed(old0 | l, bank->base + in omap_gpio_unidle()
1263 bank->regs->leveldetect0); in omap_gpio_unidle()
1264 writel_relaxed(old1 | l, bank->base + in omap_gpio_unidle()
1265 bank->regs->leveldetect1); in omap_gpio_unidle()
1267 writel_relaxed(old0, bank->base + bank->regs->leveldetect0); in omap_gpio_unidle()
1268 writel_relaxed(old1, bank->base + bank->regs->leveldetect1); in omap_gpio_unidle()
1282 raw_spin_lock_irqsave(&bank->lock, flags); in gpio_omap_cpu_notifier()
1283 if (bank->is_suspended) in gpio_omap_cpu_notifier()
1289 isr = readl_relaxed(bank->base + bank->regs->irqstatus) & mask; in gpio_omap_cpu_notifier()
1303 raw_spin_unlock_irqrestore(&bank->lock, flags); in gpio_omap_cpu_notifier()
1324 .ctrl = OMAP24XX_GPIO_CTRL,
1350 .ctrl = OMAP4_GPIO_CTRL,
1378 .compatible = "ti,omap4-gpio",
1382 .compatible = "ti,omap3-gpio",
1386 .compatible = "ti,omap2-gpio",
1395 struct device *dev = &pdev->dev; in omap_gpio_probe()
1396 struct device_node *node = dev->of_node; in omap_gpio_probe()
1405 return -EINVAL; in omap_gpio_probe()
1409 return -ENOMEM; in omap_gpio_probe()
1411 bank->dev = dev; in omap_gpio_probe()
1413 bank->irq = platform_get_irq(pdev, 0); in omap_gpio_probe()
1414 if (bank->irq < 0) in omap_gpio_probe()
1415 return bank->irq; in omap_gpio_probe()
1417 bank->chip.parent = dev; in omap_gpio_probe()
1418 bank->chip.owner = THIS_MODULE; in omap_gpio_probe()
1419 bank->dbck_flag = pdata->dbck_flag; in omap_gpio_probe()
1420 bank->stride = pdata->bank_stride; in omap_gpio_probe()
1421 bank->width = pdata->bank_width; in omap_gpio_probe()
1422 bank->is_mpuio = pdata->is_mpuio; in omap_gpio_probe()
1423 bank->non_wakeup_gpios = pdata->non_wakeup_gpios; in omap_gpio_probe()
1424 bank->regs = pdata->regs; in omap_gpio_probe()
1427 if (!of_property_read_bool(node, "ti,gpio-always-on")) in omap_gpio_probe()
1428 bank->loses_context = true; in omap_gpio_probe()
1430 bank->loses_context = pdata->loses_context; in omap_gpio_probe()
1432 if (bank->loses_context) in omap_gpio_probe()
1433 bank->get_context_loss_count = in omap_gpio_probe()
1434 pdata->get_context_loss_count; in omap_gpio_probe()
1437 if (bank->regs->set_dataout && bank->regs->clr_dataout) in omap_gpio_probe()
1438 bank->set_dataout = omap_set_gpio_dataout_reg; in omap_gpio_probe()
1440 bank->set_dataout = omap_set_gpio_dataout_mask; in omap_gpio_probe()
1442 raw_spin_lock_init(&bank->lock); in omap_gpio_probe()
1443 raw_spin_lock_init(&bank->wa_lock); in omap_gpio_probe()
1446 bank->base = devm_platform_ioremap_resource(pdev, 0); in omap_gpio_probe()
1447 if (IS_ERR(bank->base)) { in omap_gpio_probe()
1448 return PTR_ERR(bank->base); in omap_gpio_probe()
1451 if (bank->dbck_flag) { in omap_gpio_probe()
1452 bank->dbck = devm_clk_get(dev, "dbclk"); in omap_gpio_probe()
1453 if (IS_ERR(bank->dbck)) { in omap_gpio_probe()
1456 bank->dbck_flag = false; in omap_gpio_probe()
1458 clk_prepare(bank->dbck); in omap_gpio_probe()
1467 if (bank->is_mpuio) in omap_gpio_probe()
1476 if (bank->dbck_flag) in omap_gpio_probe()
1477 clk_unprepare(bank->dbck); in omap_gpio_probe()
1483 bank->nb.notifier_call = gpio_omap_cpu_notifier; in omap_gpio_probe()
1484 cpu_pm_register_notifier(&bank->nb); in omap_gpio_probe()
1495 cpu_pm_unregister_notifier(&bank->nb); in omap_gpio_remove()
1496 gpiochip_remove(&bank->chip); in omap_gpio_remove()
1497 pm_runtime_disable(&pdev->dev); in omap_gpio_remove()
1498 if (bank->dbck_flag) in omap_gpio_remove()
1499 clk_unprepare(bank->dbck); in omap_gpio_remove()
1507 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_runtime_suspend()
1509 bank->is_suspended = true; in omap_gpio_runtime_suspend()
1510 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_runtime_suspend()
1520 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_runtime_resume()
1522 bank->is_suspended = false; in omap_gpio_runtime_resume()
1523 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_runtime_resume()
1532 if (bank->is_suspended) in omap_gpio_suspend()
1535 bank->needs_resume = 1; in omap_gpio_suspend()
1544 if (!bank->needs_resume) in omap_gpio_resume()
1547 bank->needs_resume = 0; in omap_gpio_resume()
1586 MODULE_ALIAS("platform:gpio-omap");