root/drivers/gpio/gpio-xgene.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xgene_gpio_get
  2. __xgene_gpio_set
  3. xgene_gpio_set
  4. xgene_gpio_get_direction
  5. xgene_gpio_dir_in
  6. xgene_gpio_dir_out
  7. xgene_gpio_suspend
  8. xgene_gpio_resume
  9. xgene_gpio_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * AppliedMicro X-Gene SoC GPIO Driver
   4  *
   5  * Copyright (c) 2014, Applied Micro Circuits Corporation
   6  * Author: Feng Kan <fkan@apm.com>.
   7  */
   8 
   9 #include <linux/acpi.h>
  10 #include <linux/kernel.h>
  11 #include <linux/init.h>
  12 #include <linux/io.h>
  13 #include <linux/spinlock.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/gpio/driver.h>
  16 #include <linux/types.h>
  17 #include <linux/bitops.h>
  18 
  19 #define GPIO_SET_DR_OFFSET      0x0C
  20 #define GPIO_DATA_OFFSET        0x14
  21 #define GPIO_BANK_STRIDE        0x0C
  22 
  23 #define XGENE_GPIOS_PER_BANK    16
  24 #define XGENE_MAX_GPIO_BANKS    3
  25 #define XGENE_MAX_GPIOS         (XGENE_GPIOS_PER_BANK * XGENE_MAX_GPIO_BANKS)
  26 
  27 #define GPIO_BIT_OFFSET(x)      (x % XGENE_GPIOS_PER_BANK)
  28 #define GPIO_BANK_OFFSET(x)     ((x / XGENE_GPIOS_PER_BANK) * GPIO_BANK_STRIDE)
  29 
  30 struct xgene_gpio {
  31         struct gpio_chip        chip;
  32         void __iomem            *base;
  33         spinlock_t              lock;
  34         u32                     set_dr_val[XGENE_MAX_GPIO_BANKS];
  35 };
  36 
  37 static int xgene_gpio_get(struct gpio_chip *gc, unsigned int offset)
  38 {
  39         struct xgene_gpio *chip = gpiochip_get_data(gc);
  40         unsigned long bank_offset;
  41         u32 bit_offset;
  42 
  43         bank_offset = GPIO_DATA_OFFSET + GPIO_BANK_OFFSET(offset);
  44         bit_offset = GPIO_BIT_OFFSET(offset);
  45         return !!(ioread32(chip->base + bank_offset) & BIT(bit_offset));
  46 }
  47 
  48 static void __xgene_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
  49 {
  50         struct xgene_gpio *chip = gpiochip_get_data(gc);
  51         unsigned long bank_offset;
  52         u32 setval, bit_offset;
  53 
  54         bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset);
  55         bit_offset = GPIO_BIT_OFFSET(offset) + XGENE_GPIOS_PER_BANK;
  56 
  57         setval = ioread32(chip->base + bank_offset);
  58         if (val)
  59                 setval |= BIT(bit_offset);
  60         else
  61                 setval &= ~BIT(bit_offset);
  62         iowrite32(setval, chip->base + bank_offset);
  63 }
  64 
  65 static void xgene_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
  66 {
  67         struct xgene_gpio *chip = gpiochip_get_data(gc);
  68         unsigned long flags;
  69 
  70         spin_lock_irqsave(&chip->lock, flags);
  71         __xgene_gpio_set(gc, offset, val);
  72         spin_unlock_irqrestore(&chip->lock, flags);
  73 }
  74 
  75 static int xgene_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
  76 {
  77         struct xgene_gpio *chip = gpiochip_get_data(gc);
  78         unsigned long bank_offset, bit_offset;
  79 
  80         bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset);
  81         bit_offset = GPIO_BIT_OFFSET(offset);
  82 
  83         return !!(ioread32(chip->base + bank_offset) & BIT(bit_offset));
  84 }
  85 
  86 static int xgene_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
  87 {
  88         struct xgene_gpio *chip = gpiochip_get_data(gc);
  89         unsigned long flags, bank_offset;
  90         u32 dirval, bit_offset;
  91 
  92         bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset);
  93         bit_offset = GPIO_BIT_OFFSET(offset);
  94 
  95         spin_lock_irqsave(&chip->lock, flags);
  96 
  97         dirval = ioread32(chip->base + bank_offset);
  98         dirval |= BIT(bit_offset);
  99         iowrite32(dirval, chip->base + bank_offset);
 100 
 101         spin_unlock_irqrestore(&chip->lock, flags);
 102 
 103         return 0;
 104 }
 105 
 106 static int xgene_gpio_dir_out(struct gpio_chip *gc,
 107                                         unsigned int offset, int val)
 108 {
 109         struct xgene_gpio *chip = gpiochip_get_data(gc);
 110         unsigned long flags, bank_offset;
 111         u32 dirval, bit_offset;
 112 
 113         bank_offset = GPIO_SET_DR_OFFSET + GPIO_BANK_OFFSET(offset);
 114         bit_offset = GPIO_BIT_OFFSET(offset);
 115 
 116         spin_lock_irqsave(&chip->lock, flags);
 117 
 118         dirval = ioread32(chip->base + bank_offset);
 119         dirval &= ~BIT(bit_offset);
 120         iowrite32(dirval, chip->base + bank_offset);
 121         __xgene_gpio_set(gc, offset, val);
 122 
 123         spin_unlock_irqrestore(&chip->lock, flags);
 124 
 125         return 0;
 126 }
 127 
 128 static __maybe_unused int xgene_gpio_suspend(struct device *dev)
 129 {
 130         struct xgene_gpio *gpio = dev_get_drvdata(dev);
 131         unsigned long bank_offset;
 132         unsigned int bank;
 133 
 134         for (bank = 0; bank < XGENE_MAX_GPIO_BANKS; bank++) {
 135                 bank_offset = GPIO_SET_DR_OFFSET + bank * GPIO_BANK_STRIDE;
 136                 gpio->set_dr_val[bank] = ioread32(gpio->base + bank_offset);
 137         }
 138         return 0;
 139 }
 140 
 141 static __maybe_unused int xgene_gpio_resume(struct device *dev)
 142 {
 143         struct xgene_gpio *gpio = dev_get_drvdata(dev);
 144         unsigned long bank_offset;
 145         unsigned int bank;
 146 
 147         for (bank = 0; bank < XGENE_MAX_GPIO_BANKS; bank++) {
 148                 bank_offset = GPIO_SET_DR_OFFSET + bank * GPIO_BANK_STRIDE;
 149                 iowrite32(gpio->set_dr_val[bank], gpio->base + bank_offset);
 150         }
 151         return 0;
 152 }
 153 
 154 static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume);
 155 
 156 static int xgene_gpio_probe(struct platform_device *pdev)
 157 {
 158         struct resource *res;
 159         struct xgene_gpio *gpio;
 160         int err = 0;
 161 
 162         gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
 163         if (!gpio) {
 164                 err = -ENOMEM;
 165                 goto err;
 166         }
 167 
 168         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 169         if (!res) {
 170                 err = -EINVAL;
 171                 goto err;
 172         }
 173 
 174         gpio->base = devm_ioremap_nocache(&pdev->dev, res->start,
 175                                                         resource_size(res));
 176         if (!gpio->base) {
 177                 err = -ENOMEM;
 178                 goto err;
 179         }
 180 
 181         gpio->chip.ngpio = XGENE_MAX_GPIOS;
 182 
 183         spin_lock_init(&gpio->lock);
 184         gpio->chip.parent = &pdev->dev;
 185         gpio->chip.get_direction = xgene_gpio_get_direction;
 186         gpio->chip.direction_input = xgene_gpio_dir_in;
 187         gpio->chip.direction_output = xgene_gpio_dir_out;
 188         gpio->chip.get = xgene_gpio_get;
 189         gpio->chip.set = xgene_gpio_set;
 190         gpio->chip.label = dev_name(&pdev->dev);
 191         gpio->chip.base = -1;
 192 
 193         platform_set_drvdata(pdev, gpio);
 194 
 195         err = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
 196         if (err) {
 197                 dev_err(&pdev->dev,
 198                         "failed to register gpiochip.\n");
 199                 goto err;
 200         }
 201 
 202         dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n");
 203         return 0;
 204 err:
 205         dev_err(&pdev->dev, "X-Gene GPIO driver registration failed.\n");
 206         return err;
 207 }
 208 
 209 static const struct of_device_id xgene_gpio_of_match[] = {
 210         { .compatible = "apm,xgene-gpio", },
 211         {},
 212 };
 213 
 214 #ifdef CONFIG_ACPI
 215 static const struct acpi_device_id xgene_gpio_acpi_match[] = {
 216         { "APMC0D14", 0 },
 217         { },
 218 };
 219 #endif
 220 
 221 static struct platform_driver xgene_gpio_driver = {
 222         .driver = {
 223                 .name = "xgene-gpio",
 224                 .of_match_table = xgene_gpio_of_match,
 225                 .acpi_match_table = ACPI_PTR(xgene_gpio_acpi_match),
 226                 .pm     = &xgene_gpio_pm,
 227         },
 228         .probe = xgene_gpio_probe,
 229 };
 230 builtin_platform_driver(xgene_gpio_driver);

/* [<][>][^][v][top][bottom][index][help] */