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