14e6670feSJoseph Chen /* 24e6670feSJoseph Chen * (C) Copyright 2017 Rockchip Electronics Co., Ltd 34e6670feSJoseph Chen * 44e6670feSJoseph Chen * SPDX-License-Identifier: GPL-2.0+ 54e6670feSJoseph Chen */ 64e6670feSJoseph Chen 74e6670feSJoseph Chen #ifndef _IRQ_GENERIC_H 84e6670feSJoseph Chen #define _IRQ_GENERIC_H 94e6670feSJoseph Chen 104e6670feSJoseph Chen #include <asm-generic/gpio.h> 114e6670feSJoseph Chen #include <common.h> 124e6670feSJoseph Chen #include <dt-bindings/pinctrl/rockchip.h> 134e6670feSJoseph Chen 14269512fdSJoseph Chen #define IRQ_I(fmt, args...) printf("IRQ: "fmt, ##args) 15269512fdSJoseph Chen #define IRQ_W(fmt, args...) printf("IRQ Warn: "fmt, ##args) 16269512fdSJoseph Chen #define IRQ_E(fmt, args...) printf("IRQ Err: "fmt, ##args) 17269512fdSJoseph Chen #define IRQ_D(fmt, args...) debug("IRQ Debug "fmt, ##args) 18269512fdSJoseph Chen 194e6670feSJoseph Chen /* 204e6670feSJoseph Chen * IRQ line status. 214e6670feSJoseph Chen * 224e6670feSJoseph Chen * IRQ_TYPE_NONE - default, unspecified type 234e6670feSJoseph Chen * IRQ_TYPE_EDGE_RISING - rising edge triggered 244e6670feSJoseph Chen * IRQ_TYPE_EDGE_FALLING - falling edge triggered 254e6670feSJoseph Chen * IRQ_TYPE_EDGE_BOTH - rising and falling edge triggered 264e6670feSJoseph Chen * IRQ_TYPE_LEVEL_HIGH - high level triggered 274e6670feSJoseph Chen * IRQ_TYPE_LEVEL_LOW - low level triggered 284e6670feSJoseph Chen * IRQ_TYPE_LEVEL_MASK - mask to filter out the level bits 294e6670feSJoseph Chen * IRQ_TYPE_SENSE_MASK - mask for all the above bits 304e6670feSJoseph Chen */ 314e6670feSJoseph Chen enum { 324e6670feSJoseph Chen IRQ_TYPE_NONE = 0x00000000, 334e6670feSJoseph Chen IRQ_TYPE_EDGE_RISING = 0x00000001, 344e6670feSJoseph Chen IRQ_TYPE_EDGE_FALLING = 0x00000002, 354e6670feSJoseph Chen IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING), 364e6670feSJoseph Chen IRQ_TYPE_LEVEL_HIGH = 0x00000004, 374e6670feSJoseph Chen IRQ_TYPE_LEVEL_LOW = 0x00000008, 384e6670feSJoseph Chen IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), 394e6670feSJoseph Chen IRQ_TYPE_SENSE_MASK = 0x0000000f, 404e6670feSJoseph Chen }; 414e6670feSJoseph Chen 424e6670feSJoseph Chen /* 434e6670feSJoseph Chen * struct irq_chip - hardware interrupt chip descriptor 444e6670feSJoseph Chen * 454e6670feSJoseph Chen * @name: name for irq chip 464e6670feSJoseph Chen * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) 474e6670feSJoseph Chen * @irq_disable: disable the interrupt 484e6670feSJoseph Chen * @irq_ack: start of a new interrupt 494e6670feSJoseph Chen * @irq_eoi: end of interrupt 504e6670feSJoseph Chen * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ 514e6670feSJoseph Chen */ 524e6670feSJoseph Chen struct irq_chip { 534e6670feSJoseph Chen const char *name; 544e6670feSJoseph Chen int (*irq_init)(void); 55ed837edfSJoseph Chen int (*irq_suspend)(void); 56ed837edfSJoseph Chen int (*irq_resume)(void); 574e6670feSJoseph Chen int (*irq_get)(void); 584e6670feSJoseph Chen int (*irq_enable)(int irq); 594e6670feSJoseph Chen int (*irq_disable)(int irq); 604e6670feSJoseph Chen void (*irq_ack)(int irq); 614e6670feSJoseph Chen void (*irq_eoi)(int irq); 624e6670feSJoseph Chen int (*irq_set_type)(int irq, unsigned int flow_type); 63c234b81eSJoseph Chen int (*irq_revert_type)(int irq); 64c234b81eSJoseph Chen int (*irq_get_gpio_level)(int irq); 654e6670feSJoseph Chen }; 664e6670feSJoseph Chen 67*41766119SJoseph Chen /* 68*41766119SJoseph Chen * Virtual irq chip structure 69*41766119SJoseph Chen */ 70*41766119SJoseph Chen typedef int(virq_i2c_write_t)(struct udevice *dev, uint reg, uint value); 71*41766119SJoseph Chen typedef int(virq_i2c_read_t)(struct udevice *dev, uint reg); 72*41766119SJoseph Chen 73*41766119SJoseph Chen struct virq_reg { 74*41766119SJoseph Chen uint reg_offset; 75*41766119SJoseph Chen uint mask; 76*41766119SJoseph Chen }; 77*41766119SJoseph Chen 78*41766119SJoseph Chen struct virq_chip { 79*41766119SJoseph Chen uint status_base; 80*41766119SJoseph Chen uint mask_base; 81*41766119SJoseph Chen uint irq_reg_stride; 82*41766119SJoseph Chen uint irq_unalign_reg_idx; 83*41766119SJoseph Chen uint irq_unalign_reg_stride; 84*41766119SJoseph Chen int num_regs; 85*41766119SJoseph Chen const struct virq_reg *irqs; 86*41766119SJoseph Chen int num_irqs; 87*41766119SJoseph Chen virq_i2c_read_t *i2c_read; 88*41766119SJoseph Chen virq_i2c_write_t *i2c_write; 89*41766119SJoseph Chen }; 90*41766119SJoseph Chen 914e6670feSJoseph Chen /* APIs for irqs */ 924e6670feSJoseph Chen void irq_install_handler(int irq, interrupt_handler_t *handler, void *data); 934e6670feSJoseph Chen void irq_free_handler(int irq); 944e6670feSJoseph Chen int irq_set_irq_type(int irq, unsigned int type); 95c234b81eSJoseph Chen int irq_revert_irq_type(int irq); 964e6670feSJoseph Chen int irq_handler_enable(int irq); 974e6670feSJoseph Chen int irq_handler_disable(int irq); 98c234b81eSJoseph Chen int irq_get_gpio_level(int irq); 99ed837edfSJoseph Chen int irqs_suspend(void); 100ed837edfSJoseph Chen int irqs_resume(void); 1018696cc38SJoseph Chen int irq_is_busy(int irq); 1024e6670feSJoseph Chen int gpio_to_irq(struct gpio_desc *gpio); 1034e6670feSJoseph Chen 1044e6670feSJoseph Chen /* 1054e6670feSJoseph Chen * Assign gpio to irq directly. Don't use it without special reasons. 1064e6670feSJoseph Chen * 1074e6670feSJoseph Chen * Usage example: 1084e6670feSJoseph Chen * int gpio0_a0, irq; 1094e6670feSJoseph Chen * 1104e6670feSJoseph Chen * gpio = RK_IRQ_GPIO(RK_GPIO0, RK_PA0); 1114e6670feSJoseph Chen * irq = hard_gpio_to_irq(gpio0_a0); 1124e6670feSJoseph Chen * irq_install_handler(irq, ...); 1134e6670feSJoseph Chen */ 1144e6670feSJoseph Chen #define GPIO_BANK_SHIFT 8 1154e6670feSJoseph Chen #define RK_IRQ_GPIO(bank, pin) (((bank) << GPIO_BANK_SHIFT) | (pin)) 116269512fdSJoseph Chen 1174e6670feSJoseph Chen int hard_gpio_to_irq(unsigned gpio); 1185db1153eSJoseph Chen int phandle_gpio_to_irq(u32 gpio_phandle, u32 pin); 1194e6670feSJoseph Chen 120*41766119SJoseph Chen /* Virtual irq */ 121*41766119SJoseph Chen int virq_to_irq(struct virq_chip *chip, int virq); 122*41766119SJoseph Chen int virq_add_chip(struct udevice *dev, struct virq_chip *chip, 123*41766119SJoseph Chen int irq, int enable); 124*41766119SJoseph Chen 1254e6670feSJoseph Chen #endif /* _IRQ_GENERIC_H */ 126