linux/drivers/gpio/gpio-msm-v2.c
<<
>>
Prefs
   1/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
   2 *
   3 * This program is free software; you can redistribute it and/or modify
   4 * it under the terms of the GNU General Public License version 2 and
   5 * only version 2 as published by the Free Software Foundation.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 *
  12 * You should have received a copy of the GNU General Public License
  13 * along with this program; if not, write to the Free Software
  14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15 * 02110-1301, USA.
  16 *
  17 */
  18#define pr_fmt(fmt) "%s: " fmt, __func__
  19
  20#include <linux/bitmap.h>
  21#include <linux/bitops.h>
  22#include <linux/gpio.h>
  23#include <linux/init.h>
  24#include <linux/interrupt.h>
  25#include <linux/io.h>
  26#include <linux/irqchip/chained_irq.h>
  27#include <linux/irq.h>
  28#include <linux/module.h>
  29#include <linux/platform_device.h>
  30#include <linux/spinlock.h>
  31
  32#include <mach/msm_gpiomux.h>
  33#include <mach/msm_iomap.h>
  34
  35/* Bits of interest in the GPIO_IN_OUT register.
  36 */
  37enum {
  38        GPIO_IN  = 0,
  39        GPIO_OUT = 1
  40};
  41
  42/* Bits of interest in the GPIO_INTR_STATUS register.
  43 */
  44enum {
  45        INTR_STATUS = 0,
  46};
  47
  48/* Bits of interest in the GPIO_CFG register.
  49 */
  50enum {
  51        GPIO_OE = 9,
  52};
  53
  54/* Bits of interest in the GPIO_INTR_CFG register.
  55 * When a GPIO triggers, two separate decisions are made, controlled
  56 * by two separate flags.
  57 *
  58 * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
  59 * register for that GPIO will be updated to reflect the triggering of that
  60 * gpio.  If this bit is 0, this register will not be updated.
  61 * - Second, INTR_ENABLE controls whether an interrupt is triggered.
  62 *
  63 * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
  64 * can be triggered but the status register will not reflect it.
  65 */
  66enum {
  67        INTR_ENABLE        = 0,
  68        INTR_POL_CTL       = 1,
  69        INTR_DECT_CTL      = 2,
  70        INTR_RAW_STATUS_EN = 3,
  71};
  72
  73/* Codes of interest in GPIO_INTR_CFG_SU.
  74 */
  75enum {
  76        TARGET_PROC_SCORPION = 4,
  77        TARGET_PROC_NONE     = 7,
  78};
  79
  80
  81#define GPIO_INTR_CFG_SU(gpio)    (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
  82#define GPIO_CONFIG(gpio)         (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
  83#define GPIO_IN_OUT(gpio)         (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
  84#define GPIO_INTR_CFG(gpio)       (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
  85#define GPIO_INTR_STATUS(gpio)    (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
  86
  87/**
  88 * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
  89 *
  90 * @enabled_irqs: a bitmap used to optimize the summary-irq handler.  By
  91 * keeping track of which gpios are unmasked as irq sources, we avoid
  92 * having to do readl calls on hundreds of iomapped registers each time
  93 * the summary interrupt fires in order to locate the active interrupts.
  94 *
  95 * @wake_irqs: a bitmap for tracking which interrupt lines are enabled
  96 * as wakeup sources.  When the device is suspended, interrupts which are
  97 * not wakeup sources are disabled.
  98 *
  99 * @dual_edge_irqs: a bitmap used to track which irqs are configured
 100 * as dual-edge, as this is not supported by the hardware and requires
 101 * some special handling in the driver.
 102 */
 103struct msm_gpio_dev {
 104        struct gpio_chip gpio_chip;
 105        DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
 106        DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
 107        DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
 108};
 109
 110static DEFINE_SPINLOCK(tlmm_lock);
 111
 112static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
 113{
 114        return container_of(chip, struct msm_gpio_dev, gpio_chip);
 115}
 116
 117static inline void set_gpio_bits(unsigned n, void __iomem *reg)
 118{
 119        writel(readl(reg) | n, reg);
 120}
 121
 122static inline void clear_gpio_bits(unsigned n, void __iomem *reg)
 123{
 124        writel(readl(reg) & ~n, reg);
 125}
 126
 127static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
 128{
 129        return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN);
 130}
 131
 132static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
 133{
 134        writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset));
 135}
 136
 137static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 138{
 139        unsigned long irq_flags;
 140
 141        spin_lock_irqsave(&tlmm_lock, irq_flags);
 142        clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
 143        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 144        return 0;
 145}
 146
 147static int msm_gpio_direction_output(struct gpio_chip *chip,
 148                                unsigned offset,
 149                                int val)
 150{
 151        unsigned long irq_flags;
 152
 153        spin_lock_irqsave(&tlmm_lock, irq_flags);
 154        msm_gpio_set(chip, offset, val);
 155        set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
 156        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 157        return 0;
 158}
 159
 160static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
 161{
 162        return msm_gpiomux_get(chip->base + offset);
 163}
 164
 165static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
 166{
 167        msm_gpiomux_put(chip->base + offset);
 168}
 169
 170static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 171{
 172        return MSM_GPIO_TO_INT(chip->base + offset);
 173}
 174
 175static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
 176{
 177        return irq - MSM_GPIO_TO_INT(chip->base);
 178}
 179
 180static struct msm_gpio_dev msm_gpio = {
 181        .gpio_chip = {
 182                .base             = 0,
 183                .ngpio            = NR_GPIO_IRQS,
 184                .direction_input  = msm_gpio_direction_input,
 185                .direction_output = msm_gpio_direction_output,
 186                .get              = msm_gpio_get,
 187                .set              = msm_gpio_set,
 188                .to_irq           = msm_gpio_to_irq,
 189                .request          = msm_gpio_request,
 190                .free             = msm_gpio_free,
 191        },
 192};
 193
 194/* For dual-edge interrupts in software, since the hardware has no
 195 * such support:
 196 *
 197 * At appropriate moments, this function may be called to flip the polarity
 198 * settings of both-edge irq lines to try and catch the next edge.
 199 *
 200 * The attempt is considered successful if:
 201 * - the status bit goes high, indicating that an edge was caught, or
 202 * - the input value of the gpio doesn't change during the attempt.
 203 * If the value changes twice during the process, that would cause the first
 204 * test to fail but would force the second, as two opposite
 205 * transitions would cause a detection no matter the polarity setting.
 206 *
 207 * The do-loop tries to sledge-hammer closed the timing hole between
 208 * the initial value-read and the polarity-write - if the line value changes
 209 * during that window, an interrupt is lost, the new polarity setting is
 210 * incorrect, and the first success test will fail, causing a retry.
 211 *
 212 * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c.
 213 */
 214static void msm_gpio_update_dual_edge_pos(unsigned gpio)
 215{
 216        int loop_limit = 100;
 217        unsigned val, val2, intstat;
 218
 219        do {
 220                val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
 221                if (val)
 222                        clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
 223                else
 224                        set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
 225                val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
 226                intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS);
 227                if (intstat || val == val2)
 228                        return;
 229        } while (loop_limit-- > 0);
 230        pr_err("dual-edge irq failed to stabilize, "
 231               "interrupts dropped. %#08x != %#08x\n",
 232               val, val2);
 233}
 234
 235static void msm_gpio_irq_ack(struct irq_data *d)
 236{
 237        int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 238
 239        writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
 240        if (test_bit(gpio, msm_gpio.dual_edge_irqs))
 241                msm_gpio_update_dual_edge_pos(gpio);
 242}
 243
 244static void msm_gpio_irq_mask(struct irq_data *d)
 245{
 246        int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 247        unsigned long irq_flags;
 248
 249        spin_lock_irqsave(&tlmm_lock, irq_flags);
 250        writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
 251        clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
 252        __clear_bit(gpio, msm_gpio.enabled_irqs);
 253        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 254}
 255
 256static void msm_gpio_irq_unmask(struct irq_data *d)
 257{
 258        int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 259        unsigned long irq_flags;
 260
 261        spin_lock_irqsave(&tlmm_lock, irq_flags);
 262        __set_bit(gpio, msm_gpio.enabled_irqs);
 263        set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
 264        writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
 265        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 266}
 267
 268static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
 269{
 270        int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 271        unsigned long irq_flags;
 272        uint32_t bits;
 273
 274        spin_lock_irqsave(&tlmm_lock, irq_flags);
 275
 276        bits = readl(GPIO_INTR_CFG(gpio));
 277
 278        if (flow_type & IRQ_TYPE_EDGE_BOTH) {
 279                bits |= BIT(INTR_DECT_CTL);
 280                __irq_set_handler_locked(d->irq, handle_edge_irq);
 281                if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
 282                        __set_bit(gpio, msm_gpio.dual_edge_irqs);
 283                else
 284                        __clear_bit(gpio, msm_gpio.dual_edge_irqs);
 285        } else {
 286                bits &= ~BIT(INTR_DECT_CTL);
 287                __irq_set_handler_locked(d->irq, handle_level_irq);
 288                __clear_bit(gpio, msm_gpio.dual_edge_irqs);
 289        }
 290
 291        if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
 292                bits |= BIT(INTR_POL_CTL);
 293        else
 294                bits &= ~BIT(INTR_POL_CTL);
 295
 296        writel(bits, GPIO_INTR_CFG(gpio));
 297
 298        if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
 299                msm_gpio_update_dual_edge_pos(gpio);
 300
 301        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 302
 303        return 0;
 304}
 305
 306/*
 307 * When the summary IRQ is raised, any number of GPIO lines may be high.
 308 * It is the job of the summary handler to find all those GPIO lines
 309 * which have been set as summary IRQ lines and which are triggered,
 310 * and to call their interrupt handlers.
 311 */
 312static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
 313{
 314        unsigned long i;
 315        struct irq_chip *chip = irq_desc_get_chip(desc);
 316
 317        chained_irq_enter(chip, desc);
 318
 319        for_each_set_bit(i, msm_gpio.enabled_irqs, NR_GPIO_IRQS) {
 320                if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
 321                        generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
 322                                                           i));
 323        }
 324
 325        chained_irq_exit(chip, desc);
 326}
 327
 328static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 329{
 330        int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 331
 332        if (on) {
 333                if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
 334                        irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
 335                set_bit(gpio, msm_gpio.wake_irqs);
 336        } else {
 337                clear_bit(gpio, msm_gpio.wake_irqs);
 338                if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
 339                        irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
 340        }
 341
 342        return 0;
 343}
 344
 345static struct irq_chip msm_gpio_irq_chip = {
 346        .name           = "msmgpio",
 347        .irq_mask       = msm_gpio_irq_mask,
 348        .irq_unmask     = msm_gpio_irq_unmask,
 349        .irq_ack        = msm_gpio_irq_ack,
 350        .irq_set_type   = msm_gpio_irq_set_type,
 351        .irq_set_wake   = msm_gpio_irq_set_wake,
 352};
 353
 354static int msm_gpio_probe(struct platform_device *dev)
 355{
 356        int i, irq, ret;
 357
 358        bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
 359        bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
 360        bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
 361        msm_gpio.gpio_chip.label = dev->name;
 362        ret = gpiochip_add(&msm_gpio.gpio_chip);
 363        if (ret < 0)
 364                return ret;
 365
 366        for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
 367                irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
 368                irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
 369                                         handle_level_irq);
 370                set_irq_flags(irq, IRQF_VALID);
 371        }
 372
 373        irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
 374                                msm_summary_irq_handler);
 375        return 0;
 376}
 377
 378static int msm_gpio_remove(struct platform_device *dev)
 379{
 380        int ret = gpiochip_remove(&msm_gpio.gpio_chip);
 381
 382        if (ret < 0)
 383                return ret;
 384
 385        irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
 386
 387        return 0;
 388}
 389
 390static struct platform_driver msm_gpio_driver = {
 391        .probe = msm_gpio_probe,
 392        .remove = msm_gpio_remove,
 393        .driver = {
 394                .name = "msmgpio",
 395                .owner = THIS_MODULE,
 396        },
 397};
 398
 399static struct platform_device msm_device_gpio = {
 400        .name = "msmgpio",
 401        .id   = -1,
 402};
 403
 404static int __init msm_gpio_init(void)
 405{
 406        int rc;
 407
 408        rc = platform_driver_register(&msm_gpio_driver);
 409        if (!rc) {
 410                rc = platform_device_register(&msm_device_gpio);
 411                if (rc)
 412                        platform_driver_unregister(&msm_gpio_driver);
 413        }
 414
 415        return rc;
 416}
 417
 418static void __exit msm_gpio_exit(void)
 419{
 420        platform_device_unregister(&msm_device_gpio);
 421        platform_driver_unregister(&msm_gpio_driver);
 422}
 423
 424postcore_initcall(msm_gpio_init);
 425module_exit(msm_gpio_exit);
 426
 427MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
 428MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
 429MODULE_LICENSE("GPL v2");
 430MODULE_ALIAS("platform:msmgpio");
 431
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.