Pull irqchip updates from Marc Zyngier: - API updates: - Treewide conversion to generic_handle_domain_irq() for anything that looks like a chained interrupt controller - Update the irqdomain documentation - Use of bitmap_zalloc() throughout the tree - New functionalities: - Support for GICv3 EPPI partitions - Fixes: - Qualcomm PDC hierarchy fixes - Yet another priority decoding fix for the GICv3 pseudo-NMIs - Fix the apple-aic driver irq_eoi() callback to always unmask the interrupt - Properly handle edge interrupts on loongson-pch-pic - Let the mtk-sysirq driver advertise IRQCHIP_SKIP_SET_WAKE
Unified · Split
| @@ -55,8 +55,24 @@ exist then it will allocate a new Linux irq_desc, associate it with · 54 unmodified lines | ||
| 55 | 55 | the hwirq, and call the .map() callback so the driver can perform any |
| 56 | 56 | required hardware setup. |
| 57 | 57 | |
| 58 | −When an interrupt is received, irq_find_mapping() function should | |
| 59 | −be used to find the Linux IRQ number from the hwirq number. | |
| 58 | +Once a mapping has been established, it can be retrieved or used via a | |
| 59 | +variety of methods: | |
| 60 | + | |
| 61 | +- irq_resolve_mapping() returns a pointer to the irq_desc structure | |
| 62 | + for a given domain and hwirq number, and NULL if there was no | |
| 63 | + mapping. | |
| 64 | +- irq_find_mapping() returns a Linux IRQ number for a given domain and | |
| 65 | + hwirq number, and 0 if there was no mapping | |
| 66 | +- irq_linear_revmap() is now identical to irq_find_mapping(), and is | |
| 67 | + deprecated | |
| 68 | +- generic_handle_domain_irq() handles an interrupt described by a | |
| 69 | + domain and a hwirq number | |
| 70 | +- handle_domain_irq() does the same thing for root interrupt | |
| 71 | + controllers and deals with the set_irq_reg()/irq_enter() sequences | |
| 72 | + that most architecture requires | |
| 73 | + | |
| 74 | +Note that irq domain lookups must happen in contexts that are | |
| 75 | +compatible with a RCU read-side critical section. | |
| 60 | 76 | |
| 61 | 77 | The irq_create_mapping() function must be called *atleast once* |
| 62 | 78 | before any call to irq_find_mapping(), lest the descriptor will not |
| @@ -137,7 +153,9 @@ required. Calling irq_create_direct_mapping() will allocate a Linux · 74 unmodified lines | ||
| 137 | 153 | IRQ number and call the .map() callback so that driver can program the |
| 138 | 154 | Linux IRQ number into the hardware. |
| 139 | 155 | |
| 140 | −Most drivers cannot use this mapping. | |
| 156 | +Most drivers cannot use this mapping, and it is now gated on the | |
| 157 | +CONFIG_IRQ_DOMAIN_NOMAP option. Please refrain from introducing new | |
| 158 | +users of this API. | |
| 141 | 159 | |
| 142 | 160 | Legacy |
| 143 | 161 | ------ |
| @@ -157,6 +175,10 @@ for IRQ numbers that are passed to struct device registrations. In that · 13 unmodified lines | ||
| 157 | 175 | case the Linux IRQ numbers cannot be dynamically assigned and the legacy |
| 158 | 176 | mapping should be used. |
| 159 | 177 | |
| 178 | +As the name implies, the *_legacy() functions are deprecated and only | |
| 179 | +exist to ease the support of ancient platforms. No new users should be | |
| 180 | +added. | |
| 181 | + | |
| 160 | 182 | The legacy map assumes a contiguous range of IRQ numbers has already |
| 161 | 183 | been allocated for the controller and that the IRQ number can be |
| 162 | 184 | calculated by adding a fixed offset to the hwirq number, and |
| @@ -22,7 +22,10 @@ properties: · 21 unmodified lines | ||
| 22 | 22 | maxItems: 1 |
| 23 | 23 | |
| 24 | 24 | clocks: |
| 25 | − maxItems: 1 | |
| 25 | + minItems: 1 | |
| 26 | + items: | |
| 27 | + - description: APB interface clock source | |
| 28 | + - description: GPIO debounce reference clock source | |
| 26 | 29 | |
| 27 | 30 | gpio-controller: true |
| 28 | 31 | |
| @@ -352,7 +352,7 @@ static void idu_cascade_isr(struct irq_desc *desc) · 351 unmodified lines | ||
| 352 | 352 | irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ; |
| 353 | 353 | |
| 354 | 354 | chained_irq_enter(core_chip, desc); |
| 355 | − generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); | |
| 355 | + generic_handle_domain_irq(idu_domain, idu_hwirq); | |
| 356 | 356 | chained_irq_exit(core_chip, desc); |
| 357 | 357 | } |
| 358 | 358 | |
| @@ -196,14 +196,6 @@ static int sa1111_map_irq(struct sa1111 *sachip, irq_hw_number_t hwirq) · 195 unmodified lines | ||
| 196 | 196 | return irq_create_mapping(sachip->irqdomain, hwirq); |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | −static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq) | |
| 200 | −{ | |
| 201 | − struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq)); | |
| 202 | − | |
| 203 | − if (d) | |
| 204 | − generic_handle_irq_desc(d); | |
| 205 | −} | |
| 206 | − | |
| 207 | 199 | /* |
| 208 | 200 | * SA1111 interrupt support. Since clearing an IRQ while there are |
| 209 | 201 | * active IRQs causes the interrupt output to pulse, the upper levels |
| @@ -234,11 +226,11 @@ static void sa1111_irq_handler(struct irq_desc *desc) · 24 unmodified lines | ||
| 234 | 226 | |
| 235 | 227 | for (i = 0; stat0; i++, stat0 >>= 1) |
| 236 | 228 | if (stat0 & 1) |
| 237 | − sa1111_handle_irqdomain(irqdomain, i); | |
| 229 | + generic_handle_domain_irq(irqdomain, i); | |
| 238 | 230 | |
| 239 | 231 | for (i = 32; stat1; i++, stat1 >>= 1) |
| 240 | 232 | if (stat1 & 1) |
| 241 | − sa1111_handle_irqdomain(irqdomain, i); | |
| 233 | + generic_handle_domain_irq(irqdomain, i); | |
| 242 | 234 | |
| 243 | 235 | /* For level-based interrupts */ |
| 244 | 236 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
| @@ -39,10 +39,8 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d) · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | do { |
| 41 | 41 | pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask; |
| 42 | − for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) { | |
| 43 | − generic_handle_irq(irq_find_mapping(fpga->irqdomain, | |
| 44 | − bit)); | |
| 45 | − } | |
| 42 | + for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) | |
| 43 | + generic_handle_domain_irq(fpga->irqdomain, bit); | |
| 46 | 44 | } while (pending); |
| 47 | 45 | |
| 48 | 46 | return IRQ_HANDLED; |
| @@ -298,7 +298,7 @@ static void s3c_irq_demux(struct irq_desc *desc) · 297 unmodified lines | ||
| 298 | 298 | struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); |
| 299 | 299 | struct s3c_irq_intc *intc = irq_data->intc; |
| 300 | 300 | struct s3c_irq_intc *sub_intc = irq_data->sub_intc; |
| 301 | − unsigned int n, offset, irq; | |
| 301 | + unsigned int n, offset; | |
| 302 | 302 | unsigned long src, msk; |
| 303 | 303 | |
| 304 | 304 | /* we're using individual domains for the non-dt case |
| @@ -318,8 +318,7 @@ static void s3c_irq_demux(struct irq_desc *desc) · 13 unmodified lines | ||
| 318 | 318 | while (src) { |
| 319 | 319 | n = __ffs(src); |
| 320 | 320 | src &= ~(1 << n); |
| 321 | − irq = irq_find_mapping(sub_intc->domain, offset + n); | |
| 322 | − generic_handle_irq(irq); | |
| 321 | + generic_handle_domain_irq(sub_intc->domain, offset + n); | |
| 323 | 322 | } |
| 324 | 323 | |
| 325 | 324 | chained_irq_exit(chip, desc); |
| @@ -69,24 +69,24 @@ static void ar2315_misc_irq_handler(struct irq_desc *desc) · 68 unmodified lines | ||
| 69 | 69 | { |
| 70 | 70 | u32 pending = ar2315_rst_reg_read(AR2315_ISR) & |
| 71 | 71 | ar2315_rst_reg_read(AR2315_IMR); |
| 72 | − unsigned nr, misc_irq = 0; | |
| 72 | + unsigned nr; | |
| 73 | + int ret = 0; | |
| 73 | 74 | |
| 74 | 75 | if (pending) { |
| 75 | 76 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
| 76 | 77 | |
| 77 | 78 | nr = __ffs(pending); |
| 78 | − misc_irq = irq_find_mapping(domain, nr); | |
| 79 | − } | |
| 80 | 79 | |
| 81 | − if (misc_irq) { | |
| 82 | 80 | if (nr == AR2315_MISC_IRQ_GPIO) |
| 83 | 81 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); |
| 84 | 82 | else if (nr == AR2315_MISC_IRQ_WATCHDOG) |
| 85 | 83 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); |
| 86 | − generic_handle_irq(misc_irq); | |
| 87 | − } else { | |
| 88 | − spurious_interrupt(); | |
| 84 | + | |
| 85 | + ret = generic_handle_domain_irq(domain, nr); | |
| 89 | 86 | } |
| 87 | + | |
| 88 | + if (!pending || ret) | |
| 89 | + spurious_interrupt(); | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | static void ar2315_misc_irq_unmask(struct irq_data *d) |
| @@ -73,22 +73,21 @@ static void ar5312_misc_irq_handler(struct irq_desc *desc) · 72 unmodified lines | ||
| 73 | 73 | { |
| 74 | 74 | u32 pending = ar5312_rst_reg_read(AR5312_ISR) & |
| 75 | 75 | ar5312_rst_reg_read(AR5312_IMR); |
| 76 | − unsigned nr, misc_irq = 0; | |
| 76 | + unsigned nr; | |
| 77 | + int ret = 0; | |
| 77 | 78 | |
| 78 | 79 | if (pending) { |
| 79 | 80 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
| 80 | 81 | |
| 81 | 82 | nr = __ffs(pending); |
| 82 | − misc_irq = irq_find_mapping(domain, nr); | |
| 83 | − } | |
| 84 | 83 | |
| 85 | − if (misc_irq) { | |
| 86 | − generic_handle_irq(misc_irq); | |
| 84 | + ret = generic_handle_domain_irq(domain, nr); | |
| 87 | 85 | if (nr == AR5312_MISC_IRQ_TIMER) |
| 88 | 86 | ar5312_rst_reg_read(AR5312_TIMER); |
| 89 | − } else { | |
| 90 | − spurious_interrupt(); | |
| 91 | 87 | } |
| 88 | + | |
| 89 | + if (!pending || ret) | |
| 90 | + spurious_interrupt(); | |
| 92 | 91 | } |
| 93 | 92 | |
| 94 | 93 | /* Enable the specified AR5312_MISC_IRQ interrupt */ |
| @@ -300,7 +300,7 @@ static void ltq_hw_irq_handler(struct irq_desc *desc) · 299 unmodified lines | ||
| 300 | 300 | */ |
| 301 | 301 | irq = __fls(irq); |
| 302 | 302 | hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module); |
| 303 | − generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq)); | |
| 303 | + generic_handle_domain_irq(ltq_domain, hwirq); | |
| 304 | 304 | |
| 305 | 305 | /* if this is a EBU irq, we need to ack it or get a deadlock */ |
| 306 | 306 | if (irq == LTQ_ICU_EBU_IRQ && !module && LTQ_EBU_PCC_ISTAT != 0) |
| @@ -337,14 +337,12 @@ static void ar2315_pci_irq_handler(struct irq_desc *desc) · 336 unmodified lines | ||
| 337 | 337 | struct ar2315_pci_ctrl *apc = irq_desc_get_handler_data(desc); |
| 338 | 338 | u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) & |
| 339 | 339 | ar2315_pci_reg_read(apc, AR2315_PCI_IMR); |
| 340 | − unsigned pci_irq = 0; | |
| 340 | + int ret = 0; | |
| 341 | 341 | |
| 342 | 342 | if (pending) |
| 343 | − pci_irq = irq_find_mapping(apc->domain, __ffs(pending)); | |
| 343 | + ret = generic_handle_domain_irq(apc->domain, __ffs(pending)); | |
| 344 | 344 | |
| 345 | − if (pci_irq) | |
| 346 | − generic_handle_irq(pci_irq); | |
| 347 | − else | |
| 345 | + if (!pending || ret) | |
| 348 | 346 | spurious_interrupt(); |
| 349 | 347 | } |
| 350 | 348 | |
| @@ -140,10 +140,9 @@ static void rt3883_pci_irq_handler(struct irq_desc *desc) · 139 unmodified lines | ||
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | while (pending) { |
| 143 | − unsigned irq, bit = __ffs(pending); | |
| 143 | + unsigned bit = __ffs(pending); | |
| 144 | 144 | |
| 145 | − irq = irq_find_mapping(rpc->irq_domain, bit); | |
| 146 | − generic_handle_irq(irq); | |
| 145 | + generic_handle_domain_irq(rpc->irq_domain, bit); | |
| 147 | 146 | |
| 148 | 147 | pending &= ~BIT(bit); |
| 149 | 148 | } |
| @@ -100,7 +100,7 @@ static void ralink_intc_irq_handler(struct irq_desc *desc) · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | if (pending) { |
| 102 | 102 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
| 103 | − generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); | |
| 103 | + generic_handle_domain_irq(domain, __ffs(pending)); | |
| 104 | 104 | } else { |
| 105 | 105 | spurious_interrupt(); |
| 106 | 106 | } |
| @@ -190,7 +190,7 @@ static void ip27_do_irq_mask0(struct irq_desc *desc) · 189 unmodified lines | ||
| 190 | 190 | unsigned long *mask = per_cpu(irq_enable_mask, cpu); |
| 191 | 191 | struct irq_domain *domain; |
| 192 | 192 | u64 pend0; |
| 193 | − int irq; | |
| 193 | + int ret; | |
| 194 | 194 | |
| 195 | 195 | /* copied from Irix intpend0() */ |
| 196 | 196 | pend0 = LOCAL_HUB_L(PI_INT_PEND0); |
| @@ -216,10 +216,8 @@ static void ip27_do_irq_mask0(struct irq_desc *desc) · 19 unmodified lines | ||
| 216 | 216 | #endif |
| 217 | 217 | { |
| 218 | 218 | domain = irq_desc_get_handler_data(desc); |
| 219 | − irq = irq_linear_revmap(domain, __ffs(pend0)); | |
| 220 | − if (irq) | |
| 221 | − generic_handle_irq(irq); | |
| 222 | − else | |
| 219 | + ret = generic_handle_domain_irq(domain, __ffs(pend0)); | |
| 220 | + if (ret) | |
| 223 | 221 | spurious_interrupt(); |
| 224 | 222 | } |
| 225 | 223 | |
| @@ -232,7 +230,7 @@ static void ip27_do_irq_mask1(struct irq_desc *desc) · 6 unmodified lines | ||
| 232 | 230 | unsigned long *mask = per_cpu(irq_enable_mask, cpu); |
| 233 | 231 | struct irq_domain *domain; |
| 234 | 232 | u64 pend1; |
| 235 | − int irq; | |
| 233 | + int ret; | |
| 236 | 234 | |
| 237 | 235 | /* copied from Irix intpend0() */ |
| 238 | 236 | pend1 = LOCAL_HUB_L(PI_INT_PEND1); |
| @@ -242,10 +240,8 @@ static void ip27_do_irq_mask1(struct irq_desc *desc) · 3 unmodified lines | ||
| 242 | 240 | return; |
| 243 | 241 | |
| 244 | 242 | domain = irq_desc_get_handler_data(desc); |
| 245 | − irq = irq_linear_revmap(domain, __ffs(pend1) + 64); | |
| 246 | − if (irq) | |
| 247 | − generic_handle_irq(irq); | |
| 248 | − else | |
| 243 | + ret = generic_handle_domain_irq(domain, __ffs(pend1) + 64); | |
| 244 | + if (ret) | |
| 249 | 245 | spurious_interrupt(); |
| 250 | 246 | |
| 251 | 247 | LOCAL_HUB_L(PI_INT_PEND1); |
| @@ -99,7 +99,7 @@ static void ip30_normal_irq(struct irq_desc *desc) · 98 unmodified lines | ||
| 99 | 99 | int cpu = smp_processor_id(); |
| 100 | 100 | struct irq_domain *domain; |
| 101 | 101 | u64 pend, mask; |
| 102 | − int irq; | |
| 102 | + int ret; | |
| 103 | 103 | |
| 104 | 104 | pend = heart_read(&heart_regs->isr); |
| 105 | 105 | mask = (heart_read(&heart_regs->imr[cpu]) & |
| @@ -130,10 +130,8 @@ static void ip30_normal_irq(struct irq_desc *desc) · 24 unmodified lines | ||
| 130 | 130 | #endif |
| 131 | 131 | { |
| 132 | 132 | domain = irq_desc_get_handler_data(desc); |
| 133 | − irq = irq_linear_revmap(domain, __ffs(pend)); | |
| 134 | − if (irq) | |
| 135 | − generic_handle_irq(irq); | |
| 136 | − else | |
| 133 | + ret = generic_handle_domain_irq(domain, __ffs(pend)); | |
| 134 | + if (ret) | |
| 137 | 135 | spurious_interrupt(); |
| 138 | 136 | } |
| 139 | 137 | } |
| @@ -19,11 +19,9 @@ static u32 ienable; · 18 unmodified lines | ||
| 19 | 19 | asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) |
| 20 | 20 | { |
| 21 | 21 | struct pt_regs *oldregs = set_irq_regs(regs); |
| 22 | − int irq; | |
| 23 | 22 | |
| 24 | 23 | irq_enter(); |
| 25 | − irq = irq_find_mapping(NULL, hwirq); | |
| 26 | − generic_handle_irq(irq); | |
| 24 | + generic_handle_domain_irq(NULL, hwirq); | |
| 27 | 25 | irq_exit(); |
| 28 | 26 | |
| 29 | 27 | set_irq_regs(oldregs); |
| @@ -198,7 +198,6 @@ static void uic_irq_cascade(struct irq_desc *desc) · 197 unmodified lines | ||
| 198 | 198 | struct uic *uic = irq_desc_get_handler_data(desc); |
| 199 | 199 | u32 msr; |
| 200 | 200 | int src; |
| 201 | − int subvirq; | |
| 202 | 201 | |
| 203 | 202 | raw_spin_lock(&desc->lock); |
| 204 | 203 | if (irqd_is_level_type(idata)) |
| @@ -213,8 +212,7 @@ static void uic_irq_cascade(struct irq_desc *desc) · 8 unmodified lines | ||
| 213 | 212 | |
| 214 | 213 | src = 32 - ffs(msr); |
| 215 | 214 | |
| 216 | − subvirq = irq_linear_revmap(uic->irqhost, src); | |
| 217 | − generic_handle_irq(subvirq); | |
| 215 | + generic_handle_domain_irq(uic->irqhost, src); | |
| 218 | 216 | |
| 219 | 217 | uic_irq_ret: |
| 220 | 218 | raw_spin_lock(&desc->lock); |
| @@ -81,11 +81,10 @@ static struct irq_chip cpld_pic = { · 80 unmodified lines | ||
| 81 | 81 | .irq_unmask = cpld_unmask_irq, |
| 82 | 82 | }; |
| 83 | 83 | |
| 84 | −static int | |
| 84 | +static unsigned int | |
| 85 | 85 | cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp, |
| 86 | 86 | u8 __iomem *maskp) |
| 87 | 87 | { |
| 88 | − int cpld_irq; | |
| 89 | 88 | u8 status = in_8(statusp); |
| 90 | 89 | u8 mask = in_8(maskp); |
| 91 | 90 | |
| @@ -93,28 +92,26 @@ cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp, · 1 unmodified line | ||
| 93 | 92 | status |= (ignore | mask); |
| 94 | 93 | |
| 95 | 94 | if (status == 0xff) |
| 96 | − return 0; | |
| 97 | − | |
| 98 | − cpld_irq = ffz(status) + offset; | |
| 95 | + return ~0; | |
| 99 | 96 | |
| 100 | − return irq_linear_revmap(cpld_pic_host, cpld_irq); | |
| 97 | + return ffz(status) + offset; | |
| 101 | 98 | } |
| 102 | 99 | |
| 103 | 100 | static void cpld_pic_cascade(struct irq_desc *desc) |
| 104 | 101 | { |
| 105 | − unsigned int irq; | |
| 102 | + unsigned int hwirq; | |
| 106 | 103 | |
| 107 | − irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status, | |
| 104 | + hwirq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status, | |
| 108 | 105 | &cpld_regs->pci_mask); |
| 109 | − if (irq) { | |
| 110 | − generic_handle_irq(irq); | |
| 106 | + if (hwirq != ~0) { | |
| 107 | + generic_handle_domain_irq(cpld_pic_host, hwirq); | |
| 111 | 108 | return; |
| 112 | 109 | } |
| 113 | 110 | |
| 114 | − irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status, | |
| 111 | + hwirq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status, | |
| 115 | 112 | &cpld_regs->misc_mask); |
| 116 | − if (irq) { | |
| 117 | − generic_handle_irq(irq); | |
| 113 | + if (hwirq != ~0) { | |
| 114 | + generic_handle_domain_irq(cpld_pic_host, hwirq); | |
| 118 | 115 | return; |
| 119 | 116 | } |
| 120 | 117 | } |
| @@ -78,7 +78,7 @@ static struct irq_chip media5200_irq_chip = { · 77 unmodified lines | ||
| 78 | 78 | static void media5200_irq_cascade(struct irq_desc *desc) |
| 79 | 79 | { |
| 80 | 80 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 81 | − int sub_virq, val; | |
| 81 | + int val; | |
| 82 | 82 | u32 status, enable; |
| 83 | 83 | |
| 84 | 84 | /* Mask off the cascaded IRQ */ |
| @@ -92,11 +92,10 @@ static void media5200_irq_cascade(struct irq_desc *desc) · 7 unmodified lines | ||
| 92 | 92 | enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS); |
| 93 | 93 | val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT); |
| 94 | 94 | if (val) { |
| 95 | − sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1); | |
| 96 | − /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n", | |
| 97 | − * __func__, virq, status, enable, val - 1, sub_virq); | |
| 95 | + generic_handle_domain_irq(media5200_irq.irqhost, val - 1); | |
| 96 | + /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i\n", | |
| 97 | + * __func__, virq, status, enable, val - 1); | |
| 98 | 98 | */ |
| 99 | − generic_handle_irq(sub_virq); | |
| 100 | 99 | } |
| 101 | 100 | |
| 102 | 101 | /* Processing done; can reenable the cascade now */ |
| @@ -190,14 +190,11 @@ static struct irq_chip mpc52xx_gpt_irq_chip = { · 189 unmodified lines | ||
| 190 | 190 | static void mpc52xx_gpt_irq_cascade(struct irq_desc *desc) |
| 191 | 191 | { |
| 192 | 192 | struct mpc52xx_gpt_priv *gpt = irq_desc_get_handler_data(desc); |
| 193 | − int sub_virq; | |
| 194 | 193 | u32 status; |
| 195 | 194 | |
| 196 | 195 | status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK; |
| 197 | − if (status) { | |
| 198 | − sub_virq = irq_linear_revmap(gpt->irqhost, 0); | |
| 199 | − generic_handle_irq(sub_virq); | |
| 200 | − } | |
| 196 | + if (status) | |
| 197 | + generic_handle_domain_irq(gpt->irqhost, 0); | |
| 201 | 198 | } |
| 202 | 199 | |
| 203 | 200 | static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq, |
| @@ -91,10 +91,8 @@ static void pq2ads_pci_irq_demux(struct irq_desc *desc) · 90 unmodified lines | ||
| 91 | 91 | break; |
| 92 | 92 | |
| 93 | 93 | for (bit = 0; pend != 0; ++bit, pend <<= 1) { |
| 94 | − if (pend & 0x80000000) { | |
| 95 | − int virq = irq_linear_revmap(priv->host, bit); | |
| 96 | − generic_handle_irq(virq); | |
| 97 | − } | |
| 94 | + if (pend & 0x80000000) | |
| 95 | + generic_handle_domain_irq(priv->host, bit); | |
| 98 | 96 | } |
| 99 | 97 | } |
| 100 | 98 | } |
| @@ -106,13 +106,9 @@ static void iic_ioexc_cascade(struct irq_desc *desc) · 105 unmodified lines | ||
| 106 | 106 | out_be64(&node_iic->iic_is, ack); |
| 107 | 107 | /* handle them */ |
| 108 | 108 | for (cascade = 63; cascade >= 0; cascade--) |
| 109 | − if (bits & (0x8000000000000000UL >> cascade)) { | |
| 110 | − unsigned int cirq = | |
| 111 | − irq_linear_revmap(iic_host, | |
| 109 | + if (bits & (0x8000000000000000UL >> cascade)) | |
| 110 | + generic_handle_domain_irq(iic_host, | |
| 112 | 111 | base | cascade); |
| 113 | − if (cirq) | |
| 114 | − generic_handle_irq(cirq); | |
| 115 | − } | |
| 116 | 112 | /* post-ack level interrupts */ |
| 117 | 113 | ack = bits & ~IIC_ISR_EDGE_MASK; |
| 118 | 114 | if (ack) |
| @@ -190,16 +190,11 @@ static void spider_irq_cascade(struct irq_desc *desc) · 189 unmodified lines | ||
| 190 | 190 | { |
| 191 | 191 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 192 | 192 | struct spider_pic *pic = irq_desc_get_handler_data(desc); |
| 193 | − unsigned int cs, virq; | |
| 193 | + unsigned int cs; | |
| 194 | 194 | |
| 195 | 195 | cs = in_be32(pic->regs + TIR_CS) >> 24; |
| 196 | − if (cs == SPIDER_IRQ_INVALID) | |
| 197 | − virq = 0; | |
| 198 | − else | |
| 199 | − virq = irq_linear_revmap(pic->host, cs); | |
| 200 | − | |
| 201 | − if (virq) | |
| 202 | − generic_handle_irq(virq); | |
| 196 | + if (cs != SPIDER_IRQ_INVALID) | |
| 197 | + generic_handle_domain_irq(pic->host, cs); | |
| 203 | 198 | |
| 204 | 199 | chip->irq_eoi(&desc->irq_data); |
| 205 | 200 | } |
| @@ -108,7 +108,6 @@ static const struct irq_domain_ops hlwd_irq_domain_ops = { · 107 unmodified lines | ||
| 108 | 108 | static unsigned int __hlwd_pic_get_irq(struct irq_domain *h) |
| 109 | 109 | { |
| 110 | 110 | void __iomem *io_base = h->host_data; |
| 111 | − int irq; | |
| 112 | 111 | u32 irq_status; |
| 113 | 112 | |
| 114 | 113 | irq_status = in_be32(io_base + HW_BROADWAY_ICR) & |
| @@ -116,23 +115,22 @@ static unsigned int __hlwd_pic_get_irq(struct irq_domain *h) · 1 unmodified line | ||
| 116 | 115 | if (irq_status == 0) |
| 117 | 116 | return 0; /* no more IRQs pending */ |
| 118 | 117 | |
| 119 | − irq = __ffs(irq_status); | |
| 120 | − return irq_linear_revmap(h, irq); | |
| 118 | + return __ffs(irq_status); | |
| 121 | 119 | } |
| 122 | 120 | |
| 123 | 121 | static void hlwd_pic_irq_cascade(struct irq_desc *desc) |
| 124 | 122 | { |
| 125 | 123 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 126 | 124 | struct irq_domain *irq_domain = irq_desc_get_handler_data(desc); |
| 127 | − unsigned int virq; | |
| 125 | + unsigned int hwirq; | |
| 128 | 126 | |
| 129 | 127 | raw_spin_lock(&desc->lock); |
| 130 | 128 | chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */ |
| 131 | 129 | raw_spin_unlock(&desc->lock); |
| 132 | 130 | |
| 133 | − virq = __hlwd_pic_get_irq(irq_domain); | |
| 134 | − if (virq) | |
| 135 | − generic_handle_irq(virq); | |
| 131 | + hwirq = __hlwd_pic_get_irq(irq_domain); | |
| 132 | + if (hwirq) | |
| 133 | + generic_handle_domain_irq(irq_domain, hwirq); | |
| 136 | 134 | else |
| 137 | 135 | pr_err("spurious interrupt!\n"); |
| 138 | 136 | |
| @@ -190,7 +188,8 @@ static struct irq_domain *hlwd_pic_init(struct device_node *np) · 51 unmodified lines | ||
| 190 | 188 | |
| 191 | 189 | unsigned int hlwd_pic_get_irq(void) |
| 192 | 190 | { |
| 193 | − return __hlwd_pic_get_irq(hlwd_irq_host); | |
| 191 | + unsigned int hwirq = __hlwd_pic_get_irq(hlwd_irq_host); | |
| 192 | + return hwirq ? irq_linear_revmap(hlwd_irq_host, hwirq) : 0; | |
| 194 | 193 | } |
| 195 | 194 | |
| 196 | 195 | /* |
| @@ -46,18 +46,15 @@ void opal_handle_events(void) · 45 unmodified lines | ||
| 46 | 46 | e = READ_ONCE(last_outstanding_events) & opal_event_irqchip.mask; |
| 47 | 47 | again: |
| 48 | 48 | while (e) { |
| 49 | − int virq, hwirq; | |
| 49 | + int hwirq; | |
| 50 | 50 | |
| 51 | 51 | hwirq = fls64(e) - 1; |
| 52 | 52 | e &= ~BIT_ULL(hwirq); |
| 53 | 53 | |
| 54 | 54 | local_irq_disable(); |
| 55 | − virq = irq_find_mapping(opal_event_irqchip.domain, hwirq); | |
| 56 | − if (virq) { | |
| 57 | − irq_enter(); | |
| 58 | − generic_handle_irq(virq); | |
| 59 | − irq_exit(); | |
| 60 | − } | |
| 55 | + irq_enter(); | |
| 56 | + generic_handle_domain_irq(opal_event_irqchip.domain, hwirq); | |
| 57 | + irq_exit(); | |
| 61 | 58 | local_irq_enable(); |
| 62 | 59 | |
| 63 | 60 | cond_resched(); |
| @@ -99,7 +99,6 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data) · 98 unmodified lines | ||
| 99 | 99 | struct mpic *mpic = (struct mpic *) data; |
| 100 | 100 | u32 eisr, eimr; |
| 101 | 101 | int errint; |
| 102 | − unsigned int cascade_irq; | |
| 103 | 102 | |
| 104 | 103 | eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR); |
| 105 | 104 | eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR); |
| @@ -108,13 +107,11 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data) · 2 unmodified lines | ||
| 108 | 107 | return IRQ_NONE; |
| 109 | 108 | |
| 110 | 109 | while (eisr) { |
| 110 | + int ret; | |
| 111 | 111 | errint = __builtin_clz(eisr); |
| 112 | − cascade_irq = irq_linear_revmap(mpic->irqhost, | |
| 113 | − mpic->err_int_vecs[errint]); | |
| 114 | − WARN_ON(!cascade_irq); | |
| 115 | − if (cascade_irq) { | |
| 116 | − generic_handle_irq(cascade_irq); | |
| 117 | − } else { | |
| 112 | + ret = generic_handle_domain_irq(mpic->irqhost, | |
| 113 | + mpic->err_int_vecs[errint]); | |
| 114 | + if (WARN_ON(ret)) { | |
| 118 | 115 | eimr |= 1 << (31 - errint); |
| 119 | 116 | mpic_fsl_err_write(mpic->err_regs, eimr); |
| 120 | 117 | } |
| @@ -266,7 +266,6 @@ out_free: · 265 unmodified lines | ||
| 266 | 266 | |
| 267 | 267 | static irqreturn_t fsl_msi_cascade(int irq, void *data) |
| 268 | 268 | { |
| 269 | − unsigned int cascade_irq; | |
| 270 | 269 | struct fsl_msi *msi_data; |
| 271 | 270 | int msir_index = -1; |
| 272 | 271 | u32 msir_value = 0; |
| @@ -279,9 +278,6 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data) · 6 unmodified lines | ||
| 279 | 278 | |
| 280 | 279 | msir_index = cascade_data->index; |
| 281 | 280 | |
| 282 | − if (msir_index >= NR_MSI_REG_MAX) | |
| 283 | − cascade_irq = 0; | |
| 284 | − | |
| 285 | 281 | switch (msi_data->feature & FSL_PIC_IP_MASK) { |
| 286 | 282 | case FSL_PIC_IP_MPIC: |
| 287 | 283 | msir_value = fsl_msi_read(msi_data->msi_regs, |
| @@ -305,15 +301,15 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data) · 17 unmodified lines | ||
| 305 | 301 | } |
| 306 | 302 | |
| 307 | 303 | while (msir_value) { |
| 304 | + int err; | |
| 308 | 305 | intr_index = ffs(msir_value) - 1; |
| 309 | 306 | |
| 310 | − cascade_irq = irq_linear_revmap(msi_data->irqhost, | |
| 307 | + err = generic_handle_domain_irq(msi_data->irqhost, | |
| 311 | 308 | msi_hwirq(msi_data, msir_index, |
| 312 | 309 | intr_index + have_shift)); |
| 313 | − if (cascade_irq) { | |
| 314 | − generic_handle_irq(cascade_irq); | |
| 310 | + if (!err) | |
| 315 | 311 | ret = IRQ_HANDLED; |
| 316 | − } | |
| 312 | + | |
| 317 | 313 | have_shift += intr_index + 1; |
| 318 | 314 | msir_value = msir_value >> (intr_index + 1); |
| 319 | 315 | } |
| @@ -38,7 +38,7 @@ static void se7343_irq_demux(struct irq_desc *desc) · 37 unmodified lines | ||
| 38 | 38 | mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG); |
| 39 | 39 | |
| 40 | 40 | for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR) |
| 41 | − generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit)); | |
| 41 | + generic_handle_domain_irq(se7343_irq_domain, bit); | |
| 42 | 42 | |
| 43 | 43 | chip->irq_unmask(data); |
| 44 | 44 | } |
| @@ -37,7 +37,7 @@ static void se7722_irq_demux(struct irq_desc *desc) · 36 unmodified lines | ||
| 37 | 37 | mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); |
| 38 | 38 | |
| 39 | 39 | for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) |
| 40 | − generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); | |
| 40 | + generic_handle_domain_irq(se7722_irq_domain, bit); | |
| 41 | 41 | |
| 42 | 42 | chip->irq_unmask(data); |
| 43 | 43 | } |
| @@ -68,7 +68,7 @@ static void x3proto_gpio_irq_handler(struct irq_desc *desc) · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | mask = __raw_readw(KEYDETR); |
| 70 | 70 | for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS) |
| 71 | − generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin)); | |
| 71 | + generic_handle_domain_irq(x3proto_irq_domain, pin); | |
| 72 | 72 | |
| 73 | 73 | chip->irq_unmask(data); |
| 74 | 74 | } |
| @@ -33,8 +33,6 @@ DECLARE_PER_CPU(unsigned long, nmi_count); · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) |
| 35 | 35 | { |
| 36 | − int irq = irq_find_mapping(NULL, hwirq); | |
| 37 | − | |
| 38 | 36 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
| 39 | 37 | /* Debugging check for stack overflow: is there less than 1KB free? */ |
| 40 | 38 | { |
| @@ -48,7 +46,7 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) · 7 unmodified lines | ||
| 48 | 46 | sp - sizeof(struct thread_info)); |
| 49 | 47 | } |
| 50 | 48 | #endif |
| 51 | − generic_handle_irq(irq); | |
| 49 | + generic_handle_domain_irq(NULL, hwirq); | |
| 52 | 50 | } |
| 53 | 51 | |
| 54 | 52 | int arch_show_interrupts(struct seq_file *p, int prec) |
| @@ -1804,11 +1804,8 @@ static void altr_edac_a10_irq_handler(struct irq_desc *desc) · 1803 unmodified lines | ||
| 1804 | 1804 | regmap_read(edac->ecc_mgr_map, sm_offset, &irq_status); |
| 1805 | 1805 | |
| 1806 | 1806 | bits = irq_status; |
| 1807 | − for_each_set_bit(bit, &bits, 32) { | |
| 1808 | − irq = irq_linear_revmap(edac->domain, dberr * 32 + bit); | |
| 1809 | − if (irq) | |
| 1810 | − generic_handle_irq(irq); | |
| 1811 | − } | |
| 1807 | + for_each_set_bit(bit, &bits, 32) | |
| 1808 | + generic_handle_domain_irq(edac->domain, dberr * 32 + bit); | |
| 1812 | 1809 | |
| 1813 | 1810 | chained_irq_exit(chip, desc); |
| 1814 | 1811 | } |
| @@ -520,6 +520,14 @@ config GPIO_REG · 519 unmodified lines | ||
| 520 | 520 | A 32-bit single register GPIO fixed in/out implementation. This |
| 521 | 521 | can be used to represent any register as a set of GPIO signals. |
| 522 | 522 | |
| 523 | +config GPIO_ROCKCHIP | |
| 524 | + tristate "Rockchip GPIO support" | |
| 525 | + depends on ARCH_ROCKCHIP || COMPILE_TEST | |
| 526 | + select GPIOLIB_IRQCHIP | |
| 527 | + default ARCH_ROCKCHIP | |
| 528 | + help | |
| 529 | + Say yes here to support GPIO on Rockchip SoCs. | |
| 530 | + | |
| 523 | 531 | config GPIO_SAMA5D2_PIOBU |
| 524 | 532 | tristate "SAMA5D2 PIOBU GPIO support" |
| 525 | 533 | depends on MFD_SYSCON |
| @@ -128,6 +128,7 @@ obj-$(CONFIG_GPIO_RDA) += gpio-rda.o · 127 unmodified lines | ||
| 128 | 128 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
| 129 | 129 | obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o |
| 130 | 130 | obj-$(CONFIG_GPIO_REG) += gpio-reg.o |
| 131 | +obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o | |
| 131 | 132 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
| 132 | 133 | obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o |
| 133 | 134 | obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o |
| @@ -336,8 +336,8 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) · 335 unmodified lines | ||
| 336 | 336 | unsigned long gpio; |
| 337 | 337 | |
| 338 | 338 | for_each_set_bit(gpio, &irq_mask, 2) |
| 339 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, | |
| 340 | − 19 + gpio*24)); | |
| 339 | + generic_handle_domain_irq(chip->irq.domain, | |
| 340 | + 19 + gpio*24); | |
| 341 | 341 | |
| 342 | 342 | raw_spin_lock(&dio48egpio->lock); |
| 343 | 343 | |
| @@ -223,8 +223,8 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id) · 222 unmodified lines | ||
| 223 | 223 | for_each_set_bit(bit_num, &irq_mask, 8) { |
| 224 | 224 | gpio = bit_num + boundary * 8; |
| 225 | 225 | |
| 226 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, | |
| 227 | − gpio)); | |
| 226 | + generic_handle_domain_irq(chip->irq.domain, | |
| 227 | + gpio); | |
| 228 | 228 | } |
| 229 | 229 | } |
| 230 | 230 | |
| @@ -208,7 +208,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) · 207 unmodified lines | ||
| 208 | 208 | int gpio; |
| 209 | 209 | |
| 210 | 210 | for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) |
| 211 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio)); | |
| 211 | + generic_handle_domain_irq(chip->irq.domain, gpio); | |
| 212 | 212 | |
| 213 | 213 | raw_spin_lock(&idio16gpio->lock); |
| 214 | 214 | |
| @@ -201,9 +201,8 @@ static void altera_gpio_irq_edge_handler(struct irq_desc *desc) · 200 unmodified lines | ||
| 201 | 201 | (readl(mm_gc->regs + ALTERA_GPIO_EDGE_CAP) & |
| 202 | 202 | readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK)))) { |
| 203 | 203 | writel(status, mm_gc->regs + ALTERA_GPIO_EDGE_CAP); |
| 204 | − for_each_set_bit(i, &status, mm_gc->gc.ngpio) { | |
| 205 | − generic_handle_irq(irq_find_mapping(irqdomain, i)); | |
| 206 | − } | |
| 204 | + for_each_set_bit(i, &status, mm_gc->gc.ngpio) | |
| 205 | + generic_handle_domain_irq(irqdomain, i); | |
| 207 | 206 | } |
| 208 | 207 | |
| 209 | 208 | chained_irq_exit(chip, desc); |
| @@ -228,9 +227,9 @@ static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc) · 18 unmodified lines | ||
| 228 | 227 | status = readl(mm_gc->regs + ALTERA_GPIO_DATA); |
| 229 | 228 | status &= readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); |
| 230 | 229 | |
| 231 | − for_each_set_bit(i, &status, mm_gc->gc.ngpio) { | |
| 232 | − generic_handle_irq(irq_find_mapping(irqdomain, i)); | |
| 233 | − } | |
| 230 | + for_each_set_bit(i, &status, mm_gc->gc.ngpio) | |
| 231 | + generic_handle_domain_irq(irqdomain, i); | |
| 232 | + | |
| 234 | 233 | chained_irq_exit(chip, desc); |
| 235 | 234 | } |
| 236 | 235 | |
| @@ -392,7 +392,7 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc) · 391 unmodified lines | ||
| 392 | 392 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| 393 | 393 | struct irq_chip *ic = irq_desc_get_chip(desc); |
| 394 | 394 | struct aspeed_sgpio *data = gpiochip_get_data(gc); |
| 395 | − unsigned int i, p, girq; | |
| 395 | + unsigned int i, p; | |
| 396 | 396 | unsigned long reg; |
| 397 | 397 | |
| 398 | 398 | chained_irq_enter(ic, desc); |
| @@ -402,11 +402,8 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc) · 3 unmodified lines | ||
| 402 | 402 | |
| 403 | 403 | reg = ioread32(bank_reg(data, bank, reg_irq_status)); |
| 404 | 404 | |
| 405 | − for_each_set_bit(p, ®, 32) { | |
| 406 | − girq = irq_find_mapping(gc->irq.domain, i * 32 + p); | |
| 407 | − generic_handle_irq(girq); | |
| 408 | − } | |
| 409 | − | |
| 405 | + for_each_set_bit(p, ®, 32) | |
| 406 | + generic_handle_domain_irq(gc->irq.domain, i * 32 + p); | |
| 410 | 407 | } |
| 411 | 408 | |
| 412 | 409 | chained_irq_exit(ic, desc); |
| @@ -661,7 +661,7 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc) · 660 unmodified lines | ||
| 661 | 661 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
| 662 | 662 | struct irq_chip *ic = irq_desc_get_chip(desc); |
| 663 | 663 | struct aspeed_gpio *data = gpiochip_get_data(gc); |
| 664 | − unsigned int i, p, girq, banks; | |
| 664 | + unsigned int i, p, banks; | |
| 665 | 665 | unsigned long reg; |
| 666 | 666 | struct aspeed_gpio *gpio = gpiochip_get_data(gc); |
| 667 | 667 | |
| @@ -673,11 +673,8 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc) · 5 unmodified lines | ||
| 673 | 673 | |
| 674 | 674 | reg = ioread32(bank_reg(data, bank, reg_irq_status)); |
| 675 | 675 | |
| 676 | − for_each_set_bit(p, ®, 32) { | |
| 677 | − girq = irq_find_mapping(gc->irq.domain, i * 32 + p); | |
| 678 | − generic_handle_irq(girq); | |
| 679 | − } | |
| 680 | − | |
| 676 | + for_each_set_bit(p, ®, 32) | |
| 677 | + generic_handle_domain_irq(gc->irq.domain, i * 32 + p); | |
| 681 | 678 | } |
| 682 | 679 | |
| 683 | 680 | chained_irq_exit(ic, desc); |
| @@ -204,11 +204,8 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc) · 203 unmodified lines | ||
| 204 | 204 | |
| 205 | 205 | raw_spin_unlock_irqrestore(&ctrl->lock, flags); |
| 206 | 206 | |
| 207 | − if (pending) { | |
| 208 | − for_each_set_bit(irq, &pending, gc->ngpio) | |
| 209 | − generic_handle_irq( | |
| 210 | − irq_linear_revmap(gc->irq.domain, irq)); | |
| 211 | − } | |
| 207 | + for_each_set_bit(irq, &pending, gc->ngpio) | |
| 208 | + generic_handle_domain_irq(gc->irq.domain, irq); | |
| 212 | 209 | |
| 213 | 210 | chained_irq_exit(irqchip, desc); |
| 214 | 211 | } |
| @@ -466,9 +466,6 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) · 465 unmodified lines | ||
| 466 | 466 | (~(readl(reg_base + GPIO_INT_MASK(bank_id)))))) { |
| 467 | 467 | for_each_set_bit(bit, &sta, 32) { |
| 468 | 468 | int hwirq = GPIO_PER_BANK * bank_id + bit; |
| 469 | − int child_irq = | |
| 470 | − irq_find_mapping(bank->kona_gpio->irq_domain, | |
| 471 | − hwirq); | |
| 472 | 469 | /* |
| 473 | 470 | * Clear interrupt before handler is called so we don't |
| 474 | 471 | * miss any interrupt occurred during executing them. |
| @@ -476,7 +473,8 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) · 1 unmodified line | ||
| 476 | 473 | writel(readl(reg_base + GPIO_INT_STATUS(bank_id)) | |
| 477 | 474 | BIT(bit), reg_base + GPIO_INT_STATUS(bank_id)); |
| 478 | 475 | /* Invoke interrupt handler */ |
| 479 | − generic_handle_irq(child_irq); | |
| 476 | + generic_handle_domain_irq(bank->kona_gpio->irq_domain, | |
| 477 | + hwirq); | |
| 480 | 478 | } |
| 481 | 479 | } |
| 482 | 480 | |
| @@ -277,15 +277,14 @@ static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank) · 276 unmodified lines | ||
| 277 | 277 | unsigned long status; |
| 278 | 278 | |
| 279 | 279 | while ((status = brcmstb_gpio_get_active_irqs(bank))) { |
| 280 | − unsigned int irq, offset; | |
| 280 | + unsigned int offset; | |
| 281 | 281 | |
| 282 | 282 | for_each_set_bit(offset, &status, 32) { |
| 283 | 283 | if (offset >= bank->width) |
| 284 | 284 | dev_warn(&priv->pdev->dev, |
| 285 | 285 | "IRQ for invalid GPIO (bank=%d, offset=%d)\n", |
| 286 | 286 | bank->id, offset); |
| 287 | − irq = irq_linear_revmap(domain, hwbase + offset); | |
| 288 | − generic_handle_irq(irq); | |
| 287 | + generic_handle_domain_irq(domain, hwbase + offset); | |
| 289 | 288 | } |
| 290 | 289 | } |
| 291 | 290 | } |
| @@ -133,7 +133,7 @@ static void cdns_gpio_irq_handler(struct irq_desc *desc) · 132 unmodified lines | ||
| 133 | 133 | ~ioread32(cgpio->regs + CDNS_GPIO_IRQ_MASK); |
| 134 | 134 | |
| 135 | 135 | for_each_set_bit(hwirq, &status, chip->ngpio) |
| 136 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, hwirq)); | |
| 136 | + generic_handle_domain_irq(chip->irq.domain, hwirq); | |
| 137 | 137 | |
| 138 | 138 | chained_irq_exit(irqchip, desc); |
| 139 | 139 | } |
| @@ -369,8 +369,7 @@ static void gpio_irq_handler(struct irq_desc *desc) · 368 unmodified lines | ||
| 369 | 369 | */ |
| 370 | 370 | hw_irq = (bank_num / 2) * 32 + bit; |
| 371 | 371 | |
| 372 | − generic_handle_irq( | |
| 373 | − irq_find_mapping(d->irq_domain, hw_irq)); | |
| 372 | + generic_handle_domain_irq(d->irq_domain, hw_irq); | |
| 374 | 373 | } |
| 375 | 374 | } |
| 376 | 375 | chained_irq_exit(irq_desc_get_chip(desc), desc); |
| @@ -395,7 +395,7 @@ static struct irq_chip dln2_gpio_irqchip = { · 394 unmodified lines | ||
| 395 | 395 | static void dln2_gpio_event(struct platform_device *pdev, u16 echo, |
| 396 | 396 | const void *data, int len) |
| 397 | 397 | { |
| 398 | − int pin, irq; | |
| 398 | + int pin, ret; | |
| 399 | 399 | |
| 400 | 400 | const struct { |
| 401 | 401 | __le16 count; |
| @@ -416,24 +416,20 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, · 14 unmodified lines | ||
| 416 | 416 | return; |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | − irq = irq_find_mapping(dln2->gpio.irq.domain, pin); | |
| 420 | − if (!irq) { | |
| 421 | − dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); | |
| 422 | − return; | |
| 423 | − } | |
| 424 | − | |
| 425 | 419 | switch (dln2->irq_type[pin]) { |
| 426 | 420 | case DLN2_GPIO_EVENT_CHANGE_RISING: |
| 427 | − if (event->value) | |
| 428 | − generic_handle_irq(irq); | |
| 421 | + if (!event->value) | |
| 422 | + return; | |
| 429 | 423 | break; |
| 430 | 424 | case DLN2_GPIO_EVENT_CHANGE_FALLING: |
| 431 | − if (!event->value) | |
| 432 | − generic_handle_irq(irq); | |
| 425 | + if (event->value) | |
| 426 | + return; | |
| 433 | 427 | break; |
| 434 | − default: | |
| 435 | − generic_handle_irq(irq); | |
| 436 | 428 | } |
| 429 | + | |
| 430 | + ret = generic_handle_domain_irq(dln2->gpio.irq.domain, pin); | |
| 431 | + if (unlikely(ret)) | |
| 432 | + dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); | |
| 437 | 433 | } |
| 438 | 434 | |
| 439 | 435 | static int dln2_gpio_probe(struct platform_device *pdev) |
| @@ -173,7 +173,7 @@ static irqreturn_t em_gio_irq_handler(int irq, void *dev_id) · 172 unmodified lines | ||
| 173 | 173 | while ((pending = em_gio_read(p, GIO_MST))) { |
| 174 | 174 | offset = __ffs(pending); |
| 175 | 175 | em_gio_write(p, GIO_IIR, BIT(offset)); |
| 176 | − generic_handle_irq(irq_find_mapping(p->irq_domain, offset)); | |
| 176 | + generic_handle_domain_irq(p->irq_domain, offset); | |
| 177 | 177 | irqs_handled++; |
| 178 | 178 | } |
| 179 | 179 | |
| @@ -128,13 +128,13 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc) · 127 unmodified lines | ||
| 128 | 128 | */ |
| 129 | 129 | stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS); |
| 130 | 130 | for_each_set_bit(offset, &stat, 8) |
| 131 | − generic_handle_irq(irq_find_mapping(epg->gc[0].gc.irq.domain, | |
| 132 | − offset)); | |
| 131 | + generic_handle_domain_irq(epg->gc[0].gc.irq.domain, | |
| 132 | + offset); | |
| 133 | 133 | |
| 134 | 134 | stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS); |
| 135 | 135 | for_each_set_bit(offset, &stat, 8) |
| 136 | − generic_handle_irq(irq_find_mapping(epg->gc[1].gc.irq.domain, | |
| 137 | − offset)); | |
| 136 | + generic_handle_domain_irq(epg->gc[1].gc.irq.domain, | |
| 137 | + offset); | |
| 138 | 138 | |
| 139 | 139 | chained_irq_exit(irqchip, desc); |
| 140 | 140 | } |
| @@ -149,8 +149,7 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc) · 148 unmodified lines | ||
| 149 | 149 | stat = readl(g->base + GPIO_INT_STAT_RAW); |
| 150 | 150 | if (stat) |
| 151 | 151 | for_each_set_bit(offset, &stat, gc->ngpio) |
| 152 | − generic_handle_irq(irq_find_mapping(gc->irq.domain, | |
| 153 | − offset)); | |
| 152 | + generic_handle_domain_irq(gc->irq.domain, offset); | |
| 154 | 153 | |
| 155 | 154 | chained_irq_exit(irqchip, desc); |
| 156 | 155 | } |
| @@ -186,8 +186,8 @@ static void hisi_gpio_irq_handler(struct irq_desc *desc) · 185 unmodified lines | ||
| 186 | 186 | |
| 187 | 187 | chained_irq_enter(irq_c, desc); |
| 188 | 188 | for_each_set_bit(hwirq, &irq_msk, HISI_GPIO_LINE_NUM_MAX) |
| 189 | − generic_handle_irq(irq_find_mapping(hisi_gpio->chip.irq.domain, | |
| 190 | − hwirq)); | |
| 189 | + generic_handle_domain_irq(hisi_gpio->chip.irq.domain, | |
| 190 | + hwirq); | |
| 191 | 191 | chained_irq_exit(irq_c, desc); |
| 192 | 192 | } |
| 193 | 193 | |
| @@ -97,11 +97,8 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | chained_irq_enter(chip, desc); |
| 99 | 99 | |
| 100 | − for_each_set_bit(hwirq, &pending, 32) { | |
| 101 | − int irq = irq_find_mapping(hlwd->gpioc.irq.domain, hwirq); | |
| 102 | − | |
| 103 | − generic_handle_irq(irq); | |
| 104 | − } | |
| 100 | + for_each_set_bit(hwirq, &pending, 32) | |
| 101 | + generic_handle_domain_irq(hlwd->gpioc.irq.domain, hwirq); | |
| 105 | 102 | |
| 106 | 103 | chained_irq_exit(chip, desc); |
| 107 | 104 | } |
| @@ -359,12 +359,8 @@ static void mrfld_irq_handler(struct irq_desc *desc) · 358 unmodified lines | ||
| 359 | 359 | /* Only interrupts that are enabled */ |
| 360 | 360 | pending &= enabled; |
| 361 | 361 | |
| 362 | − for_each_set_bit(gpio, &pending, 32) { | |
| 363 | − unsigned int irq; | |
| 364 | − | |
| 365 | − irq = irq_find_mapping(gc->irq.domain, base + gpio); | |
| 366 | − generic_handle_irq(irq); | |
| 367 | − } | |
| 362 | + for_each_set_bit(gpio, &pending, 32) | |
| 363 | + generic_handle_domain_irq(gc->irq.domain, base + gpio); | |
| 368 | 364 | } |
| 369 | 365 | |
| 370 | 366 | chained_irq_exit(irqchip, desc); |
| @@ -120,7 +120,7 @@ static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data) · 119 unmodified lines | ||
| 120 | 120 | mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER) |
| 121 | 121 | & gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR); |
| 122 | 122 | for_each_set_bit(i, &mask, 32) |
| 123 | − generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, 31 - i)); | |
| 123 | + generic_handle_domain_irq(mpc8xxx_gc->irq, 31 - i); | |
| 124 | 124 | |
| 125 | 125 | return IRQ_HANDLED; |
| 126 | 126 | } |
| @@ -95,9 +95,7 @@ mediatek_gpio_irq_handler(int irq, void *data) · 94 unmodified lines | ||
| 95 | 95 | pending = mtk_gpio_r32(rg, GPIO_REG_STAT); |
| 96 | 96 | |
| 97 | 97 | for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) { |
| 98 | − u32 map = irq_find_mapping(gc->irq.domain, bit); | |
| 99 | − | |
| 100 | − generic_handle_irq(map); | |
| 98 | + generic_handle_domain_irq(gc->irq.domain, bit); | |
| 101 | 99 | mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit)); |
| 102 | 100 | ret |= IRQ_HANDLED; |
| 103 | 101 | } |
| @@ -241,7 +241,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) · 240 unmodified lines | ||
| 241 | 241 | if (port->both_edges & (1 << irqoffset)) |
| 242 | 242 | mxc_flip_edge(port, irqoffset); |
| 243 | 243 | |
| 244 | − generic_handle_irq(irq_find_mapping(port->domain, irqoffset)); | |
| 244 | + generic_handle_domain_irq(port->domain, irqoffset); | |
| 245 | 245 | |
| 246 | 246 | irq_stat &= ~(1 << irqoffset); |
| 247 | 247 | } |
| @@ -157,7 +157,7 @@ static void mxs_gpio_irq_handler(struct irq_desc *desc) · 156 unmodified lines | ||
| 157 | 157 | if (port->both_edges & (1 << irqoffset)) |
| 158 | 158 | mxs_flip_edge(port, irqoffset); |
| 159 | 159 | |
| 160 | − generic_handle_irq(irq_find_mapping(port->domain, irqoffset)); | |
| 160 | + generic_handle_domain_irq(port->domain, irqoffset); | |
| 161 | 161 | irq_stat &= ~(1 << irqoffset); |
| 162 | 162 | } |
| 163 | 163 | } |
| @@ -611,8 +611,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) · 610 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); |
| 613 | 613 | |
| 614 | − generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, | |
| 615 | − bit)); | |
| 614 | + generic_handle_domain_irq(bank->chip.irq.domain, bit); | |
| 616 | 615 | |
| 617 | 616 | raw_spin_unlock_irqrestore(&bank->wa_lock, |
| 618 | 617 | wa_lock_flags); |
| @@ -260,7 +260,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) · 259 unmodified lines | ||
| 260 | 260 | return IRQ_NONE; |
| 261 | 261 | |
| 262 | 262 | for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) |
| 263 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio)); | |
| 263 | + generic_handle_domain_irq(chip->irq.domain, gpio); | |
| 264 | 264 | |
| 265 | 265 | raw_spin_lock(&idio16gpio->lock); |
| 266 | 266 | |
| @@ -468,8 +468,7 @@ static irqreturn_t idio_24_irq_handler(int irq, void *dev_id) · 467 unmodified lines | ||
| 468 | 468 | irq_mask = idio24gpio->irq_mask & irq_status; |
| 469 | 469 | |
| 470 | 470 | for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24) |
| 471 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, | |
| 472 | − gpio + 24)); | |
| 471 | + generic_handle_domain_irq(chip->irq.domain, gpio + 24); | |
| 473 | 472 | |
| 474 | 473 | raw_spin_lock(&idio24gpio->lock); |
| 475 | 474 | |
| @@ -223,8 +223,8 @@ static void pl061_irq_handler(struct irq_desc *desc) · 222 unmodified lines | ||
| 223 | 223 | pending = readb(pl061->base + GPIOMIS); |
| 224 | 224 | if (pending) { |
| 225 | 225 | for_each_set_bit(offset, &pending, PL061_GPIO_NR) |
| 226 | − generic_handle_irq(irq_find_mapping(gc->irq.domain, | |
| 227 | − offset)); | |
| 226 | + generic_handle_domain_irq(gc->irq.domain, | |
| 227 | + offset); | |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | chained_irq_exit(irqchip, desc); |
| @@ -455,9 +455,8 @@ static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d) · 454 unmodified lines | ||
| 455 | 455 | for_each_set_bit(n, &gedr, BITS_PER_LONG) { |
| 456 | 456 | loop = 1; |
| 457 | 457 | |
| 458 | − generic_handle_irq( | |
| 459 | − irq_find_mapping(pchip->irqdomain, | |
| 460 | − gpio + n)); | |
| 458 | + generic_handle_domain_irq(pchip->irqdomain, | |
| 459 | + gpio + n); | |
| 461 | 460 | } |
| 462 | 461 | } |
| 463 | 462 | handled += loop; |
| @@ -471,9 +470,9 @@ static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d) · 7 unmodified lines | ||
| 471 | 470 | struct pxa_gpio_chip *pchip = d; |
| 472 | 471 | |
| 473 | 472 | if (in_irq == pchip->irq0) { |
| 474 | − generic_handle_irq(irq_find_mapping(pchip->irqdomain, 0)); | |
| 473 | + generic_handle_domain_irq(pchip->irqdomain, 0); | |
| 475 | 474 | } else if (in_irq == pchip->irq1) { |
| 476 | − generic_handle_irq(irq_find_mapping(pchip->irqdomain, 1)); | |
| 475 | + generic_handle_domain_irq(pchip->irqdomain, 1); | |
| 477 | 476 | } else { |
| 478 | 477 | pr_err("%s() unknown irq %d\n", __func__, in_irq); |
| 479 | 478 | return IRQ_NONE; |
| @@ -213,8 +213,8 @@ static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) · 212 unmodified lines | ||
| 213 | 213 | gpio_rcar_read(p, INTMSK))) { |
| 214 | 214 | offset = __ffs(pending); |
| 215 | 215 | gpio_rcar_write(p, INTCLR, BIT(offset)); |
| 216 | − generic_handle_irq(irq_find_mapping(p->gpio_chip.irq.domain, | |
| 217 | − offset)); | |
| 216 | + generic_handle_domain_irq(p->gpio_chip.irq.domain, | |
| 217 | + offset); | |
| 218 | 218 | irqs_handled++; |
| 219 | 219 | } |
| 220 | 220 | |
| @@ -181,7 +181,7 @@ static void rda_gpio_irq_handler(struct irq_desc *desc) · 180 unmodified lines | ||
| 181 | 181 | struct irq_chip *ic = irq_desc_get_chip(desc); |
| 182 | 182 | struct rda_gpio *rda_gpio = gpiochip_get_data(chip); |
| 183 | 183 | unsigned long status; |
| 184 | − u32 n, girq; | |
| 184 | + u32 n; | |
| 185 | 185 | |
| 186 | 186 | chained_irq_enter(ic, desc); |
| 187 | 187 | |
| @@ -189,10 +189,8 @@ static void rda_gpio_irq_handler(struct irq_desc *desc) · 1 unmodified line | ||
| 189 | 189 | /* Only lower 8 bits are capable of generating interrupts */ |
| 190 | 190 | status &= RDA_GPIO_IRQ_MASK; |
| 191 | 191 | |
| 192 | − for_each_set_bit(n, &status, RDA_GPIO_BANK_NR) { | |
| 193 | − girq = irq_find_mapping(chip->irq.domain, n); | |
| 194 | − generic_handle_irq(girq); | |
| 195 | − } | |
| 192 | + for_each_set_bit(n, &status, RDA_GPIO_BANK_NR) | |
| 193 | + generic_handle_domain_irq(chip->irq.domain, n); | |
| 196 | 194 | |
| 197 | 195 | chained_irq_exit(ic, desc); |
| 198 | 196 | } |
| @@ -196,7 +196,6 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc) · 195 unmodified lines | ||
| 196 | 196 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); |
| 197 | 197 | unsigned int lines_done; |
| 198 | 198 | unsigned int port_pin_count; |
| 199 | − unsigned int irq; | |
| 200 | 199 | unsigned long status; |
| 201 | 200 | int offset; |
| 202 | 201 | |
| @@ -205,10 +204,8 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc) · 2 unmodified lines | ||
| 205 | 204 | for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) { |
| 206 | 205 | status = realtek_gpio_read_isr(ctrl, lines_done / 8); |
| 207 | 206 | port_pin_count = min(gc->ngpio - lines_done, 8U); |
| 208 | − for_each_set_bit(offset, &status, port_pin_count) { | |
| 209 | − irq = irq_find_mapping(gc->irq.domain, offset); | |
| 210 | − generic_handle_irq(irq); | |
| 211 | − } | |
| 207 | + for_each_set_bit(offset, &status, port_pin_count) | |
| 208 | + generic_handle_domain_irq(gc->irq.domain, offset); | |
| 212 | 209 | } |
| 213 | 210 | |
| 214 | 211 | chained_irq_exit(irq_chip, desc); |
| @@ -0,0 +1,771 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2013 MundoReader S.L. | |
| 4 | + * Author: Heiko Stuebner <heiko@sntech.de> | |
| 5 | + * | |
| 6 | + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <linux/bitops.h> | |
| 10 | +#include <linux/clk.h> | |
| 11 | +#include <linux/device.h> | |
| 12 | +#include <linux/err.h> | |
| 13 | +#include <linux/gpio/driver.h> | |
| 14 | +#include <linux/init.h> | |
| 15 | +#include <linux/interrupt.h> | |
| 16 | +#include <linux/io.h> | |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <linux/of.h> | |
| 19 | +#include <linux/of_address.h> | |
| 20 | +#include <linux/of_device.h> | |
| 21 | +#include <linux/of_irq.h> | |
| 22 | +#include <linux/regmap.h> | |
| 23 | + | |
| 24 | +#include "../pinctrl/core.h" | |
| 25 | +#include "../pinctrl/pinctrl-rockchip.h" | |
| 26 | + | |
| 27 | +#define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */ | |
| 28 | +#define GPIO_TYPE_V2 (0x01000C2B) /* GPIO Version ID 0x01000C2B */ | |
| 29 | + | |
| 30 | +static const struct rockchip_gpio_regs gpio_regs_v1 = { | |
| 31 | + .port_dr = 0x00, | |
| 32 | + .port_ddr = 0x04, | |
| 33 | + .int_en = 0x30, | |
| 34 | + .int_mask = 0x34, | |
| 35 | + .int_type = 0x38, | |
| 36 | + .int_polarity = 0x3c, | |
| 37 | + .int_status = 0x40, | |
| 38 | + .int_rawstatus = 0x44, | |
| 39 | + .debounce = 0x48, | |
| 40 | + .port_eoi = 0x4c, | |
| 41 | + .ext_port = 0x50, | |
| 42 | +}; | |
| 43 | + | |
| 44 | +static const struct rockchip_gpio_regs gpio_regs_v2 = { | |
| 45 | + .port_dr = 0x00, | |
| 46 | + .port_ddr = 0x08, | |
| 47 | + .int_en = 0x10, | |
| 48 | + .int_mask = 0x18, | |
| 49 | + .int_type = 0x20, | |
| 50 | + .int_polarity = 0x28, | |
| 51 | + .int_bothedge = 0x30, | |
| 52 | + .int_status = 0x50, | |
| 53 | + .int_rawstatus = 0x58, | |
| 54 | + .debounce = 0x38, | |
| 55 | + .dbclk_div_en = 0x40, | |
| 56 | + .dbclk_div_con = 0x48, | |
| 57 | + .port_eoi = 0x60, | |
| 58 | + .ext_port = 0x70, | |
| 59 | + .version_id = 0x78, | |
| 60 | +}; | |
| 61 | + | |
| 62 | +static inline void gpio_writel_v2(u32 val, void __iomem *reg) | |
| 63 | +{ | |
| 64 | + writel((val & 0xffff) | 0xffff0000, reg); | |
| 65 | + writel((val >> 16) | 0xffff0000, reg + 0x4); | |
| 66 | +} | |
| 67 | + | |
| 68 | +static inline u32 gpio_readl_v2(void __iomem *reg) | |
| 69 | +{ | |
| 70 | + return readl(reg + 0x4) << 16 | readl(reg); | |
| 71 | +} | |
| 72 | + | |
| 73 | +static inline void rockchip_gpio_writel(struct rockchip_pin_bank *bank, | |
| 74 | + u32 value, unsigned int offset) | |
| 75 | +{ | |
| 76 | + void __iomem *reg = bank->reg_base + offset; | |
| 77 | + | |
| 78 | + if (bank->gpio_type == GPIO_TYPE_V2) | |
| 79 | + gpio_writel_v2(value, reg); | |
| 80 | + else | |
| 81 | + writel(value, reg); | |
| 82 | +} | |
| 83 | + | |
| 84 | +static inline u32 rockchip_gpio_readl(struct rockchip_pin_bank *bank, | |
| 85 | + unsigned int offset) | |
| 86 | +{ | |
| 87 | + void __iomem *reg = bank->reg_base + offset; | |
| 88 | + u32 value; | |
| 89 | + | |
| 90 | + if (bank->gpio_type == GPIO_TYPE_V2) | |
| 91 | + value = gpio_readl_v2(reg); | |
| 92 | + else | |
| 93 | + value = readl(reg); | |
| 94 | + | |
| 95 | + return value; | |
| 96 | +} | |
| 97 | + | |
| 98 | +static inline void rockchip_gpio_writel_bit(struct rockchip_pin_bank *bank, | |
| 99 | + u32 bit, u32 value, | |
| 100 | + unsigned int offset) | |
| 101 | +{ | |
| 102 | + void __iomem *reg = bank->reg_base + offset; | |
| 103 | + u32 data; | |
| 104 | + | |
| 105 | + if (bank->gpio_type == GPIO_TYPE_V2) { | |
| 106 | + if (value) | |
| 107 | + data = BIT(bit % 16) | BIT(bit % 16 + 16); | |
| 108 | + else | |
| 109 | + data = BIT(bit % 16 + 16); | |
| 110 | + writel(data, bit >= 16 ? reg + 0x4 : reg); | |
| 111 | + } else { | |
| 112 | + data = readl(reg); | |
| 113 | + data &= ~BIT(bit); | |
| 114 | + if (value) | |
| 115 | + data |= BIT(bit); | |
| 116 | + writel(data, reg); | |
| 117 | + } | |
| 118 | +} | |
| 119 | + | |
| 120 | +static inline u32 rockchip_gpio_readl_bit(struct rockchip_pin_bank *bank, | |
| 121 | + u32 bit, unsigned int offset) | |
| 122 | +{ | |
| 123 | + void __iomem *reg = bank->reg_base + offset; | |
| 124 | + u32 data; | |
| 125 | + | |
| 126 | + if (bank->gpio_type == GPIO_TYPE_V2) { | |
| 127 | + data = readl(bit >= 16 ? reg + 0x4 : reg); | |
| 128 | + data >>= bit % 16; | |
| 129 | + } else { | |
| 130 | + data = readl(reg); | |
| 131 | + data >>= bit; | |
| 132 | + } | |
| 133 | + | |
| 134 | + return data & (0x1); | |
| 135 | +} | |
| 136 | + | |
| 137 | +static int rockchip_gpio_get_direction(struct gpio_chip *chip, | |
| 138 | + unsigned int offset) | |
| 139 | +{ | |
| 140 | + struct rockchip_pin_bank *bank = gpiochip_get_data(chip); | |
| 141 | + u32 data; | |
| 142 | + | |
| 143 | + data = rockchip_gpio_readl_bit(bank, offset, bank->gpio_regs->port_ddr); | |
| 144 | + if (data & BIT(offset)) | |
| 145 | + return GPIO_LINE_DIRECTION_OUT; | |
| 146 | + | |
| 147 | + return GPIO_LINE_DIRECTION_IN; | |
| 148 | +} | |
| 149 | + | |
| 150 | +static int rockchip_gpio_set_direction(struct gpio_chip *chip, | |
| 151 | + unsigned int offset, bool input) | |
| 152 | +{ | |
| 153 | + struct rockchip_pin_bank *bank = gpiochip_get_data(chip); | |
| 154 | + unsigned long flags; | |
| 155 | + u32 data = input ? 0 : 1; | |
| 156 | + | |
| 157 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 158 | + rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); | |
| 159 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 160 | + | |
| 161 | + return 0; | |
| 162 | +} | |
| 163 | + | |
| 164 | +static void rockchip_gpio_set(struct gpio_chip *gc, unsigned int offset, | |
| 165 | + int value) | |
| 166 | +{ | |
| 167 | + struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 168 | + unsigned long flags; | |
| 169 | + | |
| 170 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 171 | + rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr); | |
| 172 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 173 | +} | |
| 174 | + | |
| 175 | +static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset) | |
| 176 | +{ | |
| 177 | + struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 178 | + u32 data; | |
| 179 | + | |
| 180 | + data = readl(bank->reg_base + bank->gpio_regs->ext_port); | |
| 181 | + data >>= offset; | |
| 182 | + data &= 1; | |
| 183 | + | |
| 184 | + return data; | |
| 185 | +} | |
| 186 | + | |
| 187 | +static int rockchip_gpio_set_debounce(struct gpio_chip *gc, | |
| 188 | + unsigned int offset, | |
| 189 | + unsigned int debounce) | |
| 190 | +{ | |
| 191 | + struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 192 | + const struct rockchip_gpio_regs *reg = bank->gpio_regs; | |
| 193 | + unsigned long flags, div_reg, freq, max_debounce; | |
| 194 | + bool div_debounce_support; | |
| 195 | + unsigned int cur_div_reg; | |
| 196 | + u64 div; | |
| 197 | + | |
| 198 | + if (!IS_ERR(bank->db_clk)) { | |
| 199 | + div_debounce_support = true; | |
| 200 | + freq = clk_get_rate(bank->db_clk); | |
| 201 | + max_debounce = (GENMASK(23, 0) + 1) * 2 * 1000000 / freq; | |
| 202 | + if (debounce > max_debounce) | |
| 203 | + return -EINVAL; | |
| 204 | + | |
| 205 | + div = debounce * freq; | |
| 206 | + div_reg = DIV_ROUND_CLOSEST_ULL(div, 2 * USEC_PER_SEC) - 1; | |
| 207 | + } else { | |
| 208 | + div_debounce_support = false; | |
| 209 | + } | |
| 210 | + | |
| 211 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 212 | + | |
| 213 | + /* Only the v1 needs to configure div_en and div_con for dbclk */ | |
| 214 | + if (debounce) { | |
| 215 | + if (div_debounce_support) { | |
| 216 | + /* Configure the max debounce from consumers */ | |
| 217 | + cur_div_reg = readl(bank->reg_base + | |
| 218 | + reg->dbclk_div_con); | |
| 219 | + if (cur_div_reg < div_reg) | |
| 220 | + writel(div_reg, bank->reg_base + | |
| 221 | + reg->dbclk_div_con); | |
| 222 | + rockchip_gpio_writel_bit(bank, offset, 1, | |
| 223 | + reg->dbclk_div_en); | |
| 224 | + } | |
| 225 | + | |
| 226 | + rockchip_gpio_writel_bit(bank, offset, 1, reg->debounce); | |
| 227 | + } else { | |
| 228 | + if (div_debounce_support) | |
| 229 | + rockchip_gpio_writel_bit(bank, offset, 0, | |
| 230 | + reg->dbclk_div_en); | |
| 231 | + | |
| 232 | + rockchip_gpio_writel_bit(bank, offset, 0, reg->debounce); | |
| 233 | + } | |
| 234 | + | |
| 235 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 236 | + | |
| 237 | + /* Enable or disable dbclk at last */ | |
| 238 | + if (div_debounce_support) { | |
| 239 | + if (debounce) | |
| 240 | + clk_prepare_enable(bank->db_clk); | |
| 241 | + else | |
| 242 | + clk_disable_unprepare(bank->db_clk); | |
| 243 | + } | |
| 244 | + | |
| 245 | + return 0; | |
| 246 | +} | |
| 247 | + | |
| 248 | +static int rockchip_gpio_direction_input(struct gpio_chip *gc, | |
| 249 | + unsigned int offset) | |
| 250 | +{ | |
| 251 | + return rockchip_gpio_set_direction(gc, offset, true); | |
| 252 | +} | |
| 253 | + | |
| 254 | +static int rockchip_gpio_direction_output(struct gpio_chip *gc, | |
| 255 | + unsigned int offset, int value) | |
| 256 | +{ | |
| 257 | + rockchip_gpio_set(gc, offset, value); | |
| 258 | + | |
| 259 | + return rockchip_gpio_set_direction(gc, offset, false); | |
| 260 | +} | |
| 261 | + | |
| 262 | +/* | |
| 263 | + * gpiolib set_config callback function. The setting of the pin | |
| 264 | + * mux function as 'gpio output' will be handled by the pinctrl subsystem | |
| 265 | + * interface. | |
| 266 | + */ | |
| 267 | +static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset, | |
| 268 | + unsigned long config) | |
| 269 | +{ | |
| 270 | + enum pin_config_param param = pinconf_to_config_param(config); | |
| 271 | + | |
| 272 | + switch (param) { | |
| 273 | + case PIN_CONFIG_INPUT_DEBOUNCE: | |
| 274 | + rockchip_gpio_set_debounce(gc, offset, true); | |
| 275 | + /* | |
| 276 | + * Rockchip's gpio could only support up to one period | |
| 277 | + * of the debounce clock(pclk), which is far away from | |
| 278 | + * satisftying the requirement, as pclk is usually near | |
| 279 | + * 100MHz shared by all peripherals. So the fact is it | |
| 280 | + * has crippled debounce capability could only be useful | |
| 281 | + * to prevent any spurious glitches from waking up the system | |
| 282 | + * if the gpio is conguired as wakeup interrupt source. Let's | |
| 283 | + * still return -ENOTSUPP as before, to make sure the caller | |
| 284 | + * of gpiod_set_debounce won't change its behaviour. | |
| 285 | + */ | |
| 286 | + return -ENOTSUPP; | |
| 287 | + default: | |
| 288 | + return -ENOTSUPP; | |
| 289 | + } | |
| 290 | +} | |
| 291 | + | |
| 292 | +/* | |
| 293 | + * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin | |
| 294 | + * and a virtual IRQ, if not already present. | |
| 295 | + */ | |
| 296 | +static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) | |
| 297 | +{ | |
| 298 | + struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 299 | + unsigned int virq; | |
| 300 | + | |
| 301 | + if (!bank->domain) | |
| 302 | + return -ENXIO; | |
| 303 | + | |
| 304 | + virq = irq_create_mapping(bank->domain, offset); | |
| 305 | + | |
| 306 | + return (virq) ? : -ENXIO; | |
| 307 | +} | |
| 308 | + | |
| 309 | +static const struct gpio_chip rockchip_gpiolib_chip = { | |
| 310 | + .request = gpiochip_generic_request, | |
| 311 | + .free = gpiochip_generic_free, | |
| 312 | + .set = rockchip_gpio_set, | |
| 313 | + .get = rockchip_gpio_get, | |
| 314 | + .get_direction = rockchip_gpio_get_direction, | |
| 315 | + .direction_input = rockchip_gpio_direction_input, | |
| 316 | + .direction_output = rockchip_gpio_direction_output, | |
| 317 | + .set_config = rockchip_gpio_set_config, | |
| 318 | + .to_irq = rockchip_gpio_to_irq, | |
| 319 | + .owner = THIS_MODULE, | |
| 320 | +}; | |
| 321 | + | |
| 322 | +static void rockchip_irq_demux(struct irq_desc *desc) | |
| 323 | +{ | |
| 324 | + struct irq_chip *chip = irq_desc_get_chip(desc); | |
| 325 | + struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc); | |
| 326 | + u32 pend; | |
| 327 | + | |
| 328 | + dev_dbg(bank->dev, "got irq for bank %s\n", bank->name); | |
| 329 | + | |
| 330 | + chained_irq_enter(chip, desc); | |
| 331 | + | |
| 332 | + pend = readl_relaxed(bank->reg_base + bank->gpio_regs->int_status); | |
| 333 | + | |
| 334 | + while (pend) { | |
| 335 | + unsigned int irq, virq; | |
| 336 | + | |
| 337 | + irq = __ffs(pend); | |
| 338 | + pend &= ~BIT(irq); | |
| 339 | + virq = irq_find_mapping(bank->domain, irq); | |
| 340 | + | |
| 341 | + if (!virq) { | |
| 342 | + dev_err(bank->dev, "unmapped irq %d\n", irq); | |
| 343 | + continue; | |
| 344 | + } | |
| 345 | + | |
| 346 | + dev_dbg(bank->dev, "handling irq %d\n", irq); | |
| 347 | + | |
| 348 | + /* | |
| 349 | + * Triggering IRQ on both rising and falling edge | |
| 350 | + * needs manual intervention. | |
| 351 | + */ | |
| 352 | + if (bank->toggle_edge_mode & BIT(irq)) { | |
| 353 | + u32 data, data_old, polarity; | |
| 354 | + unsigned long flags; | |
| 355 | + | |
| 356 | + data = readl_relaxed(bank->reg_base + | |
| 357 | + bank->gpio_regs->ext_port); | |
| 358 | + do { | |
| 359 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 360 | + | |
| 361 | + polarity = readl_relaxed(bank->reg_base + | |
| 362 | + bank->gpio_regs->int_polarity); | |
| 363 | + if (data & BIT(irq)) | |
| 364 | + polarity &= ~BIT(irq); | |
| 365 | + else | |
| 366 | + polarity |= BIT(irq); | |
| 367 | + writel(polarity, | |
| 368 | + bank->reg_base + | |
| 369 | + bank->gpio_regs->int_polarity); | |
| 370 | + | |
| 371 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 372 | + | |
| 373 | + data_old = data; | |
| 374 | + data = readl_relaxed(bank->reg_base + | |
| 375 | + bank->gpio_regs->ext_port); | |
| 376 | + } while ((data & BIT(irq)) != (data_old & BIT(irq))); | |
| 377 | + } | |
| 378 | + | |
| 379 | + generic_handle_irq(virq); | |
| 380 | + } | |
| 381 | + | |
| 382 | + chained_irq_exit(chip, desc); | |
| 383 | +} | |
| 384 | + | |
| 385 | +static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |
| 386 | +{ | |
| 387 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 388 | + struct rockchip_pin_bank *bank = gc->private; | |
| 389 | + u32 mask = BIT(d->hwirq); | |
| 390 | + u32 polarity; | |
| 391 | + u32 level; | |
| 392 | + u32 data; | |
| 393 | + unsigned long flags; | |
| 394 | + int ret = 0; | |
| 395 | + | |
| 396 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 397 | + | |
| 398 | + rockchip_gpio_writel_bit(bank, d->hwirq, 0, | |
| 399 | + bank->gpio_regs->port_ddr); | |
| 400 | + | |
| 401 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 402 | + | |
| 403 | + if (type & IRQ_TYPE_EDGE_BOTH) | |
| 404 | + irq_set_handler_locked(d, handle_edge_irq); | |
| 405 | + else | |
| 406 | + irq_set_handler_locked(d, handle_level_irq); | |
| 407 | + | |
| 408 | + raw_spin_lock_irqsave(&bank->slock, flags); | |
| 409 | + | |
| 410 | + level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); | |
| 411 | + polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); | |
| 412 | + | |
| 413 | + switch (type) { | |
| 414 | + case IRQ_TYPE_EDGE_BOTH: | |
| 415 | + if (bank->gpio_type == GPIO_TYPE_V2) { | |
| 416 | + bank->toggle_edge_mode &= ~mask; | |
| 417 | + rockchip_gpio_writel_bit(bank, d->hwirq, 1, | |
| 418 | + bank->gpio_regs->int_bothedge); | |
| 419 | + goto out; | |
| 420 | + } else { | |
| 421 | + bank->toggle_edge_mode |= mask; | |
| 422 | + level |= mask; | |
| 423 | + | |
| 424 | + /* | |
| 425 | + * Determine gpio state. If 1 next interrupt should be | |
| 426 | + * falling otherwise rising. | |
| 427 | + */ | |
| 428 | + data = readl(bank->reg_base + bank->gpio_regs->ext_port); | |
| 429 | + if (data & mask) | |
| 430 | + polarity &= ~mask; | |
| 431 | + else | |
| 432 | + polarity |= mask; | |
| 433 | + } | |
| 434 | + break; | |
| 435 | + case IRQ_TYPE_EDGE_RISING: | |
| 436 | + bank->toggle_edge_mode &= ~mask; | |
| 437 | + level |= mask; | |
| 438 | + polarity |= mask; | |
| 439 | + break; | |
| 440 | + case IRQ_TYPE_EDGE_FALLING: | |
| 441 | + bank->toggle_edge_mode &= ~mask; | |
| 442 | + level |= mask; | |
| 443 | + polarity &= ~mask; | |
| 444 | + break; | |
| 445 | + case IRQ_TYPE_LEVEL_HIGH: | |
| 446 | + bank->toggle_edge_mode &= ~mask; | |
| 447 | + level &= ~mask; | |
| 448 | + polarity |= mask; | |
| 449 | + break; | |
| 450 | + case IRQ_TYPE_LEVEL_LOW: | |
| 451 | + bank->toggle_edge_mode &= ~mask; | |
| 452 | + level &= ~mask; | |
| 453 | + polarity &= ~mask; | |
| 454 | + break; | |
| 455 | + default: | |
| 456 | + ret = -EINVAL; | |
| 457 | + goto out; | |
| 458 | + } | |
| 459 | + | |
| 460 | + rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); | |
| 461 | + rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity); | |
| 462 | +out: | |
| 463 | + raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 464 | + | |
| 465 | + return ret; | |
| 466 | +} | |
| 467 | + | |
| 468 | +static void rockchip_irq_suspend(struct irq_data *d) | |
| 469 | +{ | |
| 470 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 471 | + struct rockchip_pin_bank *bank = gc->private; | |
| 472 | + | |
| 473 | + bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask); | |
| 474 | + irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask); | |
| 475 | +} | |
| 476 | + | |
| 477 | +static void rockchip_irq_resume(struct irq_data *d) | |
| 478 | +{ | |
| 479 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 480 | + struct rockchip_pin_bank *bank = gc->private; | |
| 481 | + | |
| 482 | + irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask); | |
| 483 | +} | |
| 484 | + | |
| 485 | +static void rockchip_irq_enable(struct irq_data *d) | |
| 486 | +{ | |
| 487 | + irq_gc_mask_clr_bit(d); | |
| 488 | +} | |
| 489 | + | |
| 490 | +static void rockchip_irq_disable(struct irq_data *d) | |
| 491 | +{ | |
| 492 | + irq_gc_mask_set_bit(d); | |
| 493 | +} | |
| 494 | + | |
| 495 | +static int rockchip_interrupts_register(struct rockchip_pin_bank *bank) | |
| 496 | +{ | |
| 497 | + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | |
| 498 | + struct irq_chip_generic *gc; | |
| 499 | + int ret; | |
| 500 | + | |
| 501 | + bank->domain = irq_domain_add_linear(bank->of_node, 32, | |
| 502 | + &irq_generic_chip_ops, NULL); | |
| 503 | + if (!bank->domain) { | |
| 504 | + dev_warn(bank->dev, "could not init irq domain for bank %s\n", | |
| 505 | + bank->name); | |
| 506 | + return -EINVAL; | |
| 507 | + } | |
| 508 | + | |
| 509 | + ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, | |
| 510 | + "rockchip_gpio_irq", | |
| 511 | + handle_level_irq, | |
| 512 | + clr, 0, 0); | |
| 513 | + if (ret) { | |
| 514 | + dev_err(bank->dev, "could not alloc generic chips for bank %s\n", | |
| 515 | + bank->name); | |
| 516 | + irq_domain_remove(bank->domain); | |
| 517 | + return -EINVAL; | |
| 518 | + } | |
| 519 | + | |
| 520 | + gc = irq_get_domain_generic_chip(bank->domain, 0); | |
| 521 | + if (bank->gpio_type == GPIO_TYPE_V2) { | |
| 522 | + gc->reg_writel = gpio_writel_v2; | |
| 523 | + gc->reg_readl = gpio_readl_v2; | |
| 524 | + } | |
| 525 | + | |
| 526 | + gc->reg_base = bank->reg_base; | |
| 527 | + gc->private = bank; | |
| 528 | + gc->chip_types[0].regs.mask = bank->gpio_regs->int_mask; | |
| 529 | + gc->chip_types[0].regs.ack = bank->gpio_regs->port_eoi; | |
| 530 | + gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; | |
| 531 | + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; | |
| 532 | + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; | |
| 533 | + gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; | |
| 534 | + gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; | |
| 535 | + gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | |
| 536 | + gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; | |
| 537 | + gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; | |
| 538 | + gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; | |
| 539 | + gc->wake_enabled = IRQ_MSK(bank->nr_pins); | |
| 540 | + | |
| 541 | + /* | |
| 542 | + * Linux assumes that all interrupts start out disabled/masked. | |
| 543 | + * Our driver only uses the concept of masked and always keeps | |
| 544 | + * things enabled, so for us that's all masked and all enabled. | |
| 545 | + */ | |
| 546 | + rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_mask); | |
| 547 | + rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->port_eoi); | |
| 548 | + rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_en); | |
| 549 | + gc->mask_cache = 0xffffffff; | |
| 550 | + | |
| 551 | + irq_set_chained_handler_and_data(bank->irq, | |
| 552 | + rockchip_irq_demux, bank); | |
| 553 | + | |
| 554 | + return 0; | |
| 555 | +} | |
| 556 | + | |
| 557 | +static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) | |
| 558 | +{ | |
| 559 | + struct gpio_chip *gc; | |
| 560 | + int ret; | |
| 561 | + | |
| 562 | + bank->gpio_chip = rockchip_gpiolib_chip; | |
| 563 | + | |
| 564 | + gc = &bank->gpio_chip; | |
| 565 | + gc->base = bank->pin_base; | |
| 566 | + gc->ngpio = bank->nr_pins; | |
| 567 | + gc->label = bank->name; | |
| 568 | + gc->parent = bank->dev; | |
| 569 | +#ifdef CONFIG_OF_GPIO | |
| 570 | + gc->of_node = of_node_get(bank->of_node); | |
| 571 | +#endif | |
| 572 | + | |
| 573 | + ret = gpiochip_add_data(gc, bank); | |
| 574 | + if (ret) { | |
| 575 | + dev_err(bank->dev, "failed to add gpiochip %s, %d\n", | |
| 576 | + gc->label, ret); | |
| 577 | + return ret; | |
| 578 | + } | |
| 579 | + | |
| 580 | + /* | |
| 581 | + * For DeviceTree-supported systems, the gpio core checks the | |
| 582 | + * pinctrl's device node for the "gpio-ranges" property. | |
| 583 | + * If it is present, it takes care of adding the pin ranges | |
| 584 | + * for the driver. In this case the driver can skip ahead. | |
| 585 | + * | |
| 586 | + * In order to remain compatible with older, existing DeviceTree | |
| 587 | + * files which don't set the "gpio-ranges" property or systems that | |
| 588 | + * utilize ACPI the driver has to call gpiochip_add_pin_range(). | |
| 589 | + */ | |
| 590 | + if (!of_property_read_bool(bank->of_node, "gpio-ranges")) { | |
| 591 | + struct device_node *pctlnp = of_get_parent(bank->of_node); | |
| 592 | + struct pinctrl_dev *pctldev = NULL; | |
| 593 | + | |
| 594 | + if (!pctlnp) | |
| 595 | + return -ENODATA; | |
| 596 | + | |
| 597 | + pctldev = of_pinctrl_get(pctlnp); | |
| 598 | + if (!pctldev) | |
| 599 | + return -ENODEV; | |
| 600 | + | |
| 601 | + ret = gpiochip_add_pin_range(gc, dev_name(pctldev->dev), 0, | |
| 602 | + gc->base, gc->ngpio); | |
| 603 | + if (ret) { | |
| 604 | + dev_err(bank->dev, "Failed to add pin range\n"); | |
| 605 | + goto fail; | |
| 606 | + } | |
| 607 | + } | |
| 608 | + | |
| 609 | + ret = rockchip_interrupts_register(bank); | |
| 610 | + if (ret) { | |
| 611 | + dev_err(bank->dev, "failed to register interrupt, %d\n", ret); | |
| 612 | + goto fail; | |
| 613 | + } | |
| 614 | + | |
| 615 | + return 0; | |
| 616 | + | |
| 617 | +fail: | |
| 618 | + gpiochip_remove(&bank->gpio_chip); | |
| 619 | + | |
| 620 | + return ret; | |
| 621 | +} | |
| 622 | + | |
| 623 | +static int rockchip_get_bank_data(struct rockchip_pin_bank *bank) | |
| 624 | +{ | |
| 625 | + struct resource res; | |
| 626 | + int id = 0; | |
| 627 | + | |
| 628 | + if (of_address_to_resource(bank->of_node, 0, &res)) { | |
| 629 | + dev_err(bank->dev, "cannot find IO resource for bank\n"); | |
| 630 | + return -ENOENT; | |
| 631 | + } | |
| 632 | + | |
| 633 | + bank->reg_base = devm_ioremap_resource(bank->dev, &res); | |
| 634 | + if (IS_ERR(bank->reg_base)) | |
| 635 | + return PTR_ERR(bank->reg_base); | |
| 636 | + | |
| 637 | + bank->irq = irq_of_parse_and_map(bank->of_node, 0); | |
| 638 | + if (!bank->irq) | |
| 639 | + return -EINVAL; | |
| 640 | + | |
| 641 | + bank->clk = of_clk_get(bank->of_node, 0); | |
| 642 | + if (IS_ERR(bank->clk)) | |
| 643 | + return PTR_ERR(bank->clk); | |
| 644 | + | |
| 645 | + clk_prepare_enable(bank->clk); | |
| 646 | + id = readl(bank->reg_base + gpio_regs_v2.version_id); | |
| 647 | + | |
| 648 | + /* If not gpio v2, that is default to v1. */ | |
| 649 | + if (id == GPIO_TYPE_V2) { | |
| 650 | + bank->gpio_regs = &gpio_regs_v2; | |
| 651 | + bank->gpio_type = GPIO_TYPE_V2; | |
| 652 | + bank->db_clk = of_clk_get(bank->of_node, 1); | |
| 653 | + if (IS_ERR(bank->db_clk)) { | |
| 654 | + dev_err(bank->dev, "cannot find debounce clk\n"); | |
| 655 | + clk_disable_unprepare(bank->clk); | |
| 656 | + return -EINVAL; | |
| 657 | + } | |
| 658 | + } else { | |
| 659 | + bank->gpio_regs = &gpio_regs_v1; | |
| 660 | + bank->gpio_type = GPIO_TYPE_V1; | |
| 661 | + } | |
| 662 | + | |
| 663 | + return 0; | |
| 664 | +} | |
| 665 | + | |
| 666 | +static struct rockchip_pin_bank * | |
| 667 | +rockchip_gpio_find_bank(struct pinctrl_dev *pctldev, int id) | |
| 668 | +{ | |
| 669 | + struct rockchip_pinctrl *info; | |
| 670 | + struct rockchip_pin_bank *bank; | |
| 671 | + int i, found = 0; | |
| 672 | + | |
| 673 | + info = pinctrl_dev_get_drvdata(pctldev); | |
| 674 | + bank = info->ctrl->pin_banks; | |
| 675 | + for (i = 0; i < info->ctrl->nr_banks; i++, bank++) { | |
| 676 | + if (bank->bank_num == id) { | |
| 677 | + found = 1; | |
| 678 | + break; | |
| 679 | + } | |
| 680 | + } | |
| 681 | + | |
| 682 | + return found ? bank : NULL; | |
| 683 | +} | |
| 684 | + | |
| 685 | +static int rockchip_gpio_probe(struct platform_device *pdev) | |
| 686 | +{ | |
| 687 | + struct device *dev = &pdev->dev; | |
| 688 | + struct device_node *np = dev->of_node; | |
| 689 | + struct device_node *pctlnp = of_get_parent(np); | |
| 690 | + struct pinctrl_dev *pctldev = NULL; | |
| 691 | + struct rockchip_pin_bank *bank = NULL; | |
| 692 | + static int gpio; | |
| 693 | + int id, ret; | |
| 694 | + | |
| 695 | + if (!np || !pctlnp) | |
| 696 | + return -ENODEV; | |
| 697 | + | |
| 698 | + pctldev = of_pinctrl_get(pctlnp); | |
| 699 | + if (!pctldev) | |
| 700 | + return -EPROBE_DEFER; | |
| 701 | + | |
| 702 | + id = of_alias_get_id(np, "gpio"); | |
| 703 | + if (id < 0) | |
| 704 | + id = gpio++; | |
| 705 | + | |
| 706 | + bank = rockchip_gpio_find_bank(pctldev, id); | |
| 707 | + if (!bank) | |
| 708 | + return -EINVAL; | |
| 709 | + | |
| 710 | + bank->dev = dev; | |
| 711 | + bank->of_node = np; | |
| 712 | + | |
| 713 | + raw_spin_lock_init(&bank->slock); | |
| 714 | + | |
| 715 | + ret = rockchip_get_bank_data(bank); | |
| 716 | + if (ret) | |
| 717 | + return ret; | |
| 718 | + | |
| 719 | + ret = rockchip_gpiolib_register(bank); | |
| 720 | + if (ret) { | |
| 721 | + clk_disable_unprepare(bank->clk); | |
| 722 | + return ret; | |
| 723 | + } | |
| 724 | + | |
| 725 | + platform_set_drvdata(pdev, bank); | |
| 726 | + dev_info(dev, "probed %pOF\n", np); | |
| 727 | + | |
| 728 | + return 0; | |
| 729 | +} | |
| 730 | + | |
| 731 | +static int rockchip_gpio_remove(struct platform_device *pdev) | |
| 732 | +{ | |
| 733 | + struct rockchip_pin_bank *bank = platform_get_drvdata(pdev); | |
| 734 | + | |
| 735 | + clk_disable_unprepare(bank->clk); | |
| 736 | + gpiochip_remove(&bank->gpio_chip); | |
| 737 | + | |
| 738 | + return 0; | |
| 739 | +} | |
| 740 | + | |
| 741 | +static const struct of_device_id rockchip_gpio_match[] = { | |
| 742 | + { .compatible = "rockchip,gpio-bank", }, | |
| 743 | + { .compatible = "rockchip,rk3188-gpio-bank0" }, | |
| 744 | + { }, | |
| 745 | +}; | |
| 746 | + | |
| 747 | +static struct platform_driver rockchip_gpio_driver = { | |
| 748 | + .probe = rockchip_gpio_probe, | |
| 749 | + .remove = rockchip_gpio_remove, | |
| 750 | + .driver = { | |
| 751 | + .name = "rockchip-gpio", | |
| 752 | + .of_match_table = rockchip_gpio_match, | |
| 753 | + }, | |
| 754 | +}; | |
| 755 | + | |
| 756 | +static int __init rockchip_gpio_init(void) | |
| 757 | +{ | |
| 758 | + return platform_driver_register(&rockchip_gpio_driver); | |
| 759 | +} | |
| 760 | +postcore_initcall(rockchip_gpio_init); | |
| 761 | + | |
| 762 | +static void __exit rockchip_gpio_exit(void) | |
| 763 | +{ | |
| 764 | + platform_driver_unregister(&rockchip_gpio_driver); | |
| 765 | +} | |
| 766 | +module_exit(rockchip_gpio_exit); | |
| 767 | + | |
| 768 | +MODULE_DESCRIPTION("Rockchip gpio driver"); | |
| 769 | +MODULE_ALIAS("platform:rockchip-gpio"); | |
| 770 | +MODULE_LICENSE("GPL v2"); | |
| 771 | +MODULE_DEVICE_TABLE(of, rockchip_gpio_match); | |
| @@ -259,7 +259,7 @@ static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context) · 258 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | pending = (resume_status << sch->resume_base) | core_status; |
| 261 | 261 | for_each_set_bit(offset, &pending, sch->chip.ngpio) |
| 262 | − generic_handle_irq(irq_find_mapping(gc->irq.domain, offset)); | |
| 262 | + generic_handle_domain_irq(gc->irq.domain, offset); | |
| 263 | 263 | |
| 264 | 264 | /* Set returning value depending on whether we handled an interrupt */ |
| 265 | 265 | ret = pending ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
| @@ -84,7 +84,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) · 83 unmodified lines | ||
| 84 | 84 | return IRQ_NONE; |
| 85 | 85 | |
| 86 | 86 | for_each_set_bit(irq_bit, &irq_stat, 32) |
| 87 | − generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); | |
| 87 | + generic_handle_domain_irq(sd->id, irq_bit); | |
| 88 | 88 | |
| 89 | 89 | return IRQ_HANDLED; |
| 90 | 90 | } |
| @@ -189,7 +189,7 @@ static void sprd_gpio_irq_handler(struct irq_desc *desc) · 188 unmodified lines | ||
| 189 | 189 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); |
| 190 | 190 | struct irq_chip *ic = irq_desc_get_chip(desc); |
| 191 | 191 | struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip); |
| 192 | − u32 bank, n, girq; | |
| 192 | + u32 bank, n; | |
| 193 | 193 | |
| 194 | 194 | chained_irq_enter(ic, desc); |
| 195 | 195 | |
| @@ -198,13 +198,9 @@ static void sprd_gpio_irq_handler(struct irq_desc *desc) · 2 unmodified lines | ||
| 198 | 198 | unsigned long reg = readl_relaxed(base + SPRD_GPIO_MIS) & |
| 199 | 199 | SPRD_GPIO_BANK_MASK; |
| 200 | 200 | |
| 201 | − for_each_set_bit(n, ®, SPRD_GPIO_BANK_NR) { | |
| 202 | − girq = irq_find_mapping(chip->irq.domain, | |
| 203 | − bank * SPRD_GPIO_BANK_NR + n); | |
| 204 | − | |
| 205 | − generic_handle_irq(girq); | |
| 206 | − } | |
| 207 | − | |
| 201 | + for_each_set_bit(n, ®, SPRD_GPIO_BANK_NR) | |
| 202 | + generic_handle_domain_irq(chip->irq.domain, | |
| 203 | + bank * SPRD_GPIO_BANK_NR + n); | |
| 208 | 204 | } |
| 209 | 205 | chained_irq_exit(ic, desc); |
| 210 | 206 | } |
| @@ -100,7 +100,7 @@ static irqreturn_t tb10x_gpio_irq_cascade(int irq, void *data) · 99 unmodified lines | ||
| 100 | 100 | int i; |
| 101 | 101 | |
| 102 | 102 | for_each_set_bit(i, &bits, 32) |
| 103 | − generic_handle_irq(irq_find_mapping(tb10x_gpio->domain, i)); | |
| 103 | + generic_handle_domain_irq(tb10x_gpio->domain, i); | |
| 104 | 104 | |
| 105 | 105 | return IRQ_HANDLED; |
| 106 | 106 | } |
| @@ -408,6 +408,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc) · 407 unmodified lines | ||
| 408 | 408 | lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); |
| 409 | 409 | |
| 410 | 410 | for_each_set_bit(pin, &sta, 8) { |
| 411 | + int ret; | |
| 412 | + | |
| 411 | 413 | tegra_gpio_writel(tgi, 1 << pin, |
| 412 | 414 | GPIO_INT_CLR(tgi, gpio)); |
| 413 | 415 | |
| @@ -420,11 +422,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc) · 6 unmodified lines | ||
| 420 | 422 | chained_irq_exit(chip, desc); |
| 421 | 423 | } |
| 422 | 424 | |
| 423 | − irq = irq_find_mapping(domain, gpio + pin); | |
| 424 | − if (WARN_ON(irq == 0)) | |
| 425 | − continue; | |
| 426 | − | |
| 427 | − generic_handle_irq(irq); | |
| 425 | + ret = generic_handle_domain_irq(domain, gpio + pin); | |
| 426 | + WARN_RATELIMIT(ret, "hwirq = %d", gpio + pin); | |
| 428 | 427 | } |
| 429 | 428 | } |
| 430 | 429 | |
| @@ -456,7 +456,7 @@ static void tegra186_gpio_irq(struct irq_desc *desc) · 455 unmodified lines | ||
| 456 | 456 | |
| 457 | 457 | for (i = 0; i < gpio->soc->num_ports; i++) { |
| 458 | 458 | const struct tegra_gpio_port *port = &gpio->soc->ports[i]; |
| 459 | − unsigned int pin, irq; | |
| 459 | + unsigned int pin; | |
| 460 | 460 | unsigned long value; |
| 461 | 461 | void __iomem *base; |
| 462 | 462 | |
| @@ -469,11 +469,8 @@ static void tegra186_gpio_irq(struct irq_desc *desc) · 6 unmodified lines | ||
| 469 | 469 | value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); |
| 470 | 470 | |
| 471 | 471 | for_each_set_bit(pin, &value, port->pins) { |
| 472 | − irq = irq_find_mapping(domain, offset + pin); | |
| 473 | − if (WARN_ON(irq == 0)) | |
| 474 | − continue; | |
| 475 | − | |
| 476 | − generic_handle_irq(irq); | |
| 472 | + int ret = generic_handle_domain_irq(domain, offset + pin); | |
| 473 | + WARN_RATELIMIT(ret, "hwirq = %d", offset + pin); | |
| 477 | 474 | } |
| 478 | 475 | |
| 479 | 476 | skip: |
| @@ -183,7 +183,7 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc) · 182 unmodified lines | ||
| 183 | 183 | struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); |
| 184 | 184 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); |
| 185 | 185 | unsigned long irq_bits; |
| 186 | − int i = 0, child_irq; | |
| 186 | + int i = 0; | |
| 187 | 187 | u8 irq_status; |
| 188 | 188 | |
| 189 | 189 | chained_irq_enter(irq_chip, desc); |
| @@ -192,11 +192,9 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc) · 2 unmodified lines | ||
| 192 | 192 | tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS); |
| 193 | 193 | |
| 194 | 194 | irq_bits = irq_status; |
| 195 | − for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { | |
| 196 | − child_irq = irq_find_mapping(gpio->chip.irq.domain, | |
| 197 | − i + TQMX86_NGPO); | |
| 198 | − generic_handle_irq(child_irq); | |
| 199 | − } | |
| 195 | + for_each_set_bit(i, &irq_bits, TQMX86_NGPI) | |
| 196 | + generic_handle_domain_irq(gpio->chip.irq.domain, | |
| 197 | + i + TQMX86_NGPO); | |
| 200 | 198 | |
| 201 | 199 | chained_irq_exit(irq_chip, desc); |
| 202 | 200 | } |
| @@ -149,7 +149,7 @@ static void vf610_gpio_irq_handler(struct irq_desc *desc) · 148 unmodified lines | ||
| 149 | 149 | for_each_set_bit(pin, &irq_isfr, VF610_GPIO_PER_PORT) { |
| 150 | 150 | vf610_gpio_writel(BIT(pin), port->base + PORT_ISFR); |
| 151 | 151 | |
| 152 | − generic_handle_irq(irq_find_mapping(port->gc.irq.domain, pin)); | |
| 152 | + generic_handle_domain_irq(port->gc.irq.domain, pin); | |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | chained_irq_exit(chip, desc); |
| @@ -339,8 +339,8 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id) · 338 unmodified lines | ||
| 339 | 339 | for_each_set_bit(port, &int_pending, 3) { |
| 340 | 340 | int_id = inb(ws16c48gpio->base + 8 + port); |
| 341 | 341 | for_each_set_bit(gpio, &int_id, 8) |
| 342 | − generic_handle_irq(irq_find_mapping( | |
| 343 | − chip->irq.domain, gpio + 8*port)); | |
| 342 | + generic_handle_domain_irq(chip->irq.domain, | |
| 343 | + gpio + 8*port); | |
| 344 | 344 | } |
| 345 | 345 | |
| 346 | 346 | int_pending = inb(ws16c48gpio->base + 6) & 0x7; |
| @@ -185,7 +185,7 @@ static irqreturn_t iproc_gpio_irq_handler(int irq, void *data) · 184 unmodified lines | ||
| 185 | 185 | int_bits = level | event; |
| 186 | 186 | |
| 187 | 187 | for_each_set_bit(bit, &int_bits, gc->ngpio) |
| 188 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit)); | |
| 188 | + generic_handle_domain_irq(gc->irq.domain, bit); | |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | return int_bits ? IRQ_HANDLED : IRQ_NONE; |
| @@ -538,7 +538,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) · 537 unmodified lines | ||
| 538 | 538 | |
| 539 | 539 | for_each_set_bit(bit, all, 64) { |
| 540 | 540 | irq_offset = xgpio_from_bit(chip, bit); |
| 541 | − generic_handle_irq(irq_find_mapping(gc->irq.domain, irq_offset)); | |
| 541 | + generic_handle_domain_irq(gc->irq.domain, irq_offset); | |
| 542 | 542 | } |
| 543 | 543 | |
| 544 | 544 | chained_irq_exit(irqchip, desc); |
| @@ -216,8 +216,7 @@ static void xlp_gpio_generic_handler(struct irq_desc *desc) · 215 unmodified lines | ||
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | if (gpio_stat & BIT(gpio % XLP_GPIO_REGSZ)) |
| 219 | − generic_handle_irq(irq_find_mapping( | |
| 220 | − priv->chip.irq.domain, gpio)); | |
| 219 | + generic_handle_domain_irq(priv->chip.irq.domain, gpio); | |
| 221 | 220 | } |
| 222 | 221 | chained_irq_exit(irqchip, desc); |
| 223 | 222 | } |
| @@ -628,12 +628,8 @@ static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio, · 627 unmodified lines | ||
| 628 | 628 | if (!pending) |
| 629 | 629 | return; |
| 630 | 630 | |
| 631 | − for_each_set_bit(offset, &pending, 32) { | |
| 632 | − unsigned int gpio_irq; | |
| 633 | − | |
| 634 | − gpio_irq = irq_find_mapping(irqdomain, offset + bank_offset); | |
| 635 | − generic_handle_irq(gpio_irq); | |
| 636 | − } | |
| 631 | + for_each_set_bit(offset, &pending, 32) | |
| 632 | + generic_handle_domain_irq(irqdomain, offset + bank_offset); | |
| 637 | 633 | } |
| 638 | 634 | |
| 639 | 635 | /** |
| @@ -502,7 +502,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, · 501 unmodified lines | ||
| 502 | 502 | |
| 503 | 503 | } else if ((client_id == AMDGPU_IRQ_CLIENTID_LEGACY) && |
| 504 | 504 | adev->irq.virq[src_id]) { |
| 505 | − generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id)); | |
| 505 | + generic_handle_domain_irq(adev->irq.domain, src_id); | |
| 506 | 506 | |
| 507 | 507 | } else if (!adev->irq.client[client_id].sources) { |
| 508 | 508 | DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n", |
| @@ -45,20 +45,13 @@ static void dpu_mdss_irq(struct irq_desc *desc) · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | while (interrupts) { |
| 47 | 47 | irq_hw_number_t hwirq = fls(interrupts) - 1; |
| 48 | − unsigned int mapping; | |
| 49 | 48 | int rc; |
| 50 | 49 | |
| 51 | − mapping = irq_find_mapping(dpu_mdss->irq_controller.domain, | |
| 52 | − hwirq); | |
| 53 | − if (mapping == 0) { | |
| 54 | − DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq); | |
| 55 | − break; | |
| 56 | − } | |
| 57 | − | |
| 58 | − rc = generic_handle_irq(mapping); | |
| 50 | + rc = generic_handle_domain_irq(dpu_mdss->irq_controller.domain, | |
| 51 | + hwirq); | |
| 59 | 52 | if (rc < 0) { |
| 60 | − DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n", | |
| 61 | − hwirq, mapping, rc); | |
| 53 | + DRM_ERROR("handle irq fail: irq=%lu rc=%d\n", | |
| 54 | + hwirq, rc); | |
| 62 | 55 | break; |
| 63 | 56 | } |
| 64 | 57 | |
| @@ -50,8 +50,7 @@ static irqreturn_t mdss_irq(int irq, void *arg) · 49 unmodified lines | ||
| 50 | 50 | while (intr) { |
| 51 | 51 | irq_hw_number_t hwirq = fls(intr) - 1; |
| 52 | 52 | |
| 53 | − generic_handle_irq(irq_find_mapping( | |
| 54 | − mdp5_mdss->irqcontroller.domain, hwirq)); | |
| 53 | + generic_handle_domain_irq(mdp5_mdss->irqcontroller.domain, hwirq); | |
| 55 | 54 | intr &= ~(1 << hwirq); |
| 56 | 55 | } |
| 57 | 56 | |
| @@ -1003,19 +1003,16 @@ err_cpmem: · 1002 unmodified lines | ||
| 1003 | 1003 | static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs) |
| 1004 | 1004 | { |
| 1005 | 1005 | unsigned long status; |
| 1006 | − int i, bit, irq; | |
| 1006 | + int i, bit; | |
| 1007 | 1007 | |
| 1008 | 1008 | for (i = 0; i < num_regs; i++) { |
| 1009 | 1009 | |
| 1010 | 1010 | status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i])); |
| 1011 | 1011 | status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i])); |
| 1012 | 1012 | |
| 1013 | − for_each_set_bit(bit, &status, 32) { | |
| 1014 | − irq = irq_linear_revmap(ipu->domain, | |
| 1015 | − regs[i] * 32 + bit); | |
| 1016 | − if (irq) | |
| 1017 | − generic_handle_irq(irq); | |
| 1018 | − } | |
| 1013 | + for_each_set_bit(bit, &status, 32) | |
| 1014 | + generic_handle_domain_irq(ipu->domain, | |
| 1015 | + regs[i] * 32 + bit); | |
| 1019 | 1016 | } |
| 1020 | 1017 | } |
| 1021 | 1018 | |
| @@ -267,9 +267,7 @@ static int alpine_msix_init(struct device_node *node, · 266 unmodified lines | ||
| 267 | 267 | goto err_priv; |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | − priv->msi_map = kcalloc(BITS_TO_LONGS(priv->num_spis), | |
| 271 | − sizeof(*priv->msi_map), | |
| 272 | − GFP_KERNEL); | |
| 270 | + priv->msi_map = bitmap_zalloc(priv->num_spis, GFP_KERNEL); | |
| 273 | 271 | if (!priv->msi_map) { |
| 274 | 272 | ret = -ENOMEM; |
| 275 | 273 | goto err_priv; |
| @@ -285,7 +283,7 @@ static int alpine_msix_init(struct device_node *node, · 9 unmodified lines | ||
| 285 | 283 | return 0; |
| 286 | 284 | |
| 287 | 285 | err_map: |
| 288 | − kfree(priv->msi_map); | |
| 286 | + bitmap_free(priv->msi_map); | |
| 289 | 287 | err_priv: |
| 290 | 288 | kfree(priv); |
| 291 | 289 | return ret; |
| @@ -226,7 +226,7 @@ static void aic_irq_eoi(struct irq_data *d) · 225 unmodified lines | ||
| 226 | 226 | * Reading the interrupt reason automatically acknowledges and masks |
| 227 | 227 | * the IRQ, so we just unmask it here if needed. |
| 228 | 228 | */ |
| 229 | − if (!irqd_irq_disabled(d) && !irqd_irq_masked(d)) | |
| 229 | + if (!irqd_irq_masked(d)) | |
| 230 | 230 | aic_irq_unmask(d); |
| 231 | 231 | } |
| 232 | 232 | |
| @@ -269,7 +269,7 @@ static void gicv2m_teardown(void) · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | list_for_each_entry_safe(v2m, tmp, &v2m_nodes, entry) { |
| 271 | 271 | list_del(&v2m->entry); |
| 272 | − kfree(v2m->bm); | |
| 272 | + bitmap_free(v2m->bm); | |
| 273 | 273 | iounmap(v2m->base); |
| 274 | 274 | of_node_put(to_of_node(v2m->fwnode)); |
| 275 | 275 | if (is_fwnode_irqchip(v2m->fwnode)) |
| @@ -386,8 +386,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode, · 110 unmodified lines | ||
| 386 | 386 | break; |
| 387 | 387 | } |
| 388 | 388 | } |
| 389 | − v2m->bm = kcalloc(BITS_TO_LONGS(v2m->nr_spis), sizeof(long), | |
| 390 | − GFP_KERNEL); | |
| 389 | + v2m->bm = bitmap_zalloc(v2m->nr_spis, GFP_KERNEL); | |
| 391 | 390 | if (!v2m->bm) { |
| 392 | 391 | ret = -ENOMEM; |
| 393 | 392 | goto err_iounmap; |
| @@ -2140,7 +2140,7 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) · 2139 unmodified lines | ||
| 2140 | 2140 | if (err) |
| 2141 | 2141 | goto out; |
| 2142 | 2142 | |
| 2143 | − bitmap = kcalloc(BITS_TO_LONGS(nr_irqs), sizeof (long), GFP_ATOMIC); | |
| 2143 | + bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC); | |
| 2144 | 2144 | if (!bitmap) |
| 2145 | 2145 | goto out; |
| 2146 | 2146 | |
| @@ -2156,7 +2156,7 @@ out: · 9 unmodified lines | ||
| 2156 | 2156 | static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids) |
| 2157 | 2157 | { |
| 2158 | 2158 | WARN_ON(free_lpi_range(base, nr_ids)); |
| 2159 | − kfree(bitmap); | |
| 2159 | + bitmap_free(bitmap); | |
| 2160 | 2160 | } |
| 2161 | 2161 | |
| 2162 | 2162 | static void gic_reset_prop_table(void *va) |
| @@ -3387,7 +3387,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 1224 unmodified lines | ||
| 3387 | 3387 | if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) { |
| 3388 | 3388 | kfree(dev); |
| 3389 | 3389 | kfree(itt); |
| 3390 | − kfree(lpi_map); | |
| 3390 | + bitmap_free(lpi_map); | |
| 3391 | 3391 | kfree(col_map); |
| 3392 | 3392 | return NULL; |
| 3393 | 3393 | } |
| @@ -290,8 +290,7 @@ int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent) · 289 unmodified lines | ||
| 290 | 290 | if (ret) |
| 291 | 291 | goto err_free_mbi; |
| 292 | 292 | |
| 293 | − mbi_ranges[n].bm = kcalloc(BITS_TO_LONGS(mbi_ranges[n].nr_spis), | |
| 294 | − sizeof(long), GFP_KERNEL); | |
| 293 | + mbi_ranges[n].bm = bitmap_zalloc(mbi_ranges[n].nr_spis, GFP_KERNEL); | |
| 295 | 294 | if (!mbi_ranges[n].bm) { |
| 296 | 295 | ret = -ENOMEM; |
| 297 | 296 | goto err_free_mbi; |
| @@ -329,7 +328,7 @@ int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent) · 31 unmodified lines | ||
| 329 | 328 | err_free_mbi: |
| 330 | 329 | if (mbi_ranges) { |
| 331 | 330 | for (n = 0; n < mbi_range_nr; n++) |
| 332 | − kfree(mbi_ranges[n].bm); | |
| 331 | + bitmap_free(mbi_ranges[n].bm); | |
| 333 | 332 | kfree(mbi_ranges); |
| 334 | 333 | } |
| 335 | 334 | |
| @@ -100,6 +100,27 @@ EXPORT_SYMBOL(gic_pmr_sync); · 99 unmodified lines | ||
| 100 | 100 | DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities); |
| 101 | 101 | EXPORT_SYMBOL(gic_nonsecure_priorities); |
| 102 | 102 | |
| 103 | +/* | |
| 104 | + * When the Non-secure world has access to group 0 interrupts (as a | |
| 105 | + * consequence of SCR_EL3.FIQ == 0), reading the ICC_RPR_EL1 register will | |
| 106 | + * return the Distributor's view of the interrupt priority. | |
| 107 | + * | |
| 108 | + * When GIC security is enabled (GICD_CTLR.DS == 0), the interrupt priority | |
| 109 | + * written by software is moved to the Non-secure range by the Distributor. | |
| 110 | + * | |
| 111 | + * If both are true (which is when gic_nonsecure_priorities gets enabled), | |
| 112 | + * we need to shift down the priority programmed by software to match it | |
| 113 | + * against the value returned by ICC_RPR_EL1. | |
| 114 | + */ | |
| 115 | +#define GICD_INT_RPR_PRI(priority) \ | |
| 116 | + ({ \ | |
| 117 | + u32 __priority = (priority); \ | |
| 118 | + if (static_branch_unlikely(&gic_nonsecure_priorities)) \ | |
| 119 | + __priority = 0x80 | (__priority >> 1); \ | |
| 120 | + \ | |
| 121 | + __priority; \ | |
| 122 | + }) | |
| 123 | + | |
| 103 | 124 | /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */ |
| 104 | 125 | static refcount_t *ppi_nmi_refs; |
| 105 | 126 | |
| @@ -446,18 +467,23 @@ static void gic_irq_set_prio(struct irq_data *d, u8 prio) · 340 unmodified lines | ||
| 446 | 467 | writeb_relaxed(prio, base + offset + index); |
| 447 | 468 | } |
| 448 | 469 | |
| 449 | −static u32 gic_get_ppi_index(struct irq_data *d) | |
| 470 | +static u32 __gic_get_ppi_index(irq_hw_number_t hwirq) | |
| 450 | 471 | { |
| 451 | − switch (get_intid_range(d)) { | |
| 472 | + switch (__get_intid_range(hwirq)) { | |
| 452 | 473 | case PPI_RANGE: |
| 453 | − return d->hwirq - 16; | |
| 474 | + return hwirq - 16; | |
| 454 | 475 | case EPPI_RANGE: |
| 455 | − return d->hwirq - EPPI_BASE_INTID + 16; | |
| 476 | + return hwirq - EPPI_BASE_INTID + 16; | |
| 456 | 477 | default: |
| 457 | 478 | unreachable(); |
| 458 | 479 | } |
| 459 | 480 | } |
| 460 | 481 | |
| 482 | +static u32 gic_get_ppi_index(struct irq_data *d) | |
| 483 | +{ | |
| 484 | + return __gic_get_ppi_index(d->hwirq); | |
| 485 | +} | |
| 486 | + | |
| 461 | 487 | static int gic_irq_nmi_setup(struct irq_data *d) |
| 462 | 488 | { |
| 463 | 489 | struct irq_desc *desc = irq_to_desc(d->irq); |
| @@ -687,7 +713,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs · 223 unmodified lines | ||
| 687 | 713 | return; |
| 688 | 714 | |
| 689 | 715 | if (gic_supports_nmi() && |
| 690 | − unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) { | |
| 716 | + unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) { | |
| 691 | 717 | gic_handle_nmi(irqnr, regs); |
| 692 | 718 | return; |
| 693 | 719 | } |
| @@ -1467,10 +1493,34 @@ static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, · 773 unmodified lines | ||
| 1467 | 1493 | } |
| 1468 | 1494 | } |
| 1469 | 1495 | |
| 1496 | +static bool fwspec_is_partitioned_ppi(struct irq_fwspec *fwspec, | |
| 1497 | + irq_hw_number_t hwirq) | |
| 1498 | +{ | |
| 1499 | + enum gic_intid_range range; | |
| 1500 | + | |
| 1501 | + if (!gic_data.ppi_descs) | |
| 1502 | + return false; | |
| 1503 | + | |
| 1504 | + if (!is_of_node(fwspec->fwnode)) | |
| 1505 | + return false; | |
| 1506 | + | |
| 1507 | + if (fwspec->param_count < 4 || !fwspec->param[3]) | |
| 1508 | + return false; | |
| 1509 | + | |
| 1510 | + range = __get_intid_range(hwirq); | |
| 1511 | + if (range != PPI_RANGE && range != EPPI_RANGE) | |
| 1512 | + return false; | |
| 1513 | + | |
| 1514 | + return true; | |
| 1515 | +} | |
| 1516 | + | |
| 1470 | 1517 | static int gic_irq_domain_select(struct irq_domain *d, |
| 1471 | 1518 | struct irq_fwspec *fwspec, |
| 1472 | 1519 | enum irq_domain_bus_token bus_token) |
| 1473 | 1520 | { |
| 1521 | + unsigned int type, ret, ppi_idx; | |
| 1522 | + irq_hw_number_t hwirq; | |
| 1523 | + | |
| 1474 | 1524 | /* Not for us */ |
| 1475 | 1525 | if (fwspec->fwnode != d->fwnode) |
| 1476 | 1526 | return 0; |
| @@ -1479,16 +1529,19 @@ static int gic_irq_domain_select(struct irq_domain *d, · 2 unmodified lines | ||
| 1479 | 1529 | if (!is_of_node(fwspec->fwnode)) |
| 1480 | 1530 | return 1; |
| 1481 | 1531 | |
| 1532 | + ret = gic_irq_domain_translate(d, fwspec, &hwirq, &type); | |
| 1533 | + if (WARN_ON_ONCE(ret)) | |
| 1534 | + return 0; | |
| 1535 | + | |
| 1536 | + if (!fwspec_is_partitioned_ppi(fwspec, hwirq)) | |
| 1537 | + return d == gic_data.domain; | |
| 1538 | + | |
| 1482 | 1539 | /* |
| 1483 | 1540 | * If this is a PPI and we have a 4th (non-null) parameter, |
| 1484 | 1541 | * then we need to match the partition domain. |
| 1485 | 1542 | */ |
| 1486 | − if (fwspec->param_count >= 4 && | |
| 1487 | − fwspec->param[0] == 1 && fwspec->param[3] != 0 && | |
| 1488 | − gic_data.ppi_descs) | |
| 1489 | − return d == partition_get_domain(gic_data.ppi_descs[fwspec->param[1]]); | |
| 1490 | − | |
| 1491 | − return d == gic_data.domain; | |
| 1543 | + ppi_idx = __gic_get_ppi_index(hwirq); | |
| 1544 | + return d == partition_get_domain(gic_data.ppi_descs[ppi_idx]); | |
| 1492 | 1545 | } |
| 1493 | 1546 | |
| 1494 | 1547 | static const struct irq_domain_ops gic_irq_domain_ops = { |
| @@ -1503,7 +1556,9 @@ static int partition_domain_translate(struct irq_domain *d, · 8 unmodified lines | ||
| 1503 | 1556 | unsigned long *hwirq, |
| 1504 | 1557 | unsigned int *type) |
| 1505 | 1558 | { |
| 1559 | + unsigned long ppi_intid; | |
| 1506 | 1560 | struct device_node *np; |
| 1561 | + unsigned int ppi_idx; | |
| 1507 | 1562 | int ret; |
| 1508 | 1563 | |
| 1509 | 1564 | if (!gic_data.ppi_descs) |
| @@ -1513,7 +1568,12 @@ static int partition_domain_translate(struct irq_domain *d, · 3 unmodified lines | ||
| 1513 | 1568 | if (WARN_ON(!np)) |
| 1514 | 1569 | return -EINVAL; |
| 1515 | 1570 | |
| 1516 | − ret = partition_translate_id(gic_data.ppi_descs[fwspec->param[1]], | |
| 1571 | + ret = gic_irq_domain_translate(d, fwspec, &ppi_intid, type); | |
| 1572 | + if (WARN_ON_ONCE(ret)) | |
| 1573 | + return 0; | |
| 1574 | + | |
| 1575 | + ppi_idx = __gic_get_ppi_index(ppi_intid); | |
| 1576 | + ret = partition_translate_id(gic_data.ppi_descs[ppi_idx], | |
| 1517 | 1577 | of_node_to_fwnode(np)); |
| 1518 | 1578 | if (ret < 0) |
| 1519 | 1579 | return ret; |
| @@ -92,18 +92,22 @@ static int pch_pic_set_type(struct irq_data *d, unsigned int type) · 91 unmodified lines | ||
| 92 | 92 | case IRQ_TYPE_EDGE_RISING: |
| 93 | 93 | pch_pic_bitset(priv, PCH_PIC_EDGE, d->hwirq); |
| 94 | 94 | pch_pic_bitclr(priv, PCH_PIC_POL, d->hwirq); |
| 95 | + irq_set_handler_locked(d, handle_edge_irq); | |
| 95 | 96 | break; |
| 96 | 97 | case IRQ_TYPE_EDGE_FALLING: |
| 97 | 98 | pch_pic_bitset(priv, PCH_PIC_EDGE, d->hwirq); |
| 98 | 99 | pch_pic_bitset(priv, PCH_PIC_POL, d->hwirq); |
| 100 | + irq_set_handler_locked(d, handle_edge_irq); | |
| 99 | 101 | break; |
| 100 | 102 | case IRQ_TYPE_LEVEL_HIGH: |
| 101 | 103 | pch_pic_bitclr(priv, PCH_PIC_EDGE, d->hwirq); |
| 102 | 104 | pch_pic_bitclr(priv, PCH_PIC_POL, d->hwirq); |
| 105 | + irq_set_handler_locked(d, handle_level_irq); | |
| 103 | 106 | break; |
| 104 | 107 | case IRQ_TYPE_LEVEL_LOW: |
| 105 | 108 | pch_pic_bitclr(priv, PCH_PIC_EDGE, d->hwirq); |
| 106 | 109 | pch_pic_bitset(priv, PCH_PIC_POL, d->hwirq); |
| 110 | + irq_set_handler_locked(d, handle_level_irq); | |
| 107 | 111 | break; |
| 108 | 112 | default: |
| 109 | 113 | ret = -EINVAL; |
| @@ -113,11 +117,24 @@ static int pch_pic_set_type(struct irq_data *d, unsigned int type) · 3 unmodified lines | ||
| 113 | 117 | return ret; |
| 114 | 118 | } |
| 115 | 119 | |
| 120 | +static void pch_pic_ack_irq(struct irq_data *d) | |
| 121 | +{ | |
| 122 | + unsigned int reg; | |
| 123 | + struct pch_pic *priv = irq_data_get_irq_chip_data(d); | |
| 124 | + | |
| 125 | + reg = readl(priv->base + PCH_PIC_EDGE + PIC_REG_IDX(d->hwirq) * 4); | |
| 126 | + if (reg & BIT(PIC_REG_BIT(d->hwirq))) { | |
| 127 | + writel(BIT(PIC_REG_BIT(d->hwirq)), | |
| 128 | + priv->base + PCH_PIC_CLR + PIC_REG_IDX(d->hwirq) * 4); | |
| 129 | + } | |
| 130 | + irq_chip_ack_parent(d); | |
| 131 | +} | |
| 132 | + | |
| 116 | 133 | static struct irq_chip pch_pic_irq_chip = { |
| 117 | 134 | .name = "PCH PIC", |
| 118 | 135 | .irq_mask = pch_pic_mask_irq, |
| 119 | 136 | .irq_unmask = pch_pic_unmask_irq, |
| 120 | − .irq_ack = irq_chip_ack_parent, | |
| 137 | + .irq_ack = pch_pic_ack_irq, | |
| 121 | 138 | .irq_set_affinity = irq_chip_set_affinity_parent, |
| 122 | 139 | .irq_set_type = pch_pic_set_type, |
| 123 | 140 | }; |
| @@ -362,10 +362,7 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) · 361 unmodified lines | ||
| 362 | 362 | |
| 363 | 363 | msi_data->irqs_num = MSI_IRQS_PER_MSIR * |
| 364 | 364 | (1 << msi_data->cfg->ibs_shift); |
| 365 | − msi_data->used = devm_kcalloc(&pdev->dev, | |
| 366 | − BITS_TO_LONGS(msi_data->irqs_num), | |
| 367 | − sizeof(*msi_data->used), | |
| 368 | − GFP_KERNEL); | |
| 365 | + msi_data->used = devm_bitmap_zalloc(&pdev->dev, msi_data->irqs_num, GFP_KERNEL); | |
| 369 | 366 | if (!msi_data->used) |
| 370 | 367 | return -ENOMEM; |
| 371 | 368 | /* |
| @@ -65,6 +65,7 @@ static struct irq_chip mtk_sysirq_chip = { · 64 unmodified lines | ||
| 65 | 65 | .irq_set_type = mtk_sysirq_set_type, |
| 66 | 66 | .irq_retrigger = irq_chip_retrigger_hierarchy, |
| 67 | 67 | .irq_set_affinity = irq_chip_set_affinity_parent, |
| 68 | + .flags = IRQCHIP_SKIP_SET_WAKE, | |
| 68 | 69 | }; |
| 69 | 70 | |
| 70 | 71 | static int mtk_sysirq_domain_translate(struct irq_domain *d, |
| @@ -210,9 +210,7 @@ static int mvebu_gicp_probe(struct platform_device *pdev) · 209 unmodified lines | ||
| 210 | 210 | gicp->spi_cnt += gicp->spi_ranges[i].count; |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | − gicp->spi_bitmap = devm_kcalloc(&pdev->dev, | |
| 214 | − BITS_TO_LONGS(gicp->spi_cnt), sizeof(long), | |
| 215 | − GFP_KERNEL); | |
| 213 | + gicp->spi_bitmap = devm_bitmap_zalloc(&pdev->dev, gicp->spi_cnt, GFP_KERNEL); | |
| 216 | 214 | if (!gicp->spi_bitmap) |
| 217 | 215 | return -ENOMEM; |
| 218 | 216 | |
| @@ -171,8 +171,7 @@ static int __init mvebu_odmi_init(struct device_node *node, · 170 unmodified lines | ||
| 171 | 171 | if (!odmis) |
| 172 | 172 | return -ENOMEM; |
| 173 | 173 | |
| 174 | − odmis_bm = kcalloc(BITS_TO_LONGS(odmis_count * NODMIS_PER_FRAME), | |
| 175 | − sizeof(long), GFP_KERNEL); | |
| 174 | + odmis_bm = bitmap_zalloc(odmis_count * NODMIS_PER_FRAME, GFP_KERNEL); | |
| 176 | 175 | if (!odmis_bm) { |
| 177 | 176 | ret = -ENOMEM; |
| 178 | 177 | goto err_alloc; |
| @@ -227,7 +226,7 @@ err_unmap: · 48 unmodified lines | ||
| 227 | 226 | if (odmi->base && !IS_ERR(odmi->base)) |
| 228 | 227 | iounmap(odmis[i].base); |
| 229 | 228 | } |
| 230 | − kfree(odmis_bm); | |
| 229 | + bitmap_free(odmis_bm); | |
| 231 | 230 | err_alloc: |
| 232 | 231 | kfree(odmis); |
| 233 | 232 | return ret; |
| @@ -215,8 +215,7 @@ struct partition_desc *partition_create_desc(struct fwnode_handle *fwnode, · 214 unmodified lines | ||
| 215 | 215 | goto out; |
| 216 | 216 | desc->domain = d; |
| 217 | 217 | |
| 218 | − desc->bitmap = kcalloc(BITS_TO_LONGS(nr_parts), sizeof(long), | |
| 219 | − GFP_KERNEL); | |
| 218 | + desc->bitmap = bitmap_zalloc(nr_parts, GFP_KERNEL); | |
| 220 | 219 | if (WARN_ON(!desc->bitmap)) |
| 221 | 220 | goto out; |
| 222 | 221 | |
| @@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i) · 52 unmodified lines | ||
| 53 | 53 | return readl_relaxed(pdc_base + reg + i * sizeof(u32)); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | −static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d, | |
| 57 | − enum irqchip_irq_state which, | |
| 58 | − bool *state) | |
| 59 | −{ | |
| 60 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 61 | − return 0; | |
| 62 | − | |
| 63 | − return irq_chip_get_parent_state(d, which, state); | |
| 64 | −} | |
| 65 | − | |
| 66 | −static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d, | |
| 67 | − enum irqchip_irq_state which, | |
| 68 | − bool value) | |
| 69 | −{ | |
| 70 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 71 | − return 0; | |
| 72 | − | |
| 73 | − return irq_chip_set_parent_state(d, which, value); | |
| 74 | −} | |
| 75 | − | |
| 76 | 56 | static void pdc_enable_intr(struct irq_data *d, bool on) |
| 77 | 57 | { |
| 78 | 58 | int pin_out = d->hwirq; |
| @@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on) · 12 unmodified lines | ||
| 91 | 71 | |
| 92 | 72 | static void qcom_pdc_gic_disable(struct irq_data *d) |
| 93 | 73 | { |
| 94 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 95 | − return; | |
| 96 | − | |
| 97 | 74 | pdc_enable_intr(d, false); |
| 98 | 75 | irq_chip_disable_parent(d); |
| 99 | 76 | } |
| 100 | 77 | |
| 101 | 78 | static void qcom_pdc_gic_enable(struct irq_data *d) |
| 102 | 79 | { |
| 103 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 104 | − return; | |
| 105 | − | |
| 106 | 80 | pdc_enable_intr(d, true); |
| 107 | 81 | irq_chip_enable_parent(d); |
| 108 | 82 | } |
| 109 | 83 | |
| 110 | −static void qcom_pdc_gic_mask(struct irq_data *d) | |
| 111 | −{ | |
| 112 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 113 | − return; | |
| 114 | − | |
| 115 | − irq_chip_mask_parent(d); | |
| 116 | −} | |
| 117 | − | |
| 118 | −static void qcom_pdc_gic_unmask(struct irq_data *d) | |
| 119 | −{ | |
| 120 | − if (d->hwirq == GPIO_NO_WAKE_IRQ) | |
| 121 | − return; | |
| 122 | − | |
| 123 | − irq_chip_unmask_parent(d); | |
| 124 | −} | |
| 125 | − | |
| 126 | 84 | /* |
| 127 | 85 | * GIC does not handle falling edge or active low. To allow falling edge and |
| 128 | 86 | * active low interrupts to be handled at GIC, PDC has an inverter that inverts |
| @@ -159,14 +117,10 @@ enum pdc_irq_config_bits { · 30 unmodified lines | ||
| 159 | 117 | */ |
| 160 | 118 | static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) |
| 161 | 119 | { |
| 162 | − int pin_out = d->hwirq; | |
| 163 | 120 | enum pdc_irq_config_bits pdc_type; |
| 164 | 121 | enum pdc_irq_config_bits old_pdc_type; |
| 165 | 122 | int ret; |
| 166 | 123 | |
| 167 | − if (pin_out == GPIO_NO_WAKE_IRQ) | |
| 168 | − return 0; | |
| 169 | − | |
| 170 | 124 | switch (type) { |
| 171 | 125 | case IRQ_TYPE_EDGE_RISING: |
| 172 | 126 | pdc_type = PDC_EDGE_RISING; |
| @@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) · 18 unmodified lines | ||
| 191 | 145 | return -EINVAL; |
| 192 | 146 | } |
| 193 | 147 | |
| 194 | − old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out); | |
| 195 | − pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); | |
| 148 | + old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); | |
| 149 | + pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); | |
| 196 | 150 | |
| 197 | 151 | ret = irq_chip_set_type_parent(d, type); |
| 198 | 152 | if (ret) |
| @@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) · 17 unmodified lines | ||
| 216 | 170 | static struct irq_chip qcom_pdc_gic_chip = { |
| 217 | 171 | .name = "PDC", |
| 218 | 172 | .irq_eoi = irq_chip_eoi_parent, |
| 219 | − .irq_mask = qcom_pdc_gic_mask, | |
| 220 | − .irq_unmask = qcom_pdc_gic_unmask, | |
| 173 | + .irq_mask = irq_chip_mask_parent, | |
| 174 | + .irq_unmask = irq_chip_unmask_parent, | |
| 221 | 175 | .irq_disable = qcom_pdc_gic_disable, |
| 222 | 176 | .irq_enable = qcom_pdc_gic_enable, |
| 223 | − .irq_get_irqchip_state = qcom_pdc_gic_get_irqchip_state, | |
| 224 | − .irq_set_irqchip_state = qcom_pdc_gic_set_irqchip_state, | |
| 177 | + .irq_get_irqchip_state = irq_chip_get_parent_state, | |
| 178 | + .irq_set_irqchip_state = irq_chip_set_parent_state, | |
| 225 | 179 | .irq_retrigger = irq_chip_retrigger_hierarchy, |
| 226 | 180 | .irq_set_type = qcom_pdc_gic_set_type, |
| 227 | 181 | .flags = IRQCHIP_MASK_ON_SUSPEND | |
| @@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, · 54 unmodified lines | ||
| 282 | 236 | |
| 283 | 237 | parent_hwirq = get_parent_hwirq(hwirq); |
| 284 | 238 | if (parent_hwirq == PDC_NO_PARENT_IRQ) |
| 285 | − return 0; | |
| 239 | + return irq_domain_disconnect_hierarchy(domain->parent, virq); | |
| 286 | 240 | |
| 287 | 241 | if (type & IRQ_TYPE_EDGE_BOTH) |
| 288 | 242 | type = IRQ_TYPE_EDGE_RISING; |
| @@ -319,17 +273,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq, · 30 unmodified lines | ||
| 319 | 273 | if (ret) |
| 320 | 274 | return ret; |
| 321 | 275 | |
| 276 | + if (hwirq == GPIO_NO_WAKE_IRQ) | |
| 277 | + return irq_domain_disconnect_hierarchy(domain, virq); | |
| 278 | + | |
| 322 | 279 | ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, |
| 323 | 280 | &qcom_pdc_gic_chip, NULL); |
| 324 | 281 | if (ret) |
| 325 | 282 | return ret; |
| 326 | 283 | |
| 327 | − if (hwirq == GPIO_NO_WAKE_IRQ) | |
| 328 | − return 0; | |
| 329 | − | |
| 330 | 284 | parent_hwirq = get_parent_hwirq(hwirq); |
| 331 | 285 | if (parent_hwirq == PDC_NO_PARENT_IRQ) |
| 332 | − return 0; | |
| 286 | + return irq_domain_disconnect_hierarchy(domain->parent, virq); | |
| 333 | 287 | |
| 334 | 288 | if (type & IRQ_TYPE_EDGE_BOTH) |
| 335 | 289 | type = IRQ_TYPE_EDGE_RISING; |
| @@ -2364,7 +2364,7 @@ static bool read_mailbox_0(void) · 2363 unmodified lines | ||
| 2364 | 2364 | |
| 2365 | 2365 | for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { |
| 2366 | 2366 | if (ev & prcmu_irq_bit[n]) |
| 2367 | − generic_handle_irq(irq_find_mapping(db8500_irq_domain, n)); | |
| 2367 | + generic_handle_domain_irq(db8500_irq_domain, n); | |
| 2368 | 2368 | } |
| 2369 | 2369 | r = true; |
| 2370 | 2370 | break; |
| @@ -35,10 +35,10 @@ static void mx25_tsadc_irq_handler(struct irq_desc *desc) · 34 unmodified lines | ||
| 35 | 35 | regmap_read(tsadc->regs, MX25_TSC_TGSR, &status); |
| 36 | 36 | |
| 37 | 37 | if (status & MX25_TGSR_GCQ_INT) |
| 38 | − generic_handle_irq(irq_find_mapping(tsadc->domain, 1)); | |
| 38 | + generic_handle_domain_irq(tsadc->domain, 1); | |
| 39 | 39 | |
| 40 | 40 | if (status & MX25_TGSR_TCQ_INT) |
| 41 | − generic_handle_irq(irq_find_mapping(tsadc->domain, 0)); | |
| 41 | + generic_handle_domain_irq(tsadc->domain, 0); | |
| 42 | 42 | |
| 43 | 43 | chained_irq_exit(chip, desc); |
| 44 | 44 | } |
| @@ -105,19 +105,15 @@ static void ioc3_irq_handler(struct irq_desc *desc) · 104 unmodified lines | ||
| 105 | 105 | struct ioc3_priv_data *ipd = domain->host_data; |
| 106 | 106 | struct ioc3 __iomem *regs = ipd->regs; |
| 107 | 107 | u32 pending, mask; |
| 108 | − unsigned int irq; | |
| 109 | 108 | |
| 110 | 109 | pending = readl(®s->sio_ir); |
| 111 | 110 | mask = readl(®s->sio_ies); |
| 112 | 111 | pending &= mask; /* Mask off not enabled interrupts */ |
| 113 | 112 | |
| 114 | − if (pending) { | |
| 115 | − irq = irq_find_mapping(domain, __ffs(pending)); | |
| 116 | − if (irq) | |
| 117 | − generic_handle_irq(irq); | |
| 118 | − } else { | |
| 113 | + if (pending) | |
| 114 | + generic_handle_domain_irq(domain, __ffs(pending)); | |
| 115 | + else | |
| 119 | 116 | spurious_interrupt(); |
| 120 | − } | |
| 121 | 117 | } |
| 122 | 118 | |
| 123 | 119 | /* |
| @@ -122,7 +122,7 @@ bail: · 121 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) |
| 124 | 124 | { |
| 125 | − int pmirq, irq, i, ret = 0; | |
| 125 | + int pmirq, i, ret = 0; | |
| 126 | 126 | unsigned int bits; |
| 127 | 127 | |
| 128 | 128 | ret = pm8xxx_read_block_irq(chip, block, &bits); |
| @@ -139,8 +139,7 @@ static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) · 10 unmodified lines | ||
| 139 | 139 | for (i = 0; i < 8; i++) { |
| 140 | 140 | if (bits & (1 << i)) { |
| 141 | 141 | pmirq = block * 8 + i; |
| 142 | − irq = irq_find_mapping(chip->irqdomain, pmirq); | |
| 143 | − generic_handle_irq(irq); | |
| 142 | + generic_handle_domain_irq(chip->irqdomain, pmirq); | |
| 144 | 143 | } |
| 145 | 144 | } |
| 146 | 145 | return 0; |
| @@ -199,7 +198,7 @@ static void pm8xxx_irq_handler(struct irq_desc *desc) · 52 unmodified lines | ||
| 199 | 198 | static void pm8821_irq_block_handler(struct pm_irq_chip *chip, |
| 200 | 199 | int master, int block) |
| 201 | 200 | { |
| 202 | − int pmirq, irq, i, ret; | |
| 201 | + int pmirq, i, ret; | |
| 203 | 202 | unsigned int bits; |
| 204 | 203 | |
| 205 | 204 | ret = regmap_read(chip->regmap, |
| @@ -216,8 +215,7 @@ static void pm8821_irq_block_handler(struct pm_irq_chip *chip, · 10 unmodified lines | ||
| 216 | 215 | for (i = 0; i < 8; i++) { |
| 217 | 216 | if (bits & BIT(i)) { |
| 218 | 217 | pmirq = block * 8 + i; |
| 219 | − irq = irq_find_mapping(chip->irqdomain, pmirq); | |
| 220 | − generic_handle_irq(irq); | |
| 218 | + generic_handle_domain_irq(chip->irqdomain, pmirq); | |
| 221 | 219 | } |
| 222 | 220 | } |
| 223 | 221 | } |
| @@ -833,7 +833,7 @@ static void owl_gpio_irq_handler(struct irq_desc *desc) · 832 unmodified lines | ||
| 833 | 833 | unsigned int parent = irq_desc_get_irq(desc); |
| 834 | 834 | const struct owl_gpio_port *port; |
| 835 | 835 | void __iomem *base; |
| 836 | − unsigned int pin, irq, offset = 0, i; | |
| 836 | + unsigned int pin, offset = 0, i; | |
| 837 | 837 | unsigned long pending_irq; |
| 838 | 838 | |
| 839 | 839 | chained_irq_enter(chip, desc); |
| @@ -849,8 +849,7 @@ static void owl_gpio_irq_handler(struct irq_desc *desc) · 9 unmodified lines | ||
| 849 | 849 | pending_irq = readl_relaxed(base + port->intc_pd); |
| 850 | 850 | |
| 851 | 851 | for_each_set_bit(pin, &pending_irq, port->pins) { |
| 852 | − irq = irq_find_mapping(domain, offset + pin); | |
| 853 | − generic_handle_irq(irq); | |
| 852 | + generic_handle_domain_irq(domain, offset + pin); | |
| 854 | 853 | |
| 855 | 854 | /* clear pending interrupt */ |
| 856 | 855 | owl_gpio_update_reg(base + port->intc_pd, pin, true); |
| @@ -395,8 +395,8 @@ static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, · 394 unmodified lines | ||
| 395 | 395 | events &= pc->enabled_irq_map[bank]; |
| 396 | 396 | for_each_set_bit(offset, &events, 32) { |
| 397 | 397 | gpio = (32 * bank) + offset; |
| 398 | − generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain, | |
| 399 | − gpio)); | |
| 398 | + generic_handle_domain_irq(pc->gpio_chip.irq.domain, | |
| 399 | + gpio); | |
| 400 | 400 | } |
| 401 | 401 | } |
| 402 | 402 | |
| @@ -176,7 +176,6 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc) · 175 unmodified lines | ||
| 176 | 176 | |
| 177 | 177 | for_each_set_bit(bit, &val, NGPIOS_PER_BANK) { |
| 178 | 178 | unsigned pin = NGPIOS_PER_BANK * i + bit; |
| 179 | − int child_irq = irq_find_mapping(gc->irq.domain, pin); | |
| 180 | 179 | |
| 181 | 180 | /* |
| 182 | 181 | * Clear the interrupt before invoking the |
| @@ -185,7 +184,7 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc) · 2 unmodified lines | ||
| 185 | 184 | writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) + |
| 186 | 185 | IPROC_GPIO_INT_CLR_OFFSET); |
| 187 | 186 | |
| 188 | − generic_handle_irq(child_irq); | |
| 187 | + generic_handle_domain_irq(gc->irq.domain, pin); | |
| 189 | 188 | } |
| 190 | 189 | } |
| 191 | 190 | |
| @@ -155,8 +155,7 @@ static irqreturn_t nsp_gpio_irq_handler(int irq, void *data) · 154 unmodified lines | ||
| 155 | 155 | int_bits = level | event; |
| 156 | 156 | |
| 157 | 157 | for_each_set_bit(bit, &int_bits, gc->ngpio) |
| 158 | − generic_handle_irq( | |
| 159 | − irq_linear_revmap(gc->irq.domain, bit)); | |
| 158 | + generic_handle_domain_irq(gc->irq.domain, bit); | |
| 160 | 159 | } |
| 161 | 160 | |
| 162 | 161 | return int_bits ? IRQ_HANDLED : IRQ_NONE; |
| @@ -1444,7 +1444,6 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) · 1443 unmodified lines | ||
| 1444 | 1444 | u32 base, pin; |
| 1445 | 1445 | void __iomem *reg; |
| 1446 | 1446 | unsigned long pending; |
| 1447 | − unsigned int virq; | |
| 1448 | 1447 | |
| 1449 | 1448 | /* check from GPIO controller which pin triggered the interrupt */ |
| 1450 | 1449 | for (base = 0; base < vg->chip.ngpio; base += 32) { |
| @@ -1460,10 +1459,8 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) · 9 unmodified lines | ||
| 1460 | 1459 | raw_spin_lock(&byt_lock); |
| 1461 | 1460 | pending = readl(reg); |
| 1462 | 1461 | raw_spin_unlock(&byt_lock); |
| 1463 | − for_each_set_bit(pin, &pending, 32) { | |
| 1464 | − virq = irq_find_mapping(vg->chip.irq.domain, base + pin); | |
| 1465 | − generic_handle_irq(virq); | |
| 1466 | − } | |
| 1462 | + for_each_set_bit(pin, &pending, 32) | |
| 1463 | + generic_handle_domain_irq(vg->chip.irq.domain, base + pin); | |
| 1467 | 1464 | } |
| 1468 | 1465 | chip->irq_eoi(data); |
| 1469 | 1466 | } |
| @@ -1409,11 +1409,10 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) · 1408 unmodified lines | ||
| 1409 | 1409 | raw_spin_unlock_irqrestore(&chv_lock, flags); |
| 1410 | 1410 | |
| 1411 | 1411 | for_each_set_bit(intr_line, &pending, community->nirqs) { |
| 1412 | − unsigned int irq, offset; | |
| 1412 | + unsigned int offset; | |
| 1413 | 1413 | |
| 1414 | 1414 | offset = cctx->intr_lines[intr_line]; |
| 1415 | − irq = irq_find_mapping(gc->irq.domain, offset); | |
| 1416 | − generic_handle_irq(irq); | |
| 1415 | + generic_handle_domain_irq(gc->irq.domain, offset); | |
| 1417 | 1416 | } |
| 1418 | 1417 | |
| 1419 | 1418 | chained_irq_exit(chip, desc); |
| @@ -653,12 +653,8 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) · 652 unmodified lines | ||
| 653 | 653 | /* Only interrupts that are enabled */ |
| 654 | 654 | pending = ioread32(reg) & ioread32(ena); |
| 655 | 655 | |
| 656 | − for_each_set_bit(pin, &pending, 32) { | |
| 657 | − unsigned int irq; | |
| 658 | − | |
| 659 | − irq = irq_find_mapping(lg->chip.irq.domain, base + pin); | |
| 660 | − generic_handle_irq(irq); | |
| 661 | − } | |
| 656 | + for_each_set_bit(pin, &pending, 32) | |
| 657 | + generic_handle_domain_irq(lg->chip.irq.domain, base + pin); | |
| 662 | 658 | } |
| 663 | 659 | chip->irq_eoi(data); |
| 664 | 660 | } |
| @@ -319,7 +319,7 @@ static void mtk_eint_irq_handler(struct irq_desc *desc) · 318 unmodified lines | ||
| 319 | 319 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 320 | 320 | struct mtk_eint *eint = irq_desc_get_handler_data(desc); |
| 321 | 321 | unsigned int status, eint_num; |
| 322 | − int offset, mask_offset, index, virq; | |
| 322 | + int offset, mask_offset, index; | |
| 323 | 323 | void __iomem *reg = mtk_eint_get_offset(eint, 0, eint->regs->stat); |
| 324 | 324 | int dual_edge, start_level, curr_level; |
| 325 | 325 | |
| @@ -331,7 +331,6 @@ static void mtk_eint_irq_handler(struct irq_desc *desc) · 5 unmodified lines | ||
| 331 | 331 | offset = __ffs(status); |
| 332 | 332 | mask_offset = eint_num >> 5; |
| 333 | 333 | index = eint_num + offset; |
| 334 | − virq = irq_find_mapping(eint->domain, index); | |
| 335 | 334 | status &= ~BIT(offset); |
| 336 | 335 | |
| 337 | 336 | /* |
| @@ -361,7 +360,7 @@ static void mtk_eint_irq_handler(struct irq_desc *desc) · 23 unmodified lines | ||
| 361 | 360 | index); |
| 362 | 361 | } |
| 363 | 362 | |
| 364 | − generic_handle_irq(virq); | |
| 363 | + generic_handle_domain_irq(eint->domain, index); | |
| 365 | 364 | |
| 366 | 365 | if (dual_edge) { |
| 367 | 366 | curr_level = mtk_eint_flip_edge(eint, index); |
| @@ -815,7 +815,7 @@ static void nmk_gpio_irq_handler(struct irq_desc *desc) · 814 unmodified lines | ||
| 815 | 815 | while (status) { |
| 816 | 816 | int bit = __ffs(status); |
| 817 | 817 | |
| 818 | − generic_handle_irq(irq_find_mapping(chip->irq.domain, bit)); | |
| 818 | + generic_handle_domain_irq(chip->irq.domain, bit); | |
| 819 | 819 | status &= ~BIT(bit); |
| 820 | 820 | } |
| 821 | 821 | |
| @@ -231,7 +231,7 @@ static void npcmgpio_irq_handler(struct irq_desc *desc) · 230 unmodified lines | ||
| 231 | 231 | |
| 232 | 232 | sts &= en; |
| 233 | 233 | for_each_set_bit(bit, (const void *)&sts, NPCM7XX_GPIO_PER_BANK) |
| 234 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit)); | |
| 234 | + generic_handle_domain_irq(gc->irq.domain, bit); | |
| 235 | 235 | chained_irq_exit(chip, desc); |
| 236 | 236 | } |
| 237 | 237 | |
| @@ -621,14 +621,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) · 620 unmodified lines | ||
| 621 | 621 | if (!(regval & PIN_IRQ_PENDING) || |
| 622 | 622 | !(regval & BIT(INTERRUPT_MASK_OFF))) |
| 623 | 623 | continue; |
| 624 | − irq = irq_find_mapping(gc->irq.domain, irqnr + i); | |
| 625 | − if (irq != 0) | |
| 626 | − generic_handle_irq(irq); | |
| 624 | + generic_handle_domain_irq(gc->irq.domain, irqnr + i); | |
| 627 | 625 | |
| 628 | 626 | /* Clear interrupt. |
| 629 | 627 | * We must read the pin register again, in case the |
| 630 | 628 | * value was changed while executing |
| 631 | − * generic_handle_irq() above. | |
| 629 | + * generic_handle_domain_irq() above. | |
| 632 | 630 | * If we didn't find a mapping for the interrupt, |
| 633 | 631 | * disable it in order to avoid a system hang caused |
| 634 | 632 | * by an interrupt storm. |
| @@ -1712,10 +1712,8 @@ static void gpio_irq_handler(struct irq_desc *desc) · 1711 unmodified lines | ||
| 1712 | 1712 | continue; |
| 1713 | 1713 | } |
| 1714 | 1714 | |
| 1715 | − for_each_set_bit(n, &isr, BITS_PER_LONG) { | |
| 1716 | − generic_handle_irq(irq_find_mapping( | |
| 1717 | − gpio_chip->irq.domain, n)); | |
| 1718 | − } | |
| 1715 | + for_each_set_bit(n, &isr, BITS_PER_LONG) | |
| 1716 | + generic_handle_domain_irq(gpio_chip->irq.domain, n); | |
| 1719 | 1717 | } |
| 1720 | 1718 | chained_irq_exit(chip, desc); |
| 1721 | 1719 | /* now it may re-trigger */ |
| @@ -155,7 +155,7 @@ static void eqbr_irq_handler(struct irq_desc *desc) · 154 unmodified lines | ||
| 155 | 155 | pins = readl(gctrl->membase + GPIO_IRNCR); |
| 156 | 156 | |
| 157 | 157 | for_each_set_bit(offset, &pins, gc->ngpio) |
| 158 | − generic_handle_irq(irq_find_mapping(gc->irq.domain, offset)); | |
| 158 | + generic_handle_domain_irq(gc->irq.domain, offset); | |
| 159 | 159 | |
| 160 | 160 | chained_irq_exit(ic, desc); |
| 161 | 161 | } |
| @@ -3080,7 +3080,7 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc) · 3079 unmodified lines | ||
| 3080 | 3080 | flag = ingenic_gpio_read_reg(jzgc, JZ4730_GPIO_GPFR); |
| 3081 | 3081 | |
| 3082 | 3082 | for_each_set_bit(i, &flag, 32) |
| 3083 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, i)); | |
| 3083 | + generic_handle_domain_irq(gc->irq.domain, i); | |
| 3084 | 3084 | chained_irq_exit(irq_chip, desc); |
| 3085 | 3085 | } |
| 3086 | 3086 | |
| @@ -673,7 +673,7 @@ static void sgpio_irq_handler(struct irq_desc *desc) · 672 unmodified lines | ||
| 673 | 673 | |
| 674 | 674 | for_each_set_bit(port, &val, SGPIO_BITS_PER_WORD) { |
| 675 | 675 | gpio = sgpio_addr_to_pin(priv, port, bit); |
| 676 | − generic_handle_irq(irq_linear_revmap(chip->irq.domain, gpio)); | |
| 676 | + generic_handle_domain_irq(chip->irq.domain, gpio); | |
| 677 | 677 | } |
| 678 | 678 | |
| 679 | 679 | chained_irq_exit(parent_chip, desc); |
| @@ -1290,8 +1290,7 @@ static void ocelot_irq_handler(struct irq_desc *desc) · 1289 unmodified lines | ||
| 1290 | 1290 | |
| 1291 | 1291 | for_each_set_bit(irq, &irqs, |
| 1292 | 1292 | min(32U, info->desc->npins - 32 * i)) |
| 1293 | − generic_handle_irq(irq_linear_revmap(chip->irq.domain, | |
| 1294 | − irq + 32 * i)); | |
| 1293 | + generic_handle_domain_irq(chip->irq.domain, irq + 32 * i); | |
| 1295 | 1294 | |
| 1296 | 1295 | chained_irq_exit(parent_chip, desc); |
| 1297 | 1296 | } |
| @@ -1055,7 +1055,7 @@ static void oxnas_gpio_irq_handler(struct irq_desc *desc) · 1054 unmodified lines | ||
| 1055 | 1055 | stat = readl(bank->reg_base + IRQ_PENDING); |
| 1056 | 1056 | |
| 1057 | 1057 | for_each_set_bit(pin, &stat, BITS_PER_LONG) |
| 1058 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); | |
| 1058 | + generic_handle_domain_irq(gc->irq.domain, pin); | |
| 1059 | 1059 | |
| 1060 | 1060 | chained_irq_exit(chip, desc); |
| 1061 | 1061 | } |
| @@ -2101,7 +2101,7 @@ static void pic32_gpio_irq_handler(struct irq_desc *desc) · 2100 unmodified lines | ||
| 2101 | 2101 | pending = pic32_gpio_get_pending(gc, stat); |
| 2102 | 2102 | |
| 2103 | 2103 | for_each_set_bit(pin, &pending, BITS_PER_LONG) |
| 2104 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); | |
| 2104 | + generic_handle_domain_irq(gc->irq.domain, pin); | |
| 2105 | 2105 | |
| 2106 | 2106 | chained_irq_exit(chip, desc); |
| 2107 | 2107 | } |
| @@ -1306,7 +1306,7 @@ static void pistachio_gpio_irq_handler(struct irq_desc *desc) · 1305 unmodified lines | ||
| 1306 | 1306 | pending = gpio_readl(bank, GPIO_INTERRUPT_STATUS) & |
| 1307 | 1307 | gpio_readl(bank, GPIO_INTERRUPT_EN); |
| 1308 | 1308 | for_each_set_bit(pin, &pending, 16) |
| 1309 | − generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); | |
| 1309 | + generic_handle_domain_irq(gc->irq.domain, pin); | |
| 1310 | 1310 | chained_irq_exit(chip, desc); |
| 1311 | 1311 | } |
| 1312 | 1312 | |
| @@ -21,8 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/io.h> |
| 22 | 22 | #include <linux/bitops.h> |
| 23 | 23 | #include <linux/gpio/driver.h> |
| 24 | −#include <linux/of_device.h> | |
| 25 | 24 | #include <linux/of_address.h> |
| 25 | +#include <linux/of_device.h> | |
| 26 | 26 | #include <linux/of_irq.h> |
| 27 | 27 | #include <linux/pinctrl/machine.h> |
| 28 | 28 | #include <linux/pinctrl/pinconf.h> |
| @@ -37,35 +37,7 @@ · 8 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | #include "core.h" |
| 39 | 39 | #include "pinconf.h" |
| 40 | − | |
| 41 | −/* GPIO control registers */ | |
| 42 | −#define GPIO_SWPORT_DR 0x00 | |
| 43 | −#define GPIO_SWPORT_DDR 0x04 | |
| 44 | −#define GPIO_INTEN 0x30 | |
| 45 | −#define GPIO_INTMASK 0x34 | |
| 46 | −#define GPIO_INTTYPE_LEVEL 0x38 | |
| 47 | −#define GPIO_INT_POLARITY 0x3c | |
| 48 | −#define GPIO_INT_STATUS 0x40 | |
| 49 | −#define GPIO_INT_RAWSTATUS 0x44 | |
| 50 | −#define GPIO_DEBOUNCE 0x48 | |
| 51 | −#define GPIO_PORTS_EOI 0x4c | |
| 52 | −#define GPIO_EXT_PORT 0x50 | |
| 53 | −#define GPIO_LS_SYNC 0x60 | |
| 54 | − | |
| 55 | −enum rockchip_pinctrl_type { | |
| 56 | − PX30, | |
| 57 | − RV1108, | |
| 58 | − RK2928, | |
| 59 | − RK3066B, | |
| 60 | − RK3128, | |
| 61 | − RK3188, | |
| 62 | − RK3288, | |
| 63 | − RK3308, | |
| 64 | − RK3368, | |
| 65 | − RK3399, | |
| 66 | − RK3568, | |
| 67 | −}; | |
| 68 | − | |
| 40 | +#include "pinctrl-rockchip.h" | |
| 69 | 41 | |
| 70 | 42 | /** |
| 71 | 43 | * Generate a bitmask for setting a value (v) with a write mask bit in hiword |
| @@ -84,103 +56,6 @@ enum rockchip_pinctrl_type { · 12 unmodified lines | ||
| 84 | 56 | #define IOMUX_WIDTH_3BIT BIT(4) |
| 85 | 57 | #define IOMUX_WIDTH_2BIT BIT(5) |
| 86 | 58 | |
| 87 | −/** | |
| 88 | − * struct rockchip_iomux | |
| 89 | − * @type: iomux variant using IOMUX_* constants | |
| 90 | − * @offset: if initialized to -1 it will be autocalculated, by specifying | |
| 91 | − * an initial offset value the relevant source offset can be reset | |
| 92 | − * to a new value for autocalculating the following iomux registers. | |
| 93 | − */ | |
| 94 | −struct rockchip_iomux { | |
| 95 | − int type; | |
| 96 | − int offset; | |
| 97 | −}; | |
| 98 | − | |
| 99 | −/* | |
| 100 | − * enum type index corresponding to rockchip_perpin_drv_list arrays index. | |
| 101 | − */ | |
| 102 | −enum rockchip_pin_drv_type { | |
| 103 | − DRV_TYPE_IO_DEFAULT = 0, | |
| 104 | − DRV_TYPE_IO_1V8_OR_3V0, | |
| 105 | − DRV_TYPE_IO_1V8_ONLY, | |
| 106 | − DRV_TYPE_IO_1V8_3V0_AUTO, | |
| 107 | − DRV_TYPE_IO_3V3_ONLY, | |
| 108 | − DRV_TYPE_MAX | |
| 109 | −}; | |
| 110 | − | |
| 111 | −/* | |
| 112 | − * enum type index corresponding to rockchip_pull_list arrays index. | |
| 113 | − */ | |
| 114 | −enum rockchip_pin_pull_type { | |
| 115 | − PULL_TYPE_IO_DEFAULT = 0, | |
| 116 | − PULL_TYPE_IO_1V8_ONLY, | |
| 117 | − PULL_TYPE_MAX | |
| 118 | −}; | |
| 119 | − | |
| 120 | −/** | |
| 121 | − * struct rockchip_drv | |
| 122 | − * @drv_type: drive strength variant using rockchip_perpin_drv_type | |
| 123 | − * @offset: if initialized to -1 it will be autocalculated, by specifying | |
| 124 | − * an initial offset value the relevant source offset can be reset | |
| 125 | − * to a new value for autocalculating the following drive strength | |
| 126 | − * registers. if used chips own cal_drv func instead to calculate | |
| 127 | − * registers offset, the variant could be ignored. | |
| 128 | − */ | |
| 129 | −struct rockchip_drv { | |
| 130 | − enum rockchip_pin_drv_type drv_type; | |
| 131 | − int offset; | |
| 132 | −}; | |
| 133 | − | |
| 134 | −/** | |
| 135 | − * struct rockchip_pin_bank | |
| 136 | − * @reg_base: register base of the gpio bank | |
| 137 | − * @regmap_pull: optional separate register for additional pull settings | |
| 138 | − * @clk: clock of the gpio bank | |
| 139 | − * @irq: interrupt of the gpio bank | |
| 140 | − * @saved_masks: Saved content of GPIO_INTEN at suspend time. | |
| 141 | − * @pin_base: first pin number | |
| 142 | − * @nr_pins: number of pins in this bank | |
| 143 | − * @name: name of the bank | |
| 144 | − * @bank_num: number of the bank, to account for holes | |
| 145 | − * @iomux: array describing the 4 iomux sources of the bank | |
| 146 | − * @drv: array describing the 4 drive strength sources of the bank | |
| 147 | − * @pull_type: array describing the 4 pull type sources of the bank | |
| 148 | − * @valid: is all necessary information present | |
| 149 | − * @of_node: dt node of this bank | |
| 150 | − * @drvdata: common pinctrl basedata | |
| 151 | − * @domain: irqdomain of the gpio bank | |
| 152 | − * @gpio_chip: gpiolib chip | |
| 153 | − * @grange: gpio range | |
| 154 | − * @slock: spinlock for the gpio bank | |
| 155 | − * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode | |
| 156 | − * @recalced_mask: bit mask to indicate a need to recalulate the mask | |
| 157 | − * @route_mask: bits describing the routing pins of per bank | |
| 158 | − */ | |
| 159 | −struct rockchip_pin_bank { | |
| 160 | − void __iomem *reg_base; | |
| 161 | − struct regmap *regmap_pull; | |
| 162 | − struct clk *clk; | |
| 163 | − int irq; | |
| 164 | − u32 saved_masks; | |
| 165 | − u32 pin_base; | |
| 166 | − u8 nr_pins; | |
| 167 | − char *name; | |
| 168 | − u8 bank_num; | |
| 169 | − struct rockchip_iomux iomux[4]; | |
| 170 | − struct rockchip_drv drv[4]; | |
| 171 | − enum rockchip_pin_pull_type pull_type[4]; | |
| 172 | − bool valid; | |
| 173 | − struct device_node *of_node; | |
| 174 | − struct rockchip_pinctrl *drvdata; | |
| 175 | − struct irq_domain *domain; | |
| 176 | − struct gpio_chip gpio_chip; | |
| 177 | − struct pinctrl_gpio_range grange; | |
| 178 | − raw_spinlock_t slock; | |
| 179 | − u32 toggle_edge_mode; | |
| 180 | − u32 recalced_mask; | |
| 181 | − u32 route_mask; | |
| 182 | −}; | |
| 183 | − | |
| 184 | 59 | #define PIN_BANK(id, pins, label) \ |
| 185 | 60 | { \ |
| 186 | 61 | .bank_num = id, \ |
| @@ -320,119 +195,6 @@ struct rockchip_pin_bank { · 133 unmodified lines | ||
| 320 | 195 | #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ |
| 321 | 196 | PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) |
| 322 | 197 | |
| 323 | −/** | |
| 324 | − * struct rockchip_mux_recalced_data: represent a pin iomux data. | |
| 325 | − * @num: bank number. | |
| 326 | − * @pin: pin number. | |
| 327 | − * @bit: index at register. | |
| 328 | − * @reg: register offset. | |
| 329 | − * @mask: mask bit | |
| 330 | − */ | |
| 331 | −struct rockchip_mux_recalced_data { | |
| 332 | − u8 num; | |
| 333 | − u8 pin; | |
| 334 | − u32 reg; | |
| 335 | − u8 bit; | |
| 336 | − u8 mask; | |
| 337 | −}; | |
| 338 | − | |
| 339 | −enum rockchip_mux_route_location { | |
| 340 | − ROCKCHIP_ROUTE_SAME = 0, | |
| 341 | − ROCKCHIP_ROUTE_PMU, | |
| 342 | − ROCKCHIP_ROUTE_GRF, | |
| 343 | −}; | |
| 344 | − | |
| 345 | −/** | |
| 346 | − * struct rockchip_mux_recalced_data: represent a pin iomux data. | |
| 347 | − * @bank_num: bank number. | |
| 348 | − * @pin: index at register or used to calc index. | |
| 349 | − * @func: the min pin. | |
| 350 | − * @route_location: the mux route location (same, pmu, grf). | |
| 351 | − * @route_offset: the max pin. | |
| 352 | − * @route_val: the register offset. | |
| 353 | − */ | |
| 354 | −struct rockchip_mux_route_data { | |
| 355 | − u8 bank_num; | |
| 356 | − u8 pin; | |
| 357 | − u8 func; | |
| 358 | − enum rockchip_mux_route_location route_location; | |
| 359 | − u32 route_offset; | |
| 360 | − u32 route_val; | |
| 361 | −}; | |
| 362 | − | |
| 363 | −struct rockchip_pin_ctrl { | |
| 364 | − struct rockchip_pin_bank *pin_banks; | |
| 365 | − u32 nr_banks; | |
| 366 | − u32 nr_pins; | |
| 367 | − char *label; | |
| 368 | − enum rockchip_pinctrl_type type; | |
| 369 | − int grf_mux_offset; | |
| 370 | − int pmu_mux_offset; | |
| 371 | − int grf_drv_offset; | |
| 372 | − int pmu_drv_offset; | |
| 373 | − struct rockchip_mux_recalced_data *iomux_recalced; | |
| 374 | − u32 niomux_recalced; | |
| 375 | − struct rockchip_mux_route_data *iomux_routes; | |
| 376 | − u32 niomux_routes; | |
| 377 | − | |
| 378 | − void (*pull_calc_reg)(struct rockchip_pin_bank *bank, | |
| 379 | − int pin_num, struct regmap **regmap, | |
| 380 | − int *reg, u8 *bit); | |
| 381 | − void (*drv_calc_reg)(struct rockchip_pin_bank *bank, | |
| 382 | − int pin_num, struct regmap **regmap, | |
| 383 | − int *reg, u8 *bit); | |
| 384 | − int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, | |
| 385 | − int pin_num, struct regmap **regmap, | |
| 386 | − int *reg, u8 *bit); | |
| 387 | −}; | |
| 388 | − | |
| 389 | −struct rockchip_pin_config { | |
| 390 | − unsigned int func; | |
| 391 | − unsigned long *configs; | |
| 392 | − unsigned int nconfigs; | |
| 393 | −}; | |
| 394 | − | |
| 395 | −/** | |
| 396 | − * struct rockchip_pin_group: represent group of pins of a pinmux function. | |
| 397 | − * @name: name of the pin group, used to lookup the group. | |
| 398 | − * @pins: the pins included in this group. | |
| 399 | − * @npins: number of pins included in this group. | |
| 400 | − * @data: local pin configuration | |
| 401 | − */ | |
| 402 | −struct rockchip_pin_group { | |
| 403 | − const char *name; | |
| 404 | − unsigned int npins; | |
| 405 | − unsigned int *pins; | |
| 406 | − struct rockchip_pin_config *data; | |
| 407 | −}; | |
| 408 | − | |
| 409 | −/** | |
| 410 | − * struct rockchip_pmx_func: represent a pin function. | |
| 411 | − * @name: name of the pin function, used to lookup the function. | |
| 412 | − * @groups: one or more names of pin groups that provide this function. | |
| 413 | − * @ngroups: number of groups included in @groups. | |
| 414 | − */ | |
| 415 | −struct rockchip_pmx_func { | |
| 416 | − const char *name; | |
| 417 | − const char **groups; | |
| 418 | − u8 ngroups; | |
| 419 | −}; | |
| 420 | − | |
| 421 | −struct rockchip_pinctrl { | |
| 422 | − struct regmap *regmap_base; | |
| 423 | − int reg_size; | |
| 424 | − struct regmap *regmap_pull; | |
| 425 | − struct regmap *regmap_pmu; | |
| 426 | − struct device *dev; | |
| 427 | − struct rockchip_pin_ctrl *ctrl; | |
| 428 | − struct pinctrl_desc pctl; | |
| 429 | − struct pinctrl_dev *pctl_dev; | |
| 430 | − struct rockchip_pin_group *groups; | |
| 431 | − unsigned int ngroups; | |
| 432 | − struct rockchip_pmx_func *functions; | |
| 433 | − unsigned int nfunctions; | |
| 434 | −}; | |
| 435 | − | |
| 436 | 198 | static struct regmap_config rockchip_regmap_config = { |
| 437 | 199 | .reg_bits = 32, |
| 438 | 200 | .val_bits = 32, |
| @@ -2295,86 +2057,11 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, · 1856 unmodified lines | ||
| 2295 | 2057 | return 0; |
| 2296 | 2058 | } |
| 2297 | 2059 | |
| 2298 | −static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | |
| 2299 | −{ | |
| 2300 | − struct rockchip_pin_bank *bank = gpiochip_get_data(chip); | |
| 2301 | − u32 data; | |
| 2302 | − int ret; | |
| 2303 | − | |
| 2304 | − ret = clk_enable(bank->clk); | |
| 2305 | − if (ret < 0) { | |
| 2306 | − dev_err(bank->drvdata->dev, | |
| 2307 | − "failed to enable clock for bank %s\n", bank->name); | |
| 2308 | − return ret; | |
| 2309 | − } | |
| 2310 | − data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | |
| 2311 | − clk_disable(bank->clk); | |
| 2312 | − | |
| 2313 | − if (data & BIT(offset)) | |
| 2314 | − return GPIO_LINE_DIRECTION_OUT; | |
| 2315 | − | |
| 2316 | − return GPIO_LINE_DIRECTION_IN; | |
| 2317 | −} | |
| 2318 | − | |
| 2319 | −/* | |
| 2320 | − * The calls to gpio_direction_output() and gpio_direction_input() | |
| 2321 | − * leads to this function call (via the pinctrl_gpio_direction_{input|output}() | |
| 2322 | − * function called from the gpiolib interface). | |
| 2323 | − */ | |
| 2324 | −static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, | |
| 2325 | − int pin, bool input) | |
| 2326 | −{ | |
| 2327 | − struct rockchip_pin_bank *bank; | |
| 2328 | − int ret; | |
| 2329 | − unsigned long flags; | |
| 2330 | − u32 data; | |
| 2331 | − | |
| 2332 | − bank = gpiochip_get_data(chip); | |
| 2333 | − | |
| 2334 | − ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); | |
| 2335 | − if (ret < 0) | |
| 2336 | − return ret; | |
| 2337 | − | |
| 2338 | − clk_enable(bank->clk); | |
| 2339 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 2340 | − | |
| 2341 | − data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | |
| 2342 | − /* set bit to 1 for output, 0 for input */ | |
| 2343 | − if (!input) | |
| 2344 | − data |= BIT(pin); | |
| 2345 | − else | |
| 2346 | − data &= ~BIT(pin); | |
| 2347 | − writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | |
| 2348 | − | |
| 2349 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 2350 | − clk_disable(bank->clk); | |
| 2351 | − | |
| 2352 | − return 0; | |
| 2353 | −} | |
| 2354 | − | |
| 2355 | −static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | |
| 2356 | − struct pinctrl_gpio_range *range, | |
| 2357 | − unsigned offset, bool input) | |
| 2358 | −{ | |
| 2359 | − struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
| 2360 | − struct gpio_chip *chip; | |
| 2361 | − int pin; | |
| 2362 | − | |
| 2363 | − chip = range->gc; | |
| 2364 | − pin = offset - chip->base; | |
| 2365 | − dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", | |
| 2366 | − offset, range->name, pin, input ? "input" : "output"); | |
| 2367 | − | |
| 2368 | − return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base, | |
| 2369 | − input); | |
| 2370 | −} | |
| 2371 | − | |
| 2372 | 2060 | static const struct pinmux_ops rockchip_pmx_ops = { |
| 2373 | 2061 | .get_functions_count = rockchip_pmx_get_funcs_count, |
| 2374 | 2062 | .get_function_name = rockchip_pmx_get_func_name, |
| 2375 | 2063 | .get_function_groups = rockchip_pmx_get_groups, |
| 2376 | 2064 | .set_mux = rockchip_pmx_set, |
| 2377 | − .gpio_set_direction = rockchip_pmx_gpio_set_direction, | |
| 2378 | 2065 | }; |
| 2379 | 2066 | |
| 2380 | 2067 | /* |
| @@ -2405,15 +2092,13 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, · 24 unmodified lines | ||
| 2405 | 2092 | return false; |
| 2406 | 2093 | } |
| 2407 | 2094 | |
| 2408 | −static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value); | |
| 2409 | −static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); | |
| 2410 | − | |
| 2411 | 2095 | /* set the pin config settings for a specified pin */ |
| 2412 | 2096 | static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, |
| 2413 | 2097 | unsigned long *configs, unsigned num_configs) |
| 2414 | 2098 | { |
| 2415 | 2099 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
| 2416 | 2100 | struct rockchip_pin_bank *bank = pin_to_bank(info, pin); |
| 2101 | + struct gpio_chip *gpio = &bank->gpio_chip; | |
| 2417 | 2102 | enum pin_config_param param; |
| 2418 | 2103 | u32 arg; |
| 2419 | 2104 | int i; |
| @@ -2446,10 +2131,13 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, · 26 unmodified lines | ||
| 2446 | 2131 | return rc; |
| 2447 | 2132 | break; |
| 2448 | 2133 | case PIN_CONFIG_OUTPUT: |
| 2449 | − rockchip_gpio_set(&bank->gpio_chip, | |
| 2450 | − pin - bank->pin_base, arg); | |
| 2451 | − rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip, | |
| 2452 | − pin - bank->pin_base, false); | |
| 2134 | + rc = rockchip_set_mux(bank, pin - bank->pin_base, | |
| 2135 | + RK_FUNC_GPIO); | |
| 2136 | + if (rc != RK_FUNC_GPIO) | |
| 2137 | + return -EINVAL; | |
| 2138 | + | |
| 2139 | + rc = gpio->direction_output(gpio, pin - bank->pin_base, | |
| 2140 | + arg); | |
| 2453 | 2141 | if (rc) |
| 2454 | 2142 | return rc; |
| 2455 | 2143 | break; |
| @@ -2487,6 +2175,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, · 31 unmodified lines | ||
| 2487 | 2175 | { |
| 2488 | 2176 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
| 2489 | 2177 | struct rockchip_pin_bank *bank = pin_to_bank(info, pin); |
| 2178 | + struct gpio_chip *gpio = &bank->gpio_chip; | |
| 2490 | 2179 | enum pin_config_param param = pinconf_to_config_param(*config); |
| 2491 | 2180 | u16 arg; |
| 2492 | 2181 | int rc; |
| @@ -2515,7 +2204,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, · 22 unmodified lines | ||
| 2515 | 2204 | if (rc != RK_FUNC_GPIO) |
| 2516 | 2205 | return -EINVAL; |
| 2517 | 2206 | |
| 2518 | − rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); | |
| 2207 | + rc = gpio->get(gpio, pin - bank->pin_base); | |
| 2519 | 2208 | if (rc < 0) |
| 2520 | 2209 | return rc; |
| 2521 | 2210 | |
| @@ -2753,7 +2442,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, · 231 unmodified lines | ||
| 2753 | 2442 | ctrldesc->npins = info->ctrl->nr_pins; |
| 2754 | 2443 | |
| 2755 | 2444 | pdesc = pindesc; |
| 2756 | − for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) { | |
| 2445 | + for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) { | |
| 2757 | 2446 | pin_bank = &info->ctrl->pin_banks[bank]; |
| 2758 | 2447 | for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { |
| 2759 | 2448 | pdesc->number = k; |
| @@ -2773,553 +2462,9 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, · 13 unmodified lines | ||
| 2773 | 2462 | return PTR_ERR(info->pctl_dev); |
| 2774 | 2463 | } |
| 2775 | 2464 | |
| 2776 | − for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { | |
| 2777 | − pin_bank = &info->ctrl->pin_banks[bank]; | |
| 2778 | − pin_bank->grange.name = pin_bank->name; | |
| 2779 | − pin_bank->grange.id = bank; | |
| 2780 | − pin_bank->grange.pin_base = pin_bank->pin_base; | |
| 2781 | − pin_bank->grange.base = pin_bank->gpio_chip.base; | |
| 2782 | − pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; | |
| 2783 | − pin_bank->grange.gc = &pin_bank->gpio_chip; | |
| 2784 | − pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); | |
| 2785 | − } | |
| 2786 | − | |
| 2787 | 2465 | return 0; |
| 2788 | 2466 | } |
| 2789 | 2467 | |
| 2790 | −/* | |
| 2791 | − * GPIO handling | |
| 2792 | − */ | |
| 2793 | − | |
| 2794 | −static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | |
| 2795 | −{ | |
| 2796 | − struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 2797 | − void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR; | |
| 2798 | − unsigned long flags; | |
| 2799 | − u32 data; | |
| 2800 | − | |
| 2801 | − clk_enable(bank->clk); | |
| 2802 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 2803 | − | |
| 2804 | − data = readl(reg); | |
| 2805 | − data &= ~BIT(offset); | |
| 2806 | − if (value) | |
| 2807 | − data |= BIT(offset); | |
| 2808 | − writel(data, reg); | |
| 2809 | − | |
| 2810 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 2811 | − clk_disable(bank->clk); | |
| 2812 | −} | |
| 2813 | − | |
| 2814 | −/* | |
| 2815 | − * Returns the level of the pin for input direction and setting of the DR | |
| 2816 | − * register for output gpios. | |
| 2817 | − */ | |
| 2818 | −static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) | |
| 2819 | −{ | |
| 2820 | − struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 2821 | − u32 data; | |
| 2822 | − | |
| 2823 | − clk_enable(bank->clk); | |
| 2824 | − data = readl(bank->reg_base + GPIO_EXT_PORT); | |
| 2825 | − clk_disable(bank->clk); | |
| 2826 | − data >>= offset; | |
| 2827 | − data &= 1; | |
| 2828 | − return data; | |
| 2829 | −} | |
| 2830 | − | |
| 2831 | −/* | |
| 2832 | − * gpiolib gpio_direction_input callback function. The setting of the pin | |
| 2833 | − * mux function as 'gpio input' will be handled by the pinctrl subsystem | |
| 2834 | − * interface. | |
| 2835 | − */ | |
| 2836 | −static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | |
| 2837 | −{ | |
| 2838 | − return pinctrl_gpio_direction_input(gc->base + offset); | |
| 2839 | −} | |
| 2840 | − | |
| 2841 | −/* | |
| 2842 | − * gpiolib gpio_direction_output callback function. The setting of the pin | |
| 2843 | − * mux function as 'gpio output' will be handled by the pinctrl subsystem | |
| 2844 | − * interface. | |
| 2845 | − */ | |
| 2846 | −static int rockchip_gpio_direction_output(struct gpio_chip *gc, | |
| 2847 | − unsigned offset, int value) | |
| 2848 | −{ | |
| 2849 | − rockchip_gpio_set(gc, offset, value); | |
| 2850 | − return pinctrl_gpio_direction_output(gc->base + offset); | |
| 2851 | −} | |
| 2852 | − | |
| 2853 | −static void rockchip_gpio_set_debounce(struct gpio_chip *gc, | |
| 2854 | − unsigned int offset, bool enable) | |
| 2855 | −{ | |
| 2856 | − struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 2857 | − void __iomem *reg = bank->reg_base + GPIO_DEBOUNCE; | |
| 2858 | − unsigned long flags; | |
| 2859 | − u32 data; | |
| 2860 | − | |
| 2861 | − clk_enable(bank->clk); | |
| 2862 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 2863 | − | |
| 2864 | − data = readl(reg); | |
| 2865 | − if (enable) | |
| 2866 | − data |= BIT(offset); | |
| 2867 | − else | |
| 2868 | − data &= ~BIT(offset); | |
| 2869 | − writel(data, reg); | |
| 2870 | − | |
| 2871 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 2872 | − clk_disable(bank->clk); | |
| 2873 | −} | |
| 2874 | − | |
| 2875 | −/* | |
| 2876 | − * gpiolib set_config callback function. The setting of the pin | |
| 2877 | − * mux function as 'gpio output' will be handled by the pinctrl subsystem | |
| 2878 | − * interface. | |
| 2879 | − */ | |
| 2880 | −static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset, | |
| 2881 | − unsigned long config) | |
| 2882 | −{ | |
| 2883 | − enum pin_config_param param = pinconf_to_config_param(config); | |
| 2884 | − | |
| 2885 | − switch (param) { | |
| 2886 | − case PIN_CONFIG_INPUT_DEBOUNCE: | |
| 2887 | − rockchip_gpio_set_debounce(gc, offset, true); | |
| 2888 | − /* | |
| 2889 | − * Rockchip's gpio could only support up to one period | |
| 2890 | − * of the debounce clock(pclk), which is far away from | |
| 2891 | − * satisftying the requirement, as pclk is usually near | |
| 2892 | − * 100MHz shared by all peripherals. So the fact is it | |
| 2893 | − * has crippled debounce capability could only be useful | |
| 2894 | − * to prevent any spurious glitches from waking up the system | |
| 2895 | − * if the gpio is conguired as wakeup interrupt source. Let's | |
| 2896 | − * still return -ENOTSUPP as before, to make sure the caller | |
| 2897 | − * of gpiod_set_debounce won't change its behaviour. | |
| 2898 | − */ | |
| 2899 | − return -ENOTSUPP; | |
| 2900 | − default: | |
| 2901 | − return -ENOTSUPP; | |
| 2902 | − } | |
| 2903 | −} | |
| 2904 | − | |
| 2905 | −/* | |
| 2906 | − * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin | |
| 2907 | − * and a virtual IRQ, if not already present. | |
| 2908 | − */ | |
| 2909 | −static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |
| 2910 | −{ | |
| 2911 | − struct rockchip_pin_bank *bank = gpiochip_get_data(gc); | |
| 2912 | − unsigned int virq; | |
| 2913 | − | |
| 2914 | − if (!bank->domain) | |
| 2915 | − return -ENXIO; | |
| 2916 | − | |
| 2917 | − clk_enable(bank->clk); | |
| 2918 | − virq = irq_create_mapping(bank->domain, offset); | |
| 2919 | − clk_disable(bank->clk); | |
| 2920 | − | |
| 2921 | − return (virq) ? : -ENXIO; | |
| 2922 | −} | |
| 2923 | − | |
| 2924 | −static const struct gpio_chip rockchip_gpiolib_chip = { | |
| 2925 | − .request = gpiochip_generic_request, | |
| 2926 | − .free = gpiochip_generic_free, | |
| 2927 | − .set = rockchip_gpio_set, | |
| 2928 | − .get = rockchip_gpio_get, | |
| 2929 | − .get_direction = rockchip_gpio_get_direction, | |
| 2930 | − .direction_input = rockchip_gpio_direction_input, | |
| 2931 | − .direction_output = rockchip_gpio_direction_output, | |
| 2932 | − .set_config = rockchip_gpio_set_config, | |
| 2933 | − .to_irq = rockchip_gpio_to_irq, | |
| 2934 | − .owner = THIS_MODULE, | |
| 2935 | −}; | |
| 2936 | − | |
| 2937 | −/* | |
| 2938 | − * Interrupt handling | |
| 2939 | − */ | |
| 2940 | − | |
| 2941 | −static void rockchip_irq_demux(struct irq_desc *desc) | |
| 2942 | −{ | |
| 2943 | − struct irq_chip *chip = irq_desc_get_chip(desc); | |
| 2944 | − struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc); | |
| 2945 | − u32 pend; | |
| 2946 | − | |
| 2947 | − dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); | |
| 2948 | − | |
| 2949 | − chained_irq_enter(chip, desc); | |
| 2950 | − | |
| 2951 | − pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); | |
| 2952 | − | |
| 2953 | − while (pend) { | |
| 2954 | − unsigned int irq, virq; | |
| 2955 | − | |
| 2956 | − irq = __ffs(pend); | |
| 2957 | − pend &= ~BIT(irq); | |
| 2958 | − virq = irq_find_mapping(bank->domain, irq); | |
| 2959 | − | |
| 2960 | − if (!virq) { | |
| 2961 | − dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); | |
| 2962 | − continue; | |
| 2963 | − } | |
| 2964 | − | |
| 2965 | − dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq); | |
| 2966 | − | |
| 2967 | − /* | |
| 2968 | − * Triggering IRQ on both rising and falling edge | |
| 2969 | − * needs manual intervention. | |
| 2970 | − */ | |
| 2971 | − if (bank->toggle_edge_mode & BIT(irq)) { | |
| 2972 | − u32 data, data_old, polarity; | |
| 2973 | − unsigned long flags; | |
| 2974 | − | |
| 2975 | − data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); | |
| 2976 | − do { | |
| 2977 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 2978 | − | |
| 2979 | − polarity = readl_relaxed(bank->reg_base + | |
| 2980 | − GPIO_INT_POLARITY); | |
| 2981 | − if (data & BIT(irq)) | |
| 2982 | − polarity &= ~BIT(irq); | |
| 2983 | − else | |
| 2984 | − polarity |= BIT(irq); | |
| 2985 | − writel(polarity, | |
| 2986 | − bank->reg_base + GPIO_INT_POLARITY); | |
| 2987 | − | |
| 2988 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 2989 | − | |
| 2990 | − data_old = data; | |
| 2991 | − data = readl_relaxed(bank->reg_base + | |
| 2992 | − GPIO_EXT_PORT); | |
| 2993 | − } while ((data & BIT(irq)) != (data_old & BIT(irq))); | |
| 2994 | − } | |
| 2995 | − | |
| 2996 | − generic_handle_irq(virq); | |
| 2997 | − } | |
| 2998 | − | |
| 2999 | − chained_irq_exit(chip, desc); | |
| 3000 | −} | |
| 3001 | − | |
| 3002 | −static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |
| 3003 | −{ | |
| 3004 | − struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 3005 | − struct rockchip_pin_bank *bank = gc->private; | |
| 3006 | − u32 mask = BIT(d->hwirq); | |
| 3007 | − u32 polarity; | |
| 3008 | − u32 level; | |
| 3009 | − u32 data; | |
| 3010 | − unsigned long flags; | |
| 3011 | − int ret; | |
| 3012 | − | |
| 3013 | − /* make sure the pin is configured as gpio input */ | |
| 3014 | − ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); | |
| 3015 | − if (ret < 0) | |
| 3016 | − return ret; | |
| 3017 | − | |
| 3018 | − clk_enable(bank->clk); | |
| 3019 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 3020 | − | |
| 3021 | − data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | |
| 3022 | − data &= ~mask; | |
| 3023 | − writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | |
| 3024 | − | |
| 3025 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 3026 | − | |
| 3027 | − if (type & IRQ_TYPE_EDGE_BOTH) | |
| 3028 | − irq_set_handler_locked(d, handle_edge_irq); | |
| 3029 | − else | |
| 3030 | − irq_set_handler_locked(d, handle_level_irq); | |
| 3031 | − | |
| 3032 | − raw_spin_lock_irqsave(&bank->slock, flags); | |
| 3033 | − irq_gc_lock(gc); | |
| 3034 | − | |
| 3035 | − level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); | |
| 3036 | − polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY); | |
| 3037 | − | |
| 3038 | − switch (type) { | |
| 3039 | − case IRQ_TYPE_EDGE_BOTH: | |
| 3040 | − bank->toggle_edge_mode |= mask; | |
| 3041 | − level |= mask; | |
| 3042 | − | |
| 3043 | − /* | |
| 3044 | − * Determine gpio state. If 1 next interrupt should be falling | |
| 3045 | − * otherwise rising. | |
| 3046 | − */ | |
| 3047 | − data = readl(bank->reg_base + GPIO_EXT_PORT); | |
| 3048 | − if (data & mask) | |
| 3049 | − polarity &= ~mask; | |
| 3050 | − else | |
| 3051 | − polarity |= mask; | |
| 3052 | − break; | |
| 3053 | − case IRQ_TYPE_EDGE_RISING: | |
| 3054 | − bank->toggle_edge_mode &= ~mask; | |
| 3055 | − level |= mask; | |
| 3056 | − polarity |= mask; | |
| 3057 | − break; | |
| 3058 | − case IRQ_TYPE_EDGE_FALLING: | |
| 3059 | − bank->toggle_edge_mode &= ~mask; | |
| 3060 | − level |= mask; | |
| 3061 | − polarity &= ~mask; | |
| 3062 | − break; | |
| 3063 | − case IRQ_TYPE_LEVEL_HIGH: | |
| 3064 | − bank->toggle_edge_mode &= ~mask; | |
| 3065 | − level &= ~mask; | |
| 3066 | − polarity |= mask; | |
| 3067 | − break; | |
| 3068 | − case IRQ_TYPE_LEVEL_LOW: | |
| 3069 | − bank->toggle_edge_mode &= ~mask; | |
| 3070 | − level &= ~mask; | |
| 3071 | − polarity &= ~mask; | |
| 3072 | − break; | |
| 3073 | − default: | |
| 3074 | − irq_gc_unlock(gc); | |
| 3075 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 3076 | − clk_disable(bank->clk); | |
| 3077 | − return -EINVAL; | |
| 3078 | − } | |
| 3079 | − | |
| 3080 | − writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL); | |
| 3081 | − writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); | |
| 3082 | − | |
| 3083 | − irq_gc_unlock(gc); | |
| 3084 | − raw_spin_unlock_irqrestore(&bank->slock, flags); | |
| 3085 | − clk_disable(bank->clk); | |
| 3086 | − | |
| 3087 | − return 0; | |
| 3088 | −} | |
| 3089 | − | |
| 3090 | −static void rockchip_irq_suspend(struct irq_data *d) | |
| 3091 | −{ | |
| 3092 | − struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 3093 | − struct rockchip_pin_bank *bank = gc->private; | |
| 3094 | − | |
| 3095 | − clk_enable(bank->clk); | |
| 3096 | − bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK); | |
| 3097 | − irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK); | |
| 3098 | − clk_disable(bank->clk); | |
| 3099 | −} | |
| 3100 | − | |
| 3101 | −static void rockchip_irq_resume(struct irq_data *d) | |
| 3102 | −{ | |
| 3103 | − struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 3104 | − struct rockchip_pin_bank *bank = gc->private; | |
| 3105 | − | |
| 3106 | − clk_enable(bank->clk); | |
| 3107 | − irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK); | |
| 3108 | − clk_disable(bank->clk); | |
| 3109 | −} | |
| 3110 | − | |
| 3111 | −static void rockchip_irq_enable(struct irq_data *d) | |
| 3112 | −{ | |
| 3113 | − struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 3114 | − struct rockchip_pin_bank *bank = gc->private; | |
| 3115 | − | |
| 3116 | − clk_enable(bank->clk); | |
| 3117 | − irq_gc_mask_clr_bit(d); | |
| 3118 | −} | |
| 3119 | − | |
| 3120 | −static void rockchip_irq_disable(struct irq_data *d) | |
| 3121 | −{ | |
| 3122 | − struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 3123 | − struct rockchip_pin_bank *bank = gc->private; | |
| 3124 | − | |
| 3125 | − irq_gc_mask_set_bit(d); | |
| 3126 | − clk_disable(bank->clk); | |
| 3127 | −} | |
| 3128 | − | |
| 3129 | −static int rockchip_interrupts_register(struct platform_device *pdev, | |
| 3130 | − struct rockchip_pinctrl *info) | |
| 3131 | −{ | |
| 3132 | − struct rockchip_pin_ctrl *ctrl = info->ctrl; | |
| 3133 | − struct rockchip_pin_bank *bank = ctrl->pin_banks; | |
| 3134 | − unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | |
| 3135 | − struct irq_chip_generic *gc; | |
| 3136 | − int ret; | |
| 3137 | − int i; | |
| 3138 | − | |
| 3139 | − for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | |
| 3140 | − if (!bank->valid) { | |
| 3141 | − dev_warn(&pdev->dev, "bank %s is not valid\n", | |
| 3142 | − bank->name); | |
| 3143 | − continue; | |
| 3144 | − } | |
| 3145 | − | |
| 3146 | − ret = clk_enable(bank->clk); | |
| 3147 | − if (ret) { | |
| 3148 | − dev_err(&pdev->dev, "failed to enable clock for bank %s\n", | |
| 3149 | − bank->name); | |
| 3150 | − continue; | |
| 3151 | − } | |
| 3152 | − | |
| 3153 | − bank->domain = irq_domain_add_linear(bank->of_node, 32, | |
| 3154 | − &irq_generic_chip_ops, NULL); | |
| 3155 | − if (!bank->domain) { | |
| 3156 | − dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", | |
| 3157 | − bank->name); | |
| 3158 | − clk_disable(bank->clk); | |
| 3159 | − continue; | |
| 3160 | − } | |
| 3161 | − | |
| 3162 | − ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, | |
| 3163 | − "rockchip_gpio_irq", handle_level_irq, | |
| 3164 | − clr, 0, 0); | |
| 3165 | − if (ret) { | |
| 3166 | − dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n", | |
| 3167 | − bank->name); | |
| 3168 | − irq_domain_remove(bank->domain); | |
| 3169 | − clk_disable(bank->clk); | |
| 3170 | − continue; | |
| 3171 | − } | |
| 3172 | − | |
| 3173 | − gc = irq_get_domain_generic_chip(bank->domain, 0); | |
| 3174 | − gc->reg_base = bank->reg_base; | |
| 3175 | − gc->private = bank; | |
| 3176 | − gc->chip_types[0].regs.mask = GPIO_INTMASK; | |
| 3177 | − gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; | |
| 3178 | − gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; | |
| 3179 | − gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; | |
| 3180 | − gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; | |
| 3181 | − gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; | |
| 3182 | − gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; | |
| 3183 | − gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | |
| 3184 | − gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; | |
| 3185 | − gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; | |
| 3186 | − gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; | |
| 3187 | − gc->wake_enabled = IRQ_MSK(bank->nr_pins); | |
| 3188 | − | |
| 3189 | − /* | |
| 3190 | − * Linux assumes that all interrupts start out disabled/masked. | |
| 3191 | − * Our driver only uses the concept of masked and always keeps | |
| 3192 | − * things enabled, so for us that's all masked and all enabled. | |
| 3193 | − */ | |
| 3194 | − writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTMASK); | |
| 3195 | − writel_relaxed(0xffffffff, bank->reg_base + GPIO_PORTS_EOI); | |
| 3196 | − writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTEN); | |
| 3197 | − gc->mask_cache = 0xffffffff; | |
| 3198 | − | |
| 3199 | − irq_set_chained_handler_and_data(bank->irq, | |
| 3200 | − rockchip_irq_demux, bank); | |
| 3201 | − clk_disable(bank->clk); | |
| 3202 | − } | |
| 3203 | − | |
| 3204 | − return 0; | |
| 3205 | −} | |
| 3206 | − | |
| 3207 | −static int rockchip_gpiolib_register(struct platform_device *pdev, | |
| 3208 | − struct rockchip_pinctrl *info) | |
| 3209 | −{ | |
| 3210 | − struct rockchip_pin_ctrl *ctrl = info->ctrl; | |
| 3211 | − struct rockchip_pin_bank *bank = ctrl->pin_banks; | |
| 3212 | − struct gpio_chip *gc; | |
| 3213 | − int ret; | |
| 3214 | − int i; | |
| 3215 | − | |
| 3216 | − for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | |
| 3217 | − if (!bank->valid) { | |
| 3218 | − dev_warn(&pdev->dev, "bank %s is not valid\n", | |
| 3219 | − bank->name); | |
| 3220 | − continue; | |
| 3221 | − } | |
| 3222 | − | |
| 3223 | − bank->gpio_chip = rockchip_gpiolib_chip; | |
| 3224 | − | |
| 3225 | − gc = &bank->gpio_chip; | |
| 3226 | − gc->base = bank->pin_base; | |
| 3227 | − gc->ngpio = bank->nr_pins; | |
| 3228 | − gc->parent = &pdev->dev; | |
| 3229 | − gc->of_node = bank->of_node; | |
| 3230 | − gc->label = bank->name; | |
| 3231 | − | |
| 3232 | − ret = gpiochip_add_data(gc, bank); | |
| 3233 | − if (ret) { | |
| 3234 | − dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", | |
| 3235 | − gc->label, ret); | |
| 3236 | − goto fail; | |
| 3237 | − } | |
| 3238 | − } | |
| 3239 | − | |
| 3240 | − rockchip_interrupts_register(pdev, info); | |
| 3241 | − | |
| 3242 | − return 0; | |
| 3243 | − | |
| 3244 | −fail: | |
| 3245 | − for (--i, --bank; i >= 0; --i, --bank) { | |
| 3246 | − if (!bank->valid) | |
| 3247 | − continue; | |
| 3248 | − gpiochip_remove(&bank->gpio_chip); | |
| 3249 | − } | |
| 3250 | − return ret; | |
| 3251 | −} | |
| 3252 | − | |
| 3253 | −static int rockchip_gpiolib_unregister(struct platform_device *pdev, | |
| 3254 | − struct rockchip_pinctrl *info) | |
| 3255 | −{ | |
| 3256 | − struct rockchip_pin_ctrl *ctrl = info->ctrl; | |
| 3257 | − struct rockchip_pin_bank *bank = ctrl->pin_banks; | |
| 3258 | − int i; | |
| 3259 | − | |
| 3260 | − for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | |
| 3261 | − if (!bank->valid) | |
| 3262 | − continue; | |
| 3263 | − gpiochip_remove(&bank->gpio_chip); | |
| 3264 | − } | |
| 3265 | − | |
| 3266 | − return 0; | |
| 3267 | −} | |
| 3268 | − | |
| 3269 | −static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, | |
| 3270 | − struct rockchip_pinctrl *info) | |
| 3271 | −{ | |
| 3272 | − struct resource res; | |
| 3273 | − void __iomem *base; | |
| 3274 | − | |
| 3275 | − if (of_address_to_resource(bank->of_node, 0, &res)) { | |
| 3276 | − dev_err(info->dev, "cannot find IO resource for bank\n"); | |
| 3277 | − return -ENOENT; | |
| 3278 | − } | |
| 3279 | − | |
| 3280 | − bank->reg_base = devm_ioremap_resource(info->dev, &res); | |
| 3281 | − if (IS_ERR(bank->reg_base)) | |
| 3282 | − return PTR_ERR(bank->reg_base); | |
| 3283 | − | |
| 3284 | − /* | |
| 3285 | − * special case, where parts of the pull setting-registers are | |
| 3286 | − * part of the PMU register space | |
| 3287 | − */ | |
| 3288 | − if (of_device_is_compatible(bank->of_node, | |
| 3289 | − "rockchip,rk3188-gpio-bank0")) { | |
| 3290 | − struct device_node *node; | |
| 3291 | − | |
| 3292 | − node = of_parse_phandle(bank->of_node->parent, | |
| 3293 | − "rockchip,pmu", 0); | |
| 3294 | − if (!node) { | |
| 3295 | − if (of_address_to_resource(bank->of_node, 1, &res)) { | |
| 3296 | − dev_err(info->dev, "cannot find IO resource for bank\n"); | |
| 3297 | − return -ENOENT; | |
| 3298 | − } | |
| 3299 | − | |
| 3300 | − base = devm_ioremap_resource(info->dev, &res); | |
| 3301 | − if (IS_ERR(base)) | |
| 3302 | − return PTR_ERR(base); | |
| 3303 | − rockchip_regmap_config.max_register = | |
| 3304 | − resource_size(&res) - 4; | |
| 3305 | − rockchip_regmap_config.name = | |
| 3306 | − "rockchip,rk3188-gpio-bank0-pull"; | |
| 3307 | − bank->regmap_pull = devm_regmap_init_mmio(info->dev, | |
| 3308 | − base, | |
| 3309 | − &rockchip_regmap_config); | |
| 3310 | − } | |
| 3311 | − of_node_put(node); | |
| 3312 | − } | |
| 3313 | − | |
| 3314 | − bank->irq = irq_of_parse_and_map(bank->of_node, 0); | |
| 3315 | − | |
| 3316 | − bank->clk = of_clk_get(bank->of_node, 0); | |
| 3317 | − if (IS_ERR(bank->clk)) | |
| 3318 | − return PTR_ERR(bank->clk); | |
| 3319 | − | |
| 3320 | − return clk_prepare(bank->clk); | |
| 3321 | −} | |
| 3322 | − | |
| 3323 | 2468 | static const struct of_device_id rockchip_pinctrl_dt_match[]; |
| 3324 | 2469 | |
| 3325 | 2470 | /* retrieve the soc specific data */ |
| @@ -3329,7 +2474,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( · 3 unmodified lines | ||
| 3329 | 2474 | { |
| 3330 | 2475 | const struct of_device_id *match; |
| 3331 | 2476 | struct device_node *node = pdev->dev.of_node; |
| 3332 | − struct device_node *np; | |
| 3333 | 2477 | struct rockchip_pin_ctrl *ctrl; |
| 3334 | 2478 | struct rockchip_pin_bank *bank; |
| 3335 | 2479 | int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; |
| @@ -3337,23 +2481,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( · 1 unmodified line | ||
| 3337 | 2481 | match = of_match_node(rockchip_pinctrl_dt_match, node); |
| 3338 | 2482 | ctrl = (struct rockchip_pin_ctrl *)match->data; |
| 3339 | 2483 | |
| 3340 | − for_each_child_of_node(node, np) { | |
| 3341 | − if (!of_find_property(np, "gpio-controller", NULL)) | |
| 3342 | − continue; | |
| 3343 | − | |
| 3344 | − bank = ctrl->pin_banks; | |
| 3345 | − for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | |
| 3346 | − if (!strcmp(bank->name, np->name)) { | |
| 3347 | − bank->of_node = np; | |
| 3348 | − | |
| 3349 | − if (!rockchip_get_bank_data(bank, d)) | |
| 3350 | − bank->valid = true; | |
| 3351 | − | |
| 3352 | − break; | |
| 3353 | − } | |
| 3354 | − } | |
| 3355 | − } | |
| 3356 | − | |
| 3357 | 2484 | grf_offs = ctrl->grf_mux_offset; |
| 3358 | 2485 | pmu_offs = ctrl->pmu_mux_offset; |
| 3359 | 2486 | drv_pmu_offs = ctrl->pmu_drv_offset; |
| @@ -3574,18 +2701,18 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) · 214 unmodified lines | ||
| 3574 | 2701 | return PTR_ERR(info->regmap_pmu); |
| 3575 | 2702 | } |
| 3576 | 2703 | |
| 3577 | − ret = rockchip_gpiolib_register(pdev, info); | |
| 2704 | + ret = rockchip_pinctrl_register(pdev, info); | |
| 3578 | 2705 | if (ret) |
| 3579 | 2706 | return ret; |
| 3580 | 2707 | |
| 3581 | − ret = rockchip_pinctrl_register(pdev, info); | |
| 2708 | + platform_set_drvdata(pdev, info); | |
| 2709 | + | |
| 2710 | + ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL); | |
| 3582 | 2711 | if (ret) { |
| 3583 | − rockchip_gpiolib_unregister(pdev, info); | |
| 2712 | + dev_err(&pdev->dev, "failed to register gpio device\n"); | |
| 3584 | 2713 | return ret; |
| 3585 | 2714 | } |
| 3586 | 2715 | |
| 3587 | − platform_set_drvdata(pdev, info); | |
| 3588 | − | |
| 3589 | 2716 | return 0; |
| 3590 | 2717 | } |
| 3591 | 2718 | |
| @@ -0,0 +1,287 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2020-2021 Rockchip Electronics Co. Ltd. | |
| 4 | + * | |
| 5 | + * Copyright (c) 2013 MundoReader S.L. | |
| 6 | + * Author: Heiko Stuebner <heiko@sntech.de> | |
| 7 | + * | |
| 8 | + * With some ideas taken from pinctrl-samsung: | |
| 9 | + * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
| 10 | + * http://www.samsung.com | |
| 11 | + * Copyright (c) 2012 Linaro Ltd | |
| 12 | + * https://www.linaro.org | |
| 13 | + * | |
| 14 | + * and pinctrl-at91: | |
| 15 | + * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#ifndef _PINCTRL_ROCKCHIP_H | |
| 19 | +#define _PINCTRL_ROCKCHIP_H | |
| 20 | + | |
| 21 | +enum rockchip_pinctrl_type { | |
| 22 | + PX30, | |
| 23 | + RV1108, | |
| 24 | + RK2928, | |
| 25 | + RK3066B, | |
| 26 | + RK3128, | |
| 27 | + RK3188, | |
| 28 | + RK3288, | |
| 29 | + RK3308, | |
| 30 | + RK3368, | |
| 31 | + RK3399, | |
| 32 | + RK3568, | |
| 33 | +}; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * struct rockchip_gpio_regs | |
| 37 | + * @port_dr: data register | |
| 38 | + * @port_ddr: data direction register | |
| 39 | + * @int_en: interrupt enable | |
| 40 | + * @int_mask: interrupt mask | |
| 41 | + * @int_type: interrupt trigger type, such as high, low, edge trriger type. | |
| 42 | + * @int_polarity: interrupt polarity enable register | |
| 43 | + * @int_bothedge: interrupt bothedge enable register | |
| 44 | + * @int_status: interrupt status register | |
| 45 | + * @int_rawstatus: int_status = int_rawstatus & int_mask | |
| 46 | + * @debounce: enable debounce for interrupt signal | |
| 47 | + * @dbclk_div_en: enable divider for debounce clock | |
| 48 | + * @dbclk_div_con: setting for divider of debounce clock | |
| 49 | + * @port_eoi: end of interrupt of the port | |
| 50 | + * @ext_port: port data from external | |
| 51 | + * @version_id: controller version register | |
| 52 | + */ | |
| 53 | +struct rockchip_gpio_regs { | |
| 54 | + u32 port_dr; | |
| 55 | + u32 port_ddr; | |
| 56 | + u32 int_en; | |
| 57 | + u32 int_mask; | |
| 58 | + u32 int_type; | |
| 59 | + u32 int_polarity; | |
| 60 | + u32 int_bothedge; | |
| 61 | + u32 int_status; | |
| 62 | + u32 int_rawstatus; | |
| 63 | + u32 debounce; | |
| 64 | + u32 dbclk_div_en; | |
| 65 | + u32 dbclk_div_con; | |
| 66 | + u32 port_eoi; | |
| 67 | + u32 ext_port; | |
| 68 | + u32 version_id; | |
| 69 | +}; | |
| 70 | + | |
| 71 | +/** | |
| 72 | + * struct rockchip_iomux | |
| 73 | + * @type: iomux variant using IOMUX_* constants | |
| 74 | + * @offset: if initialized to -1 it will be autocalculated, by specifying | |
| 75 | + * an initial offset value the relevant source offset can be reset | |
| 76 | + * to a new value for autocalculating the following iomux registers. | |
| 77 | + */ | |
| 78 | +struct rockchip_iomux { | |
| 79 | + int type; | |
| 80 | + int offset; | |
| 81 | +}; | |
| 82 | + | |
| 83 | +/* | |
| 84 | + * enum type index corresponding to rockchip_perpin_drv_list arrays index. | |
| 85 | + */ | |
| 86 | +enum rockchip_pin_drv_type { | |
| 87 | + DRV_TYPE_IO_DEFAULT = 0, | |
| 88 | + DRV_TYPE_IO_1V8_OR_3V0, | |
| 89 | + DRV_TYPE_IO_1V8_ONLY, | |
| 90 | + DRV_TYPE_IO_1V8_3V0_AUTO, | |
| 91 | + DRV_TYPE_IO_3V3_ONLY, | |
| 92 | + DRV_TYPE_MAX | |
| 93 | +}; | |
| 94 | + | |
| 95 | +/* | |
| 96 | + * enum type index corresponding to rockchip_pull_list arrays index. | |
| 97 | + */ | |
| 98 | +enum rockchip_pin_pull_type { | |
| 99 | + PULL_TYPE_IO_DEFAULT = 0, | |
| 100 | + PULL_TYPE_IO_1V8_ONLY, | |
| 101 | + PULL_TYPE_MAX | |
| 102 | +}; | |
| 103 | + | |
| 104 | +/** | |
| 105 | + * struct rockchip_drv | |
| 106 | + * @drv_type: drive strength variant using rockchip_perpin_drv_type | |
| 107 | + * @offset: if initialized to -1 it will be autocalculated, by specifying | |
| 108 | + * an initial offset value the relevant source offset can be reset | |
| 109 | + * to a new value for autocalculating the following drive strength | |
| 110 | + * registers. if used chips own cal_drv func instead to calculate | |
| 111 | + * registers offset, the variant could be ignored. | |
| 112 | + */ | |
| 113 | +struct rockchip_drv { | |
| 114 | + enum rockchip_pin_drv_type drv_type; | |
| 115 | + int offset; | |
| 116 | +}; | |
| 117 | + | |
| 118 | +/** | |
| 119 | + * struct rockchip_pin_bank | |
| 120 | + * @dev: the pinctrl device bind to the bank | |
| 121 | + * @reg_base: register base of the gpio bank | |
| 122 | + * @regmap_pull: optional separate register for additional pull settings | |
| 123 | + * @clk: clock of the gpio bank | |
| 124 | + * @db_clk: clock of the gpio debounce | |
| 125 | + * @irq: interrupt of the gpio bank | |
| 126 | + * @saved_masks: Saved content of GPIO_INTEN at suspend time. | |
| 127 | + * @pin_base: first pin number | |
| 128 | + * @nr_pins: number of pins in this bank | |
| 129 | + * @name: name of the bank | |
| 130 | + * @bank_num: number of the bank, to account for holes | |
| 131 | + * @iomux: array describing the 4 iomux sources of the bank | |
| 132 | + * @drv: array describing the 4 drive strength sources of the bank | |
| 133 | + * @pull_type: array describing the 4 pull type sources of the bank | |
| 134 | + * @valid: is all necessary information present | |
| 135 | + * @of_node: dt node of this bank | |
| 136 | + * @drvdata: common pinctrl basedata | |
| 137 | + * @domain: irqdomain of the gpio bank | |
| 138 | + * @gpio_chip: gpiolib chip | |
| 139 | + * @grange: gpio range | |
| 140 | + * @slock: spinlock for the gpio bank | |
| 141 | + * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode | |
| 142 | + * @recalced_mask: bit mask to indicate a need to recalulate the mask | |
| 143 | + * @route_mask: bits describing the routing pins of per bank | |
| 144 | + */ | |
| 145 | +struct rockchip_pin_bank { | |
| 146 | + struct device *dev; | |
| 147 | + void __iomem *reg_base; | |
| 148 | + struct regmap *regmap_pull; | |
| 149 | + struct clk *clk; | |
| 150 | + struct clk *db_clk; | |
| 151 | + int irq; | |
| 152 | + u32 saved_masks; | |
| 153 | + u32 pin_base; | |
| 154 | + u8 nr_pins; | |
| 155 | + char *name; | |
| 156 | + u8 bank_num; | |
| 157 | + struct rockchip_iomux iomux[4]; | |
| 158 | + struct rockchip_drv drv[4]; | |
| 159 | + enum rockchip_pin_pull_type pull_type[4]; | |
| 160 | + bool valid; | |
| 161 | + struct device_node *of_node; | |
| 162 | + struct rockchip_pinctrl *drvdata; | |
| 163 | + struct irq_domain *domain; | |
| 164 | + struct gpio_chip gpio_chip; | |
| 165 | + struct pinctrl_gpio_range grange; | |
| 166 | + raw_spinlock_t slock; | |
| 167 | + const struct rockchip_gpio_regs *gpio_regs; | |
| 168 | + u32 gpio_type; | |
| 169 | + u32 toggle_edge_mode; | |
| 170 | + u32 recalced_mask; | |
| 171 | + u32 route_mask; | |
| 172 | +}; | |
| 173 | + | |
| 174 | +/** | |
| 175 | + * struct rockchip_mux_recalced_data: represent a pin iomux data. | |
| 176 | + * @num: bank number. | |
| 177 | + * @pin: pin number. | |
| 178 | + * @bit: index at register. | |
| 179 | + * @reg: register offset. | |
| 180 | + * @mask: mask bit | |
| 181 | + */ | |
| 182 | +struct rockchip_mux_recalced_data { | |
| 183 | + u8 num; | |
| 184 | + u8 pin; | |
| 185 | + u32 reg; | |
| 186 | + u8 bit; | |
| 187 | + u8 mask; | |
| 188 | +}; | |
| 189 | + | |
| 190 | +enum rockchip_mux_route_location { | |
| 191 | + ROCKCHIP_ROUTE_SAME = 0, | |
| 192 | + ROCKCHIP_ROUTE_PMU, | |
| 193 | + ROCKCHIP_ROUTE_GRF, | |
| 194 | +}; | |
| 195 | + | |
| 196 | +/** | |
| 197 | + * struct rockchip_mux_recalced_data: represent a pin iomux data. | |
| 198 | + * @bank_num: bank number. | |
| 199 | + * @pin: index at register or used to calc index. | |
| 200 | + * @func: the min pin. | |
| 201 | + * @route_location: the mux route location (same, pmu, grf). | |
| 202 | + * @route_offset: the max pin. | |
| 203 | + * @route_val: the register offset. | |
| 204 | + */ | |
| 205 | +struct rockchip_mux_route_data { | |
| 206 | + u8 bank_num; | |
| 207 | + u8 pin; | |
| 208 | + u8 func; | |
| 209 | + enum rockchip_mux_route_location route_location; | |
| 210 | + u32 route_offset; | |
| 211 | + u32 route_val; | |
| 212 | +}; | |
| 213 | + | |
| 214 | +struct rockchip_pin_ctrl { | |
| 215 | + struct rockchip_pin_bank *pin_banks; | |
| 216 | + u32 nr_banks; | |
| 217 | + u32 nr_pins; | |
| 218 | + char *label; | |
| 219 | + enum rockchip_pinctrl_type type; | |
| 220 | + int grf_mux_offset; | |
| 221 | + int pmu_mux_offset; | |
| 222 | + int grf_drv_offset; | |
| 223 | + int pmu_drv_offset; | |
| 224 | + struct rockchip_mux_recalced_data *iomux_recalced; | |
| 225 | + u32 niomux_recalced; | |
| 226 | + struct rockchip_mux_route_data *iomux_routes; | |
| 227 | + u32 niomux_routes; | |
| 228 | + | |
| 229 | + void (*pull_calc_reg)(struct rockchip_pin_bank *bank, | |
| 230 | + int pin_num, struct regmap **regmap, | |
| 231 | + int *reg, u8 *bit); | |
| 232 | + void (*drv_calc_reg)(struct rockchip_pin_bank *bank, | |
| 233 | + int pin_num, struct regmap **regmap, | |
| 234 | + int *reg, u8 *bit); | |
| 235 | + int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, | |
| 236 | + int pin_num, struct regmap **regmap, | |
| 237 | + int *reg, u8 *bit); | |
| 238 | +}; | |
| 239 | + | |
| 240 | +struct rockchip_pin_config { | |
| 241 | + unsigned int func; | |
| 242 | + unsigned long *configs; | |
| 243 | + unsigned int nconfigs; | |
| 244 | +}; | |
| 245 | + | |
| 246 | +/** | |
| 247 | + * struct rockchip_pin_group: represent group of pins of a pinmux function. | |
| 248 | + * @name: name of the pin group, used to lookup the group. | |
| 249 | + * @pins: the pins included in this group. | |
| 250 | + * @npins: number of pins included in this group. | |
| 251 | + * @data: local pin configuration | |
| 252 | + */ | |
| 253 | +struct rockchip_pin_group { | |
| 254 | + const char *name; | |
| 255 | + unsigned int npins; | |
| 256 | + unsigned int *pins; | |
| 257 | + struct rockchip_pin_config *data; | |
| 258 | +}; | |
| 259 | + | |
| 260 | +/** | |
| 261 | + * struct rockchip_pmx_func: represent a pin function. | |
| 262 | + * @name: name of the pin function, used to lookup the function. | |
| 263 | + * @groups: one or more names of pin groups that provide this function. | |
| 264 | + * @ngroups: number of groups included in @groups. | |
| 265 | + */ | |
| 266 | +struct rockchip_pmx_func { | |
| 267 | + const char *name; | |
| 268 | + const char **groups; | |
| 269 | + u8 ngroups; | |
| 270 | +}; | |
| 271 | + | |
| 272 | +struct rockchip_pinctrl { | |
| 273 | + struct regmap *regmap_base; | |
| 274 | + int reg_size; | |
| 275 | + struct regmap *regmap_pull; | |
| 276 | + struct regmap *regmap_pmu; | |
| 277 | + struct device *dev; | |
| 278 | + struct rockchip_pin_ctrl *ctrl; | |
| 279 | + struct pinctrl_desc pctl; | |
| 280 | + struct pinctrl_dev *pctl_dev; | |
| 281 | + struct rockchip_pin_group *groups; | |
| 282 | + unsigned int ngroups; | |
| 283 | + struct rockchip_pmx_func *functions; | |
| 284 | + unsigned int nfunctions; | |
| 285 | +}; | |
| 286 | + | |
| 287 | +#endif | |
| @@ -1491,8 +1491,8 @@ static int pcs_irq_handle(struct pcs_soc_data *pcs_soc) · 1490 unmodified lines | ||
| 1491 | 1491 | mask = pcs->read(pcswi->reg); |
| 1492 | 1492 | raw_spin_unlock(&pcs->lock); |
| 1493 | 1493 | if (mask & pcs_soc->irq_status_mask) { |
| 1494 | − generic_handle_irq(irq_find_mapping(pcs->domain, | |
| 1495 | − pcswi->hwirq)); | |
| 1494 | + generic_handle_domain_irq(pcs->domain, | |
| 1495 | + pcswi->hwirq); | |
| 1496 | 1496 | count++; |
| 1497 | 1497 | } |
| 1498 | 1498 | } |
| @@ -1420,7 +1420,7 @@ static void __gpio_irq_handler(struct st_gpio_bank *bank) · 1419 unmodified lines | ||
| 1420 | 1420 | continue; |
| 1421 | 1421 | } |
| 1422 | 1422 | |
| 1423 | − generic_handle_irq(irq_find_mapping(bank->gpio_chip.irq.domain, n)); | |
| 1423 | + generic_handle_domain_irq(bank->gpio_chip.irq.domain, n); | |
| 1424 | 1424 | } |
| 1425 | 1425 | } |
| 1426 | 1426 | } |
| @@ -1177,7 +1177,6 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) · 1176 unmodified lines | ||
| 1177 | 1177 | const struct msm_pingroup *g; |
| 1178 | 1178 | struct msm_pinctrl *pctrl = gpiochip_get_data(gc); |
| 1179 | 1179 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 1180 | − int irq_pin; | |
| 1181 | 1180 | int handled = 0; |
| 1182 | 1181 | u32 val; |
| 1183 | 1182 | int i; |
| @@ -1192,8 +1191,7 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) · 8 unmodified lines | ||
| 1192 | 1191 | g = &pctrl->soc->groups[i]; |
| 1193 | 1192 | val = msm_readl_intr_status(pctrl, g); |
| 1194 | 1193 | if (val & BIT(g->intr_status_bit)) { |
| 1195 | − irq_pin = irq_find_mapping(gc->irq.domain, i); | |
| 1196 | − generic_handle_irq(irq_pin); | |
| 1194 | + generic_handle_domain_irq(gc->irq.domain, i); | |
| 1197 | 1195 | handled++; |
| 1198 | 1196 | } |
| 1199 | 1197 | } |
| @@ -246,7 +246,8 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) · 245 unmodified lines | ||
| 246 | 246 | { |
| 247 | 247 | struct samsung_pinctrl_drv_data *d = data; |
| 248 | 248 | struct samsung_pin_bank *bank = d->pin_banks; |
| 249 | − unsigned int svc, group, pin, virq; | |
| 249 | + unsigned int svc, group, pin; | |
| 250 | + int ret; | |
| 250 | 251 | |
| 251 | 252 | svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); |
| 252 | 253 | group = EXYNOS_SVC_GROUP(svc); |
| @@ -256,10 +257,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) · 3 unmodified lines | ||
| 256 | 257 | return IRQ_HANDLED; |
| 257 | 258 | bank += (group - 1); |
| 258 | 259 | |
| 259 | − virq = irq_linear_revmap(bank->irq_domain, pin); | |
| 260 | − if (!virq) | |
| 260 | + ret = generic_handle_domain_irq(bank->irq_domain, pin); | |
| 261 | + if (ret) | |
| 261 | 262 | return IRQ_NONE; |
| 262 | − generic_handle_irq(virq); | |
| 263 | + | |
| 263 | 264 | return IRQ_HANDLED; |
| 264 | 265 | } |
| 265 | 266 | |
| @@ -473,12 +474,10 @@ static void exynos_irq_eint0_15(struct irq_desc *desc) · 207 unmodified lines | ||
| 473 | 474 | struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc); |
| 474 | 475 | struct samsung_pin_bank *bank = eintd->bank; |
| 475 | 476 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 476 | − int eint_irq; | |
| 477 | 477 | |
| 478 | 478 | chained_irq_enter(chip, desc); |
| 479 | 479 | |
| 480 | − eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq); | |
| 481 | − generic_handle_irq(eint_irq); | |
| 480 | + generic_handle_domain_irq(bank->irq_domain, eintd->irq); | |
| 482 | 481 | |
| 483 | 482 | chained_irq_exit(chip, desc); |
| 484 | 483 | } |
| @@ -490,7 +489,7 @@ static inline void exynos_irq_demux_eint(unsigned int pend, · 5 unmodified lines | ||
| 490 | 489 | |
| 491 | 490 | while (pend) { |
| 492 | 491 | irq = fls(pend) - 1; |
| 493 | − generic_handle_irq(irq_find_mapping(domain, irq)); | |
| 492 | + generic_handle_domain_irq(domain, irq); | |
| 494 | 493 | pend &= ~(1 << irq); |
| 495 | 494 | } |
| 496 | 495 | } |
| @@ -234,14 +234,12 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc) · 233 unmodified lines | ||
| 234 | 234 | { |
| 235 | 235 | struct irq_data *data = irq_desc_get_irq_data(desc); |
| 236 | 236 | struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc); |
| 237 | − unsigned int virq; | |
| 237 | + int ret; | |
| 238 | 238 | |
| 239 | 239 | /* the first 4 eints have a simple 1 to 1 mapping */ |
| 240 | − virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq); | |
| 240 | + ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq); | |
| 241 | 241 | /* Something must be really wrong if an unmapped EINT is unmasked */ |
| 242 | − BUG_ON(!virq); | |
| 243 | − | |
| 244 | − generic_handle_irq(virq); | |
| 242 | + BUG_ON(ret); | |
| 245 | 243 | } |
| 246 | 244 | |
| 247 | 245 | /* Handling of EINTs 0-3 on S3C2412 and S3C2413 */ |
| @@ -290,16 +288,14 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc) · 42 unmodified lines | ||
| 290 | 288 | struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc); |
| 291 | 289 | struct irq_data *data = irq_desc_get_irq_data(desc); |
| 292 | 290 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
| 293 | − unsigned int virq; | |
| 291 | + int ret; | |
| 294 | 292 | |
| 295 | 293 | chained_irq_enter(chip, desc); |
| 296 | 294 | |
| 297 | 295 | /* the first 4 eints have a simple 1 to 1 mapping */ |
| 298 | − virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq); | |
| 296 | + ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq); | |
| 299 | 297 | /* Something must be really wrong if an unmapped EINT is unmasked */ |
| 300 | − BUG_ON(!virq); | |
| 301 | − | |
| 302 | − generic_handle_irq(virq); | |
| 298 | + BUG_ON(ret); | |
| 303 | 299 | |
| 304 | 300 | chained_irq_exit(chip, desc); |
| 305 | 301 | } |
| @@ -364,15 +360,14 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc, · 58 unmodified lines | ||
| 364 | 360 | pend &= range; |
| 365 | 361 | |
| 366 | 362 | while (pend) { |
| 367 | − unsigned int virq, irq; | |
| 363 | + unsigned int irq; | |
| 364 | + int ret; | |
| 368 | 365 | |
| 369 | 366 | irq = __ffs(pend); |
| 370 | 367 | pend &= ~(1 << irq); |
| 371 | − virq = irq_linear_revmap(data->domains[irq], irq - offset); | |
| 368 | + ret = generic_handle_domain_irq(data->domains[irq], irq - offset); | |
| 372 | 369 | /* Something is really wrong if an unmapped EINT is unmasked */ |
| 373 | − BUG_ON(!virq); | |
| 374 | − | |
| 375 | − generic_handle_irq(virq); | |
| 370 | + BUG_ON(ret); | |
| 376 | 371 | } |
| 377 | 372 | |
| 378 | 373 | chained_irq_exit(chip, desc); |
| @@ -414,7 +414,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) · 413 unmodified lines | ||
| 414 | 414 | unsigned int svc; |
| 415 | 415 | unsigned int group; |
| 416 | 416 | unsigned int pin; |
| 417 | − unsigned int virq; | |
| 417 | + int ret; | |
| 418 | 418 | |
| 419 | 419 | svc = readl(drvdata->virt_base + SERVICE_REG); |
| 420 | 420 | group = SVC_GROUP(svc); |
| @@ -431,14 +431,12 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) · 10 unmodified lines | ||
| 431 | 431 | pin -= 8; |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | − virq = irq_linear_revmap(data->domains[group], pin); | |
| 434 | + ret = generic_handle_domain_irq(data->domains[group], pin); | |
| 435 | 435 | /* |
| 436 | 436 | * Something must be really wrong if an unmapped EINT |
| 437 | 437 | * was unmasked... |
| 438 | 438 | */ |
| 439 | − BUG_ON(!virq); | |
| 440 | − | |
| 441 | − generic_handle_irq(virq); | |
| 439 | + BUG_ON(ret); | |
| 442 | 440 | } while (1); |
| 443 | 441 | |
| 444 | 442 | chained_irq_exit(chip, desc); |
| @@ -607,18 +605,17 @@ static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range) · 162 unmodified lines | ||
| 607 | 605 | pend &= range; |
| 608 | 606 | |
| 609 | 607 | while (pend) { |
| 610 | − unsigned int virq, irq; | |
| 608 | + unsigned int irq; | |
| 609 | + int ret; | |
| 611 | 610 | |
| 612 | 611 | irq = fls(pend) - 1; |
| 613 | 612 | pend &= ~(1 << irq); |
| 614 | − virq = irq_linear_revmap(data->domains[irq], data->pins[irq]); | |
| 613 | + ret = generic_handle_domain_irq(data->domains[irq], data->pins[irq]); | |
| 615 | 614 | /* |
| 616 | 615 | * Something must be really wrong if an unmapped EINT |
| 617 | 616 | * was unmasked... |
| 618 | 617 | */ |
| 619 | − BUG_ON(!virq); | |
| 620 | − | |
| 621 | − generic_handle_irq(virq); | |
| 618 | + BUG_ON(ret); | |
| 622 | 619 | } |
| 623 | 620 | |
| 624 | 621 | chained_irq_exit(chip, desc); |
| @@ -400,8 +400,7 @@ static void plgpio_irq_handler(struct irq_desc *desc) · 399 unmodified lines | ||
| 400 | 400 | |
| 401 | 401 | /* get correct irq line number */ |
| 402 | 402 | pin = i * MAX_GPIO_PER_REG + pin; |
| 403 | − generic_handle_irq( | |
| 404 | − irq_find_mapping(gc->irq.domain, pin)); | |
| 403 | + generic_handle_domain_irq(gc->irq.domain, pin); | |
| 405 | 404 | } |
| 406 | 405 | } |
| 407 | 406 | chained_irq_exit(irqchip, desc); |
| @@ -1149,11 +1149,9 @@ static void sunxi_pinctrl_irq_handler(struct irq_desc *desc) · 1148 unmodified lines | ||
| 1149 | 1149 | if (val) { |
| 1150 | 1150 | int irqoffset; |
| 1151 | 1151 | |
| 1152 | − for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) { | |
| 1153 | − int pin_irq = irq_find_mapping(pctl->domain, | |
| 1154 | − bank * IRQ_PER_BANK + irqoffset); | |
| 1155 | − generic_handle_irq(pin_irq); | |
| 1156 | − } | |
| 1152 | + for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) | |
| 1153 | + generic_handle_domain_irq(pctl->domain, | |
| 1154 | + bank * IRQ_PER_BANK + irqoffset); | |
| 1157 | 1155 | } |
| 1158 | 1156 | |
| 1159 | 1157 | chained_irq_exit(chip, desc); |
| @@ -1215,6 +1215,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain, · 1214 unmodified lines | ||
| 1215 | 1215 | irqd->chip = ERR_PTR(-ENOTCONN); |
| 1216 | 1216 | return 0; |
| 1217 | 1217 | } |
| 1218 | +EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy); | |
| 1218 | 1219 | |
| 1219 | 1220 | static int irq_domain_trim_hierarchy(unsigned int virq) |
| 1220 | 1221 | { |