irq.c (0ff555192a8d20385d49d1c420e2e8d409b3c0da) | irq.c (9569dae75f6f6987e79fa26cf6da3fc24006c996) |
---|---|
1/* 2 * arch/arm/mach-orion5x/irq.c 3 * 4 * Core IRQ functions for Marvell Orion System On Chip 5 * 6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com> 7 * 8 * This file is licensed under the terms of the GNU General Public --- 8 unchanged lines hidden (view full) --- 17#include <asm/gpio.h> 18#include <mach/orion5x.h> 19#include <plat/irq.h> 20#include "common.h" 21 22/***************************************************************************** 23 * Orion GPIO IRQ 24 * | 1/* 2 * arch/arm/mach-orion5x/irq.c 3 * 4 * Core IRQ functions for Marvell Orion System On Chip 5 * 6 * Maintainer: Tzachi Perelstein <tzachi@marvell.com> 7 * 8 * This file is licensed under the terms of the GNU General Public --- 8 unchanged lines hidden (view full) --- 17#include <asm/gpio.h> 18#include <mach/orion5x.h> 19#include <plat/irq.h> 20#include "common.h" 21 22/***************************************************************************** 23 * Orion GPIO IRQ 24 * |
25 * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same | 25 * GPIO_IN_POL register controls whether GPIO_DATA_IN will hold the same |
26 * value of the line or the opposite value. 27 * 28 * Level IRQ handlers: DATA_IN is used directly as cause register. 29 * Interrupt are masked by LEVEL_MASK registers. 30 * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE. 31 * Interrupt are masked by EDGE_MASK registers. 32 * Both-edge handlers: Similar to regular Edge handlers, but also swaps 33 * the polarity to catch the next line transaction. --- 43 unchanged lines hidden (view full) --- 77 orion5x_setbits(GPIO_EDGE_MASK, 1 << pin); 78} 79 80static int orion5x_gpio_set_irq_type(u32 irq, u32 type) 81{ 82 int pin = irq_to_gpio(irq); 83 struct irq_desc *desc; 84 | 26 * value of the line or the opposite value. 27 * 28 * Level IRQ handlers: DATA_IN is used directly as cause register. 29 * Interrupt are masked by LEVEL_MASK registers. 30 * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE. 31 * Interrupt are masked by EDGE_MASK registers. 32 * Both-edge handlers: Similar to regular Edge handlers, but also swaps 33 * the polarity to catch the next line transaction. --- 43 unchanged lines hidden (view full) --- 77 orion5x_setbits(GPIO_EDGE_MASK, 1 << pin); 78} 79 80static int orion5x_gpio_set_irq_type(u32 irq, u32 type) 81{ 82 int pin = irq_to_gpio(irq); 83 struct irq_desc *desc; 84 |
85 if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) { | 85 if ((readl(GPIO_IO_CONF(pin)) & (1 << pin)) == 0) { |
86 printk(KERN_ERR "orion5x_gpio_set_irq_type failed " 87 "(irq %d, pin %d).\n", irq, pin); 88 return -EINVAL; 89 } 90 91 desc = irq_desc + irq; 92 93 switch (type) { 94 case IRQ_TYPE_LEVEL_HIGH: 95 desc->handle_irq = handle_level_irq; 96 desc->status |= IRQ_LEVEL; | 86 printk(KERN_ERR "orion5x_gpio_set_irq_type failed " 87 "(irq %d, pin %d).\n", irq, pin); 88 return -EINVAL; 89 } 90 91 desc = irq_desc + irq; 92 93 switch (type) { 94 case IRQ_TYPE_LEVEL_HIGH: 95 desc->handle_irq = handle_level_irq; 96 desc->status |= IRQ_LEVEL; |
97 orion5x_clrbits(GPIO_IN_POL, (1 << pin)); | 97 orion5x_clrbits(GPIO_IN_POL(pin), (1 << pin)); |
98 break; 99 case IRQ_TYPE_LEVEL_LOW: 100 desc->handle_irq = handle_level_irq; 101 desc->status |= IRQ_LEVEL; | 98 break; 99 case IRQ_TYPE_LEVEL_LOW: 100 desc->handle_irq = handle_level_irq; 101 desc->status |= IRQ_LEVEL; |
102 orion5x_setbits(GPIO_IN_POL, (1 << pin)); | 102 orion5x_setbits(GPIO_IN_POL(pin), (1 << pin)); |
103 break; 104 case IRQ_TYPE_EDGE_RISING: 105 desc->handle_irq = handle_edge_irq; 106 desc->status &= ~IRQ_LEVEL; | 103 break; 104 case IRQ_TYPE_EDGE_RISING: 105 desc->handle_irq = handle_edge_irq; 106 desc->status &= ~IRQ_LEVEL; |
107 orion5x_clrbits(GPIO_IN_POL, (1 << pin)); | 107 orion5x_clrbits(GPIO_IN_POL(pin), (1 << pin)); |
108 break; 109 case IRQ_TYPE_EDGE_FALLING: 110 desc->handle_irq = handle_edge_irq; 111 desc->status &= ~IRQ_LEVEL; | 108 break; 109 case IRQ_TYPE_EDGE_FALLING: 110 desc->handle_irq = handle_edge_irq; 111 desc->status &= ~IRQ_LEVEL; |
112 orion5x_setbits(GPIO_IN_POL, (1 << pin)); | 112 orion5x_setbits(GPIO_IN_POL(pin), (1 << pin)); |
113 break; 114 case IRQ_TYPE_EDGE_BOTH: 115 desc->handle_irq = handle_edge_irq; 116 desc->status &= ~IRQ_LEVEL; 117 /* 118 * set initial polarity based on current input level 119 */ | 113 break; 114 case IRQ_TYPE_EDGE_BOTH: 115 desc->handle_irq = handle_edge_irq; 116 desc->status &= ~IRQ_LEVEL; 117 /* 118 * set initial polarity based on current input level 119 */ |
120 if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN)) | 120 if ((readl(GPIO_IN_POL(pin)) ^ readl(GPIO_DATA_IN(pin))) |
121 & (1 << pin)) | 121 & (1 << pin)) |
122 orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */ | 122 orion5x_setbits(GPIO_IN_POL(pin), (1 << pin)); /* falling */ |
123 else | 123 else |
124 orion5x_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */ | 124 orion5x_clrbits(GPIO_IN_POL(pin), (1 << pin)); /* rising */ |
125 126 break; 127 default: 128 printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); 129 return -EINVAL; 130 } 131 132 desc->status &= ~IRQ_TYPE_SENSE_MASK; --- 11 unchanged lines hidden (view full) --- 144}; 145 146static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 147{ 148 u32 cause, offs, pin; 149 150 BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); 151 offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8; | 125 126 break; 127 default: 128 printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); 129 return -EINVAL; 130 } 131 132 desc->status &= ~IRQ_TYPE_SENSE_MASK; --- 11 unchanged lines hidden (view full) --- 144}; 145 146static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 147{ 148 u32 cause, offs, pin; 149 150 BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); 151 offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8; |
152 cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) | | 152 cause = (readl(GPIO_DATA_IN(offs)) & readl(GPIO_LEVEL_MASK)) | |
153 (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK)); 154 155 for (pin = offs; pin < offs + 8; pin++) { 156 if (cause & (1 << pin)) { 157 irq = gpio_to_irq(pin); 158 desc = irq_desc + irq; 159 if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { 160 /* Swap polarity (race with GPIO line) */ | 153 (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK)); 154 155 for (pin = offs; pin < offs + 8; pin++) { 156 if (cause & (1 << pin)) { 157 irq = gpio_to_irq(pin); 158 desc = irq_desc + irq; 159 if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { 160 /* Swap polarity (race with GPIO line) */ |
161 u32 polarity = readl(GPIO_IN_POL); | 161 u32 polarity = readl(GPIO_IN_POL(pin)); |
162 polarity ^= 1 << pin; | 162 polarity ^= 1 << pin; |
163 writel(polarity, GPIO_IN_POL); | 163 writel(polarity, GPIO_IN_POL(pin)); |
164 } 165 generic_handle_irq(irq); 166 } 167 } 168} 169 170static void __init orion5x_init_gpio_irq(void) 171{ --- 40 unchanged lines hidden --- | 164 } 165 generic_handle_irq(irq); 166 } 167 } 168} 169 170static void __init orion5x_init_gpio_irq(void) 171{ --- 40 unchanged lines hidden --- |