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