root/drivers/gpio/gpio-tqmx86.c

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

DEFINITIONS

This source file includes following definitions.
  1. tqmx86_gpio_read
  2. tqmx86_gpio_write
  3. tqmx86_gpio_get
  4. tqmx86_gpio_set
  5. tqmx86_gpio_direction_input
  6. tqmx86_gpio_direction_output
  7. tqmx86_gpio_get_direction
  8. tqmx86_gpio_irq_mask
  9. tqmx86_gpio_irq_unmask
  10. tqmx86_gpio_irq_set_type
  11. tqmx86_gpio_irq_handler
  12. tqmx86_gpio_runtime_suspend
  13. tqmx86_gpio_runtime_resume
  14. tqmx86_init_irq_valid_mask
  15. tqmx86_gpio_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * TQ-Systems TQMx86 PLD GPIO driver
   4  *
   5  * Based on vendor driver by:
   6  *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
   7  */
   8 
   9 #include <linux/bitops.h>
  10 #include <linux/errno.h>
  11 #include <linux/gpio/driver.h>
  12 #include <linux/init.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/pm_runtime.h>
  18 #include <linux/slab.h>
  19 
  20 #define TQMX86_NGPIO    8
  21 #define TQMX86_NGPO     4       /* 0-3 - output */
  22 #define TQMX86_NGPI     4       /* 4-7 - input */
  23 #define TQMX86_DIR_INPUT_MASK   0xf0    /* 0-3 - output, 4-7 - input */
  24 
  25 #define TQMX86_GPIODD   0       /* GPIO Data Direction Register */
  26 #define TQMX86_GPIOD    1       /* GPIO Data Register */
  27 #define TQMX86_GPIIC    3       /* GPI Interrupt Configuration Register */
  28 #define TQMX86_GPIIS    4       /* GPI Interrupt Status Register */
  29 
  30 #define TQMX86_GPII_FALLING     BIT(0)
  31 #define TQMX86_GPII_RISING      BIT(1)
  32 #define TQMX86_GPII_MASK        (BIT(0) | BIT(1))
  33 #define TQMX86_GPII_BITS        2
  34 
  35 struct tqmx86_gpio_data {
  36         struct gpio_chip        chip;
  37         struct irq_chip         irq_chip;
  38         void __iomem            *io_base;
  39         int                     irq;
  40         raw_spinlock_t          spinlock;
  41         u8                      irq_type[TQMX86_NGPI];
  42 };
  43 
  44 static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
  45 {
  46         return ioread8(gd->io_base + reg);
  47 }
  48 
  49 static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
  50                               unsigned int reg)
  51 {
  52         iowrite8(val, gd->io_base + reg);
  53 }
  54 
  55 static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
  56 {
  57         struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
  58 
  59         return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
  60 }
  61 
  62 static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
  63                             int value)
  64 {
  65         struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
  66         unsigned long flags;
  67         u8 val;
  68 
  69         raw_spin_lock_irqsave(&gpio->spinlock, flags);
  70         val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
  71         if (value)
  72                 val |= BIT(offset);
  73         else
  74                 val &= ~BIT(offset);
  75         tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
  76         raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
  77 }
  78 
  79 static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
  80                                        unsigned int offset)
  81 {
  82         /* Direction cannot be changed. Validate is an input. */
  83         if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
  84                 return 0;
  85         else
  86                 return -EINVAL;
  87 }
  88 
  89 static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
  90                                         unsigned int offset,
  91                                         int value)
  92 {
  93         /* Direction cannot be changed, validate is an output */
  94         if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
  95                 return -EINVAL;
  96 
  97         tqmx86_gpio_set(chip, offset, value);
  98         return 0;
  99 }
 100 
 101 static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
 102                                      unsigned int offset)
 103 {
 104         return !!(TQMX86_DIR_INPUT_MASK & BIT(offset));
 105 }
 106 
 107 static void tqmx86_gpio_irq_mask(struct irq_data *data)
 108 {
 109         unsigned int offset = (data->hwirq - TQMX86_NGPO);
 110         struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 111                 irq_data_get_irq_chip_data(data));
 112         unsigned long flags;
 113         u8 gpiic, mask;
 114 
 115         mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 116 
 117         raw_spin_lock_irqsave(&gpio->spinlock, flags);
 118         gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 119         gpiic &= ~mask;
 120         tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 121         raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 122 }
 123 
 124 static void tqmx86_gpio_irq_unmask(struct irq_data *data)
 125 {
 126         unsigned int offset = (data->hwirq - TQMX86_NGPO);
 127         struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 128                 irq_data_get_irq_chip_data(data));
 129         unsigned long flags;
 130         u8 gpiic, mask;
 131 
 132         mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 133 
 134         raw_spin_lock_irqsave(&gpio->spinlock, flags);
 135         gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 136         gpiic &= ~mask;
 137         gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
 138         tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 139         raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 140 }
 141 
 142 static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
 143 {
 144         struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 145                 irq_data_get_irq_chip_data(data));
 146         unsigned int offset = (data->hwirq - TQMX86_NGPO);
 147         unsigned int edge_type = type & IRQF_TRIGGER_MASK;
 148         unsigned long flags;
 149         u8 new_type, gpiic;
 150 
 151         switch (edge_type) {
 152         case IRQ_TYPE_EDGE_RISING:
 153                 new_type = TQMX86_GPII_RISING;
 154                 break;
 155         case IRQ_TYPE_EDGE_FALLING:
 156                 new_type = TQMX86_GPII_FALLING;
 157                 break;
 158         case IRQ_TYPE_EDGE_BOTH:
 159                 new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
 160                 break;
 161         default:
 162                 return -EINVAL; /* not supported */
 163         }
 164 
 165         gpio->irq_type[offset] = new_type;
 166 
 167         raw_spin_lock_irqsave(&gpio->spinlock, flags);
 168         gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 169         gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
 170         gpiic |= new_type << (offset * TQMX86_GPII_BITS);
 171         tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 172         raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 173 
 174         return 0;
 175 }
 176 
 177 static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
 178 {
 179         struct gpio_chip *chip = irq_desc_get_handler_data(desc);
 180         struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 181         struct irq_chip *irq_chip = irq_desc_get_chip(desc);
 182         unsigned long irq_bits;
 183         int i = 0, child_irq;
 184         u8 irq_status;
 185 
 186         chained_irq_enter(irq_chip, desc);
 187 
 188         irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 189         tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 190 
 191         irq_bits = irq_status;
 192         for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
 193                 child_irq = irq_find_mapping(gpio->chip.irq.domain,
 194                                              i + TQMX86_NGPO);
 195                 generic_handle_irq(child_irq);
 196         }
 197 
 198         chained_irq_exit(irq_chip, desc);
 199 }
 200 
 201 /* Minimal runtime PM is needed by the IRQ subsystem */
 202 static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
 203 {
 204         return 0;
 205 }
 206 
 207 static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)
 208 {
 209         return 0;
 210 }
 211 
 212 static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
 213         SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,
 214                            tqmx86_gpio_runtime_resume, NULL)
 215 };
 216 
 217 static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
 218                                        unsigned long *valid_mask,
 219                                        unsigned int ngpios)
 220 {
 221         /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
 222         clear_bit(0, valid_mask);
 223         clear_bit(1, valid_mask);
 224         clear_bit(2, valid_mask);
 225         clear_bit(3, valid_mask);
 226 }
 227 
 228 static int tqmx86_gpio_probe(struct platform_device *pdev)
 229 {
 230         struct device *dev = &pdev->dev;
 231         struct tqmx86_gpio_data *gpio;
 232         struct gpio_chip *chip;
 233         struct gpio_irq_chip *girq;
 234         void __iomem *io_base;
 235         struct resource *res;
 236         int ret, irq;
 237 
 238         irq = platform_get_irq(pdev, 0);
 239         if (irq < 0)
 240                 return irq;
 241 
 242         res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 243         if (!res) {
 244                 dev_err(&pdev->dev, "Cannot get I/O\n");
 245                 return -ENODEV;
 246         }
 247 
 248         io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
 249         if (!io_base)
 250                 return -ENOMEM;
 251 
 252         gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 253         if (!gpio)
 254                 return -ENOMEM;
 255 
 256         raw_spin_lock_init(&gpio->spinlock);
 257         gpio->io_base = io_base;
 258 
 259         tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
 260 
 261         platform_set_drvdata(pdev, gpio);
 262 
 263         chip = &gpio->chip;
 264         chip->label = "gpio-tqmx86";
 265         chip->owner = THIS_MODULE;
 266         chip->can_sleep = false;
 267         chip->base = -1;
 268         chip->direction_input = tqmx86_gpio_direction_input;
 269         chip->direction_output = tqmx86_gpio_direction_output;
 270         chip->get_direction = tqmx86_gpio_get_direction;
 271         chip->get = tqmx86_gpio_get;
 272         chip->set = tqmx86_gpio_set;
 273         chip->ngpio = TQMX86_NGPIO;
 274         chip->parent = pdev->dev.parent;
 275 
 276         pm_runtime_enable(&pdev->dev);
 277 
 278         if (irq) {
 279                 struct irq_chip *irq_chip = &gpio->irq_chip;
 280                 u8 irq_status;
 281 
 282                 irq_chip->name = chip->label;
 283                 irq_chip->parent_device = &pdev->dev;
 284                 irq_chip->irq_mask = tqmx86_gpio_irq_mask;
 285                 irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
 286                 irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
 287 
 288                 /* Mask all interrupts */
 289                 tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
 290 
 291                 /* Clear all pending interrupts */
 292                 irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 293                 tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 294 
 295                 girq = &chip->irq;
 296                 girq->chip = irq_chip;
 297                 girq->parent_handler = tqmx86_gpio_irq_handler;
 298                 girq->num_parents = 1;
 299                 girq->parents = devm_kcalloc(&pdev->dev, 1,
 300                                              sizeof(*girq->parents),
 301                                              GFP_KERNEL);
 302                 if (!girq->parents) {
 303                         ret = -ENOMEM;
 304                         goto out_pm_dis;
 305                 }
 306                 girq->parents[0] = irq;
 307                 girq->default_type = IRQ_TYPE_NONE;
 308                 girq->handler = handle_simple_irq;
 309                 girq->init_valid_mask = tqmx86_init_irq_valid_mask;
 310         }
 311 
 312         ret = devm_gpiochip_add_data(dev, chip, gpio);
 313         if (ret) {
 314                 dev_err(dev, "Could not register GPIO chip\n");
 315                 goto out_pm_dis;
 316         }
 317 
 318         dev_info(dev, "GPIO functionality initialized with %d pins\n",
 319                  chip->ngpio);
 320 
 321         return 0;
 322 
 323 out_pm_dis:
 324         pm_runtime_disable(&pdev->dev);
 325 
 326         return ret;
 327 }
 328 
 329 static struct platform_driver tqmx86_gpio_driver = {
 330         .driver = {
 331                 .name = "tqmx86-gpio",
 332                 .pm = &tqmx86_gpio_dev_pm_ops,
 333         },
 334         .probe          = tqmx86_gpio_probe,
 335 };
 336 
 337 module_platform_driver(tqmx86_gpio_driver);
 338 
 339 MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
 340 MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 341 MODULE_LICENSE("GPL");
 342 MODULE_ALIAS("platform:tqmx86-gpio");

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