linux/drivers/gpio/gpio-em.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Emma Mobile GPIO Support - GIO
   4 *
   5 *  Copyright (C) 2012 Magnus Damm
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/platform_device.h>
  10#include <linux/spinlock.h>
  11#include <linux/interrupt.h>
  12#include <linux/ioport.h>
  13#include <linux/io.h>
  14#include <linux/irq.h>
  15#include <linux/irqdomain.h>
  16#include <linux/bitops.h>
  17#include <linux/err.h>
  18#include <linux/gpio/driver.h>
  19#include <linux/slab.h>
  20#include <linux/module.h>
  21#include <linux/pinctrl/consumer.h>
  22
  23struct em_gio_priv {
  24        void __iomem *base0;
  25        void __iomem *base1;
  26        spinlock_t sense_lock;
  27        struct platform_device *pdev;
  28        struct gpio_chip gpio_chip;
  29        struct irq_chip irq_chip;
  30        struct irq_domain *irq_domain;
  31};
  32
  33#define GIO_E1 0x00
  34#define GIO_E0 0x04
  35#define GIO_EM 0x04
  36#define GIO_OL 0x08
  37#define GIO_OH 0x0c
  38#define GIO_I 0x10
  39#define GIO_IIA 0x14
  40#define GIO_IEN 0x18
  41#define GIO_IDS 0x1c
  42#define GIO_IIM 0x1c
  43#define GIO_RAW 0x20
  44#define GIO_MST 0x24
  45#define GIO_IIR 0x28
  46
  47#define GIO_IDT0 0x40
  48#define GIO_IDT1 0x44
  49#define GIO_IDT2 0x48
  50#define GIO_IDT3 0x4c
  51#define GIO_RAWBL 0x50
  52#define GIO_RAWBH 0x54
  53#define GIO_IRBL 0x58
  54#define GIO_IRBH 0x5c
  55
  56#define GIO_IDT(n) (GIO_IDT0 + ((n) * 4))
  57
  58static inline unsigned long em_gio_read(struct em_gio_priv *p, int offs)
  59{
  60        if (offs < GIO_IDT0)
  61                return ioread32(p->base0 + offs);
  62        else
  63                return ioread32(p->base1 + (offs - GIO_IDT0));
  64}
  65
  66static inline void em_gio_write(struct em_gio_priv *p, int offs,
  67                                unsigned long value)
  68{
  69        if (offs < GIO_IDT0)
  70                iowrite32(value, p->base0 + offs);
  71        else
  72                iowrite32(value, p->base1 + (offs - GIO_IDT0));
  73}
  74
  75static void em_gio_irq_disable(struct irq_data *d)
  76{
  77        struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
  78
  79        em_gio_write(p, GIO_IDS, BIT(irqd_to_hwirq(d)));
  80}
  81
  82static void em_gio_irq_enable(struct irq_data *d)
  83{
  84        struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
  85
  86        em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
  87}
  88
  89static int em_gio_irq_reqres(struct irq_data *d)
  90{
  91        struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
  92        int ret;
  93
  94        ret = gpiochip_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d));
  95        if (ret) {
  96                dev_err(p->gpio_chip.parent,
  97                        "unable to lock HW IRQ %lu for IRQ\n",
  98                        irqd_to_hwirq(d));
  99                return ret;
 100        }
 101        return 0;
 102}
 103
 104static void em_gio_irq_relres(struct irq_data *d)
 105{
 106        struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
 107
 108        gpiochip_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d));
 109}
 110
 111
 112#define GIO_ASYNC(x) (x + 8)
 113
 114static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
 115        [IRQ_TYPE_EDGE_RISING] = GIO_ASYNC(0x00),
 116        [IRQ_TYPE_EDGE_FALLING] = GIO_ASYNC(0x01),
 117        [IRQ_TYPE_LEVEL_HIGH] = GIO_ASYNC(0x02),
 118        [IRQ_TYPE_LEVEL_LOW] = GIO_ASYNC(0x03),
 119        [IRQ_TYPE_EDGE_BOTH] = GIO_ASYNC(0x04),
 120};
 121
 122static int em_gio_irq_set_type(struct irq_data *d, unsigned int type)
 123{
 124        unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK];
 125        struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
 126        unsigned int reg, offset, shift;
 127        unsigned long flags;
 128        unsigned long tmp;
 129
 130        if (!value)
 131                return -EINVAL;
 132
 133        offset = irqd_to_hwirq(d);
 134
 135        pr_debug("gio: sense irq = %d, mode = %d\n", offset, value);
 136
 137        /* 8 x 4 bit fields in 4 IDT registers */
 138        reg = GIO_IDT(offset >> 3);
 139        shift = (offset & 0x07) << 4;
 140
 141        spin_lock_irqsave(&p->sense_lock, flags);
 142
 143        /* disable the interrupt in IIA */
 144        tmp = em_gio_read(p, GIO_IIA);
 145        tmp &= ~BIT(offset);
 146        em_gio_write(p, GIO_IIA, tmp);
 147
 148        /* change the sense setting in IDT */
 149        tmp = em_gio_read(p, reg);
 150        tmp &= ~(0xf << shift);
 151        tmp |= value << shift;
 152        em_gio_write(p, reg, tmp);
 153
 154        /* clear pending interrupts */
 155        em_gio_write(p, GIO_IIR, BIT(offset));
 156
 157        /* enable the interrupt in IIA */
 158        tmp = em_gio_read(p, GIO_IIA);
 159        tmp |= BIT(offset);
 160        em_gio_write(p, GIO_IIA, tmp);
 161
 162        spin_unlock_irqrestore(&p->sense_lock, flags);
 163
 164        return 0;
 165}
 166
 167static irqreturn_t em_gio_irq_handler(int irq, void *dev_id)
 168{
 169        struct em_gio_priv *p = dev_id;
 170        unsigned long pending;
 171        unsigned int offset, irqs_handled = 0;
 172
 173        while ((pending = em_gio_read(p, GIO_MST))) {
 174                offset = __ffs(pending);
 175                em_gio_write(p, GIO_IIR, BIT(offset));
 176                generic_handle_irq(irq_find_mapping(p->irq_domain, offset));
 177                irqs_handled++;
 178        }
 179
 180        return irqs_handled ? IRQ_HANDLED : IRQ_NONE;
 181}
 182
 183static inline struct em_gio_priv *gpio_to_priv(struct gpio_chip *chip)
 184{
 185        return gpiochip_get_data(chip);
 186}
 187
 188static int em_gio_direction_input(struct gpio_chip *chip, unsigned offset)
 189{
 190        em_gio_write(gpio_to_priv(chip), GIO_E0, BIT(offset));
 191        return 0;
 192}
 193
 194static int em_gio_get(struct gpio_chip *chip, unsigned offset)
 195{
 196        return !!(em_gio_read(gpio_to_priv(chip), GIO_I) & BIT(offset));
 197}
 198
 199static void __em_gio_set(struct gpio_chip *chip, unsigned int reg,
 200                         unsigned shift, int value)
 201{
 202        /* upper 16 bits contains mask and lower 16 actual value */
 203        em_gio_write(gpio_to_priv(chip), reg,
 204                     (BIT(shift + 16)) | (value << shift));
 205}
 206
 207static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value)
 208{
 209        /* output is split into two registers */
 210        if (offset < 16)
 211                __em_gio_set(chip, GIO_OL, offset, value);
 212        else
 213                __em_gio_set(chip, GIO_OH, offset - 16, value);
 214}
 215
 216static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
 217                                   int value)
 218{
 219        /* write GPIO value to output before selecting output mode of pin */
 220        em_gio_set(chip, offset, value);
 221        em_gio_write(gpio_to_priv(chip), GIO_E1, BIT(offset));
 222        return 0;
 223}
 224
 225static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
 226{
 227        return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset);
 228}
 229
 230static int em_gio_request(struct gpio_chip *chip, unsigned offset)
 231{
 232        return pinctrl_gpio_request(chip->base + offset);
 233}
 234
 235static void em_gio_free(struct gpio_chip *chip, unsigned offset)
 236{
 237        pinctrl_gpio_free(chip->base + offset);
 238
 239        /* Set the GPIO as an input to ensure that the next GPIO request won't
 240        * drive the GPIO pin as an output.
 241        */
 242        em_gio_direction_input(chip, offset);
 243}
 244
 245static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int irq,
 246                                 irq_hw_number_t hwirq)
 247{
 248        struct em_gio_priv *p = h->host_data;
 249
 250        pr_debug("gio: map hw irq = %d, irq = %d\n", (int)hwirq, irq);
 251
 252        irq_set_chip_data(irq, h->host_data);
 253        irq_set_chip_and_handler(irq, &p->irq_chip, handle_level_irq);
 254        return 0;
 255}
 256
 257static const struct irq_domain_ops em_gio_irq_domain_ops = {
 258        .map    = em_gio_irq_domain_map,
 259        .xlate  = irq_domain_xlate_twocell,
 260};
 261
 262static int em_gio_probe(struct platform_device *pdev)
 263{
 264        struct em_gio_priv *p;
 265        struct resource *io[2], *irq[2];
 266        struct gpio_chip *gpio_chip;
 267        struct irq_chip *irq_chip;
 268        const char *name = dev_name(&pdev->dev);
 269        unsigned int ngpios;
 270        int ret;
 271
 272        p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
 273        if (!p) {
 274                ret = -ENOMEM;
 275                goto err0;
 276        }
 277
 278        p->pdev = pdev;
 279        platform_set_drvdata(pdev, p);
 280        spin_lock_init(&p->sense_lock);
 281
 282        io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 283        io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 284        irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 285        irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
 286
 287        if (!io[0] || !io[1] || !irq[0] || !irq[1]) {
 288                dev_err(&pdev->dev, "missing IRQ or IOMEM\n");
 289                ret = -EINVAL;
 290                goto err0;
 291        }
 292
 293        p->base0 = devm_ioremap_nocache(&pdev->dev, io[0]->start,
 294                                        resource_size(io[0]));
 295        if (!p->base0) {
 296                dev_err(&pdev->dev, "failed to remap low I/O memory\n");
 297                ret = -ENXIO;
 298                goto err0;
 299        }
 300
 301        p->base1 = devm_ioremap_nocache(&pdev->dev, io[1]->start,
 302                                   resource_size(io[1]));
 303        if (!p->base1) {
 304                dev_err(&pdev->dev, "failed to remap high I/O memory\n");
 305                ret = -ENXIO;
 306                goto err0;
 307        }
 308
 309        if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
 310                dev_err(&pdev->dev, "Missing ngpios OF property\n");
 311                ret = -EINVAL;
 312                goto err0;
 313        }
 314
 315        gpio_chip = &p->gpio_chip;
 316        gpio_chip->of_node = pdev->dev.of_node;
 317        gpio_chip->direction_input = em_gio_direction_input;
 318        gpio_chip->get = em_gio_get;
 319        gpio_chip->direction_output = em_gio_direction_output;
 320        gpio_chip->set = em_gio_set;
 321        gpio_chip->to_irq = em_gio_to_irq;
 322        gpio_chip->request = em_gio_request;
 323        gpio_chip->free = em_gio_free;
 324        gpio_chip->label = name;
 325        gpio_chip->parent = &pdev->dev;
 326        gpio_chip->owner = THIS_MODULE;
 327        gpio_chip->base = -1;
 328        gpio_chip->ngpio = ngpios;
 329
 330        irq_chip = &p->irq_chip;
 331        irq_chip->name = name;
 332        irq_chip->irq_mask = em_gio_irq_disable;
 333        irq_chip->irq_unmask = em_gio_irq_enable;
 334        irq_chip->irq_set_type = em_gio_irq_set_type;
 335        irq_chip->irq_request_resources = em_gio_irq_reqres;
 336        irq_chip->irq_release_resources = em_gio_irq_relres;
 337        irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;
 338
 339        p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, ngpios, 0,
 340                                              &em_gio_irq_domain_ops, p);
 341        if (!p->irq_domain) {
 342                ret = -ENXIO;
 343                dev_err(&pdev->dev, "cannot initialize irq domain\n");
 344                goto err0;
 345        }
 346
 347        if (devm_request_irq(&pdev->dev, irq[0]->start,
 348                             em_gio_irq_handler, 0, name, p)) {
 349                dev_err(&pdev->dev, "failed to request low IRQ\n");
 350                ret = -ENOENT;
 351                goto err1;
 352        }
 353
 354        if (devm_request_irq(&pdev->dev, irq[1]->start,
 355                             em_gio_irq_handler, 0, name, p)) {
 356                dev_err(&pdev->dev, "failed to request high IRQ\n");
 357                ret = -ENOENT;
 358                goto err1;
 359        }
 360
 361        ret = gpiochip_add_data(gpio_chip, p);
 362        if (ret) {
 363                dev_err(&pdev->dev, "failed to add GPIO controller\n");
 364                goto err1;
 365        }
 366
 367        return 0;
 368
 369err1:
 370        irq_domain_remove(p->irq_domain);
 371err0:
 372        return ret;
 373}
 374
 375static int em_gio_remove(struct platform_device *pdev)
 376{
 377        struct em_gio_priv *p = platform_get_drvdata(pdev);
 378
 379        gpiochip_remove(&p->gpio_chip);
 380
 381        irq_domain_remove(p->irq_domain);
 382        return 0;
 383}
 384
 385static const struct of_device_id em_gio_dt_ids[] = {
 386        { .compatible = "renesas,em-gio", },
 387        {},
 388};
 389MODULE_DEVICE_TABLE(of, em_gio_dt_ids);
 390
 391static struct platform_driver em_gio_device_driver = {
 392        .probe          = em_gio_probe,
 393        .remove         = em_gio_remove,
 394        .driver         = {
 395                .name   = "em_gio",
 396                .of_match_table = em_gio_dt_ids,
 397        }
 398};
 399
 400static int __init em_gio_init(void)
 401{
 402        return platform_driver_register(&em_gio_device_driver);
 403}
 404postcore_initcall(em_gio_init);
 405
 406static void __exit em_gio_exit(void)
 407{
 408        platform_driver_unregister(&em_gio_device_driver);
 409}
 410module_exit(em_gio_exit);
 411
 412MODULE_AUTHOR("Magnus Damm");
 413MODULE_DESCRIPTION("Renesas Emma Mobile GIO Driver");
 414MODULE_LICENSE("GPL v2");
 415