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/driver.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
  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        if (bus->bustype == SSB_BUSTYPE_SSB)
 236                chip->base              = 0;
 237        else
 238                chip->base              = -1;
 239
 240        err = ssb_gpio_irq_chipco_domain_init(bus);
 241        if (err)
 242                return err;
 243
 244        err = gpiochip_add_data(chip, bus);
 245        if (err) {
 246                ssb_gpio_irq_chipco_domain_exit(bus);
 247                return err;
 248        }
 249
 250        return 0;
 251}
 252
 253/**************************************************
 254 * EXTIF
 255 **************************************************/
 256
 257#ifdef CONFIG_SSB_DRIVER_EXTIF
 258
 259static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned int gpio)
 260{
 261        struct ssb_bus *bus = gpiochip_get_data(chip);
 262
 263        return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
 264}
 265
 266static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned int gpio,
 267                                     int value)
 268{
 269        struct ssb_bus *bus = gpiochip_get_data(chip);
 270
 271        ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
 272}
 273
 274static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
 275                                          unsigned int gpio)
 276{
 277        struct ssb_bus *bus = gpiochip_get_data(chip);
 278
 279        ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
 280        return 0;
 281}
 282
 283static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
 284                                           unsigned int gpio, int value)
 285{
 286        struct ssb_bus *bus = gpiochip_get_data(chip);
 287
 288        ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
 289        ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
 290        return 0;
 291}
 292
 293#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 294static void ssb_gpio_irq_extif_mask(struct irq_data *d)
 295{
 296        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 297        int gpio = irqd_to_hwirq(d);
 298
 299        ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
 300}
 301
 302static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
 303{
 304        struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
 305        int gpio = irqd_to_hwirq(d);
 306        u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
 307
 308        ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
 309        ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
 310}
 311
 312static struct irq_chip ssb_gpio_irq_extif_chip = {
 313        .name           = "SSB-GPIO-EXTIF",
 314        .irq_mask       = ssb_gpio_irq_extif_mask,
 315        .irq_unmask     = ssb_gpio_irq_extif_unmask,
 316};
 317
 318static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
 319{
 320        struct ssb_bus *bus = dev_id;
 321        struct ssb_extif *extif = &bus->extif;
 322        u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
 323        u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
 324        u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
 325        unsigned long irqs = (val ^ pol) & mask;
 326        int gpio;
 327
 328        if (!irqs)
 329                return IRQ_NONE;
 330
 331        for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
 332                generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
 333        ssb_extif_gpio_polarity(extif, irqs, val & irqs);
 334
 335        return IRQ_HANDLED;
 336}
 337
 338static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
 339{
 340        struct ssb_extif *extif = &bus->extif;
 341        struct gpio_chip *chip = &bus->gpio;
 342        int gpio, hwirq, err;
 343
 344        if (bus->bustype != SSB_BUSTYPE_SSB)
 345                return 0;
 346
 347        bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
 348                                                &irq_domain_simple_ops, extif);
 349        if (!bus->irq_domain) {
 350                err = -ENODEV;
 351                goto err_irq_domain;
 352        }
 353        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 354                int irq = irq_create_mapping(bus->irq_domain, gpio);
 355
 356                irq_set_chip_data(irq, bus);
 357                irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
 358                                         handle_simple_irq);
 359        }
 360
 361        hwirq = ssb_mips_irq(bus->extif.dev) + 2;
 362        err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
 363                          "gpio", bus);
 364        if (err)
 365                goto err_req_irq;
 366
 367        ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
 368
 369        return 0;
 370
 371err_req_irq:
 372        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 373                int irq = irq_find_mapping(bus->irq_domain, gpio);
 374
 375                irq_dispose_mapping(irq);
 376        }
 377        irq_domain_remove(bus->irq_domain);
 378err_irq_domain:
 379        return err;
 380}
 381
 382static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
 383{
 384        struct ssb_extif *extif = &bus->extif;
 385        struct gpio_chip *chip = &bus->gpio;
 386        int gpio;
 387
 388        if (bus->bustype != SSB_BUSTYPE_SSB)
 389                return;
 390
 391        free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
 392        for (gpio = 0; gpio < chip->ngpio; gpio++) {
 393                int irq = irq_find_mapping(bus->irq_domain, gpio);
 394
 395                irq_dispose_mapping(irq);
 396        }
 397        irq_domain_remove(bus->irq_domain);
 398}
 399#else
 400static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
 401{
 402        return 0;
 403}
 404
 405static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
 406{
 407}
 408#endif
 409
 410static int ssb_gpio_extif_init(struct ssb_bus *bus)
 411{
 412        struct gpio_chip *chip = &bus->gpio;
 413        int err;
 414
 415        chip->label             = "ssb_extif_gpio";
 416        chip->owner             = THIS_MODULE;
 417        chip->get               = ssb_gpio_extif_get_value;
 418        chip->set               = ssb_gpio_extif_set_value;
 419        chip->direction_input   = ssb_gpio_extif_direction_input;
 420        chip->direction_output  = ssb_gpio_extif_direction_output;
 421#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
 422        chip->to_irq            = ssb_gpio_to_irq;
 423#endif
 424        chip->ngpio             = 5;
 425        /* There is just one SoC in one device and its GPIO addresses should be
 426         * deterministic to address them more easily. The other buses could get
 427         * a random base number. */
 428        if (bus->bustype == SSB_BUSTYPE_SSB)
 429                chip->base              = 0;
 430        else
 431                chip->base              = -1;
 432
 433        err = ssb_gpio_irq_extif_domain_init(bus);
 434        if (err)
 435                return err;
 436
 437        err = gpiochip_add_data(chip, bus);
 438        if (err) {
 439                ssb_gpio_irq_extif_domain_exit(bus);
 440                return err;
 441        }
 442
 443        return 0;
 444}
 445
 446#else
 447static int ssb_gpio_extif_init(struct ssb_bus *bus)
 448{
 449        return -ENOTSUPP;
 450}
 451#endif
 452
 453/**************************************************
 454 * Init
 455 **************************************************/
 456
 457int ssb_gpio_init(struct ssb_bus *bus)
 458{
 459        if (ssb_chipco_available(&bus->chipco))
 460                return ssb_gpio_chipco_init(bus);
 461        else if (ssb_extif_available(&bus->extif))
 462                return ssb_gpio_extif_init(bus);
 463        else
 464                SSB_WARN_ON(1);
 465
 466        return -1;
 467}
 468
 469int ssb_gpio_unregister(struct ssb_bus *bus)
 470{
 471        if (ssb_chipco_available(&bus->chipco) ||
 472            ssb_extif_available(&bus->extif)) {
 473                gpiochip_remove(&bus->gpio);
 474                return 0;
 475        } else {
 476                SSB_WARN_ON(1);
 477        }
 478
 479        return -1;
 480}
 481