linux/arch/powerpc/platforms/4xx/gpio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * PPC4xx gpio driver
   4 *
   5 * Copyright (c) 2008 Harris Corporation
   6 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
   7 * Copyright (c) MontaVista Software, Inc. 2008.
   8 *
   9 * Author: Steve Falco <sfalco@harris.com>
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/init.h>
  14#include <linux/spinlock.h>
  15#include <linux/io.h>
  16#include <linux/of.h>
  17#include <linux/of_gpio.h>
  18#include <linux/gpio/driver.h>
  19#include <linux/types.h>
  20#include <linux/slab.h>
  21
  22#define GPIO_MASK(gpio)         (0x80000000 >> (gpio))
  23#define GPIO_MASK2(gpio)        (0xc0000000 >> ((gpio) * 2))
  24
  25/* Physical GPIO register layout */
  26struct ppc4xx_gpio {
  27        __be32 or;
  28        __be32 tcr;
  29        __be32 osrl;
  30        __be32 osrh;
  31        __be32 tsrl;
  32        __be32 tsrh;
  33        __be32 odr;
  34        __be32 ir;
  35        __be32 rr1;
  36        __be32 rr2;
  37        __be32 rr3;
  38        __be32 reserved1;
  39        __be32 isr1l;
  40        __be32 isr1h;
  41        __be32 isr2l;
  42        __be32 isr2h;
  43        __be32 isr3l;
  44        __be32 isr3h;
  45};
  46
  47struct ppc4xx_gpio_chip {
  48        struct of_mm_gpio_chip mm_gc;
  49        spinlock_t lock;
  50};
  51
  52/*
  53 * GPIO LIB API implementation for GPIOs
  54 *
  55 * There are a maximum of 32 gpios in each gpio controller.
  56 */
  57
  58static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
  59{
  60        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  61        struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
  62
  63        return !!(in_be32(&regs->ir) & GPIO_MASK(gpio));
  64}
  65
  66static inline void
  67__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  68{
  69        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  70        struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
  71
  72        if (val)
  73                setbits32(&regs->or, GPIO_MASK(gpio));
  74        else
  75                clrbits32(&regs->or, GPIO_MASK(gpio));
  76}
  77
  78static void
  79ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  80{
  81        struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
  82        unsigned long flags;
  83
  84        spin_lock_irqsave(&chip->lock, flags);
  85
  86        __ppc4xx_gpio_set(gc, gpio, val);
  87
  88        spin_unlock_irqrestore(&chip->lock, flags);
  89
  90        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
  91}
  92
  93static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
  94{
  95        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  96        struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
  97        struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
  98        unsigned long flags;
  99
 100        spin_lock_irqsave(&chip->lock, flags);
 101
 102        /* Disable open-drain function */
 103        clrbits32(&regs->odr, GPIO_MASK(gpio));
 104
 105        /* Float the pin */
 106        clrbits32(&regs->tcr, GPIO_MASK(gpio));
 107
 108        /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
 109        if (gpio < 16) {
 110                clrbits32(&regs->osrl, GPIO_MASK2(gpio));
 111                clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
 112        } else {
 113                clrbits32(&regs->osrh, GPIO_MASK2(gpio));
 114                clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
 115        }
 116
 117        spin_unlock_irqrestore(&chip->lock, flags);
 118
 119        return 0;
 120}
 121
 122static int
 123ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 124{
 125        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 126        struct ppc4xx_gpio_chip *chip = gpiochip_get_data(gc);
 127        struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
 128        unsigned long flags;
 129
 130        spin_lock_irqsave(&chip->lock, flags);
 131
 132        /* First set initial value */
 133        __ppc4xx_gpio_set(gc, gpio, val);
 134
 135        /* Disable open-drain function */
 136        clrbits32(&regs->odr, GPIO_MASK(gpio));
 137
 138        /* Drive the pin */
 139        setbits32(&regs->tcr, GPIO_MASK(gpio));
 140
 141        /* Bits 0-15 use TSRL, bits 16-31 use TSRH */
 142        if (gpio < 16) {
 143                clrbits32(&regs->osrl, GPIO_MASK2(gpio));
 144                clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
 145        } else {
 146                clrbits32(&regs->osrh, GPIO_MASK2(gpio));
 147                clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
 148        }
 149
 150        spin_unlock_irqrestore(&chip->lock, flags);
 151
 152        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
 153
 154        return 0;
 155}
 156
 157static int __init ppc4xx_add_gpiochips(void)
 158{
 159        struct device_node *np;
 160
 161        for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") {
 162                int ret;
 163                struct ppc4xx_gpio_chip *ppc4xx_gc;
 164                struct of_mm_gpio_chip *mm_gc;
 165                struct gpio_chip *gc;
 166
 167                ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
 168                if (!ppc4xx_gc) {
 169                        ret = -ENOMEM;
 170                        goto err;
 171                }
 172
 173                spin_lock_init(&ppc4xx_gc->lock);
 174
 175                mm_gc = &ppc4xx_gc->mm_gc;
 176                gc = &mm_gc->gc;
 177
 178                gc->ngpio = 32;
 179                gc->direction_input = ppc4xx_gpio_dir_in;
 180                gc->direction_output = ppc4xx_gpio_dir_out;
 181                gc->get = ppc4xx_gpio_get;
 182                gc->set = ppc4xx_gpio_set;
 183
 184                ret = of_mm_gpiochip_add_data(np, mm_gc, ppc4xx_gc);
 185                if (ret)
 186                        goto err;
 187                continue;
 188err:
 189                pr_err("%pOF: registration failed with status %d\n", np, ret);
 190                kfree(ppc4xx_gc);
 191                /* try others anyway */
 192        }
 193        return 0;
 194}
 195arch_initcall(ppc4xx_add_gpiochips);
 196