Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: SAMSUNG: S5P: Convert irq-gpioint to generic irq chip

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Thomas Gleixner and committed by
Mark Brown
ad739dcf cfefd21e

+27 -89
+27 -89
arch/arm/plat-s5p/irq-gpioint.c
··· 41 41 42 42 LIST_HEAD(banks); 43 43 44 - static int s5p_gpioint_get_offset(struct irq_data *data) 44 + static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) 45 45 { 46 - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); 47 - return data->irq - chip->irq_base; 48 - } 49 - 50 - static void s5p_gpioint_ack(struct irq_data *data) 51 - { 52 - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); 53 - int group, offset, pend_offset; 54 - unsigned int value; 55 - 56 - group = chip->group; 57 - offset = s5p_gpioint_get_offset(data); 58 - pend_offset = REG_OFFSET(group); 59 - 60 - value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); 61 - value |= BIT(offset); 62 - __raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset); 63 - } 64 - 65 - static void s5p_gpioint_mask(struct irq_data *data) 66 - { 67 - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); 68 - int group, offset, mask_offset; 69 - unsigned int value; 70 - 71 - group = chip->group; 72 - offset = s5p_gpioint_get_offset(data); 73 - mask_offset = REG_OFFSET(group); 74 - 75 - value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); 76 - value |= BIT(offset); 77 - __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset); 78 - } 79 - 80 - static void s5p_gpioint_unmask(struct irq_data *data) 81 - { 82 - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); 83 - int group, offset, mask_offset; 84 - unsigned int value; 85 - 86 - group = chip->group; 87 - offset = s5p_gpioint_get_offset(data); 88 - mask_offset = REG_OFFSET(group); 89 - 90 - value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); 91 - value &= ~BIT(offset); 92 - __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset); 93 - } 94 - 95 - static void s5p_gpioint_mask_ack(struct irq_data *data) 96 - { 97 - s5p_gpioint_mask(data); 98 - s5p_gpioint_ack(data); 99 - } 100 - 101 - static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type) 102 - { 103 - struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data); 104 - int group, offset, con_offset; 105 - unsigned int value; 106 - 107 - group = chip->group; 108 - offset = s5p_gpioint_get_offset(data); 109 - con_offset = REG_OFFSET(group); 46 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 47 + struct irq_chip_type *ct = gc->chip_types; 48 + unsigned int shift = (d->irq - gc->irq_base) << 2; 110 49 111 50 switch (type) { 112 51 case IRQ_TYPE_EDGE_RISING: ··· 69 130 return -EINVAL; 70 131 } 71 132 72 - value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset); 73 - value &= ~(0x7 << (offset * 0x4)); 74 - value |= (type << (offset * 0x4)); 75 - __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset); 76 - 133 + gc->type_cache &= ~(0x7 << shift); 134 + gc->type_cache |= type << shift; 135 + writel(gc->type_cache, gc->reg_base + ct->regs.type); 77 136 return 0; 78 137 } 79 - 80 - static struct irq_chip s5p_gpioint = { 81 - .name = "s5p_gpioint", 82 - .irq_ack = s5p_gpioint_ack, 83 - .irq_mask = s5p_gpioint_mask, 84 - .irq_mask_ack = s5p_gpioint_mask_ack, 85 - .irq_unmask = s5p_gpioint_unmask, 86 - .irq_set_type = s5p_gpioint_set_type, 87 - }; 88 138 89 139 static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) 90 140 { ··· 107 179 static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) 108 180 { 109 181 static int used_gpioint_groups = 0; 110 - int irq, group = chip->group; 111 - int i; 182 + int group = chip->group; 112 183 struct s5p_gpioint_bank *bank = NULL; 184 + struct irq_chip_generic *gc; 185 + struct irq_chip_type *ct; 113 186 114 187 if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) 115 188 return -ENOMEM; ··· 140 211 * chained GPIO irq has been successfully registered, allocate new gpio 141 212 * int group and assign irq nubmers 142 213 */ 143 - 144 214 chip->irq_base = S5P_GPIOINT_BASE + 145 215 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; 146 216 used_gpioint_groups++; 147 217 148 218 bank->chips[group - bank->start] = chip; 149 - for (i = 0; i < chip->chip.ngpio; i++) { 150 - irq = chip->irq_base + i; 151 - irq_set_chip(irq, &s5p_gpioint); 152 - irq_set_handler_data(irq, chip); 153 - irq_set_handler(irq, handle_level_irq); 154 - set_irq_flags(irq, IRQF_VALID); 155 - } 219 + 220 + gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, 221 + (void __iomem *)GPIO_BASE(chip), 222 + handle_level_irq); 223 + if (!gc) 224 + return -ENOMEM; 225 + ct = gc->chip_types; 226 + ct->chip.irq_ack = irq_gc_ack; 227 + ct->chip.irq_mask = irq_gc_mask_set_bit; 228 + ct->chip.irq_unmask = irq_gc_mask_clr_bit; 229 + ct->chip.irq_set_type = s5p_gpioint_set_type, 230 + ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group); 231 + ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group); 232 + ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group); 233 + irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), 234 + IRQ_GC_INIT_MASK_CACHE, 235 + IRQ_NOREQUEST | IRQ_NOPROBE, 0); 156 236 return 0; 157 237 } 158 238