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 of_device_id meson_irq_gpio_matches[] = { 67 { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params }, 68 { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params }, 69 { .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params }, 70 { .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params }, 71 { } 72 }; 73 74 struct meson_gpio_irq_controller { 75 unsigned int nr_hwirq; 76 void __iomem *base; 77 u32 channel_irqs[NUM_CHANNEL]; 78 DECLARE_BITMAP(channel_map, NUM_CHANNEL); 79 spinlock_t lock; 80 }; 81 82 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, 83 unsigned int reg, u32 mask, u32 val) 84 { 85 u32 tmp; 86 87 tmp = readl_relaxed(ctl->base + reg); 88 tmp &= ~mask; 89 tmp |= val; 90 writel_relaxed(tmp, ctl->base + reg); 91 } 92 93 static unsigned int meson_gpio_irq_channel_to_reg(unsigned int channel) 94 { 95 return (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL; 96 } 97 98 static int 99 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, 100 unsigned long hwirq, 101 u32 **channel_hwirq) 102 { 103 unsigned int reg, idx; 104 105 spin_lock(&ctl->lock); 106 107 /* Find a free channel */ 108 idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL); 109 if (idx >= NUM_CHANNEL) { 110 spin_unlock(&ctl->lock); 111 pr_err("No channel available\n"); 112 return -ENOSPC; 113 } 114 115 /* Mark the channel as used */ 116 set_bit(idx, ctl->channel_map); 117 118 /* 119 * Setup the mux of the channel to route the signal of the pad 120 * to the appropriate input of the GIC 121 */ 122 reg = meson_gpio_irq_channel_to_reg(idx); 123 meson_gpio_irq_update_bits(ctl, reg, 124 0xff << REG_PIN_SEL_SHIFT(idx), 125 hwirq << REG_PIN_SEL_SHIFT(idx)); 126 127 /* 128 * Get the hwirq number assigned to this channel through 129 * a pointer the channel_irq table. The added benifit of this 130 * method is that we can also retrieve the channel index with 131 * it, using the table base. 132 */ 133 *channel_hwirq = &(ctl->channel_irqs[idx]); 134 135 spin_unlock(&ctl->lock); 136 137 pr_debug("hwirq %lu assigned to channel %d - irq %u\n", 138 hwirq, idx, **channel_hwirq); 139 140 return 0; 141 } 142 143 static unsigned int 144 meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl, 145 u32 *channel_hwirq) 146 { 147 return channel_hwirq - ctl->channel_irqs; 148 } 149 150 static void 151 meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl, 152 u32 *channel_hwirq) 153 { 154 unsigned int idx; 155 156 idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq); 157 clear_bit(idx, ctl->channel_map); 158 } 159 160 static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl, 161 unsigned int type, 162 u32 *channel_hwirq) 163 { 164 u32 val = 0; 165 unsigned int idx; 166 167 idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq); 168 169 /* 170 * The controller has a filter block to operate in either LEVEL or 171 * EDGE mode, then signal is sent to the GIC. To enable LEVEL_LOW and 172 * EDGE_FALLING support (which the GIC does not support), the filter 173 * block is also able to invert the input signal it gets before 174 * providing it to the GIC. 175 */ 176 type &= IRQ_TYPE_SENSE_MASK; 177 178 if (type == IRQ_TYPE_EDGE_BOTH) 179 return -EINVAL; 180 181 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 182 val |= REG_EDGE_POL_EDGE(idx); 183 184 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) 185 val |= REG_EDGE_POL_LOW(idx); 186 187 spin_lock(&ctl->lock); 188 189 meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, 190 REG_EDGE_POL_MASK(idx), val); 191 192 spin_unlock(&ctl->lock); 193 194 return 0; 195 } 196 197 static unsigned int meson_gpio_irq_type_output(unsigned int type) 198 { 199 unsigned int sense = type & IRQ_TYPE_SENSE_MASK; 200 201 type &= ~IRQ_TYPE_SENSE_MASK; 202 203 /* 204 * The polarity of the signal provided to the GIC should always 205 * be high. 206 */ 207 if (sense & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) 208 type |= IRQ_TYPE_LEVEL_HIGH; 209 else if (sense & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 210 type |= IRQ_TYPE_EDGE_RISING; 211 212 return type; 213 } 214 215 static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) 216 { 217 struct meson_gpio_irq_controller *ctl = data->domain->host_data; 218 u32 *channel_hwirq = irq_data_get_irq_chip_data(data); 219 int ret; 220 221 ret = meson_gpio_irq_type_setup(ctl, type, channel_hwirq); 222 if (ret) 223 return ret; 224 225 return irq_chip_set_type_parent(data, 226 meson_gpio_irq_type_output(type)); 227 } 228 229 static struct irq_chip meson_gpio_irq_chip = { 230 .name = "meson-gpio-irqchip", 231 .irq_mask = irq_chip_mask_parent, 232 .irq_unmask = irq_chip_unmask_parent, 233 .irq_eoi = irq_chip_eoi_parent, 234 .irq_set_type = meson_gpio_irq_set_type, 235 .irq_retrigger = irq_chip_retrigger_hierarchy, 236 #ifdef CONFIG_SMP 237 .irq_set_affinity = irq_chip_set_affinity_parent, 238 #endif 239 .flags = IRQCHIP_SET_TYPE_MASKED, 240 }; 241 242 static int meson_gpio_irq_domain_translate(struct irq_domain *domain, 243 struct irq_fwspec *fwspec, 244 unsigned long *hwirq, 245 unsigned int *type) 246 { 247 if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) { 248 *hwirq = fwspec->param[0]; 249 *type = fwspec->param[1]; 250 return 0; 251 } 252 253 return -EINVAL; 254 } 255 256 static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain, 257 unsigned int virq, 258 u32 hwirq, 259 unsigned int type) 260 { 261 struct irq_fwspec fwspec; 262 263 fwspec.fwnode = domain->parent->fwnode; 264 fwspec.param_count = 3; 265 fwspec.param[0] = 0; /* SPI */ 266 fwspec.param[1] = hwirq; 267 fwspec.param[2] = meson_gpio_irq_type_output(type); 268 269 return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 270 } 271 272 static int meson_gpio_irq_domain_alloc(struct irq_domain *domain, 273 unsigned int virq, 274 unsigned int nr_irqs, 275 void *data) 276 { 277 struct irq_fwspec *fwspec = data; 278 struct meson_gpio_irq_controller *ctl = domain->host_data; 279 unsigned long hwirq; 280 u32 *channel_hwirq; 281 unsigned int type; 282 int ret; 283 284 if (WARN_ON(nr_irqs != 1)) 285 return -EINVAL; 286 287 ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type); 288 if (ret) 289 return ret; 290 291 ret = meson_gpio_irq_request_channel(ctl, hwirq, &channel_hwirq); 292 if (ret) 293 return ret; 294 295 ret = meson_gpio_irq_allocate_gic_irq(domain, virq, 296 *channel_hwirq, type); 297 if (ret < 0) { 298 pr_err("failed to allocate gic irq %u\n", *channel_hwirq); 299 meson_gpio_irq_release_channel(ctl, channel_hwirq); 300 return ret; 301 } 302 303 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, 304 &meson_gpio_irq_chip, channel_hwirq); 305 306 return 0; 307 } 308 309 static void meson_gpio_irq_domain_free(struct irq_domain *domain, 310 unsigned int virq, 311 unsigned int nr_irqs) 312 { 313 struct meson_gpio_irq_controller *ctl = domain->host_data; 314 struct irq_data *irq_data; 315 u32 *channel_hwirq; 316 317 if (WARN_ON(nr_irqs != 1)) 318 return; 319 320 irq_domain_free_irqs_parent(domain, virq, 1); 321 322 irq_data = irq_domain_get_irq_data(domain, virq); 323 channel_hwirq = irq_data_get_irq_chip_data(irq_data); 324 325 meson_gpio_irq_release_channel(ctl, channel_hwirq); 326 } 327 328 static const struct irq_domain_ops meson_gpio_irq_domain_ops = { 329 .alloc = meson_gpio_irq_domain_alloc, 330 .free = meson_gpio_irq_domain_free, 331 .translate = meson_gpio_irq_domain_translate, 332 }; 333 334 static int __init meson_gpio_irq_parse_dt(struct device_node *node, 335 struct meson_gpio_irq_controller *ctl) 336 { 337 const struct of_device_id *match; 338 const struct meson_gpio_irq_params *params; 339 int ret; 340 341 match = of_match_node(meson_irq_gpio_matches, node); 342 if (!match) 343 return -ENODEV; 344 345 params = match->data; 346 ctl->nr_hwirq = params->nr_hwirq; 347 348 ret = of_property_read_variable_u32_array(node, 349 "amlogic,channel-interrupts", 350 ctl->channel_irqs, 351 NUM_CHANNEL, 352 NUM_CHANNEL); 353 if (ret < 0) { 354 pr_err("can't get %d channel interrupts\n", NUM_CHANNEL); 355 return ret; 356 } 357 358 return 0; 359 } 360 361 static int __init meson_gpio_irq_of_init(struct device_node *node, 362 struct device_node *parent) 363 { 364 struct irq_domain *domain, *parent_domain; 365 struct meson_gpio_irq_controller *ctl; 366 int ret; 367 368 if (!parent) { 369 pr_err("missing parent interrupt node\n"); 370 return -ENODEV; 371 } 372 373 parent_domain = irq_find_host(parent); 374 if (!parent_domain) { 375 pr_err("unable to obtain parent domain\n"); 376 return -ENXIO; 377 } 378 379 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); 380 if (!ctl) 381 return -ENOMEM; 382 383 spin_lock_init(&ctl->lock); 384 385 ctl->base = of_iomap(node, 0); 386 if (!ctl->base) { 387 ret = -ENOMEM; 388 goto free_ctl; 389 } 390 391 ret = meson_gpio_irq_parse_dt(node, ctl); 392 if (ret) 393 goto free_channel_irqs; 394 395 domain = irq_domain_create_hierarchy(parent_domain, 0, ctl->nr_hwirq, 396 of_node_to_fwnode(node), 397 &meson_gpio_irq_domain_ops, 398 ctl); 399 if (!domain) { 400 pr_err("failed to add domain\n"); 401 ret = -ENODEV; 402 goto free_channel_irqs; 403 } 404 405 pr_info("%d to %d gpio interrupt mux initialized\n", 406 ctl->nr_hwirq, NUM_CHANNEL); 407 408 return 0; 409 410 free_channel_irqs: 411 iounmap(ctl->base); 412 free_ctl: 413 kfree(ctl); 414 415 return ret; 416 } 417 418 IRQCHIP_DECLARE(meson_gpio_intc, "amlogic,meson-gpio-intc", 419 meson_gpio_irq_of_init); 420