Lines Matching +full:eint +full:- +full:c

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2014-2025 MediaTek Inc.
24 #include "mtk-eint.h"
74 static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint, in mtk_eint_get_offset() argument
78 unsigned int idx = eint->pins[eint_num].index; in mtk_eint_get_offset()
79 unsigned int inst = eint->pins[eint_num].instance; in mtk_eint_get_offset()
82 reg = eint->base[inst] + offset + (idx / 32 * 4); in mtk_eint_get_offset()
87 static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint, in mtk_eint_can_en_debounce() argument
91 unsigned int bit = BIT(eint->pins[eint_num].index % 32); in mtk_eint_can_en_debounce()
92 void __iomem *reg = mtk_eint_get_offset(eint, eint_num, in mtk_eint_can_en_debounce()
93 eint->regs->sens); in mtk_eint_can_en_debounce()
100 if (eint->pins[eint_num].debounce && sens != MTK_EINT_EDGE_SENSITIVE) in mtk_eint_can_en_debounce()
106 static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq) in mtk_eint_flip_edge() argument
110 unsigned int mask = BIT(eint->pins[hwirq].index & 0x1f); in mtk_eint_flip_edge()
111 unsigned int port = (eint->pins[hwirq].index >> 5) & eint->hw->port_mask; in mtk_eint_flip_edge()
112 void __iomem *reg = eint->base[eint->pins[hwirq].instance] + (port << 2); in mtk_eint_flip_edge()
114 curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq); in mtk_eint_flip_edge()
119 reg_offset = eint->regs->pol_clr; in mtk_eint_flip_edge()
121 reg_offset = eint->regs->pol_set; in mtk_eint_flip_edge()
124 curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, in mtk_eint_flip_edge()
133 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_mask() local
134 unsigned int idx = eint->pins[d->hwirq].index; in mtk_eint_mask()
135 unsigned int inst = eint->pins[d->hwirq].instance; in mtk_eint_mask()
137 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq, in mtk_eint_mask()
138 eint->regs->mask_set); in mtk_eint_mask()
140 eint->cur_mask[inst][idx >> 5] &= ~mask; in mtk_eint_mask()
147 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_unmask() local
148 unsigned int idx = eint->pins[d->hwirq].index; in mtk_eint_unmask()
149 unsigned int inst = eint->pins[d->hwirq].instance; in mtk_eint_unmask()
151 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq, in mtk_eint_unmask()
152 eint->regs->mask_clr); in mtk_eint_unmask()
154 eint->cur_mask[inst][idx >> 5] |= mask; in mtk_eint_unmask()
158 if (eint->pins[d->hwirq].dual_edge) in mtk_eint_unmask()
159 mtk_eint_flip_edge(eint, d->hwirq); in mtk_eint_unmask()
162 static unsigned int mtk_eint_get_mask(struct mtk_eint *eint, in mtk_eint_get_mask() argument
165 unsigned int bit = BIT(eint->pins[eint_num].index % 32); in mtk_eint_get_mask()
166 void __iomem *reg = mtk_eint_get_offset(eint, eint_num, in mtk_eint_get_mask()
167 eint->regs->mask); in mtk_eint_get_mask()
174 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_ack() local
175 unsigned int mask = BIT(eint->pins[d->hwirq].index & 0x1f); in mtk_eint_ack()
176 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq, in mtk_eint_ack()
177 eint->regs->ack); in mtk_eint_ack()
184 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_set_type() local
186 unsigned int mask = BIT(eint->pins[d->hwirq].index & 0x1f); in mtk_eint_set_type()
191 dev_err(eint->dev, in mtk_eint_set_type()
192 "Can't configure IRQ%d (EINT%lu) for type 0x%X\n", in mtk_eint_set_type()
193 d->irq, d->hwirq, type); in mtk_eint_set_type()
194 return -EINVAL; in mtk_eint_set_type()
198 eint->pins[d->hwirq].dual_edge = 1; in mtk_eint_set_type()
200 eint->pins[d->hwirq].dual_edge = 0; in mtk_eint_set_type()
202 if (!mtk_eint_get_mask(eint, d->hwirq)) { in mtk_eint_set_type()
210 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr); in mtk_eint_set_type()
213 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set); in mtk_eint_set_type()
218 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr); in mtk_eint_set_type()
221 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set); in mtk_eint_set_type()
234 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_irq_set_wake() local
235 unsigned int idx = eint->pins[d->hwirq].index; in mtk_eint_irq_set_wake()
236 unsigned int inst = eint->pins[d->hwirq].instance; in mtk_eint_irq_set_wake()
241 eint->wake_mask[inst][port] |= BIT(shift); in mtk_eint_irq_set_wake()
243 eint->wake_mask[inst][port] &= ~BIT(shift); in mtk_eint_irq_set_wake()
248 static void mtk_eint_chip_write_mask(const struct mtk_eint *eint, in mtk_eint_chip_write_mask() argument
254 for (inst = 0; inst < eint->nbase; inst++) { in mtk_eint_chip_write_mask()
255 port_num = DIV_ROUND_UP(eint->base_pin_num[inst], 32); in mtk_eint_chip_write_mask()
257 reg = eint->base[inst] + (port << 2); in mtk_eint_chip_write_mask()
258 writel_relaxed(~buf[inst][port], reg + eint->regs->mask_set); in mtk_eint_chip_write_mask()
259 writel_relaxed(buf[inst][port], reg + eint->regs->mask_clr); in mtk_eint_chip_write_mask()
266 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_irq_request_resources() local
271 err = eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq, in mtk_eint_irq_request_resources()
274 dev_err(eint->dev, "Can not find pin\n"); in mtk_eint_irq_request_resources()
280 dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n", in mtk_eint_irq_request_resources()
285 err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq); in mtk_eint_irq_request_resources()
287 dev_err(eint->dev, "Can not eint mode\n"); in mtk_eint_irq_request_resources()
296 struct mtk_eint *eint = irq_data_get_irq_chip_data(d); in mtk_eint_irq_release_resources() local
300 eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq, &gpio_n, in mtk_eint_irq_release_resources()
307 .name = "mt-eint",
318 static unsigned int mtk_eint_hw_init(struct mtk_eint *eint) in mtk_eint_hw_init() argument
323 for (i = 0; i < eint->nbase; i++) { in mtk_eint_hw_init()
324 dom_reg = eint->base[i] + eint->regs->dom_en; in mtk_eint_hw_init()
325 mask_reg = eint->base[i] + eint->regs->mask_set; in mtk_eint_hw_init()
326 for (j = 0; j < eint->base_pin_num[i]; j += 32) { in mtk_eint_hw_init()
338 mtk_eint_debounce_process(struct mtk_eint *eint, int index) in mtk_eint_debounce_process() argument
342 unsigned int inst = eint->pins[index].instance; in mtk_eint_debounce_process()
343 unsigned int idx = eint->pins[index].index; in mtk_eint_debounce_process()
345 ctrl_offset = (idx / 4) * 4 + eint->regs->dbnc_ctrl; in mtk_eint_debounce_process()
346 dbnc = readl(eint->base[inst] + ctrl_offset); in mtk_eint_debounce_process()
349 ctrl_offset = (idx / 4) * 4 + eint->regs->dbnc_set; in mtk_eint_debounce_process()
351 writel(rst, eint->base[inst] + ctrl_offset); in mtk_eint_debounce_process()
358 struct mtk_eint *eint = irq_desc_get_handler_data(desc); in mtk_eint_irq_handler() local
364 for (i = 0; i < eint->nbase; i++) { in mtk_eint_irq_handler()
365 for (j = 0; j < eint->base_pin_num[i]; j += 32) { in mtk_eint_irq_handler()
367 status = readl(eint->base[i] + port * 4 + eint->regs->stat); in mtk_eint_irq_handler()
372 eint_num = eint->pin_list[i][shift + j]; in mtk_eint_irq_handler()
380 if (eint->wake_mask[i][port] & mask && in mtk_eint_irq_handler()
381 !(eint->cur_mask[i][port] & mask)) { in mtk_eint_irq_handler()
382 reg = mtk_eint_get_offset(eint, eint_num, in mtk_eint_irq_handler()
383 eint->regs->mask_set); in mtk_eint_irq_handler()
387 dual_edge = eint->pins[eint_num].dual_edge; in mtk_eint_irq_handler()
390 * Clear soft-irq in case we raised it last in mtk_eint_irq_handler()
393 reg = mtk_eint_get_offset(eint, eint_num, in mtk_eint_irq_handler()
394 eint->regs->soft_clr); in mtk_eint_irq_handler()
398 eint->gpio_xlate->get_gpio_state(eint->pctl, in mtk_eint_irq_handler()
402 generic_handle_domain_irq(eint->domain, eint_num); in mtk_eint_irq_handler()
405 curr_level = mtk_eint_flip_edge(eint, eint_num); in mtk_eint_irq_handler()
409 * interrupt, raised it through soft-irq. in mtk_eint_irq_handler()
412 reg = mtk_eint_get_offset(eint, eint_num, in mtk_eint_irq_handler()
413 eint->regs->soft_set); in mtk_eint_irq_handler()
418 if (eint->pins[eint_num].debounce) in mtk_eint_irq_handler()
419 mtk_eint_debounce_process(eint, eint_num); in mtk_eint_irq_handler()
426 int mtk_eint_do_suspend(struct mtk_eint *eint) in mtk_eint_do_suspend() argument
428 mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask); in mtk_eint_do_suspend()
434 int mtk_eint_do_resume(struct mtk_eint *eint) in mtk_eint_do_resume() argument
436 mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask); in mtk_eint_do_resume()
442 int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num, in mtk_eint_set_debounce() argument
448 unsigned int inst = eint->pins[eint_num].instance; in mtk_eint_set_debounce()
449 unsigned int idx = eint->pins[eint_num].index; in mtk_eint_set_debounce()
452 if (!eint->hw->db_time) in mtk_eint_set_debounce()
453 return -EOPNOTSUPP; in mtk_eint_set_debounce()
455 virq = irq_find_mapping(eint->domain, eint_num); in mtk_eint_set_debounce()
459 set_offset = (idx / 4) * 4 + eint->regs->dbnc_set; in mtk_eint_set_debounce()
460 clr_offset = (idx / 4) * 4 + eint->regs->dbnc_clr; in mtk_eint_set_debounce()
462 if (!mtk_eint_can_en_debounce(eint, eint_num)) in mtk_eint_set_debounce()
463 return -EINVAL; in mtk_eint_set_debounce()
465 dbnc = eint->num_db_time; in mtk_eint_set_debounce()
466 for (i = 0; i < eint->num_db_time; i++) { in mtk_eint_set_debounce()
467 if (debounce <= eint->hw->db_time[i]) { in mtk_eint_set_debounce()
473 if (!mtk_eint_get_mask(eint, eint_num)) { in mtk_eint_set_debounce()
481 writel(clr_bit, eint->base[inst] + clr_offset); in mtk_eint_set_debounce()
486 writel(rst | bit, eint->base[inst] + set_offset); in mtk_eint_set_debounce()
500 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n) in mtk_eint_find_irq() argument
504 irq = irq_find_mapping(eint->domain, eint_n); in mtk_eint_find_irq()
506 return -EINVAL; in mtk_eint_find_irq()
512 int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin) in mtk_eint_do_init() argument
517 if (!eint->regs) in mtk_eint_do_init()
518 eint->regs = &mtk_generic_eint_regs; in mtk_eint_do_init()
520 eint->base_pin_num = devm_kmalloc_array(eint->dev, eint->nbase, sizeof(u16), in mtk_eint_do_init()
522 if (!eint->base_pin_num) in mtk_eint_do_init()
523 return -ENOMEM; in mtk_eint_do_init()
526 eint->pins = eint_pin; in mtk_eint_do_init()
527 for (i = 0; i < eint->hw->ap_num; i++) { in mtk_eint_do_init()
528 inst = eint->pins[i].instance; in mtk_eint_do_init()
529 if (inst >= eint->nbase) in mtk_eint_do_init()
531 eint->base_pin_num[inst]++; in mtk_eint_do_init()
534 size = eint->hw->ap_num * sizeof(struct mtk_eint_pin); in mtk_eint_do_init()
535 eint->pins = devm_kmalloc(eint->dev, size, GFP_KERNEL); in mtk_eint_do_init()
536 if (!eint->pins) in mtk_eint_do_init()
539 eint->base_pin_num[inst] = eint->hw->ap_num; in mtk_eint_do_init()
540 for (i = 0; i < eint->hw->ap_num; i++) { in mtk_eint_do_init()
541 eint->pins[i].instance = inst; in mtk_eint_do_init()
542 eint->pins[i].index = i; in mtk_eint_do_init()
543 eint->pins[i].debounce = (i < eint->hw->db_cnt) ? 1 : 0; in mtk_eint_do_init()
547 eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL); in mtk_eint_do_init()
548 if (!eint->pin_list) in mtk_eint_do_init()
551 eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL); in mtk_eint_do_init()
552 if (!eint->wake_mask) in mtk_eint_do_init()
555 eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL); in mtk_eint_do_init()
556 if (!eint->cur_mask) in mtk_eint_do_init()
559 for (i = 0; i < eint->nbase; i++) { in mtk_eint_do_init()
560 eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16), in mtk_eint_do_init()
562 port = DIV_ROUND_UP(eint->base_pin_num[i], 32); in mtk_eint_do_init()
563 eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL); in mtk_eint_do_init()
564 eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL); in mtk_eint_do_init()
565 if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i]) in mtk_eint_do_init()
569 eint->domain = irq_domain_create_linear(dev_fwnode(eint->dev), eint->hw->ap_num, in mtk_eint_do_init()
571 if (!eint->domain) in mtk_eint_do_init()
574 if (eint->hw->db_time) { in mtk_eint_do_init()
576 if (eint->hw->db_time[i] == 0) in mtk_eint_do_init()
578 eint->num_db_time = i; in mtk_eint_do_init()
581 mtk_eint_hw_init(eint); in mtk_eint_do_init()
582 for (i = 0; i < eint->hw->ap_num; i++) { in mtk_eint_do_init()
583 inst = eint->pins[i].instance; in mtk_eint_do_init()
584 if (inst >= eint->nbase) in mtk_eint_do_init()
586 eint->pin_list[inst][eint->pins[i].index] = i; in mtk_eint_do_init()
587 virq = irq_create_mapping(eint->domain, i); in mtk_eint_do_init()
590 irq_set_chip_data(virq, eint); in mtk_eint_do_init()
593 irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler, in mtk_eint_do_init()
594 eint); in mtk_eint_do_init()
599 for (i = 0; i < eint->nbase; i++) { in mtk_eint_do_init()
600 if (eint->cur_mask[i]) in mtk_eint_do_init()
601 devm_kfree(eint->dev, eint->cur_mask[i]); in mtk_eint_do_init()
602 if (eint->wake_mask[i]) in mtk_eint_do_init()
603 devm_kfree(eint->dev, eint->wake_mask[i]); in mtk_eint_do_init()
604 if (eint->pin_list[i]) in mtk_eint_do_init()
605 devm_kfree(eint->dev, eint->pin_list[i]); in mtk_eint_do_init()
607 devm_kfree(eint->dev, eint->cur_mask); in mtk_eint_do_init()
609 devm_kfree(eint->dev, eint->wake_mask); in mtk_eint_do_init()
611 devm_kfree(eint->dev, eint->pin_list); in mtk_eint_do_init()
614 devm_kfree(eint->dev, eint->pins); in mtk_eint_do_init()
616 devm_kfree(eint->dev, eint->base_pin_num); in mtk_eint_do_init()
617 return -ENOMEM; in mtk_eint_do_init()
622 MODULE_DESCRIPTION("MediaTek EINT Driver");