linux/drivers/gpio/gpio-aspeed.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 IBM Corp.
   3 *
   4 * Joel Stanley <joel@jms.id.au>
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/io.h>
  16#include <linux/spinlock.h>
  17#include <linux/platform_device.h>
  18#include <linux/gpio/driver.h>
  19#include <linux/pinctrl/consumer.h>
  20
  21struct aspeed_gpio {
  22        struct gpio_chip chip;
  23        spinlock_t lock;
  24        void __iomem *base;
  25        int irq;
  26};
  27
  28struct aspeed_gpio_bank {
  29        uint16_t        val_regs;
  30        uint16_t        irq_regs;
  31        const char      names[4];
  32};
  33
  34static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
  35        {
  36                .val_regs = 0x0000,
  37                .irq_regs = 0x0008,
  38                .names = { 'A', 'B', 'C', 'D' },
  39        },
  40        {
  41                .val_regs = 0x0020,
  42                .irq_regs = 0x0028,
  43                .names = { 'E', 'F', 'G', 'H' },
  44        },
  45        {
  46                .val_regs = 0x0070,
  47                .irq_regs = 0x0098,
  48                .names = { 'I', 'J', 'K', 'L' },
  49        },
  50        {
  51                .val_regs = 0x0078,
  52                .irq_regs = 0x00e8,
  53                .names = { 'M', 'N', 'O', 'P' },
  54        },
  55        {
  56                .val_regs = 0x0080,
  57                .irq_regs = 0x0118,
  58                .names = { 'Q', 'R', 'S', 'T' },
  59        },
  60        {
  61                .val_regs = 0x0088,
  62                .irq_regs = 0x0148,
  63                .names = { 'U', 'V', 'W', 'X' },
  64        },
  65        /*
  66         * A bank exists for { 'Y', 'Z', "AA", "AB" }, but is not implemented.
  67         * Only half of GPIOs Y support interrupt configuration, and none of Z,
  68         * AA or AB do as they are output only.
  69         */
  70};
  71
  72#define GPIO_BANK(x)    ((x) >> 5)
  73#define GPIO_OFFSET(x)  ((x) & 0x1f)
  74#define GPIO_BIT(x)     BIT(GPIO_OFFSET(x))
  75
  76#define GPIO_DATA       0x00
  77#define GPIO_DIR        0x04
  78
  79#define GPIO_IRQ_ENABLE 0x00
  80#define GPIO_IRQ_TYPE0  0x04
  81#define GPIO_IRQ_TYPE1  0x08
  82#define GPIO_IRQ_TYPE2  0x0c
  83#define GPIO_IRQ_STATUS 0x10
  84
  85static const struct aspeed_gpio_bank *to_bank(unsigned int offset)
  86{
  87        unsigned int bank = GPIO_BANK(offset);
  88
  89        WARN_ON(bank > ARRAY_SIZE(aspeed_gpio_banks));
  90        return &aspeed_gpio_banks[bank];
  91}
  92
  93static void __iomem *bank_val_reg(struct aspeed_gpio *gpio,
  94                const struct aspeed_gpio_bank *bank,
  95                unsigned int reg)
  96{
  97        return gpio->base + bank->val_regs + reg;
  98}
  99
 100static void __iomem *bank_irq_reg(struct aspeed_gpio *gpio,
 101                const struct aspeed_gpio_bank *bank,
 102                unsigned int reg)
 103{
 104        return gpio->base + bank->irq_regs + reg;
 105}
 106
 107static int aspeed_gpio_get(struct gpio_chip *gc, unsigned int offset)
 108{
 109        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 110        const struct aspeed_gpio_bank *bank = to_bank(offset);
 111
 112        return !!(ioread32(bank_val_reg(gpio, bank, GPIO_DATA))
 113                        & GPIO_BIT(offset));
 114}
 115
 116static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 117                              int val)
 118{
 119        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 120        const struct aspeed_gpio_bank *bank = to_bank(offset);
 121        void __iomem *addr;
 122        u32 reg;
 123
 124        addr = bank_val_reg(gpio, bank, GPIO_DATA);
 125        reg = ioread32(addr);
 126
 127        if (val)
 128                reg |= GPIO_BIT(offset);
 129        else
 130                reg &= ~GPIO_BIT(offset);
 131
 132        iowrite32(reg, addr);
 133}
 134
 135static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 136                            int val)
 137{
 138        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 139        unsigned long flags;
 140
 141        spin_lock_irqsave(&gpio->lock, flags);
 142
 143        __aspeed_gpio_set(gc, offset, val);
 144
 145        spin_unlock_irqrestore(&gpio->lock, flags);
 146}
 147
 148static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 149{
 150        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 151        const struct aspeed_gpio_bank *bank = to_bank(offset);
 152        unsigned long flags;
 153        u32 reg;
 154
 155        spin_lock_irqsave(&gpio->lock, flags);
 156
 157        reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));
 158        iowrite32(reg & ~GPIO_BIT(offset), bank_val_reg(gpio, bank, GPIO_DIR));
 159
 160        spin_unlock_irqrestore(&gpio->lock, flags);
 161
 162        return 0;
 163}
 164
 165static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 166                               unsigned int offset, int val)
 167{
 168        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 169        const struct aspeed_gpio_bank *bank = to_bank(offset);
 170        unsigned long flags;
 171        u32 reg;
 172
 173        spin_lock_irqsave(&gpio->lock, flags);
 174
 175        reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));
 176        iowrite32(reg | GPIO_BIT(offset), bank_val_reg(gpio, bank, GPIO_DIR));
 177
 178        __aspeed_gpio_set(gc, offset, val);
 179
 180        spin_unlock_irqrestore(&gpio->lock, flags);
 181
 182        return 0;
 183}
 184
 185static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 186{
 187        struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 188        const struct aspeed_gpio_bank *bank = to_bank(offset);
 189        unsigned long flags;
 190        u32 val;
 191
 192        spin_lock_irqsave(&gpio->lock, flags);
 193
 194        val = ioread32(bank_val_reg(gpio, bank, GPIO_DIR)) & GPIO_BIT(offset);
 195
 196        spin_unlock_irqrestore(&gpio->lock, flags);
 197
 198        return !val;
 199
 200}
 201
 202static inline int irqd_to_aspeed_gpio_data(struct irq_data *d,
 203                struct aspeed_gpio **gpio,
 204                const struct aspeed_gpio_bank **bank,
 205                u32 *bit)
 206{
 207        int offset;
 208
 209        offset = irqd_to_hwirq(d);
 210
 211        *gpio = irq_data_get_irq_chip_data(d);
 212        *bank = to_bank(offset);
 213        *bit = GPIO_BIT(offset);
 214
 215        return 0;
 216}
 217
 218static void aspeed_gpio_irq_ack(struct irq_data *d)
 219{
 220        const struct aspeed_gpio_bank *bank;
 221        struct aspeed_gpio *gpio;
 222        unsigned long flags;
 223        void __iomem *status_addr;
 224        u32 bit;
 225        int rc;
 226
 227        rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit);
 228        if (rc)
 229                return;
 230
 231        status_addr = bank_irq_reg(gpio, bank, GPIO_IRQ_STATUS);
 232
 233        spin_lock_irqsave(&gpio->lock, flags);
 234        iowrite32(bit, status_addr);
 235        spin_unlock_irqrestore(&gpio->lock, flags);
 236}
 237
 238static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 239{
 240        const struct aspeed_gpio_bank *bank;
 241        struct aspeed_gpio *gpio;
 242        unsigned long flags;
 243        u32 reg, bit;
 244        void __iomem *addr;
 245        int rc;
 246
 247        rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit);
 248        if (rc)
 249                return;
 250
 251        addr = bank_irq_reg(gpio, bank, GPIO_IRQ_ENABLE);
 252
 253        spin_lock_irqsave(&gpio->lock, flags);
 254
 255        reg = ioread32(addr);
 256        if (set)
 257                reg |= bit;
 258        else
 259                reg &= bit;
 260        iowrite32(reg, addr);
 261
 262        spin_unlock_irqrestore(&gpio->lock, flags);
 263}
 264
 265static void aspeed_gpio_irq_mask(struct irq_data *d)
 266{
 267        aspeed_gpio_irq_set_mask(d, false);
 268}
 269
 270static void aspeed_gpio_irq_unmask(struct irq_data *d)
 271{
 272        aspeed_gpio_irq_set_mask(d, true);
 273}
 274
 275static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 276{
 277        u32 type0 = 0;
 278        u32 type1 = 0;
 279        u32 type2 = 0;
 280        u32 bit, reg;
 281        const struct aspeed_gpio_bank *bank;
 282        irq_flow_handler_t handler;
 283        struct aspeed_gpio *gpio;
 284        unsigned long flags;
 285        void __iomem *addr;
 286        int rc;
 287
 288        rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit);
 289        if (rc)
 290                return -EINVAL;
 291
 292        switch (type & IRQ_TYPE_SENSE_MASK) {
 293        case IRQ_TYPE_EDGE_BOTH:
 294                type2 |= bit;
 295        case IRQ_TYPE_EDGE_RISING:
 296                type0 |= bit;
 297        case IRQ_TYPE_EDGE_FALLING:
 298                handler = handle_edge_irq;
 299                break;
 300        case IRQ_TYPE_LEVEL_HIGH:
 301                type0 |= bit;
 302        case IRQ_TYPE_LEVEL_LOW:
 303                type1 |= bit;
 304                handler = handle_level_irq;
 305                break;
 306        default:
 307                return -EINVAL;
 308        }
 309
 310        spin_lock_irqsave(&gpio->lock, flags);
 311
 312        addr = bank_irq_reg(gpio, bank, GPIO_IRQ_TYPE0);
 313        reg = ioread32(addr);
 314        reg = (reg & ~bit) | type0;
 315        iowrite32(reg, addr);
 316
 317        addr = bank_irq_reg(gpio, bank, GPIO_IRQ_TYPE1);
 318        reg = ioread32(addr);
 319        reg = (reg & ~bit) | type1;
 320        iowrite32(reg, addr);
 321
 322        addr = bank_irq_reg(gpio, bank, GPIO_IRQ_TYPE2);
 323        reg = ioread32(addr);
 324        reg = (reg & ~bit) | type2;
 325        iowrite32(reg, addr);
 326
 327        spin_unlock_irqrestore(&gpio->lock, flags);
 328
 329        irq_set_handler_locked(d, handler);
 330
 331        return 0;
 332}
 333
 334static void aspeed_gpio_irq_handler(struct irq_desc *desc)
 335{
 336        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 337        struct irq_chip *ic = irq_desc_get_chip(desc);
 338        struct aspeed_gpio *data = gpiochip_get_data(gc);
 339        unsigned int i, p, girq;
 340        unsigned long reg;
 341
 342        chained_irq_enter(ic, desc);
 343
 344        for (i = 0; i < ARRAY_SIZE(aspeed_gpio_banks); i++) {
 345                const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
 346
 347                reg = ioread32(bank_irq_reg(data, bank, GPIO_IRQ_STATUS));
 348
 349                for_each_set_bit(p, &reg, 32) {
 350                        girq = irq_find_mapping(gc->irqdomain, i * 32 + p);
 351                        generic_handle_irq(girq);
 352                }
 353
 354        }
 355
 356        chained_irq_exit(ic, desc);
 357}
 358
 359static struct irq_chip aspeed_gpio_irqchip = {
 360        .name           = "aspeed-gpio",
 361        .irq_ack        = aspeed_gpio_irq_ack,
 362        .irq_mask       = aspeed_gpio_irq_mask,
 363        .irq_unmask     = aspeed_gpio_irq_unmask,
 364        .irq_set_type   = aspeed_gpio_set_type,
 365};
 366
 367static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
 368                struct platform_device *pdev)
 369{
 370        int rc;
 371
 372        rc = platform_get_irq(pdev, 0);
 373        if (rc < 0)
 374                return rc;
 375
 376        gpio->irq = rc;
 377
 378        rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
 379                        0, handle_bad_irq, IRQ_TYPE_NONE);
 380        if (rc) {
 381                dev_info(&pdev->dev, "Could not add irqchip\n");
 382                return rc;
 383        }
 384
 385        gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
 386                                     gpio->irq, aspeed_gpio_irq_handler);
 387
 388        return 0;
 389}
 390
 391static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
 392{
 393        return pinctrl_request_gpio(chip->base + offset);
 394}
 395
 396static void aspeed_gpio_free(struct gpio_chip *chip, unsigned int offset)
 397{
 398        pinctrl_free_gpio(chip->base + offset);
 399}
 400
 401static int __init aspeed_gpio_probe(struct platform_device *pdev)
 402{
 403        struct aspeed_gpio *gpio;
 404        struct resource *res;
 405        int rc;
 406
 407        gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
 408        if (!gpio)
 409                return -ENOMEM;
 410
 411        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 412        gpio->base = devm_ioremap_resource(&pdev->dev, res);
 413        if (IS_ERR(gpio->base))
 414                return PTR_ERR(gpio->base);
 415
 416        spin_lock_init(&gpio->lock);
 417
 418        gpio->chip.ngpio = ARRAY_SIZE(aspeed_gpio_banks) * 32;
 419
 420        gpio->chip.parent = &pdev->dev;
 421        gpio->chip.direction_input = aspeed_gpio_dir_in;
 422        gpio->chip.direction_output = aspeed_gpio_dir_out;
 423        gpio->chip.get_direction = aspeed_gpio_get_direction;
 424        gpio->chip.request = aspeed_gpio_request;
 425        gpio->chip.free = aspeed_gpio_free;
 426        gpio->chip.get = aspeed_gpio_get;
 427        gpio->chip.set = aspeed_gpio_set;
 428        gpio->chip.label = dev_name(&pdev->dev);
 429        gpio->chip.base = -1;
 430
 431        rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
 432        if (rc < 0)
 433                return rc;
 434
 435        return aspeed_gpio_setup_irqs(gpio, pdev);
 436}
 437
 438static const struct of_device_id aspeed_gpio_of_table[] = {
 439        { .compatible = "aspeed,ast2400-gpio" },
 440        { .compatible = "aspeed,ast2500-gpio" },
 441        {}
 442};
 443MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
 444
 445static struct platform_driver aspeed_gpio_driver = {
 446        .driver = {
 447                .name = KBUILD_MODNAME,
 448                .of_match_table = aspeed_gpio_of_table,
 449        },
 450};
 451
 452module_platform_driver_probe(aspeed_gpio_driver, aspeed_gpio_probe);
 453
 454MODULE_DESCRIPTION("Aspeed GPIO Driver");
 455MODULE_LICENSE("GPL");
 456