1 /* 2 * Copyright (c) 2015 Endless Mobile, Inc. 3 * Author: Carlo Caione <carlo@endlessm.com> 4 * Copyright (c) 2016 BayLibre, SAS. 5 * Author: Jerome Brunet <jbrunet@baylibre.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of version 2 of the GNU General Public License as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 * The full GNU General Public License is included in this distribution 19 * in the file called COPYING. 20 */ 21 22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23 24 #include <linux/io.h> 25 #include <linux/module.h> 26 #include <linux/irq.h> 27 #include <linux/irqdomain.h> 28 #include <linux/irqchip.h> 29 #include <linux/of.h> 30 #include <linux/of_address.h> 31 32 #define NUM_CHANNEL 8 33 #define MAX_INPUT_MUX 256 34 35 #define REG_EDGE_POL 0x00 36 #define REG_PIN_03_SEL 0x04 37 #define REG_PIN_47_SEL 0x08 38 #define REG_FILTER_SEL 0x0c 39 40 #define REG_EDGE_POL_MASK(x) (BIT(x) | BIT(16 + (x))) 41 #define REG_EDGE_POL_EDGE(x) BIT(x) 42 #define REG_EDGE_POL_LOW(x) BIT(16 + (x)) 43 #define REG_PIN_SEL_SHIFT(x) (((x) % 4) * 8) 44 #define REG_FILTER_SEL_SHIFT(x) ((x) * 4) 45 46 struct meson_gpio_irq_params { 47 unsigned int nr_hwirq; 48 }; 49 50 static const struct meson_gpio_irq_params meson8_params = { 51 .nr_hwirq = 134, 52 }; 53 54 static const struct meson_gpio_irq_params meson8b_params = { 55 .nr_hwirq = 119, 56 }; 57 58 static const struct meson_gpio_irq_params gxbb_params = { 59 .nr_hwirq = 133, 60 }; 61 62 static const struct meson_gpio_irq_params gxl_params = { 63 .nr_hwirq = 110, 64 }; 65 66 static const struct meson_gpio_irq_params axg_params = { 67 .nr_hwirq = 100, 68 }; 69 70 static const struct of_device_id meson_irq_gpio_matches[] = { 71 { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params }, 72 { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params }, 73 { .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params }, 74 { .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params }, 75 { .compatible = "amlogic,meson-axg-gpio-intc", .data = &axg_params }, 76 { } 77 }; 78 79 struct meson_gpio_irq_controller { 80 unsigned int nr_hwirq; 81 void __iomem *base; 82 u32 channel_irqs[NUM_CHANNEL]; 83 DECLARE_BITMAP(channel_map, NUM_CHANNEL); 84 spinlock_t lock; 85 }; 86 87 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, 88 unsigned int reg, u32 mask, u32 val) 89 { 90 u32 tmp; 91 92 tmp = readl_relaxed(ctl->base + reg); 93 tmp &= ~mask; 94 tmp |= val; 95 writel_relaxed(tmp, ctl->base + reg); 96 } 97 98 static unsigned int meson_gpio_irq_channel_to_reg(unsigned int channel) 99 { 100 return (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL; 101 } 102 103 static int 104 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, 105 unsigned long hwirq, 106 u32 **channel_hwirq) 107 { 108 unsigned int reg, idx; 109 110 spin_lock(&ctl->lock); 111 112 /* Find a free channel */ 113 idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL); 114 if (idx >= NUM_CHANNEL) { 115 spin_unlock(&ctl->lock); 116 pr_err("No channel available\n"); 117 return -ENOSPC; 118 } 119 120 /* Mark the channel as used */ 121 set_bit(idx, ctl->channel_map); 122 123 /* 124 * Setup the mux of the channel to route the signal of the pad 125 * to the appropriate input of the GIC 126 */ 127 reg = meson_gpio_irq_channel_to_reg(idx); 128 meson_gpio_irq_update_bits(ctl, reg, 129 0xff << REG_PIN_SEL_SHIFT(idx), 130 hwirq << REG_PIN_SEL_SHIFT(idx)); 131 132 /* 133 * Get the hwirq number assigned to this channel through 134 * a pointer the channel_irq table. The added benifit of this 135 * method is that we can also retrieve the channel index with 136 * it, using the table base. 137 */ 138 *channel_hwirq = &(ctl->channel_irqs[idx]); 139 140 spin_unlock(&ctl->lock); 141 142 pr_debug("hwirq %lu assigned to channel %d - irq %u\n", 143 hwirq, idx, **channel_hwirq); 144 145 return 0; 146 } 147 148 static unsigned int 149 meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl, 150 u32 *channel_hwirq) 151 { 152 return channel_hwirq - ctl->channel_irqs; 153 } 154 155 static void 156 meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl, 157 u32 *channel_hwirq) 158 { 159 unsigned int idx; 160 161 idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq); 162 clear_bit(idx, ctl->channel_map); 163 } 164 165 static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl, 166 unsigned int type, 167 u32 *channel_hwirq) 168 { 169 u32 val = 0; 170 unsigned int idx; 171 172 idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq); 173 174 /* 175 * The controller has a filter block to operate in either LEVEL or 176 * EDGE mode, then signal is sent to the GIC. To enable LEVEL_LOW and 177 * EDGE_FALLING support (which the GIC does not support), the filter 178 * block is also able to invert the input signal it gets before 179 * providing it to the GIC. 180 */ 181 type &= IRQ_TYPE_SENSE_MASK; 182 183 if (type == IRQ_TYPE_EDGE_BOTH) 184 return -EINVAL; 185 186 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 187 val |= REG_EDGE_POL_EDGE(idx); 188 189 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) 190 val |= REG_EDGE_POL_LOW(idx); 191 192 spin_lock(&ctl->lock); 193 194 meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, 195 REG_EDGE_POL_MASK(idx), val); 196 197 spin_unlock(&ctl->lock); 198 199 return 0; 200 } 201 202 static unsigned int meson_gpio_irq_type_output(unsigned int type) 203 { 204 unsigned int sense = type & IRQ_TYPE_SENSE_MASK; 205 206 type &= ~IRQ_TYPE_SENSE_MASK; 207 208 /* 209 * The polarity of the signal provided to the GIC should always 210 * be high. 211 */ 212 if (sense & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) 213 type |= IRQ_TYPE_LEVEL_HIGH; 214 else if (sense & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 215 type |= IRQ_TYPE_EDGE_RISING; 216 217 return type; 218 } 219 220 static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) 221 { 222 struct meson_gpio_irq_controller *ctl = data->domain->host_data; 223 u32 *channel_hwirq = irq_data_get_irq_chip_data(data); 224 int ret; 225 226 ret = meson_gpio_irq_type_setup(ctl, type, channel_hwirq); 227 if (ret) 228 return ret; 229 230 return irq_chip_set_type_parent(data, 231 meson_gpio_irq_type_output(type)); 232 } 233 234 static struct irq_chip meson_gpio_irq_chip = { 235 .name = "meson-gpio-irqchip", 236 .irq_mask = irq_chip_mask_parent, 237 .irq_unmask = irq_chip_unmask_parent, 238 .irq_eoi = irq_chip_eoi_parent, 239 .irq_set_type = meson_gpio_irq_set_type, 240 .irq_retrigger = irq_chip_retrigger_hierarchy, 241 #ifdef CONFIG_SMP 242 .irq_set_affinity = irq_chip_set_affinity_parent, 243 #endif 244 .flags = IRQCHIP_SET_TYPE_MASKED, 245 }; 246 247 static int meson_gpio_irq_domain_translate(struct irq_domain *domain, 248 struct irq_fwspec *fwspec, 249 unsigned long *hwirq, 250 unsigned int *type) 251 { 252 if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { 253 *hwirq = fwspec->param[0]; 254 *type = fwspec->param[1]; 255 return 0; 256 } 257 258 return -EINVAL; 259 } 260 261 static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain, 262 unsigned int virq, 263 u32 hwirq, 264 unsigned int type) 265 { 266 struct irq_fwspec fwspec; 267 268 fwspec.fwnode = domain->parent->fwnode; 269 fwspec.param_count = 3; 270 fwspec.param[0] = 0; /* SPI */ 271 fwspec.param[1] = hwirq; 272 fwspec.param[2] = meson_gpio_irq_type_output(type); 273 274 return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 275 } 276 277 static int meson_gpio_irq_domain_alloc(struct irq_domain *domain, 278 unsigned int virq, 279 unsigned int nr_irqs, 280 void *data) 281 { 282 struct irq_fwspec *fwspec = data; 283 struct meson_gpio_irq_controller *ctl = domain->host_data; 284 unsigned long hwirq; 285 u32 *channel_hwirq; 286 unsigned int type; 287 int ret; 288 289 if (WARN_ON(nr_irqs != 1)) 290 return -EINVAL; 291 292 ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type); 293 if (ret) 294 return ret; 295 296 ret = meson_gpio_irq_request_channel(ctl, hwirq, &channel_hwirq); 297 if (ret) 298 return ret; 299 300 ret = meson_gpio_irq_allocate_gic_irq(domain, virq, 301 *channel_hwirq, type); 302 if (ret < 0) { 303 pr_err("failed to allocate gic irq %u\n", *channel_hwirq); 304 meson_gpio_irq_release_channel(ctl, channel_hwirq); 305 return ret; 306 } 307 308 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, 309 &meson_gpio_irq_chip, channel_hwirq); 310 311 return 0; 312 } 313 314 static void meson_gpio_irq_domain_free(struct irq_domain *domain, 315 unsigned int virq, 316 unsigned int nr_irqs) 317 { 318 struct meson_gpio_irq_controller *ctl = domain->host_data; 319 struct irq_data *irq_data; 320 u32 *channel_hwirq; 321 322 if (WARN_ON(nr_irqs != 1)) 323 return; 324 325 irq_domain_free_irqs_parent(domain, virq, 1); 326 327 irq_data = irq_domain_get_irq_data(domain, virq); 328 channel_hwirq = irq_data_get_irq_chip_data(irq_data); 329 330 meson_gpio_irq_release_channel(ctl, channel_hwirq); 331 } 332 333 static const struct irq_domain_ops meson_gpio_irq_domain_ops = { 334 .alloc = meson_gpio_irq_domain_alloc, 335 .free = meson_gpio_irq_domain_free, 336 .translate = meson_gpio_irq_domain_translate, 337 }; 338 339 static int __init meson_gpio_irq_parse_dt(struct device_node *node, 340 struct meson_gpio_irq_controller *ctl) 341 { 342 const struct of_device_id *match; 343 const struct meson_gpio_irq_params *params; 344 int ret; 345 346 match = of_match_node(meson_irq_gpio_matches, node); 347 if (!match) 348 return -ENODEV; 349 350 params = match->data; 351 ctl->nr_hwirq = params->nr_hwirq; 352 353 ret = of_property_read_variable_u32_array(node, 354 "amlogic,channel-interrupts", 355 ctl->channel_irqs, 356 NUM_CHANNEL, 357 NUM_CHANNEL); 358 if (ret < 0) { 359 pr_err("can't get %d channel interrupts\n", NUM_CHANNEL); 360 return ret; 361 } 362 363 return 0; 364 } 365 366 static int __init meson_gpio_irq_of_init(struct device_node *node, 367 struct device_node *parent) 368 { 369 struct irq_domain *domain, *parent_domain; 370 struct meson_gpio_irq_controller *ctl; 371 int ret; 372 373 if (!parent) { 374 pr_err("missing parent interrupt node\n"); 375 return -ENODEV; 376 } 377 378 parent_domain = irq_find_host(parent); 379 if (!parent_domain) { 380 pr_err("unable to obtain parent domain\n"); 381 return -ENXIO; 382 } 383 384 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); 385 if (!ctl) 386 return -ENOMEM; 387 388 spin_lock_init(&ctl->lock); 389 390 ctl->base = of_iomap(node, 0); 391 if (!ctl->base) { 392 ret = -ENOMEM; 393 goto free_ctl; 394 } 395 396 ret = meson_gpio_irq_parse_dt(node, ctl); 397 if (ret) 398 goto free_channel_irqs; 399 400 domain = irq_domain_create_hierarchy(parent_domain, 0, ctl->nr_hwirq, 401 of_node_to_fwnode(node), 402 &meson_gpio_irq_domain_ops, 403 ctl); 404 if (!domain) { 405 pr_err("failed to add domain\n"); 406 ret = -ENODEV; 407 goto free_channel_irqs; 408 } 409 410 pr_info("%d to %d gpio interrupt mux initialized\n", 411 ctl->nr_hwirq, NUM_CHANNEL); 412 413 return 0; 414 415 free_channel_irqs: 416 iounmap(ctl->base); 417 free_ctl: 418 kfree(ctl); 419 420 return ret; 421 } 422 423 IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc", 424 meson_gpio_irq_of_init); 425