linux/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
<<
>>
Prefs
   1/*
   2 * MPC5200 General Purpose Timer device driver
   3 *
   4 * Copyright (c) 2009 Secret Lab Technologies Ltd.
   5 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
   6 *
   7 * This program is free software; you can redistribute  it and/or modify it
   8 * under  the terms of  the GNU General  Public License as published by the
   9 * Free Software Foundation;  either version 2 of the  License, or (at your
  10 * option) any later version.
  11 *
  12 * This file is a driver for the the General Purpose Timer (gpt) devices
  13 * found on the MPC5200 SoC.  Each timer has an IO pin which can be used
  14 * for GPIO or can be used to raise interrupts.  The timer function can
  15 * be used independently from the IO pin, or it can be used to control
  16 * output signals or measure input signals.
  17 *
  18 * This driver supports the GPIO and IRQ controller functions of the GPT
  19 * device.  Timer functions are not yet supported, nor is the watchdog
  20 * timer.
  21 *
  22 * To use the GPIO function, the following two properties must be added
  23 * to the device tree node for the gpt device (typically in the .dts file
  24 * for the board):
  25 *      gpio-controller;
  26 *      #gpio-cells = < 2 >;
  27 * This driver will register the GPIO pin if it finds the gpio-controller
  28 * property in the device tree.
  29 *
  30 * To use the IRQ controller function, the following two properties must
  31 * be added to the device tree node for the gpt device:
  32 *      interrupt-controller;
  33 *      #interrupt-cells = < 1 >;
  34 * The IRQ controller binding only uses one cell to specify the interrupt,
  35 * and the IRQ flags are encoded in the cell.  A cell is not used to encode
  36 * the IRQ number because the GPT only has a single IRQ source.  For flags,
  37 * a value of '1' means rising edge sensitive and '2' means falling edge.
  38 *
  39 * The GPIO and the IRQ controller functions can be used at the same time,
  40 * but in this use case the IO line will only work as an input.  Trying to
  41 * use it as a GPIO output will not work.
  42 *
  43 * When using the GPIO line as an output, it can either be driven as normal
  44 * IO, or it can be an Open Collector (OC) output.  At the moment it is the
  45 * responsibility of either the bootloader or the platform setup code to set
  46 * the output mode.  This driver does not change the output mode setting.
  47 */
  48
  49#include <linux/irq.h>
  50#include <linux/interrupt.h>
  51#include <linux/io.h>
  52#include <linux/of.h>
  53#include <linux/of_platform.h>
  54#include <linux/of_gpio.h>
  55#include <linux/kernel.h>
  56#include <asm/mpc52xx.h>
  57
  58MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
  59MODULE_AUTHOR("Sascha Hauer, Grant Likely");
  60MODULE_LICENSE("GPL");
  61
  62/**
  63 * struct mpc52xx_gpt - Private data structure for MPC52xx GPT driver
  64 * @dev: pointer to device structure
  65 * @regs: virtual address of GPT registers
  66 * @lock: spinlock to coordinate between different functions.
  67 * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
  68 * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
  69 */
  70struct mpc52xx_gpt_priv {
  71        struct device *dev;
  72        struct mpc52xx_gpt __iomem *regs;
  73        spinlock_t lock;
  74        struct irq_host *irqhost;
  75
  76#if defined(CONFIG_GPIOLIB)
  77        struct of_gpio_chip of_gc;
  78#endif
  79};
  80
  81#define MPC52xx_GPT_MODE_MS_MASK        (0x07)
  82#define MPC52xx_GPT_MODE_MS_IC          (0x01)
  83#define MPC52xx_GPT_MODE_MS_OC          (0x02)
  84#define MPC52xx_GPT_MODE_MS_PWM         (0x03)
  85#define MPC52xx_GPT_MODE_MS_GPIO        (0x04)
  86
  87#define MPC52xx_GPT_MODE_GPIO_MASK      (0x30)
  88#define MPC52xx_GPT_MODE_GPIO_OUT_LOW   (0x20)
  89#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH  (0x30)
  90
  91#define MPC52xx_GPT_MODE_IRQ_EN         (0x0100)
  92
  93#define MPC52xx_GPT_MODE_ICT_MASK       (0x030000)
  94#define MPC52xx_GPT_MODE_ICT_RISING     (0x010000)
  95#define MPC52xx_GPT_MODE_ICT_FALLING    (0x020000)
  96#define MPC52xx_GPT_MODE_ICT_TOGGLE     (0x030000)
  97
  98#define MPC52xx_GPT_STATUS_IRQMASK      (0x000f)
  99
 100/* ---------------------------------------------------------------------
 101 * Cascaded interrupt controller hooks
 102 */
 103
 104static void mpc52xx_gpt_irq_unmask(unsigned int virq)
 105{
 106        struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
 107        unsigned long flags;
 108
 109        spin_lock_irqsave(&gpt->lock, flags);
 110        setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
 111        spin_unlock_irqrestore(&gpt->lock, flags);
 112}
 113
 114static void mpc52xx_gpt_irq_mask(unsigned int virq)
 115{
 116        struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
 117        unsigned long flags;
 118
 119        spin_lock_irqsave(&gpt->lock, flags);
 120        clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
 121        spin_unlock_irqrestore(&gpt->lock, flags);
 122}
 123
 124static void mpc52xx_gpt_irq_ack(unsigned int virq)
 125{
 126        struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
 127
 128        out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
 129}
 130
 131static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
 132{
 133        struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
 134        unsigned long flags;
 135        u32 reg;
 136
 137        dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
 138
 139        spin_lock_irqsave(&gpt->lock, flags);
 140        reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
 141        if (flow_type & IRQF_TRIGGER_RISING)
 142                reg |= MPC52xx_GPT_MODE_ICT_RISING;
 143        if (flow_type & IRQF_TRIGGER_FALLING)
 144                reg |= MPC52xx_GPT_MODE_ICT_FALLING;
 145        out_be32(&gpt->regs->mode, reg);
 146        spin_unlock_irqrestore(&gpt->lock, flags);
 147
 148        return 0;
 149}
 150
 151static struct irq_chip mpc52xx_gpt_irq_chip = {
 152        .typename = "MPC52xx GPT",
 153        .unmask = mpc52xx_gpt_irq_unmask,
 154        .mask = mpc52xx_gpt_irq_mask,
 155        .ack = mpc52xx_gpt_irq_ack,
 156        .set_type = mpc52xx_gpt_irq_set_type,
 157};
 158
 159void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
 160{
 161        struct mpc52xx_gpt_priv *gpt = get_irq_data(virq);
 162        int sub_virq;
 163        u32 status;
 164
 165        status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK;
 166        if (status) {
 167                sub_virq = irq_linear_revmap(gpt->irqhost, 0);
 168                generic_handle_irq(sub_virq);
 169        }
 170}
 171
 172static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
 173                               irq_hw_number_t hw)
 174{
 175        struct mpc52xx_gpt_priv *gpt = h->host_data;
 176
 177        dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq);
 178        set_irq_chip_data(virq, gpt);
 179        set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
 180
 181        return 0;
 182}
 183
 184static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
 185                                 u32 *intspec, unsigned int intsize,
 186                                 irq_hw_number_t *out_hwirq,
 187                                 unsigned int *out_flags)
 188{
 189        struct mpc52xx_gpt_priv *gpt = h->host_data;
 190
 191        dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
 192
 193        if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) {
 194                dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name);
 195                return -EINVAL;
 196        }
 197
 198        *out_hwirq = 0; /* The GPT only has 1 IRQ line */
 199        *out_flags = intspec[0];
 200
 201        return 0;
 202}
 203
 204static struct irq_host_ops mpc52xx_gpt_irq_ops = {
 205        .map = mpc52xx_gpt_irq_map,
 206        .xlate = mpc52xx_gpt_irq_xlate,
 207};
 208
 209static void
 210mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 211{
 212        int cascade_virq;
 213        unsigned long flags;
 214
 215        /* Only setup cascaded IRQ if device tree claims the GPT is
 216         * an interrupt controller */
 217        if (!of_find_property(node, "interrupt-controller", NULL))
 218                return;
 219
 220        cascade_virq = irq_of_parse_and_map(node, 0);
 221
 222        gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
 223                                      &mpc52xx_gpt_irq_ops, -1);
 224        if (!gpt->irqhost) {
 225                dev_err(gpt->dev, "irq_alloc_host() failed\n");
 226                return;
 227        }
 228
 229        gpt->irqhost->host_data = gpt;
 230
 231        set_irq_data(cascade_virq, gpt);
 232        set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
 233
 234        /* Set to Input Capture mode */
 235        spin_lock_irqsave(&gpt->lock, flags);
 236        clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
 237                        MPC52xx_GPT_MODE_MS_IC);
 238        spin_unlock_irqrestore(&gpt->lock, flags);
 239
 240        dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
 241}
 242
 243
 244/* ---------------------------------------------------------------------
 245 * GPIOLIB hooks
 246 */
 247#if defined(CONFIG_GPIOLIB)
 248static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
 249{
 250        return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
 251}
 252
 253static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 254{
 255        struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
 256
 257        return (in_be32(&gpt->regs->status) >> 8) & 1;
 258}
 259
 260static void
 261mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
 262{
 263        struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
 264        unsigned long flags;
 265        u32 r;
 266
 267        dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
 268        r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
 269
 270        spin_lock_irqsave(&gpt->lock, flags);
 271        clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
 272        spin_unlock_irqrestore(&gpt->lock, flags);
 273}
 274
 275static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 276{
 277        struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
 278        unsigned long flags;
 279
 280        dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
 281
 282        spin_lock_irqsave(&gpt->lock, flags);
 283        clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
 284        spin_unlock_irqrestore(&gpt->lock, flags);
 285
 286        return 0;
 287}
 288
 289static int
 290mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 291{
 292        mpc52xx_gpt_gpio_set(gc, gpio, val);
 293        return 0;
 294}
 295
 296static void
 297mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 298{
 299        int rc;
 300
 301        /* Only setup GPIO if the device tree claims the GPT is
 302         * a GPIO controller */
 303        if (!of_find_property(node, "gpio-controller", NULL))
 304                return;
 305
 306        gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
 307        if (!gpt->of_gc.gc.label) {
 308                dev_err(gpt->dev, "out of memory\n");
 309                return;
 310        }
 311
 312        gpt->of_gc.gpio_cells = 2;
 313        gpt->of_gc.gc.ngpio = 1;
 314        gpt->of_gc.gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
 315        gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
 316        gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
 317        gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
 318        gpt->of_gc.gc.base = -1;
 319        gpt->of_gc.xlate = of_gpio_simple_xlate;
 320        node->data = &gpt->of_gc;
 321        of_node_get(node);
 322
 323        /* Setup external pin in GPIO mode */
 324        clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
 325                        MPC52xx_GPT_MODE_MS_GPIO);
 326
 327        rc = gpiochip_add(&gpt->of_gc.gc);
 328        if (rc)
 329                dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
 330
 331        dev_dbg(gpt->dev, "%s() complete.\n", __func__);
 332}
 333#else /* defined(CONFIG_GPIOLIB) */
 334static void
 335mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { }
 336#endif /* defined(CONFIG_GPIOLIB) */
 337
 338/* ---------------------------------------------------------------------
 339 * of_platform bus binding code
 340 */
 341static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
 342                                       const struct of_device_id *match)
 343{
 344        struct mpc52xx_gpt_priv *gpt;
 345
 346        gpt = kzalloc(sizeof *gpt, GFP_KERNEL);
 347        if (!gpt)
 348                return -ENOMEM;
 349
 350        spin_lock_init(&gpt->lock);
 351        gpt->dev = &ofdev->dev;
 352        gpt->regs = of_iomap(ofdev->node, 0);
 353        if (!gpt->regs) {
 354                kfree(gpt);
 355                return -ENOMEM;
 356        }
 357
 358        dev_set_drvdata(&ofdev->dev, gpt);
 359
 360        mpc52xx_gpt_gpio_setup(gpt, ofdev->node);
 361        mpc52xx_gpt_irq_setup(gpt, ofdev->node);
 362
 363        return 0;
 364}
 365
 366static int mpc52xx_gpt_remove(struct of_device *ofdev)
 367{
 368        return -EBUSY;
 369}
 370
 371static const struct of_device_id mpc52xx_gpt_match[] = {
 372        { .compatible = "fsl,mpc5200-gpt", },
 373
 374        /* Depreciated compatible values; don't use for new dts files */
 375        { .compatible = "fsl,mpc5200-gpt-gpio", },
 376        { .compatible = "mpc5200-gpt", },
 377        {}
 378};
 379
 380static struct of_platform_driver mpc52xx_gpt_driver = {
 381        .name = "mpc52xx-gpt",
 382        .match_table = mpc52xx_gpt_match,
 383        .probe = mpc52xx_gpt_probe,
 384        .remove = mpc52xx_gpt_remove,
 385};
 386
 387static int __init mpc52xx_gpt_init(void)
 388{
 389        if (of_register_platform_driver(&mpc52xx_gpt_driver))
 390                pr_err("error registering MPC52xx GPT driver\n");
 391
 392        return 0;
 393}
 394
 395/* Make sure GPIOs and IRQs get set up before anyone tries to use them */
 396subsys_initcall(mpc52xx_gpt_init);
 397