1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef _IRQ_GENERIC_H 8*4882a593Smuzhiyun #define _IRQ_GENERIC_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <asm-generic/gpio.h> 11*4882a593Smuzhiyun #include <common.h> 12*4882a593Smuzhiyun #include <dt-bindings/pinctrl/rockchip.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define IRQ_I(fmt, args...) printf("IRQ: "fmt, ##args) 15*4882a593Smuzhiyun #define IRQ_W(fmt, args...) printf("IRQ Warn: "fmt, ##args) 16*4882a593Smuzhiyun #define IRQ_E(fmt, args...) printf("IRQ Err: "fmt, ##args) 17*4882a593Smuzhiyun #define IRQ_D(fmt, args...) debug("IRQ Debug "fmt, ##args) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* 20*4882a593Smuzhiyun * IRQ line status. 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun * IRQ_TYPE_NONE - default, unspecified type 23*4882a593Smuzhiyun * IRQ_TYPE_EDGE_RISING - rising edge triggered 24*4882a593Smuzhiyun * IRQ_TYPE_EDGE_FALLING - falling edge triggered 25*4882a593Smuzhiyun * IRQ_TYPE_EDGE_BOTH - rising and falling edge triggered 26*4882a593Smuzhiyun * IRQ_TYPE_LEVEL_HIGH - high level triggered 27*4882a593Smuzhiyun * IRQ_TYPE_LEVEL_LOW - low level triggered 28*4882a593Smuzhiyun * IRQ_TYPE_LEVEL_MASK - mask to filter out the level bits 29*4882a593Smuzhiyun * IRQ_TYPE_SENSE_MASK - mask for all the above bits 30*4882a593Smuzhiyun */ 31*4882a593Smuzhiyun enum { 32*4882a593Smuzhiyun IRQ_TYPE_NONE = 0x00000000, 33*4882a593Smuzhiyun IRQ_TYPE_EDGE_RISING = 0x00000001, 34*4882a593Smuzhiyun IRQ_TYPE_EDGE_FALLING = 0x00000002, 35*4882a593Smuzhiyun IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING), 36*4882a593Smuzhiyun IRQ_TYPE_LEVEL_HIGH = 0x00000004, 37*4882a593Smuzhiyun IRQ_TYPE_LEVEL_LOW = 0x00000008, 38*4882a593Smuzhiyun IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), 39*4882a593Smuzhiyun IRQ_TYPE_SENSE_MASK = 0x0000000f, 40*4882a593Smuzhiyun }; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* 43*4882a593Smuzhiyun * struct irq_chip - hardware interrupt chip descriptor 44*4882a593Smuzhiyun * 45*4882a593Smuzhiyun * @name: name for irq chip 46*4882a593Smuzhiyun * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) 47*4882a593Smuzhiyun * @irq_disable: disable the interrupt 48*4882a593Smuzhiyun * @irq_ack: start of a new interrupt 49*4882a593Smuzhiyun * @irq_eoi: end of interrupt 50*4882a593Smuzhiyun * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ 51*4882a593Smuzhiyun */ 52*4882a593Smuzhiyun struct irq_chip { 53*4882a593Smuzhiyun const char *name; 54*4882a593Smuzhiyun int (*irq_init)(void); 55*4882a593Smuzhiyun int (*irq_suspend)(void); 56*4882a593Smuzhiyun int (*irq_resume)(void); 57*4882a593Smuzhiyun int (*irq_get)(void); 58*4882a593Smuzhiyun int (*irq_enable)(int irq); 59*4882a593Smuzhiyun int (*irq_disable)(int irq); 60*4882a593Smuzhiyun void (*irq_ack)(int irq); 61*4882a593Smuzhiyun void (*irq_eoi)(int irq); 62*4882a593Smuzhiyun int (*irq_set_type)(int irq, unsigned int flow_type); 63*4882a593Smuzhiyun int (*irq_revert_type)(int irq); 64*4882a593Smuzhiyun int (*irq_get_gpio_level)(int irq); 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* 68*4882a593Smuzhiyun * Virtual irq chip structure 69*4882a593Smuzhiyun */ 70*4882a593Smuzhiyun typedef int(virq_write_t)(struct udevice *dev, uint reg, uint value); 71*4882a593Smuzhiyun typedef int(virq_read_t)(struct udevice *dev, uint reg); 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun struct virq_reg { 74*4882a593Smuzhiyun uint reg_offset; 75*4882a593Smuzhiyun uint mask; 76*4882a593Smuzhiyun }; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun struct virq_chip { 79*4882a593Smuzhiyun uint status_base; 80*4882a593Smuzhiyun uint mask_base; 81*4882a593Smuzhiyun uint irq_reg_stride; 82*4882a593Smuzhiyun uint irq_unalign_reg_idx; 83*4882a593Smuzhiyun uint irq_unalign_reg_stride; 84*4882a593Smuzhiyun int num_regs; 85*4882a593Smuzhiyun const struct virq_reg *irqs; 86*4882a593Smuzhiyun int num_irqs; 87*4882a593Smuzhiyun virq_read_t *read; 88*4882a593Smuzhiyun virq_write_t *write; 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /* APIs for irqs */ 92*4882a593Smuzhiyun void irq_install_handler(int irq, interrupt_handler_t *handler, void *data); 93*4882a593Smuzhiyun void irq_free_handler(int irq); 94*4882a593Smuzhiyun int irq_set_irq_type(int irq, unsigned int type); 95*4882a593Smuzhiyun int irq_revert_irq_type(int irq); 96*4882a593Smuzhiyun int irq_handler_enable(int irq); 97*4882a593Smuzhiyun int irq_handler_enable_suspend_only(int irq); 98*4882a593Smuzhiyun int irq_handler_disable(int irq); 99*4882a593Smuzhiyun int irq_get_gpio_level(int irq); 100*4882a593Smuzhiyun int irqs_suspend(void); 101*4882a593Smuzhiyun int irqs_resume(void); 102*4882a593Smuzhiyun int irq_is_busy(int irq); 103*4882a593Smuzhiyun int gpio_to_irq(struct gpio_desc *gpio); 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /* 106*4882a593Smuzhiyun * Assign gpio to irq directly. Don't use it without special reasons. 107*4882a593Smuzhiyun * 108*4882a593Smuzhiyun * Usage example: 109*4882a593Smuzhiyun * int gpio0_a0, irq; 110*4882a593Smuzhiyun * 111*4882a593Smuzhiyun * gpio = RK_IRQ_GPIO(RK_GPIO0, RK_PA0); 112*4882a593Smuzhiyun * irq = hard_gpio_to_irq(gpio0_a0); 113*4882a593Smuzhiyun * irq_install_handler(irq, ...); 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun #define GPIO_BANK_SHIFT 8 116*4882a593Smuzhiyun #define RK_IRQ_GPIO(bank, pin) (((bank) << GPIO_BANK_SHIFT) | (pin)) 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun int hard_gpio_to_irq(unsigned gpio); 119*4882a593Smuzhiyun int phandle_gpio_to_irq(u32 gpio_phandle, u32 pin); 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun /* Virtual irq */ 122*4882a593Smuzhiyun int virq_to_irq(struct virq_chip *chip, int virq); 123*4882a593Smuzhiyun int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq); 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun #endif /* _IRQ_GENERIC_H */ 126