regmap-irq.c (e75d660672ddd11704b7f0fdb8ff21968587b266) | regmap-irq.c (f01ee60fffa4dc6c77122121233a793f7f696e67) |
---|---|
1/* 2 * regmap based irq_chip 3 * 4 * Copyright 2011 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 44 unchanged lines hidden (view full) --- 53 int i, ret; 54 55 /* 56 * If there's been a change in the mask write it back to the 57 * hardware. We rely on the use of the regmap core cache to 58 * suppress pointless writes. 59 */ 60 for (i = 0; i < d->chip->num_regs; i++) { | 1/* 2 * regmap based irq_chip 3 * 4 * Copyright 2011 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 44 unchanged lines hidden (view full) --- 53 int i, ret; 54 55 /* 56 * If there's been a change in the mask write it back to the 57 * hardware. We rely on the use of the regmap core cache to 58 * suppress pointless writes. 59 */ 60 for (i = 0; i < d->chip->num_regs; i++) { |
61 ret = regmap_update_bits(d->map, d->chip->mask_base + i, | 61 ret = regmap_update_bits(d->map, d->chip->mask_base + 62 (i * map->map->reg_stride), |
62 d->mask_buf_def[i], d->mask_buf[i]); 63 if (ret != 0) 64 dev_err(d->map->dev, "Failed to sync masks in %x\n", | 63 d->mask_buf_def[i], d->mask_buf[i]); 64 if (ret != 0) 65 dev_err(d->map->dev, "Failed to sync masks in %x\n", |
65 d->chip->mask_base + i); | 66 d->chip->mask_base + (i * map->reg_stride)); |
66 } 67 68 mutex_unlock(&d->lock); 69} 70 71static void regmap_irq_enable(struct irq_data *data) 72{ 73 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 74 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); 75 | 67 } 68 69 mutex_unlock(&d->lock); 70} 71 72static void regmap_irq_enable(struct irq_data *data) 73{ 74 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 75 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); 76 |
76 d->mask_buf[irq_data->reg_offset] &= ~irq_data->mask; | 77 d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; |
77} 78 79static void regmap_irq_disable(struct irq_data *data) 80{ 81 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 82 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); 83 | 78} 79 80static void regmap_irq_disable(struct irq_data *data) 81{ 82 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 83 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); 84 |
84 d->mask_buf[irq_data->reg_offset] |= irq_data->mask; | 85 d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; |
85} 86 87static struct irq_chip regmap_irq_chip = { 88 .name = "regmap", 89 .irq_bus_lock = regmap_irq_lock, 90 .irq_bus_sync_unlock = regmap_irq_sync_unlock, 91 .irq_disable = regmap_irq_disable, 92 .irq_enable = regmap_irq_enable, --- 38 unchanged lines hidden (view full) --- 131 default: 132 BUG(); 133 return IRQ_NONE; 134 } 135 136 data->status_buf[i] &= ~data->mask_buf[i]; 137 138 if (data->status_buf[i] && chip->ack_base) { | 86} 87 88static struct irq_chip regmap_irq_chip = { 89 .name = "regmap", 90 .irq_bus_lock = regmap_irq_lock, 91 .irq_bus_sync_unlock = regmap_irq_sync_unlock, 92 .irq_disable = regmap_irq_disable, 93 .irq_enable = regmap_irq_enable, --- 38 unchanged lines hidden (view full) --- 132 default: 133 BUG(); 134 return IRQ_NONE; 135 } 136 137 data->status_buf[i] &= ~data->mask_buf[i]; 138 139 if (data->status_buf[i] && chip->ack_base) { |
139 ret = regmap_write(map, chip->ack_base + i, | 140 ret = regmap_write(map, chip->ack_base + 141 (i * map->reg_stride), |
140 data->status_buf[i]); 141 if (ret != 0) 142 dev_err(map->dev, "Failed to ack 0x%x: %d\n", | 142 data->status_buf[i]); 143 if (ret != 0) 144 dev_err(map->dev, "Failed to ack 0x%x: %d\n", |
143 chip->ack_base + i, ret); | 145 chip->ack_base + (i * map->reg_stride), 146 ret); |
144 } 145 } 146 147 for (i = 0; i < chip->num_irqs; i++) { | 147 } 148 } 149 150 for (i = 0; i < chip->num_irqs; i++) { |
148 if (data->status_buf[chip->irqs[i].reg_offset] & 149 chip->irqs[i].mask) { | 151 if (data->status_buf[chip->irqs[i].reg_offset / 152 map->reg_stride] & chip->irqs[i].mask) { |
150 handle_nested_irq(data->irq_base + i); 151 handled = true; 152 } 153 } 154 155 if (handled) 156 return IRQ_HANDLED; 157 else --- 18 unchanged lines hidden (view full) --- 176int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, 177 int irq_base, struct regmap_irq_chip *chip, 178 struct regmap_irq_chip_data **data) 179{ 180 struct regmap_irq_chip_data *d; 181 int cur_irq, i; 182 int ret = -ENOMEM; 183 | 153 handle_nested_irq(data->irq_base + i); 154 handled = true; 155 } 156 } 157 158 if (handled) 159 return IRQ_HANDLED; 160 else --- 18 unchanged lines hidden (view full) --- 179int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, 180 int irq_base, struct regmap_irq_chip *chip, 181 struct regmap_irq_chip_data **data) 182{ 183 struct regmap_irq_chip_data *d; 184 int cur_irq, i; 185 int ret = -ENOMEM; 186 |
187 for (i = 0; i < chip->num_irqs; i++) { 188 if (chip->irqs[i].reg_offset % map->reg_stride) 189 return -EINVAL; 190 if (chip->irqs[i].reg_offset / map->reg_stride >= 191 chip->num_regs) 192 return -EINVAL; 193 } 194 |
|
184 irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); 185 if (irq_base < 0) { 186 dev_warn(map->dev, "Failed to allocate IRQs: %d\n", 187 irq_base); 188 return irq_base; 189 } 190 191 d = kzalloc(sizeof(*d), GFP_KERNEL); --- 21 unchanged lines hidden (view full) --- 213 goto err_alloc; 214 215 d->map = map; 216 d->chip = chip; 217 d->irq_base = irq_base; 218 mutex_init(&d->lock); 219 220 for (i = 0; i < chip->num_irqs; i++) | 195 irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); 196 if (irq_base < 0) { 197 dev_warn(map->dev, "Failed to allocate IRQs: %d\n", 198 irq_base); 199 return irq_base; 200 } 201 202 d = kzalloc(sizeof(*d), GFP_KERNEL); --- 21 unchanged lines hidden (view full) --- 224 goto err_alloc; 225 226 d->map = map; 227 d->chip = chip; 228 d->irq_base = irq_base; 229 mutex_init(&d->lock); 230 231 for (i = 0; i < chip->num_irqs; i++) |
221 d->mask_buf_def[chip->irqs[i].reg_offset] | 232 d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] |
222 |= chip->irqs[i].mask; 223 224 /* Mask all the interrupts by default */ 225 for (i = 0; i < chip->num_regs; i++) { 226 d->mask_buf[i] = d->mask_buf_def[i]; | 233 |= chip->irqs[i].mask; 234 235 /* Mask all the interrupts by default */ 236 for (i = 0; i < chip->num_regs; i++) { 237 d->mask_buf[i] = d->mask_buf_def[i]; |
227 ret = regmap_write(map, chip->mask_base + i, d->mask_buf[i]); | 238 ret = regmap_write(map, chip->mask_base + (i * map->reg_stride), 239 d->mask_buf[i]); |
228 if (ret != 0) { 229 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", | 240 if (ret != 0) { 241 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", |
230 chip->mask_base + i, ret); | 242 chip->mask_base + (i * map->reg_stride), ret); |
231 goto err_alloc; 232 } 233 } 234 235 /* Register them with genirq */ 236 for (cur_irq = irq_base; 237 cur_irq < chip->num_irqs + irq_base; 238 cur_irq++) { --- 65 unchanged lines hidden --- | 243 goto err_alloc; 244 } 245 } 246 247 /* Register them with genirq */ 248 for (cur_irq = irq_base; 249 cur_irq < chip->num_irqs + irq_base; 250 cur_irq++) { --- 65 unchanged lines hidden --- |