Lines Matching +full:bank +full:- +full:width
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>
73 u32 width; member
76 void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable);
82 #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) argument
107 static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio, in omap_set_gpio_direction() argument
110 bank->context.oe = omap_gpio_rmw(bank->base + bank->regs->direction, in omap_set_gpio_direction()
116 static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset, in omap_set_gpio_dataout_reg() argument
119 void __iomem *reg = bank->base; in omap_set_gpio_dataout_reg()
123 reg += bank->regs->set_dataout; in omap_set_gpio_dataout_reg()
124 bank->context.dataout |= l; in omap_set_gpio_dataout_reg()
126 reg += bank->regs->clr_dataout; in omap_set_gpio_dataout_reg()
127 bank->context.dataout &= ~l; in omap_set_gpio_dataout_reg()
134 static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, unsigned offset, in omap_set_gpio_dataout_mask() argument
137 bank->context.dataout = omap_gpio_rmw(bank->base + bank->regs->dataout, in omap_set_gpio_dataout_mask()
141 static inline void omap_gpio_dbck_enable(struct gpio_bank *bank) in omap_gpio_dbck_enable() argument
143 if (bank->dbck_enable_mask && !bank->dbck_enabled) { in omap_gpio_dbck_enable()
144 clk_enable(bank->dbck); in omap_gpio_dbck_enable()
145 bank->dbck_enabled = true; in omap_gpio_dbck_enable()
147 writel_relaxed(bank->dbck_enable_mask, in omap_gpio_dbck_enable()
148 bank->base + bank->regs->debounce_en); in omap_gpio_dbck_enable()
152 static inline void omap_gpio_dbck_disable(struct gpio_bank *bank) in omap_gpio_dbck_disable() argument
154 if (bank->dbck_enable_mask && bank->dbck_enabled) { in omap_gpio_dbck_disable()
160 writel_relaxed(0, bank->base + bank->regs->debounce_en); in omap_gpio_dbck_disable()
162 clk_disable(bank->dbck); in omap_gpio_dbck_disable()
163 bank->dbck_enabled = false; in omap_gpio_dbck_disable()
168 * omap2_set_gpio_debounce - low level gpio debounce time
169 * @bank: the gpio bank we're acting upon
170 * @offset: the gpio number on this @bank
179 static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset, in omap2_set_gpio_debounce() argument
186 if (!bank->dbck_flag) in omap2_set_gpio_debounce()
187 return -ENOTSUPP; in omap2_set_gpio_debounce()
190 debounce = DIV_ROUND_UP(debounce, 31) - 1; in omap2_set_gpio_debounce()
192 return -EINVAL; in omap2_set_gpio_debounce()
197 clk_enable(bank->dbck); in omap2_set_gpio_debounce()
198 writel_relaxed(debounce, bank->base + bank->regs->debounce); in omap2_set_gpio_debounce()
200 val = omap_gpio_rmw(bank->base + bank->regs->debounce_en, l, enable); in omap2_set_gpio_debounce()
201 bank->dbck_enable_mask = val; in omap2_set_gpio_debounce()
203 clk_disable(bank->dbck); in omap2_set_gpio_debounce()
212 omap_gpio_dbck_enable(bank); in omap2_set_gpio_debounce()
213 if (bank->dbck_enable_mask) { in omap2_set_gpio_debounce()
214 bank->context.debounce = debounce; in omap2_set_gpio_debounce()
215 bank->context.debounce_en = val; in omap2_set_gpio_debounce()
222 * omap_clear_gpio_debounce - clear debounce settings for a gpio
223 * @bank: the gpio bank we're acting upon
224 * @offset: the gpio number on this @bank
227 * this is the only gpio in this bank using debounce, then clear the debounce
229 * if this is the only gpio in the bank using debounce.
231 static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset) in omap_clear_gpio_debounce() argument
235 if (!bank->dbck_flag) in omap_clear_gpio_debounce()
238 if (!(bank->dbck_enable_mask & gpio_bit)) in omap_clear_gpio_debounce()
241 bank->dbck_enable_mask &= ~gpio_bit; in omap_clear_gpio_debounce()
242 bank->context.debounce_en &= ~gpio_bit; in omap_clear_gpio_debounce()
243 writel_relaxed(bank->context.debounce_en, in omap_clear_gpio_debounce()
244 bank->base + bank->regs->debounce_en); in omap_clear_gpio_debounce()
246 if (!bank->dbck_enable_mask) { in omap_clear_gpio_debounce()
247 bank->context.debounce = 0; in omap_clear_gpio_debounce()
248 writel_relaxed(bank->context.debounce, bank->base + in omap_clear_gpio_debounce()
249 bank->regs->debounce); in omap_clear_gpio_debounce()
250 clk_disable(bank->dbck); in omap_clear_gpio_debounce()
251 bank->dbck_enabled = false; in omap_clear_gpio_debounce()
256 * Off mode wake-up capable GPIOs in bank(s) that are in the wakeup domain.
257 * See TRM section for GPIO for "Wake-Up Generation" for the list of GPIOs
258 * in wakeup domain. If bank->non_wakeup_gpios is not configured, assume none
261 static bool omap_gpio_is_off_wakeup_capable(struct gpio_bank *bank, u32 gpio_mask) in omap_gpio_is_off_wakeup_capable() argument
263 u32 no_wake = bank->non_wakeup_gpios; in omap_gpio_is_off_wakeup_capable()
271 static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, in omap_set_gpio_trigger() argument
274 void __iomem *base = bank->base; in omap_set_gpio_trigger()
277 omap_gpio_rmw(base + bank->regs->leveldetect0, gpio_bit, in omap_set_gpio_trigger()
279 omap_gpio_rmw(base + bank->regs->leveldetect1, gpio_bit, in omap_set_gpio_trigger()
287 omap_gpio_rmw(base + bank->regs->risingdetect, gpio_bit, in omap_set_gpio_trigger()
289 omap_gpio_rmw(base + bank->regs->fallingdetect, gpio_bit, in omap_set_gpio_trigger()
292 bank->context.leveldetect0 = in omap_set_gpio_trigger()
293 readl_relaxed(bank->base + bank->regs->leveldetect0); in omap_set_gpio_trigger()
294 bank->context.leveldetect1 = in omap_set_gpio_trigger()
295 readl_relaxed(bank->base + bank->regs->leveldetect1); in omap_set_gpio_trigger()
296 bank->context.risingdetect = in omap_set_gpio_trigger()
297 readl_relaxed(bank->base + bank->regs->risingdetect); in omap_set_gpio_trigger()
298 bank->context.fallingdetect = in omap_set_gpio_trigger()
299 readl_relaxed(bank->base + bank->regs->fallingdetect); in omap_set_gpio_trigger()
301 bank->level_mask = bank->context.leveldetect0 | in omap_set_gpio_trigger()
302 bank->context.leveldetect1; in omap_set_gpio_trigger()
305 if (!bank->regs->irqctrl && !omap_gpio_is_off_wakeup_capable(bank, gpio)) { in omap_set_gpio_trigger()
310 * Applies for omap2 non-wakeup gpio and all omap3 gpios in omap_set_gpio_trigger()
313 bank->enabled_non_wakeup_gpios |= gpio_bit; in omap_set_gpio_trigger()
315 bank->enabled_non_wakeup_gpios &= ~gpio_bit; in omap_set_gpio_trigger()
323 static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) in omap_toggle_gpio_edge_triggering() argument
325 if (IS_ENABLED(CONFIG_ARCH_OMAP1) && bank->regs->irqctrl) { in omap_toggle_gpio_edge_triggering()
326 void __iomem *reg = bank->base + bank->regs->irqctrl; in omap_toggle_gpio_edge_triggering()
332 static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio, in omap_set_gpio_triggering() argument
335 void __iomem *reg = bank->base; in omap_set_gpio_triggering()
338 if (bank->regs->leveldetect0 && bank->regs->wkup_en) { in omap_set_gpio_triggering()
339 omap_set_gpio_trigger(bank, gpio, trigger); in omap_set_gpio_triggering()
340 } else if (bank->regs->irqctrl) { in omap_set_gpio_triggering()
341 reg += bank->regs->irqctrl; in omap_set_gpio_triggering()
345 bank->toggle_mask |= BIT(gpio); in omap_set_gpio_triggering()
351 return -EINVAL; in omap_set_gpio_triggering()
354 } else if (bank->regs->edgectrl1) { in omap_set_gpio_triggering()
356 reg += bank->regs->edgectrl2; in omap_set_gpio_triggering()
358 reg += bank->regs->edgectrl1; in omap_set_gpio_triggering()
372 static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset) in omap_enable_gpio_module() argument
374 if (bank->regs->pinctrl) { in omap_enable_gpio_module()
375 void __iomem *reg = bank->base + bank->regs->pinctrl; in omap_enable_gpio_module()
381 if (bank->regs->ctrl && !BANK_USED(bank)) { in omap_enable_gpio_module()
382 void __iomem *reg = bank->base + bank->regs->ctrl; in omap_enable_gpio_module()
389 bank->context.ctrl = ctrl; in omap_enable_gpio_module()
393 static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset) in omap_disable_gpio_module() argument
395 if (bank->regs->ctrl && !BANK_USED(bank)) { in omap_disable_gpio_module()
396 void __iomem *reg = bank->base + bank->regs->ctrl; in omap_disable_gpio_module()
403 bank->context.ctrl = ctrl; in omap_disable_gpio_module()
407 static int omap_gpio_is_input(struct gpio_bank *bank, unsigned offset) in omap_gpio_is_input() argument
409 void __iomem *reg = bank->base + bank->regs->direction; in omap_gpio_is_input()
414 static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned offset) in omap_gpio_init_irq() argument
416 if (!LINE_USED(bank->mod_usage, offset)) { in omap_gpio_init_irq()
417 omap_enable_gpio_module(bank, offset); in omap_gpio_init_irq()
418 omap_set_gpio_direction(bank, offset, 1); in omap_gpio_init_irq()
420 bank->irq_usage |= BIT(offset); in omap_gpio_init_irq()
425 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_irq_type() local
428 unsigned offset = d->hwirq; in omap_gpio_irq_type()
431 return -EINVAL; in omap_gpio_irq_type()
433 if (!bank->regs->leveldetect0 && in omap_gpio_irq_type()
435 return -EINVAL; in omap_gpio_irq_type()
437 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_type()
438 retval = omap_set_gpio_triggering(bank, offset, type); in omap_gpio_irq_type()
440 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
443 omap_gpio_init_irq(bank, offset); in omap_gpio_irq_type()
444 if (!omap_gpio_is_input(bank, offset)) { in omap_gpio_irq_type()
445 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
446 retval = -EINVAL; in omap_gpio_irq_type()
449 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_type()
468 static void omap_clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) in omap_clear_gpio_irqbank() argument
470 void __iomem *reg = bank->base; in omap_clear_gpio_irqbank()
472 reg += bank->regs->irqstatus; in omap_clear_gpio_irqbank()
476 if (bank->regs->irqstatus2) { in omap_clear_gpio_irqbank()
477 reg = bank->base + bank->regs->irqstatus2; in omap_clear_gpio_irqbank()
485 static inline void omap_clear_gpio_irqstatus(struct gpio_bank *bank, in omap_clear_gpio_irqstatus() argument
488 omap_clear_gpio_irqbank(bank, BIT(offset)); in omap_clear_gpio_irqstatus()
491 static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank) in omap_get_gpio_irqbank_mask() argument
493 void __iomem *reg = bank->base; in omap_get_gpio_irqbank_mask()
495 u32 mask = (BIT(bank->width)) - 1; in omap_get_gpio_irqbank_mask()
497 reg += bank->regs->irqenable; in omap_get_gpio_irqbank_mask()
499 if (bank->regs->irqenable_inv) in omap_get_gpio_irqbank_mask()
505 static inline void omap_set_gpio_irqenable(struct gpio_bank *bank, in omap_set_gpio_irqenable() argument
508 void __iomem *reg = bank->base; in omap_set_gpio_irqenable()
511 if (bank->regs->set_irqenable && bank->regs->clr_irqenable) { in omap_set_gpio_irqenable()
513 reg += bank->regs->set_irqenable; in omap_set_gpio_irqenable()
514 bank->context.irqenable1 |= gpio_mask; in omap_set_gpio_irqenable()
516 reg += bank->regs->clr_irqenable; in omap_set_gpio_irqenable()
517 bank->context.irqenable1 &= ~gpio_mask; in omap_set_gpio_irqenable()
521 bank->context.irqenable1 = in omap_set_gpio_irqenable()
522 omap_gpio_rmw(reg + bank->regs->irqenable, gpio_mask, in omap_set_gpio_irqenable()
523 enable ^ bank->regs->irqenable_inv); in omap_set_gpio_irqenable()
532 if (bank->regs->wkup_en && in omap_set_gpio_irqenable()
533 (bank->regs->edgectrl1 || !(bank->non_wakeup_gpios & gpio_mask))) { in omap_set_gpio_irqenable()
534 bank->context.wake_en = in omap_set_gpio_irqenable()
535 omap_gpio_rmw(bank->base + bank->regs->wkup_en, in omap_set_gpio_irqenable()
543 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_wake_enable() local
545 return irq_set_irq_wake(bank->irq, enable); in omap_gpio_wake_enable()
549 * We need to unmask the GPIO bank interrupt as soon as possible to
550 * avoid missing GPIO interrupts for other lines in the bank.
551 * Then we need to mask-read-clear-unmask the triggered GPIO lines
552 * in the bank to avoid missing nested interrupts for a GPIO line.
553 * If we wait to unmask individual GPIO lines in the bank after the
562 struct gpio_bank *bank = gpiobank; in omap_gpio_irq_handler() local
566 isr_reg = bank->base + bank->regs->irqstatus; in omap_gpio_irq_handler()
570 if (WARN_ONCE(!pm_runtime_active(bank->chip.parent), in omap_gpio_irq_handler()
575 raw_spin_lock_irqsave(&bank->lock, lock_flags); in omap_gpio_irq_handler()
577 enabled = omap_get_gpio_irqbank_mask(bank); in omap_gpio_irq_handler()
585 edge = isr & ~bank->level_mask; in omap_gpio_irq_handler()
587 omap_clear_gpio_irqbank(bank, edge); in omap_gpio_irq_handler()
589 raw_spin_unlock_irqrestore(&bank->lock, lock_flags); in omap_gpio_irq_handler()
598 raw_spin_lock_irqsave(&bank->lock, lock_flags); in omap_gpio_irq_handler()
604 * This will be indicated in the bank toggle_mask. in omap_gpio_irq_handler()
606 if (bank->toggle_mask & (BIT(bit))) in omap_gpio_irq_handler()
607 omap_toggle_gpio_edge_triggering(bank, bit); in omap_gpio_irq_handler()
609 raw_spin_unlock_irqrestore(&bank->lock, lock_flags); in omap_gpio_irq_handler()
611 raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); in omap_gpio_irq_handler()
613 generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, in omap_gpio_irq_handler()
616 raw_spin_unlock_irqrestore(&bank->wa_lock, in omap_gpio_irq_handler()
626 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_irq_startup() local
628 unsigned offset = d->hwirq; in omap_gpio_irq_startup()
630 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_startup()
632 if (!LINE_USED(bank->mod_usage, offset)) in omap_gpio_irq_startup()
633 omap_set_gpio_direction(bank, offset, 1); in omap_gpio_irq_startup()
634 omap_enable_gpio_module(bank, offset); in omap_gpio_irq_startup()
635 bank->irq_usage |= BIT(offset); in omap_gpio_irq_startup()
637 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_startup()
645 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_irq_shutdown() local
647 unsigned offset = d->hwirq; in omap_gpio_irq_shutdown()
649 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_irq_shutdown()
650 bank->irq_usage &= ~(BIT(offset)); in omap_gpio_irq_shutdown()
651 omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); in omap_gpio_irq_shutdown()
652 omap_clear_gpio_irqstatus(bank, offset); in omap_gpio_irq_shutdown()
653 omap_set_gpio_irqenable(bank, offset, 0); in omap_gpio_irq_shutdown()
654 if (!LINE_USED(bank->mod_usage, offset)) in omap_gpio_irq_shutdown()
655 omap_clear_gpio_debounce(bank, offset); in omap_gpio_irq_shutdown()
656 omap_disable_gpio_module(bank, offset); in omap_gpio_irq_shutdown()
657 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_irq_shutdown()
662 struct gpio_bank *bank = omap_irq_data_get_bank(data); in omap_gpio_irq_bus_lock() local
664 pm_runtime_get_sync(bank->chip.parent); in omap_gpio_irq_bus_lock()
669 struct gpio_bank *bank = omap_irq_data_get_bank(data); in gpio_irq_bus_sync_unlock() local
671 pm_runtime_put(bank->chip.parent); in gpio_irq_bus_sync_unlock()
676 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_mask_irq() local
677 unsigned offset = d->hwirq; in omap_gpio_mask_irq()
680 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_mask_irq()
681 omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); in omap_gpio_mask_irq()
682 omap_set_gpio_irqenable(bank, offset, 0); in omap_gpio_mask_irq()
683 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_mask_irq()
688 struct gpio_bank *bank = omap_irq_data_get_bank(d); in omap_gpio_unmask_irq() local
689 unsigned offset = d->hwirq; in omap_gpio_unmask_irq()
693 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_unmask_irq()
694 omap_set_gpio_irqenable(bank, offset, 1); in omap_gpio_unmask_irq()
697 * For level-triggered GPIOs, clearing must be done after the source in omap_gpio_unmask_irq()
701 if (bank->regs->leveldetect0 && bank->regs->wkup_en && in omap_gpio_unmask_irq()
703 omap_clear_gpio_irqstatus(bank, offset); in omap_gpio_unmask_irq()
706 omap_set_gpio_triggering(bank, offset, trigger); in omap_gpio_unmask_irq()
708 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_unmask_irq()
711 /*---------------------------------------------------------------------*/
715 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_mpuio_suspend_noirq() local
716 void __iomem *mask_reg = bank->base + in omap_mpuio_suspend_noirq()
717 OMAP_MPUIO_GPIO_MASKIT / bank->stride; in omap_mpuio_suspend_noirq()
720 raw_spin_lock_irqsave(&bank->lock, flags); in omap_mpuio_suspend_noirq()
721 writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg); in omap_mpuio_suspend_noirq()
722 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_mpuio_suspend_noirq()
729 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_mpuio_resume_noirq() local
730 void __iomem *mask_reg = bank->base + in omap_mpuio_resume_noirq()
731 OMAP_MPUIO_GPIO_MASKIT / bank->stride; in omap_mpuio_resume_noirq()
734 raw_spin_lock_irqsave(&bank->lock, flags); in omap_mpuio_resume_noirq()
735 writel_relaxed(bank->context.wake_en, mask_reg); in omap_mpuio_resume_noirq()
736 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_mpuio_resume_noirq()
756 .id = -1,
763 static inline void omap_mpuio_init(struct gpio_bank *bank) in omap_mpuio_init() argument
765 platform_set_drvdata(&omap_mpuio_device, bank); in omap_mpuio_init()
771 /*---------------------------------------------------------------------*/
775 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_request() local
778 pm_runtime_get_sync(chip->parent); in omap_gpio_request()
780 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_request()
781 omap_enable_gpio_module(bank, offset); in omap_gpio_request()
782 bank->mod_usage |= BIT(offset); in omap_gpio_request()
783 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_request()
790 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_free() local
793 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_free()
794 bank->mod_usage &= ~(BIT(offset)); in omap_gpio_free()
795 if (!LINE_USED(bank->irq_usage, offset)) { in omap_gpio_free()
796 omap_set_gpio_direction(bank, offset, 1); in omap_gpio_free()
797 omap_clear_gpio_debounce(bank, offset); in omap_gpio_free()
799 omap_disable_gpio_module(bank, offset); in omap_gpio_free()
800 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_free()
802 pm_runtime_put(chip->parent); in omap_gpio_free()
807 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_get_direction() local
809 if (readl_relaxed(bank->base + bank->regs->direction) & BIT(offset)) in omap_gpio_get_direction()
817 struct gpio_bank *bank; in omap_gpio_input() local
820 bank = gpiochip_get_data(chip); in omap_gpio_input()
821 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_input()
822 omap_set_gpio_direction(bank, offset, 1); in omap_gpio_input()
823 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_input()
829 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_get() local
832 if (omap_gpio_is_input(bank, offset)) in omap_gpio_get()
833 reg = bank->base + bank->regs->datain; in omap_gpio_get()
835 reg = bank->base + bank->regs->dataout; in omap_gpio_get()
842 struct gpio_bank *bank; in omap_gpio_output() local
845 bank = gpiochip_get_data(chip); in omap_gpio_output()
846 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_output()
847 bank->set_dataout(bank, offset, value); in omap_gpio_output()
848 omap_set_gpio_direction(bank, offset, 0); in omap_gpio_output()
849 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_output()
856 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_get_multiple() local
857 void __iomem *base = bank->base; in omap_gpio_get_multiple()
860 direction = readl_relaxed(base + bank->regs->direction); in omap_gpio_get_multiple()
864 val |= readl_relaxed(base + bank->regs->datain) & m; in omap_gpio_get_multiple()
868 val |= readl_relaxed(base + bank->regs->dataout) & m; in omap_gpio_get_multiple()
878 struct gpio_bank *bank; in omap_gpio_debounce() local
882 bank = gpiochip_get_data(chip); in omap_gpio_debounce()
884 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_debounce()
885 ret = omap2_set_gpio_debounce(bank, offset, debounce); in omap_gpio_debounce()
886 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_debounce()
889 dev_info(chip->parent, in omap_gpio_debounce()
900 int ret = -ENOTSUPP; in omap_gpio_set_config()
921 struct gpio_bank *bank; in omap_gpio_set() local
924 bank = gpiochip_get_data(chip); in omap_gpio_set()
925 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_set()
926 bank->set_dataout(bank, offset, value); in omap_gpio_set()
927 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_set()
933 struct gpio_bank *bank = gpiochip_get_data(chip); in omap_gpio_set_multiple() local
934 void __iomem *reg = bank->base + bank->regs->dataout; in omap_gpio_set_multiple()
938 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_set_multiple()
941 bank->context.dataout = l; in omap_gpio_set_multiple()
942 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_set_multiple()
945 /*---------------------------------------------------------------------*/
947 static void omap_gpio_show_rev(struct gpio_bank *bank) in omap_gpio_show_rev() argument
952 if (called || bank->regs->revision == USHRT_MAX) in omap_gpio_show_rev()
955 rev = readw_relaxed(bank->base + bank->regs->revision); in omap_gpio_show_rev()
962 static void omap_gpio_mod_init(struct gpio_bank *bank) in omap_gpio_mod_init() argument
964 void __iomem *base = bank->base; in omap_gpio_mod_init()
967 if (bank->width == 16) in omap_gpio_mod_init()
970 if (bank->is_mpuio) { in omap_gpio_mod_init()
971 writel_relaxed(l, bank->base + bank->regs->irqenable); in omap_gpio_mod_init()
975 omap_gpio_rmw(base + bank->regs->irqenable, l, in omap_gpio_mod_init()
976 bank->regs->irqenable_inv); in omap_gpio_mod_init()
977 omap_gpio_rmw(base + bank->regs->irqstatus, l, in omap_gpio_mod_init()
978 !bank->regs->irqenable_inv); in omap_gpio_mod_init()
979 if (bank->regs->debounce_en) in omap_gpio_mod_init()
980 writel_relaxed(0, base + bank->regs->debounce_en); in omap_gpio_mod_init()
983 bank->context.oe = readl_relaxed(bank->base + bank->regs->direction); in omap_gpio_mod_init()
985 if (bank->regs->ctrl) in omap_gpio_mod_init()
986 writel_relaxed(0, base + bank->regs->ctrl); in omap_gpio_mod_init()
989 static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) in omap_gpio_chip_init() argument
998 * REVISIT eventually switch from OMAP-specific gpio structs in omap_gpio_chip_init()
1001 bank->chip.request = omap_gpio_request; in omap_gpio_chip_init()
1002 bank->chip.free = omap_gpio_free; in omap_gpio_chip_init()
1003 bank->chip.get_direction = omap_gpio_get_direction; in omap_gpio_chip_init()
1004 bank->chip.direction_input = omap_gpio_input; in omap_gpio_chip_init()
1005 bank->chip.get = omap_gpio_get; in omap_gpio_chip_init()
1006 bank->chip.get_multiple = omap_gpio_get_multiple; in omap_gpio_chip_init()
1007 bank->chip.direction_output = omap_gpio_output; in omap_gpio_chip_init()
1008 bank->chip.set_config = omap_gpio_set_config; in omap_gpio_chip_init()
1009 bank->chip.set = omap_gpio_set; in omap_gpio_chip_init()
1010 bank->chip.set_multiple = omap_gpio_set_multiple; in omap_gpio_chip_init()
1011 if (bank->is_mpuio) { in omap_gpio_chip_init()
1012 bank->chip.label = "mpuio"; in omap_gpio_chip_init()
1013 if (bank->regs->wkup_en) in omap_gpio_chip_init()
1014 bank->chip.parent = &omap_mpuio_device.dev; in omap_gpio_chip_init()
1015 bank->chip.base = OMAP_MPUIO(0); in omap_gpio_chip_init()
1017 label = devm_kasprintf(bank->chip.parent, GFP_KERNEL, "gpio-%d-%d", in omap_gpio_chip_init()
1018 gpio, gpio + bank->width - 1); in omap_gpio_chip_init()
1020 return -ENOMEM; in omap_gpio_chip_init()
1021 bank->chip.label = label; in omap_gpio_chip_init()
1022 bank->chip.base = gpio; in omap_gpio_chip_init()
1024 bank->chip.ngpio = bank->width; in omap_gpio_chip_init()
1031 irq_base = devm_irq_alloc_descs(bank->chip.parent, in omap_gpio_chip_init()
1032 -1, 0, bank->width, 0); in omap_gpio_chip_init()
1034 dev_err(bank->chip.parent, "Couldn't allocate IRQ numbers\n"); in omap_gpio_chip_init()
1035 return -ENODEV; in omap_gpio_chip_init()
1040 if (bank->is_mpuio && !bank->regs->wkup_en) in omap_gpio_chip_init()
1041 irqc->irq_set_wake = NULL; in omap_gpio_chip_init()
1043 irq = &bank->chip.irq; in omap_gpio_chip_init()
1044 irq->chip = irqc; in omap_gpio_chip_init()
1045 irq->handler = handle_bad_irq; in omap_gpio_chip_init()
1046 irq->default_type = IRQ_TYPE_NONE; in omap_gpio_chip_init()
1047 irq->num_parents = 1; in omap_gpio_chip_init()
1048 irq->parents = &bank->irq; in omap_gpio_chip_init()
1049 irq->first = irq_base; in omap_gpio_chip_init()
1051 ret = gpiochip_add_data(&bank->chip, bank); in omap_gpio_chip_init()
1053 dev_err(bank->chip.parent, in omap_gpio_chip_init()
1058 ret = devm_request_irq(bank->chip.parent, bank->irq, in omap_gpio_chip_init()
1060 0, dev_name(bank->chip.parent), bank); in omap_gpio_chip_init()
1062 gpiochip_remove(&bank->chip); in omap_gpio_chip_init()
1064 if (!bank->is_mpuio) in omap_gpio_chip_init()
1065 gpio += bank->width; in omap_gpio_chip_init()
1072 const struct omap_gpio_reg_offs *regs = p->regs; in omap_gpio_init_context()
1073 void __iomem *base = p->base; in omap_gpio_init_context()
1075 p->context.ctrl = readl_relaxed(base + regs->ctrl); in omap_gpio_init_context()
1076 p->context.oe = readl_relaxed(base + regs->direction); in omap_gpio_init_context()
1077 p->context.wake_en = readl_relaxed(base + regs->wkup_en); in omap_gpio_init_context()
1078 p->context.leveldetect0 = readl_relaxed(base + regs->leveldetect0); in omap_gpio_init_context()
1079 p->context.leveldetect1 = readl_relaxed(base + regs->leveldetect1); in omap_gpio_init_context()
1080 p->context.risingdetect = readl_relaxed(base + regs->risingdetect); in omap_gpio_init_context()
1081 p->context.fallingdetect = readl_relaxed(base + regs->fallingdetect); in omap_gpio_init_context()
1082 p->context.irqenable1 = readl_relaxed(base + regs->irqenable); in omap_gpio_init_context()
1083 p->context.irqenable2 = readl_relaxed(base + regs->irqenable2); in omap_gpio_init_context()
1084 p->context.dataout = readl_relaxed(base + regs->dataout); in omap_gpio_init_context()
1086 p->context_valid = true; in omap_gpio_init_context()
1089 static void omap_gpio_restore_context(struct gpio_bank *bank) in omap_gpio_restore_context() argument
1091 const struct omap_gpio_reg_offs *regs = bank->regs; in omap_gpio_restore_context()
1092 void __iomem *base = bank->base; in omap_gpio_restore_context()
1094 writel_relaxed(bank->context.wake_en, base + regs->wkup_en); in omap_gpio_restore_context()
1095 writel_relaxed(bank->context.ctrl, base + regs->ctrl); in omap_gpio_restore_context()
1096 writel_relaxed(bank->context.leveldetect0, base + regs->leveldetect0); in omap_gpio_restore_context()
1097 writel_relaxed(bank->context.leveldetect1, base + regs->leveldetect1); in omap_gpio_restore_context()
1098 writel_relaxed(bank->context.risingdetect, base + regs->risingdetect); in omap_gpio_restore_context()
1099 writel_relaxed(bank->context.fallingdetect, base + regs->fallingdetect); in omap_gpio_restore_context()
1100 writel_relaxed(bank->context.dataout, base + regs->dataout); in omap_gpio_restore_context()
1101 writel_relaxed(bank->context.oe, base + regs->direction); in omap_gpio_restore_context()
1103 if (bank->dbck_enable_mask) { in omap_gpio_restore_context()
1104 writel_relaxed(bank->context.debounce, base + regs->debounce); in omap_gpio_restore_context()
1105 writel_relaxed(bank->context.debounce_en, in omap_gpio_restore_context()
1106 base + regs->debounce_en); in omap_gpio_restore_context()
1109 writel_relaxed(bank->context.irqenable1, base + regs->irqenable); in omap_gpio_restore_context()
1110 writel_relaxed(bank->context.irqenable2, base + regs->irqenable2); in omap_gpio_restore_context()
1113 static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) in omap_gpio_idle() argument
1115 struct device *dev = bank->chip.parent; in omap_gpio_idle()
1116 void __iomem *base = bank->base; in omap_gpio_idle()
1119 bank->saved_datain = readl_relaxed(base + bank->regs->datain); in omap_gpio_idle()
1121 if (!bank->enabled_non_wakeup_gpios) in omap_gpio_idle()
1125 mask = bank->enabled_non_wakeup_gpios & bank->context.fallingdetect; in omap_gpio_idle()
1126 mask &= ~bank->context.risingdetect; in omap_gpio_idle()
1127 bank->saved_datain |= mask; in omap_gpio_idle()
1130 mask = bank->enabled_non_wakeup_gpios & bank->context.risingdetect; in omap_gpio_idle()
1131 mask &= ~bank->context.fallingdetect; in omap_gpio_idle()
1132 bank->saved_datain &= ~mask; in omap_gpio_idle()
1139 * non-wakeup GPIOs. Otherwise spurious IRQs will be in omap_gpio_idle()
1142 if (!bank->loses_context && bank->enabled_non_wakeup_gpios) { in omap_gpio_idle()
1143 nowake = bank->enabled_non_wakeup_gpios; in omap_gpio_idle()
1144 omap_gpio_rmw(base + bank->regs->fallingdetect, nowake, ~nowake); in omap_gpio_idle()
1145 omap_gpio_rmw(base + bank->regs->risingdetect, nowake, ~nowake); in omap_gpio_idle()
1149 if (bank->get_context_loss_count) in omap_gpio_idle()
1150 bank->context_loss_count = in omap_gpio_idle()
1151 bank->get_context_loss_count(dev); in omap_gpio_idle()
1153 omap_gpio_dbck_disable(bank); in omap_gpio_idle()
1156 static void omap_gpio_unidle(struct gpio_bank *bank) in omap_gpio_unidle() argument
1158 struct device *dev = bank->chip.parent; in omap_gpio_unidle()
1167 if (bank->loses_context && !bank->context_valid) { in omap_gpio_unidle()
1168 omap_gpio_init_context(bank); in omap_gpio_unidle()
1170 if (bank->get_context_loss_count) in omap_gpio_unidle()
1171 bank->context_loss_count = in omap_gpio_unidle()
1172 bank->get_context_loss_count(dev); in omap_gpio_unidle()
1175 omap_gpio_dbck_enable(bank); in omap_gpio_unidle()
1177 if (bank->loses_context) { in omap_gpio_unidle()
1178 if (!bank->get_context_loss_count) { in omap_gpio_unidle()
1179 omap_gpio_restore_context(bank); in omap_gpio_unidle()
1181 c = bank->get_context_loss_count(dev); in omap_gpio_unidle()
1182 if (c != bank->context_loss_count) { in omap_gpio_unidle()
1183 omap_gpio_restore_context(bank); in omap_gpio_unidle()
1190 writel_relaxed(bank->context.fallingdetect, in omap_gpio_unidle()
1191 bank->base + bank->regs->fallingdetect); in omap_gpio_unidle()
1192 writel_relaxed(bank->context.risingdetect, in omap_gpio_unidle()
1193 bank->base + bank->regs->risingdetect); in omap_gpio_unidle()
1196 l = readl_relaxed(bank->base + bank->regs->datain); in omap_gpio_unidle()
1199 * Check if any of the non-wakeup interrupt GPIOs have changed in omap_gpio_unidle()
1204 l ^= bank->saved_datain; in omap_gpio_unidle()
1205 l &= bank->enabled_non_wakeup_gpios; in omap_gpio_unidle()
1211 gen0 = l & bank->context.fallingdetect; in omap_gpio_unidle()
1212 gen0 &= bank->saved_datain; in omap_gpio_unidle()
1214 gen1 = l & bank->context.risingdetect; in omap_gpio_unidle()
1215 gen1 &= ~(bank->saved_datain); in omap_gpio_unidle()
1218 gen = l & (~(bank->context.fallingdetect) & in omap_gpio_unidle()
1219 ~(bank->context.risingdetect)); in omap_gpio_unidle()
1226 old0 = readl_relaxed(bank->base + bank->regs->leveldetect0); in omap_gpio_unidle()
1227 old1 = readl_relaxed(bank->base + bank->regs->leveldetect1); in omap_gpio_unidle()
1229 if (!bank->regs->irqstatus_raw0) { in omap_gpio_unidle()
1230 writel_relaxed(old0 | gen, bank->base + in omap_gpio_unidle()
1231 bank->regs->leveldetect0); in omap_gpio_unidle()
1232 writel_relaxed(old1 | gen, bank->base + in omap_gpio_unidle()
1233 bank->regs->leveldetect1); in omap_gpio_unidle()
1236 if (bank->regs->irqstatus_raw0) { in omap_gpio_unidle()
1237 writel_relaxed(old0 | l, bank->base + in omap_gpio_unidle()
1238 bank->regs->leveldetect0); in omap_gpio_unidle()
1239 writel_relaxed(old1 | l, bank->base + in omap_gpio_unidle()
1240 bank->regs->leveldetect1); in omap_gpio_unidle()
1242 writel_relaxed(old0, bank->base + bank->regs->leveldetect0); in omap_gpio_unidle()
1243 writel_relaxed(old1, bank->base + bank->regs->leveldetect1); in omap_gpio_unidle()
1250 struct gpio_bank *bank; in gpio_omap_cpu_notifier() local
1255 bank = container_of(nb, struct gpio_bank, nb); in gpio_omap_cpu_notifier()
1257 raw_spin_lock_irqsave(&bank->lock, flags); in gpio_omap_cpu_notifier()
1258 if (bank->is_suspended) in gpio_omap_cpu_notifier()
1263 mask = omap_get_gpio_irqbank_mask(bank); in gpio_omap_cpu_notifier()
1264 isr = readl_relaxed(bank->base + bank->regs->irqstatus) & mask; in gpio_omap_cpu_notifier()
1269 omap_gpio_idle(bank, true); in gpio_omap_cpu_notifier()
1273 omap_gpio_unidle(bank); in gpio_omap_cpu_notifier()
1278 raw_spin_unlock_irqrestore(&bank->lock, flags); in gpio_omap_cpu_notifier()
1351 .compatible = "ti,omap4-gpio",
1355 .compatible = "ti,omap3-gpio",
1359 .compatible = "ti,omap2-gpio",
1368 struct device *dev = &pdev->dev; in omap_gpio_probe()
1369 struct device_node *node = dev->of_node; in omap_gpio_probe()
1372 struct gpio_bank *bank; in omap_gpio_probe() local
1378 pdata = match ? match->data : dev_get_platdata(dev); in omap_gpio_probe()
1380 return -EINVAL; in omap_gpio_probe()
1382 bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL); in omap_gpio_probe()
1383 if (!bank) in omap_gpio_probe()
1384 return -ENOMEM; in omap_gpio_probe()
1388 return -ENOMEM; in omap_gpio_probe()
1390 irqc->irq_startup = omap_gpio_irq_startup, in omap_gpio_probe()
1391 irqc->irq_shutdown = omap_gpio_irq_shutdown, in omap_gpio_probe()
1392 irqc->irq_ack = dummy_irq_chip.irq_ack, in omap_gpio_probe()
1393 irqc->irq_mask = omap_gpio_mask_irq, in omap_gpio_probe()
1394 irqc->irq_unmask = omap_gpio_unmask_irq, in omap_gpio_probe()
1395 irqc->irq_set_type = omap_gpio_irq_type, in omap_gpio_probe()
1396 irqc->irq_set_wake = omap_gpio_wake_enable, in omap_gpio_probe()
1397 irqc->irq_bus_lock = omap_gpio_irq_bus_lock, in omap_gpio_probe()
1398 irqc->irq_bus_sync_unlock = gpio_irq_bus_sync_unlock, in omap_gpio_probe()
1399 irqc->name = dev_name(&pdev->dev); in omap_gpio_probe()
1400 irqc->flags = IRQCHIP_MASK_ON_SUSPEND; in omap_gpio_probe()
1401 irqc->parent_device = dev; in omap_gpio_probe()
1403 bank->irq = platform_get_irq(pdev, 0); in omap_gpio_probe()
1404 if (bank->irq <= 0) { in omap_gpio_probe()
1405 if (!bank->irq) in omap_gpio_probe()
1406 bank->irq = -ENXIO; in omap_gpio_probe()
1407 return dev_err_probe(dev, bank->irq, "can't get irq resource\n"); in omap_gpio_probe()
1410 bank->chip.parent = dev; in omap_gpio_probe()
1411 bank->chip.owner = THIS_MODULE; in omap_gpio_probe()
1412 bank->dbck_flag = pdata->dbck_flag; in omap_gpio_probe()
1413 bank->stride = pdata->bank_stride; in omap_gpio_probe()
1414 bank->width = pdata->bank_width; in omap_gpio_probe()
1415 bank->is_mpuio = pdata->is_mpuio; in omap_gpio_probe()
1416 bank->non_wakeup_gpios = pdata->non_wakeup_gpios; in omap_gpio_probe()
1417 bank->regs = pdata->regs; in omap_gpio_probe()
1419 bank->chip.of_node = of_node_get(node); in omap_gpio_probe()
1423 if (!of_property_read_bool(node, "ti,gpio-always-on")) in omap_gpio_probe()
1424 bank->loses_context = true; in omap_gpio_probe()
1426 bank->loses_context = pdata->loses_context; in omap_gpio_probe()
1428 if (bank->loses_context) in omap_gpio_probe()
1429 bank->get_context_loss_count = in omap_gpio_probe()
1430 pdata->get_context_loss_count; in omap_gpio_probe()
1433 if (bank->regs->set_dataout && bank->regs->clr_dataout) in omap_gpio_probe()
1434 bank->set_dataout = omap_set_gpio_dataout_reg; in omap_gpio_probe()
1436 bank->set_dataout = omap_set_gpio_dataout_mask; in omap_gpio_probe()
1438 raw_spin_lock_init(&bank->lock); in omap_gpio_probe()
1439 raw_spin_lock_init(&bank->wa_lock); in omap_gpio_probe()
1442 bank->base = devm_platform_ioremap_resource(pdev, 0); in omap_gpio_probe()
1443 if (IS_ERR(bank->base)) { in omap_gpio_probe()
1444 return PTR_ERR(bank->base); in omap_gpio_probe()
1447 if (bank->dbck_flag) { in omap_gpio_probe()
1448 bank->dbck = devm_clk_get(dev, "dbclk"); in omap_gpio_probe()
1449 if (IS_ERR(bank->dbck)) { in omap_gpio_probe()
1452 bank->dbck_flag = false; in omap_gpio_probe()
1454 clk_prepare(bank->dbck); in omap_gpio_probe()
1458 platform_set_drvdata(pdev, bank); in omap_gpio_probe()
1463 if (bank->is_mpuio) in omap_gpio_probe()
1464 omap_mpuio_init(bank); in omap_gpio_probe()
1466 omap_gpio_mod_init(bank); in omap_gpio_probe()
1468 ret = omap_gpio_chip_init(bank, irqc); in omap_gpio_probe()
1472 if (bank->dbck_flag) in omap_gpio_probe()
1473 clk_unprepare(bank->dbck); in omap_gpio_probe()
1477 omap_gpio_show_rev(bank); in omap_gpio_probe()
1479 bank->nb.notifier_call = gpio_omap_cpu_notifier; in omap_gpio_probe()
1480 cpu_pm_register_notifier(&bank->nb); in omap_gpio_probe()
1489 struct gpio_bank *bank = platform_get_drvdata(pdev); in omap_gpio_remove() local
1491 cpu_pm_unregister_notifier(&bank->nb); in omap_gpio_remove()
1492 gpiochip_remove(&bank->chip); in omap_gpio_remove()
1493 pm_runtime_disable(&pdev->dev); in omap_gpio_remove()
1494 if (bank->dbck_flag) in omap_gpio_remove()
1495 clk_unprepare(bank->dbck); in omap_gpio_remove()
1502 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_gpio_runtime_suspend() local
1505 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_runtime_suspend()
1506 omap_gpio_idle(bank, true); in omap_gpio_runtime_suspend()
1507 bank->is_suspended = true; in omap_gpio_runtime_suspend()
1508 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_runtime_suspend()
1515 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_gpio_runtime_resume() local
1518 raw_spin_lock_irqsave(&bank->lock, flags); in omap_gpio_runtime_resume()
1519 omap_gpio_unidle(bank); in omap_gpio_runtime_resume()
1520 bank->is_suspended = false; in omap_gpio_runtime_resume()
1521 raw_spin_unlock_irqrestore(&bank->lock, flags); in omap_gpio_runtime_resume()
1528 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_gpio_suspend() local
1530 if (bank->is_suspended) in omap_gpio_suspend()
1533 bank->needs_resume = 1; in omap_gpio_suspend()
1540 struct gpio_bank *bank = dev_get_drvdata(dev); in omap_gpio_resume() local
1542 if (!bank->needs_resume) in omap_gpio_resume()
1545 bank->needs_resume = 0; in omap_gpio_resume()
1584 MODULE_ALIAS("platform:gpio-omap");