linux/drivers/ssb/driver_gpio.c
<<
>>
Prefs
   1/*
   2 * Sonics Silicon Backplane
   3 * GPIO driver
   4 *
   5 * Copyright 2011, Broadcom Corporation
   6 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
   7 *
   8 * Licensed under the GNU/GPL. See COPYING for details.
   9 */
  10
  11#include <linux/gpio.h>
  12#include <linux/irq.h>
  13#include <linux/interrupt.h>
  14#include <linux/irqdomain.h>
  15#include <linux/export.h>
  16#include <linux/ssb/ssb.h>
  17
  18#include "ssb_private.h"
  19
  20
  21/**************************************************
  22 * Shared
  23 **************************************************/
  24
  25static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
  26{
  27        return container_of(chip, struct ssb_bus, gpio);
  28}
  29
  30#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
  31static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
  32{
  33        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  34
  35        if (bus->bustype == SSB_BUSTYPE_SSB)
  36                return irq_find_mapping(bus->irq_domain, gpio);
  37        else
  38                return -EINVAL;
  39}
  40#endif
  41
  42/**************************************************
  43 * ChipCommon
  44 **************************************************/
  45
  46static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
  47{
  48        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  49
  50        return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);
  51}
  52
  53static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio,
  54                                      int value)
  55{
  56        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  57
  58        ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
  59}
  60
  61static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,
  62                                           unsigned gpio)
  63{
  64        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  65
  66        ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);
  67        return 0;
  68}
  69
  70static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,
  71                                            unsigned gpio, int value)
  72{
  73        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  74
  75        ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);
  76        ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
  77        return 0;
  78}
  79
  80static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio)
  81{
  82        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  83
  84        ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);
  85        /* clear pulldown */
  86        ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);
  87        /* Set pullup */
  88        ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);
  89
  90        return 0;
  91}
  92
  93static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
  94{
  95        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
  96
  97        /* clear pullup */
  98        ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
  99}
 100
 101#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 102static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
 103{
 104        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 105        int gpio = irqd_to_hwirq(d);
 106
 107        ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
 108}
 109
 110static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
 111{
 112        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 113        int gpio = irqd_to_hwirq(d);
 114        u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
 115
 116        ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
 117        ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
 118}
 119
 120static struct irq_chip ssb_gpio_irq_chipco_chip = {
 121        .name           = "SSB-GPIO-CC",
 122        .irq_mask       = ssb_gpio_irq_chipco_mask,
 123        .irq_unmask     = ssb_gpio_irq_chipco_unmask,
 124};
 125
 126static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
 127{
 128        struct ssb_bus *bus = dev_id;
 129        struct ssb_chipcommon *chipco = &bus->chipco;
 130        u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
 131        u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
 132        u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
 133        unsigned long irqs = (val ^ pol) & mask;
 134        int gpio;
 135
 136        if (!irqs)
 137                return IRQ_NONE;
 138
 139        for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
 140                generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
 141        ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
 142
 143        return IRQ_HANDLED;
 144}
 145
 146static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
 147{
 148        struct ssb_chipcommon *chipco = &bus->chipco;
 149        struct gpio_chip *chip = &bus->gpio;
 150        int gpio, hwirq, err;
 151
 152        if (bus->bustype != SSB_BUSTYPE_SSB)
 153                return 0;
 154
 155        bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
 156                                                &irq_domain_simple_ops, chipco);
 157        if (!bus->irq_domain) {
 158                err = -ENODEV;
 159                goto err_irq_domain;
 160        }
 161        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 162                int irq = irq_create_mapping(bus->irq_domain, gpio);
 163
 164                irq_set_chip_data(irq, bus);
 165                irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
 166                                         handle_simple_irq);
 167        }
 168
 169        hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
 170        err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
 171                          "gpio", bus);
 172        if (err)
 173                goto err_req_irq;
 174
 175        ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
 176        chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
 177
 178        return 0;
 179
 180err_req_irq:
 181        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 182                int irq = irq_find_mapping(bus->irq_domain, gpio);
 183
 184                irq_dispose_mapping(irq);
 185        }
 186        irq_domain_remove(bus->irq_domain);
 187err_irq_domain:
 188        return err;
 189}
 190
 191static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
 192{
 193        struct ssb_chipcommon *chipco = &bus->chipco;
 194        struct gpio_chip *chip = &bus->gpio;
 195        int gpio;
 196
 197        if (bus->bustype != SSB_BUSTYPE_SSB)
 198                return;
 199
 200        chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
 201        free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
 202        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 203                int irq = irq_find_mapping(bus->irq_domain, gpio);
 204
 205                irq_dispose_mapping(irq);
 206        }
 207        irq_domain_remove(bus->irq_domain);
 208}
 209#else
 210static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
 211{
 212        return 0;
 213}
 214
 215static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
 216{
 217}
 218#endif
 219
 220static int ssb_gpio_chipco_init(struct ssb_bus *bus)
 221{
 222        struct gpio_chip *chip = &bus->gpio;
 223        int err;
 224
 225        chip->label             = "ssb_chipco_gpio";
 226        chip->owner             = THIS_MODULE;
 227        chip->request           = ssb_gpio_chipco_request;
 228        chip->free              = ssb_gpio_chipco_free;
 229        chip->get               = ssb_gpio_chipco_get_value;
 230        chip->set               = ssb_gpio_chipco_set_value;
 231        chip->direction_input   = ssb_gpio_chipco_direction_input;
 232        chip->direction_output  = ssb_gpio_chipco_direction_output;
 233#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 234        chip->to_irq            = ssb_gpio_to_irq;
 235#endif
 236        chip->ngpio             = 16;
 237        /* There is just one SoC in one device and its GPIO addresses should be
 238         * deterministic to address them more easily. The other buses could get
 239         * a random base number. */
 240        if (bus->bustype == SSB_BUSTYPE_SSB)
 241                chip->base              = 0;
 242        else
 243                chip->base              = -1;
 244
 245        err = ssb_gpio_irq_chipco_domain_init(bus);
 246        if (err)
 247                return err;
 248
 249        err = gpiochip_add(chip);
 250        if (err) {
 251                ssb_gpio_irq_chipco_domain_exit(bus);
 252                return err;
 253        }
 254
 255        return 0;
 256}
 257
 258/**************************************************
 259 * EXTIF
 260 **************************************************/
 261
 262#ifdef CONFIG_SSB_DRIVER_EXTIF
 263
 264static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
 265{
 266        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
 267
 268        return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
 269}
 270
 271static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio,
 272                                     int value)
 273{
 274        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
 275
 276        ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
 277}
 278
 279static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
 280                                          unsigned gpio)
 281{
 282        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
 283
 284        ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
 285        return 0;
 286}
 287
 288static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
 289                                           unsigned gpio, int value)
 290{
 291        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
 292
 293        ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
 294        ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
 295        return 0;
 296}
 297
 298#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 299static void ssb_gpio_irq_extif_mask(struct irq_data *d)
 300{
 301        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 302        int gpio = irqd_to_hwirq(d);
 303
 304        ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
 305}
 306
 307static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
 308{
 309        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 310        int gpio = irqd_to_hwirq(d);
 311        u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
 312
 313        ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
 314        ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
 315}
 316
 317static struct irq_chip ssb_gpio_irq_extif_chip = {
 318        .name           = "SSB-GPIO-EXTIF",
 319        .irq_mask       = ssb_gpio_irq_extif_mask,
 320        .irq_unmask     = ssb_gpio_irq_extif_unmask,
 321};
 322
 323static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
 324{
 325        struct ssb_bus *bus = dev_id;
 326        struct ssb_extif *extif = &bus->extif;
 327        u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
 328        u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
 329        u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
 330        unsigned long irqs = (val ^ pol) & mask;
 331        int gpio;
 332
 333        if (!irqs)
 334                return IRQ_NONE;
 335
 336        for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
 337                generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
 338        ssb_extif_gpio_polarity(extif, irqs, val & irqs);
 339
 340        return IRQ_HANDLED;
 341}
 342
 343static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
 344{
 345        struct ssb_extif *extif = &bus->extif;
 346        struct gpio_chip *chip = &bus->gpio;
 347        int gpio, hwirq, err;
 348
 349        if (bus->bustype != SSB_BUSTYPE_SSB)
 350                return 0;
 351
 352        bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
 353                                                &irq_domain_simple_ops, extif);
 354        if (!bus->irq_domain) {
 355                err = -ENODEV;
 356                goto err_irq_domain;
 357        }
 358        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 359                int irq = irq_create_mapping(bus->irq_domain, gpio);
 360
 361                irq_set_chip_data(irq, bus);
 362                irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
 363                                         handle_simple_irq);
 364        }
 365
 366        hwirq = ssb_mips_irq(bus->extif.dev) + 2;
 367        err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
 368                          "gpio", bus);
 369        if (err)
 370                goto err_req_irq;
 371
 372        ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
 373
 374        return 0;
 375
 376err_req_irq:
 377        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 378                int irq = irq_find_mapping(bus->irq_domain, gpio);
 379
 380                irq_dispose_mapping(irq);
 381        }
 382        irq_domain_remove(bus->irq_domain);
 383err_irq_domain:
 384        return err;
 385}
 386
 387static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
 388{
 389        struct ssb_extif *extif = &bus->extif;
 390        struct gpio_chip *chip = &bus->gpio;
 391        int gpio;
 392
 393        if (bus->bustype != SSB_BUSTYPE_SSB)
 394                return;
 395
 396        free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
 397        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 398                int irq = irq_find_mapping(bus->irq_domain, gpio);
 399
 400                irq_dispose_mapping(irq);
 401        }
 402        irq_domain_remove(bus->irq_domain);
 403}
 404#else
 405static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
 406{
 407        return 0;
 408}
 409
 410static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
 411{
 412}
 413#endif
 414
 415static int ssb_gpio_extif_init(struct ssb_bus *bus)
 416{
 417        struct gpio_chip *chip = &bus->gpio;
 418        int err;
 419
 420        chip->label             = "ssb_extif_gpio";
 421        chip->owner             = THIS_MODULE;
 422        chip->get               = ssb_gpio_extif_get_value;
 423        chip->set               = ssb_gpio_extif_set_value;
 424        chip->direction_input   = ssb_gpio_extif_direction_input;
 425        chip->direction_output  = ssb_gpio_extif_direction_output;
 426#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 427        chip->to_irq            = ssb_gpio_to_irq;
 428#endif
 429        chip->ngpio             = 5;
 430        /* There is just one SoC in one device and its GPIO addresses should be
 431         * deterministic to address them more easily. The other buses could get
 432         * a random base number. */
 433        if (bus->bustype == SSB_BUSTYPE_SSB)
 434                chip->base              = 0;
 435        else
 436                chip->base              = -1;
 437
 438        err = ssb_gpio_irq_extif_domain_init(bus);
 439        if (err)
 440                return err;
 441
 442        err = gpiochip_add(chip);
 443        if (err) {
 444                ssb_gpio_irq_extif_domain_exit(bus);
 445                return err;
 446        }
 447
 448        return 0;
 449}
 450
 451#else
 452static int ssb_gpio_extif_init(struct ssb_bus *bus)
 453{
 454        return -ENOTSUPP;
 455}
 456#endif
 457
 458/**************************************************
 459 * Init
 460 **************************************************/
 461
 462int ssb_gpio_init(struct ssb_bus *bus)
 463{
 464        if (ssb_chipco_available(&bus->chipco))
 465                return ssb_gpio_chipco_init(bus);
 466        else if (ssb_extif_available(&bus->extif))
 467                return ssb_gpio_extif_init(bus);
 468        else
 469                SSB_WARN_ON(1);
 470
 471        return -1;
 472}
 473
 474int ssb_gpio_unregister(struct ssb_bus *bus)
 475{
 476        if (ssb_chipco_available(&bus->chipco) ||
 477            ssb_extif_available(&bus->extif)) {
 478                gpiochip_remove(&bus->gpio);
 479                return 0;
 480        } else {
 481                SSB_WARN_ON(1);
 482        }
 483
 484        return -1;
 485}
 486