linux/drivers/gpio/gpio-intel-mid.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Intel MID GPIO driver
   4 *
   5 * Copyright (c) 2008-2014,2016 Intel Corporation.
   6 */
   7
   8/* Supports:
   9 * Moorestown platform Langwell chip.
  10 * Medfield platform Penwell chip.
  11 * Clovertrail platform Cloverview chip.
  12 */
  13
  14#include <linux/delay.h>
  15#include <linux/gpio/driver.h>
  16#include <linux/init.h>
  17#include <linux/interrupt.h>
  18#include <linux/io.h>
  19#include <linux/kernel.h>
  20#include <linux/pci.h>
  21#include <linux/platform_device.h>
  22#include <linux/pm_runtime.h>
  23#include <linux/slab.h>
  24#include <linux/stddef.h>
  25
  26#define INTEL_MID_IRQ_TYPE_EDGE         (1 << 0)
  27#define INTEL_MID_IRQ_TYPE_LEVEL        (1 << 1)
  28
  29/*
  30 * Langwell chip has 64 pins and thus there are 2 32bit registers to control
  31 * each feature, while Penwell chip has 96 pins for each block, and need 3 32bit
  32 * registers to control them, so we only define the order here instead of a
  33 * structure, to get a bit offset for a pin (use GPDR as an example):
  34 *
  35 * nreg = ngpio / 32;
  36 * reg = offset / 32;
  37 * bit = offset % 32;
  38 * reg_addr = reg_base + GPDR * nreg * 4 + reg * 4;
  39 *
  40 * so the bit of reg_addr is to control pin offset's GPDR feature
  41*/
  42
  43enum GPIO_REG {
  44        GPLR = 0,       /* pin level read-only */
  45        GPDR,           /* pin direction */
  46        GPSR,           /* pin set */
  47        GPCR,           /* pin clear */
  48        GRER,           /* rising edge detect */
  49        GFER,           /* falling edge detect */
  50        GEDR,           /* edge detect result */
  51        GAFR,           /* alt function */
  52};
  53
  54/* intel_mid gpio driver data */
  55struct intel_mid_gpio_ddata {
  56        u16 ngpio;              /* number of gpio pins */
  57        u32 chip_irq_type;      /* chip interrupt type */
  58};
  59
  60struct intel_mid_gpio {
  61        struct gpio_chip                chip;
  62        void __iomem                    *reg_base;
  63        spinlock_t                      lock;
  64        struct pci_dev                  *pdev;
  65};
  66
  67static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
  68                              enum GPIO_REG reg_type)
  69{
  70        struct intel_mid_gpio *priv = gpiochip_get_data(chip);
  71        unsigned nreg = chip->ngpio / 32;
  72        u8 reg = offset / 32;
  73
  74        return priv->reg_base + reg_type * nreg * 4 + reg * 4;
  75}
  76
  77static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset,
  78                                   enum GPIO_REG reg_type)
  79{
  80        struct intel_mid_gpio *priv = gpiochip_get_data(chip);
  81        unsigned nreg = chip->ngpio / 32;
  82        u8 reg = offset / 16;
  83
  84        return priv->reg_base + reg_type * nreg * 4 + reg * 4;
  85}
  86
  87static int intel_gpio_request(struct gpio_chip *chip, unsigned offset)
  88{
  89        void __iomem *gafr = gpio_reg_2bit(chip, offset, GAFR);
  90        u32 value = readl(gafr);
  91        int shift = (offset % 16) << 1, af = (value >> shift) & 3;
  92
  93        if (af) {
  94                value &= ~(3 << shift);
  95                writel(value, gafr);
  96        }
  97        return 0;
  98}
  99
 100static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
 101{
 102        void __iomem *gplr = gpio_reg(chip, offset, GPLR);
 103
 104        return !!(readl(gplr) & BIT(offset % 32));
 105}
 106
 107static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 108{
 109        void __iomem *gpsr, *gpcr;
 110
 111        if (value) {
 112                gpsr = gpio_reg(chip, offset, GPSR);
 113                writel(BIT(offset % 32), gpsr);
 114        } else {
 115                gpcr = gpio_reg(chip, offset, GPCR);
 116                writel(BIT(offset % 32), gpcr);
 117        }
 118}
 119
 120static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 121{
 122        struct intel_mid_gpio *priv = gpiochip_get_data(chip);
 123        void __iomem *gpdr = gpio_reg(chip, offset, GPDR);
 124        u32 value;
 125        unsigned long flags;
 126
 127        if (priv->pdev)
 128                pm_runtime_get(&priv->pdev->dev);
 129
 130        spin_lock_irqsave(&priv->lock, flags);
 131        value = readl(gpdr);
 132        value &= ~BIT(offset % 32);
 133        writel(value, gpdr);
 134        spin_unlock_irqrestore(&priv->lock, flags);
 135
 136        if (priv->pdev)
 137                pm_runtime_put(&priv->pdev->dev);
 138
 139        return 0;
 140}
 141
 142static int intel_gpio_direction_output(struct gpio_chip *chip,
 143                        unsigned offset, int value)
 144{
 145        struct intel_mid_gpio *priv = gpiochip_get_data(chip);
 146        void __iomem *gpdr = gpio_reg(chip, offset, GPDR);
 147        unsigned long flags;
 148
 149        intel_gpio_set(chip, offset, value);
 150
 151        if (priv->pdev)
 152                pm_runtime_get(&priv->pdev->dev);
 153
 154        spin_lock_irqsave(&priv->lock, flags);
 155        value = readl(gpdr);
 156        value |= BIT(offset % 32);
 157        writel(value, gpdr);
 158        spin_unlock_irqrestore(&priv->lock, flags);
 159
 160        if (priv->pdev)
 161                pm_runtime_put(&priv->pdev->dev);
 162
 163        return 0;
 164}
 165
 166static int intel_mid_irq_type(struct irq_data *d, unsigned type)
 167{
 168        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 169        struct intel_mid_gpio *priv = gpiochip_get_data(gc);
 170        u32 gpio = irqd_to_hwirq(d);
 171        unsigned long flags;
 172        u32 value;
 173        void __iomem *grer = gpio_reg(&priv->chip, gpio, GRER);
 174        void __iomem *gfer = gpio_reg(&priv->chip, gpio, GFER);
 175
 176        if (gpio >= priv->chip.ngpio)
 177                return -EINVAL;
 178
 179        if (priv->pdev)
 180                pm_runtime_get(&priv->pdev->dev);
 181
 182        spin_lock_irqsave(&priv->lock, flags);
 183        if (type & IRQ_TYPE_EDGE_RISING)
 184                value = readl(grer) | BIT(gpio % 32);
 185        else
 186                value = readl(grer) & (~BIT(gpio % 32));
 187        writel(value, grer);
 188
 189        if (type & IRQ_TYPE_EDGE_FALLING)
 190                value = readl(gfer) | BIT(gpio % 32);
 191        else
 192                value = readl(gfer) & (~BIT(gpio % 32));
 193        writel(value, gfer);
 194        spin_unlock_irqrestore(&priv->lock, flags);
 195
 196        if (priv->pdev)
 197                pm_runtime_put(&priv->pdev->dev);
 198
 199        return 0;
 200}
 201
 202static void intel_mid_irq_unmask(struct irq_data *d)
 203{
 204}
 205
 206static void intel_mid_irq_mask(struct irq_data *d)
 207{
 208}
 209
 210static struct irq_chip intel_mid_irqchip = {
 211        .name           = "INTEL_MID-GPIO",
 212        .irq_mask       = intel_mid_irq_mask,
 213        .irq_unmask     = intel_mid_irq_unmask,
 214        .irq_set_type   = intel_mid_irq_type,
 215};
 216
 217static const struct intel_mid_gpio_ddata gpio_lincroft = {
 218        .ngpio = 64,
 219};
 220
 221static const struct intel_mid_gpio_ddata gpio_penwell_aon = {
 222        .ngpio = 96,
 223        .chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
 224};
 225
 226static const struct intel_mid_gpio_ddata gpio_penwell_core = {
 227        .ngpio = 96,
 228        .chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
 229};
 230
 231static const struct intel_mid_gpio_ddata gpio_cloverview_aon = {
 232        .ngpio = 96,
 233        .chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE | INTEL_MID_IRQ_TYPE_LEVEL,
 234};
 235
 236static const struct intel_mid_gpio_ddata gpio_cloverview_core = {
 237        .ngpio = 96,
 238        .chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
 239};
 240
 241static const struct pci_device_id intel_gpio_ids[] = {
 242        {
 243                /* Lincroft */
 244                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f),
 245                .driver_data = (kernel_ulong_t)&gpio_lincroft,
 246        },
 247        {
 248                /* Penwell AON */
 249                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f),
 250                .driver_data = (kernel_ulong_t)&gpio_penwell_aon,
 251        },
 252        {
 253                /* Penwell Core */
 254                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a),
 255                .driver_data = (kernel_ulong_t)&gpio_penwell_core,
 256        },
 257        {
 258                /* Cloverview Aon */
 259                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08eb),
 260                .driver_data = (kernel_ulong_t)&gpio_cloverview_aon,
 261        },
 262        {
 263                /* Cloverview Core */
 264                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7),
 265                .driver_data = (kernel_ulong_t)&gpio_cloverview_core,
 266        },
 267        { }
 268};
 269
 270static void intel_mid_irq_handler(struct irq_desc *desc)
 271{
 272        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 273        struct intel_mid_gpio *priv = gpiochip_get_data(gc);
 274        struct irq_data *data = irq_desc_get_irq_data(desc);
 275        struct irq_chip *chip = irq_data_get_irq_chip(data);
 276        u32 base, gpio, mask;
 277        unsigned long pending;
 278        void __iomem *gedr;
 279
 280        /* check GPIO controller to check which pin triggered the interrupt */
 281        for (base = 0; base < priv->chip.ngpio; base += 32) {
 282                gedr = gpio_reg(&priv->chip, base, GEDR);
 283                while ((pending = readl(gedr))) {
 284                        gpio = __ffs(pending);
 285                        mask = BIT(gpio);
 286                        /* Clear before handling so we can't lose an edge */
 287                        writel(mask, gedr);
 288                        generic_handle_irq(irq_find_mapping(gc->irq.domain,
 289                                                            base + gpio));
 290                }
 291        }
 292
 293        chip->irq_eoi(data);
 294}
 295
 296static int intel_mid_irq_init_hw(struct gpio_chip *chip)
 297{
 298        struct intel_mid_gpio *priv = gpiochip_get_data(chip);
 299        void __iomem *reg;
 300        unsigned base;
 301
 302        for (base = 0; base < priv->chip.ngpio; base += 32) {
 303                /* Clear the rising-edge detect register */
 304                reg = gpio_reg(&priv->chip, base, GRER);
 305                writel(0, reg);
 306                /* Clear the falling-edge detect register */
 307                reg = gpio_reg(&priv->chip, base, GFER);
 308                writel(0, reg);
 309                /* Clear the edge detect status register */
 310                reg = gpio_reg(&priv->chip, base, GEDR);
 311                writel(~0, reg);
 312        }
 313
 314        return 0;
 315}
 316
 317static int __maybe_unused intel_gpio_runtime_idle(struct device *dev)
 318{
 319        int err = pm_schedule_suspend(dev, 500);
 320        return err ?: -EBUSY;
 321}
 322
 323static const struct dev_pm_ops intel_gpio_pm_ops = {
 324        SET_RUNTIME_PM_OPS(NULL, NULL, intel_gpio_runtime_idle)
 325};
 326
 327static int intel_gpio_probe(struct pci_dev *pdev,
 328                          const struct pci_device_id *id)
 329{
 330        void __iomem *base;
 331        struct intel_mid_gpio *priv;
 332        u32 gpio_base;
 333        u32 irq_base;
 334        int retval;
 335        struct gpio_irq_chip *girq;
 336        struct intel_mid_gpio_ddata *ddata =
 337                                (struct intel_mid_gpio_ddata *)id->driver_data;
 338
 339        retval = pcim_enable_device(pdev);
 340        if (retval)
 341                return retval;
 342
 343        retval = pcim_iomap_regions(pdev, 1 << 0 | 1 << 1, pci_name(pdev));
 344        if (retval) {
 345                dev_err(&pdev->dev, "I/O memory mapping error\n");
 346                return retval;
 347        }
 348
 349        base = pcim_iomap_table(pdev)[1];
 350
 351        irq_base = readl(base);
 352        gpio_base = readl(sizeof(u32) + base);
 353
 354        /* release the IO mapping, since we already get the info from bar1 */
 355        pcim_iounmap_regions(pdev, 1 << 1);
 356
 357        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 358        if (!priv)
 359                return -ENOMEM;
 360
 361        priv->reg_base = pcim_iomap_table(pdev)[0];
 362        priv->chip.label = dev_name(&pdev->dev);
 363        priv->chip.parent = &pdev->dev;
 364        priv->chip.request = intel_gpio_request;
 365        priv->chip.direction_input = intel_gpio_direction_input;
 366        priv->chip.direction_output = intel_gpio_direction_output;
 367        priv->chip.get = intel_gpio_get;
 368        priv->chip.set = intel_gpio_set;
 369        priv->chip.base = gpio_base;
 370        priv->chip.ngpio = ddata->ngpio;
 371        priv->chip.can_sleep = false;
 372        priv->pdev = pdev;
 373
 374        spin_lock_init(&priv->lock);
 375
 376        girq = &priv->chip.irq;
 377        girq->chip = &intel_mid_irqchip;
 378        girq->init_hw = intel_mid_irq_init_hw;
 379        girq->parent_handler = intel_mid_irq_handler;
 380        girq->num_parents = 1;
 381        girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
 382                                     sizeof(*girq->parents),
 383                                     GFP_KERNEL);
 384        if (!girq->parents)
 385                return -ENOMEM;
 386        girq->parents[0] = pdev->irq;
 387        girq->first = irq_base;
 388        girq->default_type = IRQ_TYPE_NONE;
 389        girq->handler = handle_simple_irq;
 390
 391        pci_set_drvdata(pdev, priv);
 392
 393        retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
 394        if (retval) {
 395                dev_err(&pdev->dev, "gpiochip_add error %d\n", retval);
 396                return retval;
 397        }
 398
 399        pm_runtime_put_noidle(&pdev->dev);
 400        pm_runtime_allow(&pdev->dev);
 401
 402        return 0;
 403}
 404
 405static struct pci_driver intel_gpio_driver = {
 406        .name           = "intel_mid_gpio",
 407        .id_table       = intel_gpio_ids,
 408        .probe          = intel_gpio_probe,
 409        .driver         = {
 410                .pm     = &intel_gpio_pm_ops,
 411        },
 412};
 413
 414builtin_pci_driver(intel_gpio_driver);
 415