1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (C) 2017 Socionext Inc. 4 // Author: Masahiro Yamada <yamada.masahiro@socionext.com> 5 6 #include <linux/bits.h> 7 #include <linux/gpio/driver.h> 8 #include <linux/irq.h> 9 #include <linux/irqdomain.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/of_irq.h> 13 #include <linux/platform_device.h> 14 #include <linux/spinlock.h> 15 #include <dt-bindings/gpio/uniphier-gpio.h> 16 17 #define UNIPHIER_GPIO_IRQ_MAX_NUM 24 18 19 #define UNIPHIER_GPIO_PORT_DATA 0x0 /* data */ 20 #define UNIPHIER_GPIO_PORT_DIR 0x4 /* direction (1:in, 0:out) */ 21 #define UNIPHIER_GPIO_IRQ_EN 0x90 /* irq enable */ 22 #define UNIPHIER_GPIO_IRQ_MODE 0x94 /* irq mode (1: both edge) */ 23 #define UNIPHIER_GPIO_IRQ_FLT_EN 0x98 /* noise filter enable */ 24 #define UNIPHIER_GPIO_IRQ_FLT_CYC 0x9c /* noise filter clock cycle */ 25 26 struct uniphier_gpio_priv { 27 struct gpio_chip chip; 28 struct irq_chip irq_chip; 29 struct irq_domain *domain; 30 void __iomem *regs; 31 spinlock_t lock; 32 u32 saved_vals[]; 33 }; 34 35 static unsigned int uniphier_gpio_bank_to_reg(unsigned int bank) 36 { 37 unsigned int reg; 38 39 reg = (bank + 1) * 8; 40 41 /* 42 * Unfortunately, the GPIO port registers are not contiguous because 43 * offset 0x90-0x9f is used for IRQ. Add 0x10 when crossing the region. 44 */ 45 if (reg >= UNIPHIER_GPIO_IRQ_EN) 46 reg += 0x10; 47 48 return reg; 49 } 50 51 static void uniphier_gpio_get_bank_and_mask(unsigned int offset, 52 unsigned int *bank, u32 *mask) 53 { 54 *bank = offset / UNIPHIER_GPIO_LINES_PER_BANK; 55 *mask = BIT(offset % UNIPHIER_GPIO_LINES_PER_BANK); 56 } 57 58 static void uniphier_gpio_reg_update(struct uniphier_gpio_priv *priv, 59 unsigned int reg, u32 mask, u32 val) 60 { 61 unsigned long flags; 62 u32 tmp; 63 64 spin_lock_irqsave(&priv->lock, flags); 65 tmp = readl(priv->regs + reg); 66 tmp &= ~mask; 67 tmp |= mask & val; 68 writel(tmp, priv->regs + reg); 69 spin_unlock_irqrestore(&priv->lock, flags); 70 } 71 72 static void uniphier_gpio_bank_write(struct gpio_chip *chip, unsigned int bank, 73 unsigned int reg, u32 mask, u32 val) 74 { 75 struct uniphier_gpio_priv *priv = gpiochip_get_data(chip); 76 77 if (!mask) 78 return; 79 80 uniphier_gpio_reg_update(priv, uniphier_gpio_bank_to_reg(bank) + reg, 81 mask, val); 82 } 83 84 static void uniphier_gpio_offset_write(struct gpio_chip *chip, 85 unsigned int offset, unsigned int reg, 86 int val) 87 { 88 unsigned int bank; 89 u32 mask; 90 91 uniphier_gpio_get_bank_and_mask(offset, &bank, &mask); 92 93 uniphier_gpio_bank_write(chip, bank, reg, mask, val ? mask : 0); 94 } 95 96 static int uniphier_gpio_offset_read(struct gpio_chip *chip, 97 unsigned int offset, unsigned int reg) 98 { 99 struct uniphier_gpio_priv *priv = gpiochip_get_data(chip); 100 unsigned int bank, reg_offset; 101 u32 mask; 102 103 uniphier_gpio_get_bank_and_mask(offset, &bank, &mask); 104 reg_offset = uniphier_gpio_bank_to_reg(bank) + reg; 105 106 return !!(readl(priv->regs + reg_offset) & mask); 107 } 108 109 static int uniphier_gpio_get_direction(struct gpio_chip *chip, 110 unsigned int offset) 111 { 112 if (uniphier_gpio_offset_read(chip, offset, UNIPHIER_GPIO_PORT_DIR)) 113 return GPIO_LINE_DIRECTION_IN; 114 115 return GPIO_LINE_DIRECTION_OUT; 116 } 117 118 static int uniphier_gpio_direction_input(struct gpio_chip *chip, 119 unsigned int offset) 120 { 121 uniphier_gpio_offset_write(chip, offset, UNIPHIER_GPIO_PORT_DIR, 1); 122 123 return 0; 124 } 125 126 static int uniphier_gpio_direction_output(struct gpio_chip *chip, 127 unsigned int offset, int val) 128 { 129 uniphier_gpio_offset_write(chip, offset, UNIPHIER_GPIO_PORT_DATA, val); 130 uniphier_gpio_offset_write(chip, offset, UNIPHIER_GPIO_PORT_DIR, 0); 131 132 return 0; 133 } 134 135 static int uniphier_gpio_get(struct gpio_chip *chip, unsigned int offset) 136 { 137 return uniphier_gpio_offset_read(chip, offset, UNIPHIER_GPIO_PORT_DATA); 138 } 139 140 static void uniphier_gpio_set(struct gpio_chip *chip, 141 unsigned int offset, int val) 142 { 143 uniphier_gpio_offset_write(chip, offset, UNIPHIER_GPIO_PORT_DATA, val); 144 } 145 146 static void uniphier_gpio_set_multiple(struct gpio_chip *chip, 147 unsigned long *mask, unsigned long *bits) 148 { 149 unsigned long i, bank, bank_mask, bank_bits; 150 151 for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { 152 bank = i / UNIPHIER_GPIO_LINES_PER_BANK; 153 bank_bits = bitmap_get_value8(bits, i); 154 155 uniphier_gpio_bank_write(chip, bank, UNIPHIER_GPIO_PORT_DATA, 156 bank_mask, bank_bits); 157 } 158 } 159 160 static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) 161 { 162 struct irq_fwspec fwspec; 163 164 if (offset < UNIPHIER_GPIO_IRQ_OFFSET) 165 return -ENXIO; 166 167 fwspec.fwnode = of_node_to_fwnode(chip->parent->of_node); 168 fwspec.param_count = 2; 169 fwspec.param[0] = offset - UNIPHIER_GPIO_IRQ_OFFSET; 170 /* 171 * IRQ_TYPE_NONE is rejected by the parent irq domain. Set LEVEL_HIGH 172 * temporarily. Anyway, ->irq_set_type() will override it later. 173 */ 174 fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; 175 176 return irq_create_fwspec_mapping(&fwspec); 177 } 178 179 static void uniphier_gpio_irq_mask(struct irq_data *data) 180 { 181 struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); 182 u32 mask = BIT(irqd_to_hwirq(data)); 183 184 uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, 0); 185 186 irq_chip_mask_parent(data); 187 } 188 189 static void uniphier_gpio_irq_unmask(struct irq_data *data) 190 { 191 struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); 192 u32 mask = BIT(irqd_to_hwirq(data)); 193 194 uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, mask); 195 196 irq_chip_unmask_parent(data); 197 } 198 199 static int uniphier_gpio_irq_set_type(struct irq_data *data, unsigned int type) 200 { 201 struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); 202 u32 mask = BIT(irqd_to_hwirq(data)); 203 u32 val = 0; 204 205 if (type == IRQ_TYPE_EDGE_BOTH) { 206 val = mask; 207 type = IRQ_TYPE_EDGE_FALLING; 208 } 209 210 uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_MODE, mask, val); 211 /* To enable both edge detection, the noise filter must be enabled. */ 212 uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_FLT_EN, mask, val); 213 214 return irq_chip_set_type_parent(data, type); 215 } 216 217 static int uniphier_gpio_irq_get_parent_hwirq(struct uniphier_gpio_priv *priv, 218 unsigned int hwirq) 219 { 220 struct device_node *np = priv->chip.parent->of_node; 221 const __be32 *range; 222 u32 base, parent_base, size; 223 int len; 224 225 range = of_get_property(np, "socionext,interrupt-ranges", &len); 226 if (!range) 227 return -EINVAL; 228 229 len /= sizeof(*range); 230 231 for (; len >= 3; len -= 3) { 232 base = be32_to_cpu(*range++); 233 parent_base = be32_to_cpu(*range++); 234 size = be32_to_cpu(*range++); 235 236 if (base <= hwirq && hwirq < base + size) 237 return hwirq - base + parent_base; 238 } 239 240 return -ENOENT; 241 } 242 243 static int uniphier_gpio_irq_domain_translate(struct irq_domain *domain, 244 struct irq_fwspec *fwspec, 245 unsigned long *out_hwirq, 246 unsigned int *out_type) 247 { 248 if (WARN_ON(fwspec->param_count < 2)) 249 return -EINVAL; 250 251 *out_hwirq = fwspec->param[0]; 252 *out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; 253 254 return 0; 255 } 256 257 static int uniphier_gpio_irq_domain_alloc(struct irq_domain *domain, 258 unsigned int virq, 259 unsigned int nr_irqs, void *arg) 260 { 261 struct uniphier_gpio_priv *priv = domain->host_data; 262 struct irq_fwspec parent_fwspec; 263 irq_hw_number_t hwirq; 264 unsigned int type; 265 int ret; 266 267 if (WARN_ON(nr_irqs != 1)) 268 return -EINVAL; 269 270 ret = uniphier_gpio_irq_domain_translate(domain, arg, &hwirq, &type); 271 if (ret) 272 return ret; 273 274 ret = uniphier_gpio_irq_get_parent_hwirq(priv, hwirq); 275 if (ret < 0) 276 return ret; 277 278 /* parent is UniPhier AIDET */ 279 parent_fwspec.fwnode = domain->parent->fwnode; 280 parent_fwspec.param_count = 2; 281 parent_fwspec.param[0] = ret; 282 parent_fwspec.param[1] = (type == IRQ_TYPE_EDGE_BOTH) ? 283 IRQ_TYPE_EDGE_FALLING : type; 284 285 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, 286 &priv->irq_chip, priv); 287 if (ret) 288 return ret; 289 290 return irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec); 291 } 292 293 static int uniphier_gpio_irq_domain_activate(struct irq_domain *domain, 294 struct irq_data *data, bool early) 295 { 296 struct uniphier_gpio_priv *priv = domain->host_data; 297 struct gpio_chip *chip = &priv->chip; 298 299 return gpiochip_lock_as_irq(chip, 300 irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); 301 } 302 303 static void uniphier_gpio_irq_domain_deactivate(struct irq_domain *domain, 304 struct irq_data *data) 305 { 306 struct uniphier_gpio_priv *priv = domain->host_data; 307 struct gpio_chip *chip = &priv->chip; 308 309 gpiochip_unlock_as_irq(chip, 310 irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); 311 } 312 313 static const struct irq_domain_ops uniphier_gpio_irq_domain_ops = { 314 .alloc = uniphier_gpio_irq_domain_alloc, 315 .free = irq_domain_free_irqs_common, 316 .activate = uniphier_gpio_irq_domain_activate, 317 .deactivate = uniphier_gpio_irq_domain_deactivate, 318 .translate = uniphier_gpio_irq_domain_translate, 319 }; 320 321 static void uniphier_gpio_hw_init(struct uniphier_gpio_priv *priv) 322 { 323 /* 324 * Due to the hardware design, the noise filter must be enabled to 325 * detect both edge interrupts. This filter is intended to remove the 326 * noise from the irq lines. It does not work for GPIO input, so GPIO 327 * debounce is not supported. Unfortunately, the filter period is 328 * shared among all irq lines. Just choose a sensible period here. 329 */ 330 writel(0xff, priv->regs + UNIPHIER_GPIO_IRQ_FLT_CYC); 331 } 332 333 static unsigned int uniphier_gpio_get_nbanks(unsigned int ngpio) 334 { 335 return DIV_ROUND_UP(ngpio, UNIPHIER_GPIO_LINES_PER_BANK); 336 } 337 338 static int uniphier_gpio_probe(struct platform_device *pdev) 339 { 340 struct device *dev = &pdev->dev; 341 struct device_node *parent_np; 342 struct irq_domain *parent_domain; 343 struct uniphier_gpio_priv *priv; 344 struct gpio_chip *chip; 345 struct irq_chip *irq_chip; 346 unsigned int nregs; 347 u32 ngpios; 348 int ret; 349 350 parent_np = of_irq_find_parent(dev->of_node); 351 if (!parent_np) 352 return -ENXIO; 353 354 parent_domain = irq_find_host(parent_np); 355 of_node_put(parent_np); 356 if (!parent_domain) 357 return -EPROBE_DEFER; 358 359 ret = of_property_read_u32(dev->of_node, "ngpios", &ngpios); 360 if (ret) 361 return ret; 362 363 nregs = uniphier_gpio_get_nbanks(ngpios) * 2 + 3; 364 priv = devm_kzalloc(dev, struct_size(priv, saved_vals, nregs), 365 GFP_KERNEL); 366 if (!priv) 367 return -ENOMEM; 368 369 priv->regs = devm_platform_ioremap_resource(pdev, 0); 370 if (IS_ERR(priv->regs)) 371 return PTR_ERR(priv->regs); 372 373 spin_lock_init(&priv->lock); 374 375 chip = &priv->chip; 376 chip->label = dev_name(dev); 377 chip->parent = dev; 378 chip->request = gpiochip_generic_request; 379 chip->free = gpiochip_generic_free; 380 chip->get_direction = uniphier_gpio_get_direction; 381 chip->direction_input = uniphier_gpio_direction_input; 382 chip->direction_output = uniphier_gpio_direction_output; 383 chip->get = uniphier_gpio_get; 384 chip->set = uniphier_gpio_set; 385 chip->set_multiple = uniphier_gpio_set_multiple; 386 chip->to_irq = uniphier_gpio_to_irq; 387 chip->base = -1; 388 chip->ngpio = ngpios; 389 390 irq_chip = &priv->irq_chip; 391 irq_chip->name = dev_name(dev); 392 irq_chip->irq_mask = uniphier_gpio_irq_mask; 393 irq_chip->irq_unmask = uniphier_gpio_irq_unmask; 394 irq_chip->irq_eoi = irq_chip_eoi_parent; 395 irq_chip->irq_set_affinity = irq_chip_set_affinity_parent; 396 irq_chip->irq_set_type = uniphier_gpio_irq_set_type; 397 398 uniphier_gpio_hw_init(priv); 399 400 ret = devm_gpiochip_add_data(dev, chip, priv); 401 if (ret) 402 return ret; 403 404 priv->domain = irq_domain_create_hierarchy( 405 parent_domain, 0, 406 UNIPHIER_GPIO_IRQ_MAX_NUM, 407 of_node_to_fwnode(dev->of_node), 408 &uniphier_gpio_irq_domain_ops, priv); 409 if (!priv->domain) 410 return -ENOMEM; 411 412 platform_set_drvdata(pdev, priv); 413 414 return 0; 415 } 416 417 static void uniphier_gpio_remove(struct platform_device *pdev) 418 { 419 struct uniphier_gpio_priv *priv = platform_get_drvdata(pdev); 420 421 irq_domain_remove(priv->domain); 422 } 423 424 static int __maybe_unused uniphier_gpio_suspend(struct device *dev) 425 { 426 struct uniphier_gpio_priv *priv = dev_get_drvdata(dev); 427 unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); 428 u32 *val = priv->saved_vals; 429 unsigned int reg; 430 int i; 431 432 for (i = 0; i < nbanks; i++) { 433 reg = uniphier_gpio_bank_to_reg(i); 434 435 *val++ = readl(priv->regs + reg + UNIPHIER_GPIO_PORT_DATA); 436 *val++ = readl(priv->regs + reg + UNIPHIER_GPIO_PORT_DIR); 437 } 438 439 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_EN); 440 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_MODE); 441 *val++ = readl(priv->regs + UNIPHIER_GPIO_IRQ_FLT_EN); 442 443 return 0; 444 } 445 446 static int __maybe_unused uniphier_gpio_resume(struct device *dev) 447 { 448 struct uniphier_gpio_priv *priv = dev_get_drvdata(dev); 449 unsigned int nbanks = uniphier_gpio_get_nbanks(priv->chip.ngpio); 450 const u32 *val = priv->saved_vals; 451 unsigned int reg; 452 int i; 453 454 for (i = 0; i < nbanks; i++) { 455 reg = uniphier_gpio_bank_to_reg(i); 456 457 writel(*val++, priv->regs + reg + UNIPHIER_GPIO_PORT_DATA); 458 writel(*val++, priv->regs + reg + UNIPHIER_GPIO_PORT_DIR); 459 } 460 461 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_EN); 462 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_MODE); 463 writel(*val++, priv->regs + UNIPHIER_GPIO_IRQ_FLT_EN); 464 465 uniphier_gpio_hw_init(priv); 466 467 return 0; 468 } 469 470 static const struct dev_pm_ops uniphier_gpio_pm_ops = { 471 SET_LATE_SYSTEM_SLEEP_PM_OPS(uniphier_gpio_suspend, 472 uniphier_gpio_resume) 473 }; 474 475 static const struct of_device_id uniphier_gpio_match[] = { 476 { .compatible = "socionext,uniphier-gpio" }, 477 { /* sentinel */ } 478 }; 479 MODULE_DEVICE_TABLE(of, uniphier_gpio_match); 480 481 static struct platform_driver uniphier_gpio_driver = { 482 .probe = uniphier_gpio_probe, 483 .remove_new = uniphier_gpio_remove, 484 .driver = { 485 .name = "uniphier-gpio", 486 .of_match_table = uniphier_gpio_match, 487 .pm = &uniphier_gpio_pm_ops, 488 }, 489 }; 490 module_platform_driver(uniphier_gpio_driver); 491 492 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); 493 MODULE_DESCRIPTION("UniPhier GPIO driver"); 494 MODULE_LICENSE("GPL v2"); 495