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