673 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Renesas R-Car GPIO Support4 *5 * Copyright (C) 2014 Renesas Electronics Corporation6 * Copyright (C) 2013 Magnus Damm7 */8 9#include <linux/err.h>10#include <linux/gpio/driver.h>11#include <linux/init.h>12#include <linux/interrupt.h>13#include <linux/io.h>14#include <linux/ioport.h>15#include <linux/irq.h>16#include <linux/module.h>17#include <linux/of.h>18#include <linux/pinctrl/consumer.h>19#include <linux/platform_device.h>20#include <linux/pm_runtime.h>21#include <linux/spinlock.h>22#include <linux/slab.h>23 24struct gpio_rcar_bank_info {25 u32 iointsel;26 u32 inoutsel;27 u32 outdt;28 u32 posneg;29 u32 edglevel;30 u32 bothedge;31 u32 intmsk;32};33 34struct gpio_rcar_info {35 bool has_outdtsel;36 bool has_both_edge_trigger;37 bool has_always_in;38 bool has_inen;39};40 41struct gpio_rcar_priv {42 void __iomem *base;43 spinlock_t lock;44 struct device *dev;45 struct gpio_chip gpio_chip;46 unsigned int irq_parent;47 atomic_t wakeup_path;48 struct gpio_rcar_info info;49 struct gpio_rcar_bank_info bank_info;50};51 52#define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */53#define INOUTSEL 0x04 /* General Input/Output Switching Register */54#define OUTDT 0x08 /* General Output Register */55#define INDT 0x0c /* General Input Register */56#define INTDT 0x10 /* Interrupt Display Register */57#define INTCLR 0x14 /* Interrupt Clear Register */58#define INTMSK 0x18 /* Interrupt Mask Register */59#define MSKCLR 0x1c /* Interrupt Mask Clear Register */60#define POSNEG 0x20 /* Positive/Negative Logic Select Register */61#define EDGLEVEL 0x24 /* Edge/level Select Register */62#define FILONOFF 0x28 /* Chattering Prevention On/Off Register */63#define OUTDTSEL 0x40 /* Output Data Select Register */64#define BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */65#define INEN 0x50 /* General Input Enable Register */66 67#define RCAR_MAX_GPIO_PER_BANK 3268 69static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)70{71 return ioread32(p->base + offs);72}73 74static inline void gpio_rcar_write(struct gpio_rcar_priv *p, int offs,75 u32 value)76{77 iowrite32(value, p->base + offs);78}79 80static void gpio_rcar_modify_bit(struct gpio_rcar_priv *p, int offs,81 int bit, bool value)82{83 u32 tmp = gpio_rcar_read(p, offs);84 85 if (value)86 tmp |= BIT(bit);87 else88 tmp &= ~BIT(bit);89 90 gpio_rcar_write(p, offs, tmp);91}92 93static void gpio_rcar_irq_disable(struct irq_data *d)94{95 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);96 struct gpio_rcar_priv *p = gpiochip_get_data(gc);97 irq_hw_number_t hwirq = irqd_to_hwirq(d);98 99 gpio_rcar_write(p, INTMSK, ~BIT(hwirq));100 gpiochip_disable_irq(gc, hwirq);101}102 103static void gpio_rcar_irq_enable(struct irq_data *d)104{105 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);106 struct gpio_rcar_priv *p = gpiochip_get_data(gc);107 irq_hw_number_t hwirq = irqd_to_hwirq(d);108 109 gpiochip_enable_irq(gc, hwirq);110 gpio_rcar_write(p, MSKCLR, BIT(hwirq));111}112 113static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,114 unsigned int hwirq,115 bool active_high_rising_edge,116 bool level_trigger,117 bool both)118{119 unsigned long flags;120 121 /* follow steps in the GPIO documentation for122 * "Setting Edge-Sensitive Interrupt Input Mode" and123 * "Setting Level-Sensitive Interrupt Input Mode"124 */125 126 spin_lock_irqsave(&p->lock, flags);127 128 /* Configure positive or negative logic in POSNEG */129 gpio_rcar_modify_bit(p, POSNEG, hwirq, !active_high_rising_edge);130 131 /* Configure edge or level trigger in EDGLEVEL */132 gpio_rcar_modify_bit(p, EDGLEVEL, hwirq, !level_trigger);133 134 /* Select one edge or both edges in BOTHEDGE */135 if (p->info.has_both_edge_trigger)136 gpio_rcar_modify_bit(p, BOTHEDGE, hwirq, both);137 138 /* Select "Interrupt Input Mode" in IOINTSEL */139 gpio_rcar_modify_bit(p, IOINTSEL, hwirq, true);140 141 /* Write INTCLR in case of edge trigger */142 if (!level_trigger)143 gpio_rcar_write(p, INTCLR, BIT(hwirq));144 145 spin_unlock_irqrestore(&p->lock, flags);146}147 148static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type)149{150 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);151 struct gpio_rcar_priv *p = gpiochip_get_data(gc);152 unsigned int hwirq = irqd_to_hwirq(d);153 154 dev_dbg(p->dev, "sense irq = %d, type = %d\n", hwirq, type);155 156 switch (type & IRQ_TYPE_SENSE_MASK) {157 case IRQ_TYPE_LEVEL_HIGH:158 gpio_rcar_config_interrupt_input_mode(p, hwirq, true, true,159 false);160 break;161 case IRQ_TYPE_LEVEL_LOW:162 gpio_rcar_config_interrupt_input_mode(p, hwirq, false, true,163 false);164 break;165 case IRQ_TYPE_EDGE_RISING:166 gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,167 false);168 break;169 case IRQ_TYPE_EDGE_FALLING:170 gpio_rcar_config_interrupt_input_mode(p, hwirq, false, false,171 false);172 break;173 case IRQ_TYPE_EDGE_BOTH:174 if (!p->info.has_both_edge_trigger)175 return -EINVAL;176 gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,177 true);178 break;179 default:180 return -EINVAL;181 }182 return 0;183}184 185static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)186{187 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);188 struct gpio_rcar_priv *p = gpiochip_get_data(gc);189 int error;190 191 if (p->irq_parent) {192 error = irq_set_irq_wake(p->irq_parent, on);193 if (error) {194 dev_dbg(p->dev, "irq %u doesn't support irq_set_wake\n",195 p->irq_parent);196 p->irq_parent = 0;197 }198 }199 200 if (on)201 atomic_inc(&p->wakeup_path);202 else203 atomic_dec(&p->wakeup_path);204 205 return 0;206}207 208static const struct irq_chip gpio_rcar_irq_chip = {209 .name = "gpio-rcar",210 .irq_mask = gpio_rcar_irq_disable,211 .irq_unmask = gpio_rcar_irq_enable,212 .irq_set_type = gpio_rcar_irq_set_type,213 .irq_set_wake = gpio_rcar_irq_set_wake,214 .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED |215 IRQCHIP_MASK_ON_SUSPEND,216 GPIOCHIP_IRQ_RESOURCE_HELPERS,217};218 219static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)220{221 struct gpio_rcar_priv *p = dev_id;222 u32 pending;223 unsigned int offset, irqs_handled = 0;224 225 while ((pending = gpio_rcar_read(p, INTDT) &226 gpio_rcar_read(p, INTMSK))) {227 offset = __ffs(pending);228 gpio_rcar_write(p, INTCLR, BIT(offset));229 generic_handle_domain_irq(p->gpio_chip.irq.domain,230 offset);231 irqs_handled++;232 }233 234 return irqs_handled ? IRQ_HANDLED : IRQ_NONE;235}236 237static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,238 unsigned int gpio,239 bool output)240{241 struct gpio_rcar_priv *p = gpiochip_get_data(chip);242 unsigned long flags;243 244 /* follow steps in the GPIO documentation for245 * "Setting General Output Mode" and246 * "Setting General Input Mode"247 */248 249 spin_lock_irqsave(&p->lock, flags);250 251 /* Configure positive logic in POSNEG */252 gpio_rcar_modify_bit(p, POSNEG, gpio, false);253 254 /* Select "General Input/Output Mode" in IOINTSEL */255 gpio_rcar_modify_bit(p, IOINTSEL, gpio, false);256 257 /* Select Input Mode or Output Mode in INOUTSEL */258 gpio_rcar_modify_bit(p, INOUTSEL, gpio, output);259 260 /* Select General Output Register to output data in OUTDTSEL */261 if (p->info.has_outdtsel && output)262 gpio_rcar_modify_bit(p, OUTDTSEL, gpio, false);263 264 spin_unlock_irqrestore(&p->lock, flags);265}266 267static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset)268{269 struct gpio_rcar_priv *p = gpiochip_get_data(chip);270 int error;271 272 error = pm_runtime_get_sync(p->dev);273 if (error < 0) {274 pm_runtime_put(p->dev);275 return error;276 }277 278 error = pinctrl_gpio_request(chip, offset);279 if (error)280 pm_runtime_put(p->dev);281 282 return error;283}284 285static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset)286{287 struct gpio_rcar_priv *p = gpiochip_get_data(chip);288 289 pinctrl_gpio_free(chip, offset);290 291 /*292 * Set the GPIO as an input to ensure that the next GPIO request won't293 * drive the GPIO pin as an output.294 */295 gpio_rcar_config_general_input_output_mode(chip, offset, false);296 297 pm_runtime_put(p->dev);298}299 300static int gpio_rcar_get_direction(struct gpio_chip *chip, unsigned int offset)301{302 struct gpio_rcar_priv *p = gpiochip_get_data(chip);303 304 if (gpio_rcar_read(p, INOUTSEL) & BIT(offset))305 return GPIO_LINE_DIRECTION_OUT;306 307 return GPIO_LINE_DIRECTION_IN;308}309 310static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset)311{312 gpio_rcar_config_general_input_output_mode(chip, offset, false);313 return 0;314}315 316static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset)317{318 struct gpio_rcar_priv *p = gpiochip_get_data(chip);319 u32 bit = BIT(offset);320 321 /*322 * Before R-Car Gen3, INDT does not show correct pin state when323 * configured as output, so use OUTDT in case of output pins324 */325 if (!p->info.has_always_in && (gpio_rcar_read(p, INOUTSEL) & bit))326 return !!(gpio_rcar_read(p, OUTDT) & bit);327 else328 return !!(gpio_rcar_read(p, INDT) & bit);329}330 331static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask,332 unsigned long *bits)333{334 struct gpio_rcar_priv *p = gpiochip_get_data(chip);335 u32 bankmask, outputs, m, val = 0;336 unsigned long flags;337 338 bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0);339 if (chip->valid_mask)340 bankmask &= chip->valid_mask[0];341 342 if (!bankmask)343 return 0;344 345 if (p->info.has_always_in) {346 bits[0] = gpio_rcar_read(p, INDT) & bankmask;347 return 0;348 }349 350 spin_lock_irqsave(&p->lock, flags);351 outputs = gpio_rcar_read(p, INOUTSEL);352 m = outputs & bankmask;353 if (m)354 val |= gpio_rcar_read(p, OUTDT) & m;355 356 m = ~outputs & bankmask;357 if (m)358 val |= gpio_rcar_read(p, INDT) & m;359 spin_unlock_irqrestore(&p->lock, flags);360 361 bits[0] = val;362 return 0;363}364 365static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value)366{367 struct gpio_rcar_priv *p = gpiochip_get_data(chip);368 unsigned long flags;369 370 spin_lock_irqsave(&p->lock, flags);371 gpio_rcar_modify_bit(p, OUTDT, offset, value);372 spin_unlock_irqrestore(&p->lock, flags);373}374 375static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask,376 unsigned long *bits)377{378 struct gpio_rcar_priv *p = gpiochip_get_data(chip);379 unsigned long flags;380 u32 val, bankmask;381 382 bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0);383 if (chip->valid_mask)384 bankmask &= chip->valid_mask[0];385 386 if (!bankmask)387 return;388 389 spin_lock_irqsave(&p->lock, flags);390 val = gpio_rcar_read(p, OUTDT);391 val &= ~bankmask;392 val |= (bankmask & bits[0]);393 gpio_rcar_write(p, OUTDT, val);394 spin_unlock_irqrestore(&p->lock, flags);395}396 397static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,398 int value)399{400 /* write GPIO value to output before selecting output mode of pin */401 gpio_rcar_set(chip, offset, value);402 gpio_rcar_config_general_input_output_mode(chip, offset, true);403 return 0;404}405 406static const struct gpio_rcar_info gpio_rcar_info_gen1 = {407 .has_outdtsel = false,408 .has_both_edge_trigger = false,409 .has_always_in = false,410 .has_inen = false,411};412 413static const struct gpio_rcar_info gpio_rcar_info_gen2 = {414 .has_outdtsel = true,415 .has_both_edge_trigger = true,416 .has_always_in = false,417 .has_inen = false,418};419 420static const struct gpio_rcar_info gpio_rcar_info_gen3 = {421 .has_outdtsel = true,422 .has_both_edge_trigger = true,423 .has_always_in = true,424 .has_inen = false,425};426 427static const struct gpio_rcar_info gpio_rcar_info_gen4 = {428 .has_outdtsel = true,429 .has_both_edge_trigger = true,430 .has_always_in = true,431 .has_inen = true,432};433 434static const struct of_device_id gpio_rcar_of_table[] = {435 {436 .compatible = "renesas,gpio-r8a779a0",437 .data = &gpio_rcar_info_gen4,438 }, {439 .compatible = "renesas,rcar-gen1-gpio",440 .data = &gpio_rcar_info_gen1,441 }, {442 .compatible = "renesas,rcar-gen2-gpio",443 .data = &gpio_rcar_info_gen2,444 }, {445 .compatible = "renesas,rcar-gen3-gpio",446 .data = &gpio_rcar_info_gen3,447 }, {448 .compatible = "renesas,rcar-gen4-gpio",449 .data = &gpio_rcar_info_gen4,450 }, {451 .compatible = "renesas,gpio-rcar",452 .data = &gpio_rcar_info_gen1,453 }, {454 /* Terminator */455 },456};457 458MODULE_DEVICE_TABLE(of, gpio_rcar_of_table);459 460static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)461{462 struct device_node *np = p->dev->of_node;463 const struct gpio_rcar_info *info;464 struct of_phandle_args args;465 int ret;466 467 info = of_device_get_match_data(p->dev);468 p->info = *info;469 470 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);471 *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;472 473 if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {474 dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n",475 *npins, RCAR_MAX_GPIO_PER_BANK);476 *npins = RCAR_MAX_GPIO_PER_BANK;477 }478 479 return 0;480}481 482static void gpio_rcar_enable_inputs(struct gpio_rcar_priv *p)483{484 u32 mask = GENMASK(p->gpio_chip.ngpio - 1, 0);485 486 /* Select "Input Enable" in INEN */487 if (p->gpio_chip.valid_mask)488 mask &= p->gpio_chip.valid_mask[0];489 if (mask)490 gpio_rcar_write(p, INEN, gpio_rcar_read(p, INEN) | mask);491}492 493static int gpio_rcar_probe(struct platform_device *pdev)494{495 struct gpio_rcar_priv *p;496 struct gpio_chip *gpio_chip;497 struct gpio_irq_chip *girq;498 struct device *dev = &pdev->dev;499 const char *name = dev_name(dev);500 unsigned int npins;501 int ret;502 503 p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);504 if (!p)505 return -ENOMEM;506 507 p->dev = dev;508 spin_lock_init(&p->lock);509 510 /* Get device configuration from DT node */511 ret = gpio_rcar_parse_dt(p, &npins);512 if (ret < 0)513 return ret;514 515 platform_set_drvdata(pdev, p);516 517 pm_runtime_enable(dev);518 519 ret = platform_get_irq(pdev, 0);520 if (ret < 0)521 goto err0;522 p->irq_parent = ret;523 524 p->base = devm_platform_ioremap_resource(pdev, 0);525 if (IS_ERR(p->base)) {526 ret = PTR_ERR(p->base);527 goto err0;528 }529 530 gpio_chip = &p->gpio_chip;531 gpio_chip->request = gpio_rcar_request;532 gpio_chip->free = gpio_rcar_free;533 gpio_chip->get_direction = gpio_rcar_get_direction;534 gpio_chip->direction_input = gpio_rcar_direction_input;535 gpio_chip->get = gpio_rcar_get;536 gpio_chip->get_multiple = gpio_rcar_get_multiple;537 gpio_chip->direction_output = gpio_rcar_direction_output;538 gpio_chip->set = gpio_rcar_set;539 gpio_chip->set_multiple = gpio_rcar_set_multiple;540 gpio_chip->label = name;541 gpio_chip->parent = dev;542 gpio_chip->owner = THIS_MODULE;543 gpio_chip->base = -1;544 gpio_chip->ngpio = npins;545 546 girq = &gpio_chip->irq;547 gpio_irq_chip_set_chip(girq, &gpio_rcar_irq_chip);548 /* This will let us handle the parent IRQ in the driver */549 girq->parent_handler = NULL;550 girq->num_parents = 0;551 girq->parents = NULL;552 girq->default_type = IRQ_TYPE_NONE;553 girq->handler = handle_level_irq;554 555 ret = gpiochip_add_data(gpio_chip, p);556 if (ret) {557 dev_err(dev, "failed to add GPIO controller\n");558 goto err0;559 }560 561 irq_domain_set_pm_device(gpio_chip->irq.domain, dev);562 ret = devm_request_irq(dev, p->irq_parent, gpio_rcar_irq_handler,563 IRQF_SHARED, name, p);564 if (ret) {565 dev_err(dev, "failed to request IRQ\n");566 goto err1;567 }568 569 if (p->info.has_inen) {570 pm_runtime_get_sync(dev);571 gpio_rcar_enable_inputs(p);572 pm_runtime_put(dev);573 }574 575 dev_info(dev, "driving %d GPIOs\n", npins);576 577 return 0;578 579err1:580 gpiochip_remove(gpio_chip);581err0:582 pm_runtime_disable(dev);583 return ret;584}585 586static void gpio_rcar_remove(struct platform_device *pdev)587{588 struct gpio_rcar_priv *p = platform_get_drvdata(pdev);589 590 gpiochip_remove(&p->gpio_chip);591 592 pm_runtime_disable(&pdev->dev);593}594 595#ifdef CONFIG_PM_SLEEP596static int gpio_rcar_suspend(struct device *dev)597{598 struct gpio_rcar_priv *p = dev_get_drvdata(dev);599 600 p->bank_info.iointsel = gpio_rcar_read(p, IOINTSEL);601 p->bank_info.inoutsel = gpio_rcar_read(p, INOUTSEL);602 p->bank_info.outdt = gpio_rcar_read(p, OUTDT);603 p->bank_info.intmsk = gpio_rcar_read(p, INTMSK);604 p->bank_info.posneg = gpio_rcar_read(p, POSNEG);605 p->bank_info.edglevel = gpio_rcar_read(p, EDGLEVEL);606 if (p->info.has_both_edge_trigger)607 p->bank_info.bothedge = gpio_rcar_read(p, BOTHEDGE);608 609 if (atomic_read(&p->wakeup_path))610 device_set_wakeup_path(dev);611 612 return 0;613}614 615static int gpio_rcar_resume(struct device *dev)616{617 struct gpio_rcar_priv *p = dev_get_drvdata(dev);618 unsigned int offset;619 u32 mask;620 621 for (offset = 0; offset < p->gpio_chip.ngpio; offset++) {622 if (!gpiochip_line_is_valid(&p->gpio_chip, offset))623 continue;624 625 mask = BIT(offset);626 /* I/O pin */627 if (!(p->bank_info.iointsel & mask)) {628 if (p->bank_info.inoutsel & mask)629 gpio_rcar_direction_output(630 &p->gpio_chip, offset,631 !!(p->bank_info.outdt & mask));632 else633 gpio_rcar_direction_input(&p->gpio_chip,634 offset);635 } else {636 /* Interrupt pin */637 gpio_rcar_config_interrupt_input_mode(638 p,639 offset,640 !(p->bank_info.posneg & mask),641 !(p->bank_info.edglevel & mask),642 !!(p->bank_info.bothedge & mask));643 644 if (p->bank_info.intmsk & mask)645 gpio_rcar_write(p, MSKCLR, mask);646 }647 }648 649 if (p->info.has_inen)650 gpio_rcar_enable_inputs(p);651 652 return 0;653}654#endif /* CONFIG_PM_SLEEP*/655 656static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, gpio_rcar_resume);657 658static struct platform_driver gpio_rcar_device_driver = {659 .probe = gpio_rcar_probe,660 .remove_new = gpio_rcar_remove,661 .driver = {662 .name = "gpio_rcar",663 .pm = &gpio_rcar_pm_ops,664 .of_match_table = gpio_rcar_of_table,665 }666};667 668module_platform_driver(gpio_rcar_device_driver);669 670MODULE_AUTHOR("Magnus Damm");671MODULE_DESCRIPTION("Renesas R-Car GPIO Driver");672MODULE_LICENSE("GPL v2");673