Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Timberdale FPGA GPIO driver
0004  * Author: Mocean Laboratories
0005  * Copyright (c) 2009 Intel Corporation
0006  */
0007 
0008 /* Supports:
0009  * Timberdale FPGA GPIO
0010  */
0011 
0012 #include <linux/init.h>
0013 #include <linux/gpio/driver.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/irq.h>
0016 #include <linux/io.h>
0017 #include <linux/timb_gpio.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/slab.h>
0020 
0021 #define DRIVER_NAME "timb-gpio"
0022 
0023 #define TGPIOVAL    0x00
0024 #define TGPIODIR    0x04
0025 #define TGPIO_IER   0x08
0026 #define TGPIO_ISR   0x0c
0027 #define TGPIO_IPR   0x10
0028 #define TGPIO_ICR   0x14
0029 #define TGPIO_FLR   0x18
0030 #define TGPIO_LVR   0x1c
0031 #define TGPIO_VER   0x20
0032 #define TGPIO_BFLR  0x24
0033 
0034 struct timbgpio {
0035     void __iomem        *membase;
0036     spinlock_t      lock; /* mutual exclusion */
0037     struct gpio_chip    gpio;
0038     int         irq_base;
0039     unsigned long       last_ier;
0040 };
0041 
0042 static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
0043     unsigned offset, bool enabled)
0044 {
0045     struct timbgpio *tgpio = gpiochip_get_data(gpio);
0046     u32 reg;
0047 
0048     spin_lock(&tgpio->lock);
0049     reg = ioread32(tgpio->membase + offset);
0050 
0051     if (enabled)
0052         reg |= (1 << index);
0053     else
0054         reg &= ~(1 << index);
0055 
0056     iowrite32(reg, tgpio->membase + offset);
0057     spin_unlock(&tgpio->lock);
0058 
0059     return 0;
0060 }
0061 
0062 static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
0063 {
0064     return timbgpio_update_bit(gpio, nr, TGPIODIR, true);
0065 }
0066 
0067 static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
0068 {
0069     struct timbgpio *tgpio = gpiochip_get_data(gpio);
0070     u32 value;
0071 
0072     value = ioread32(tgpio->membase + TGPIOVAL);
0073     return (value & (1 << nr)) ? 1 : 0;
0074 }
0075 
0076 static int timbgpio_gpio_direction_output(struct gpio_chip *gpio,
0077                         unsigned nr, int val)
0078 {
0079     return timbgpio_update_bit(gpio, nr, TGPIODIR, false);
0080 }
0081 
0082 static void timbgpio_gpio_set(struct gpio_chip *gpio,
0083                 unsigned nr, int val)
0084 {
0085     timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0);
0086 }
0087 
0088 static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
0089 {
0090     struct timbgpio *tgpio = gpiochip_get_data(gpio);
0091 
0092     if (tgpio->irq_base <= 0)
0093         return -EINVAL;
0094 
0095     return tgpio->irq_base + offset;
0096 }
0097 
0098 /*
0099  * GPIO IRQ
0100  */
0101 static void timbgpio_irq_disable(struct irq_data *d)
0102 {
0103     struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
0104     int offset = d->irq - tgpio->irq_base;
0105     unsigned long flags;
0106 
0107     spin_lock_irqsave(&tgpio->lock, flags);
0108     tgpio->last_ier &= ~(1UL << offset);
0109     iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
0110     spin_unlock_irqrestore(&tgpio->lock, flags);
0111 }
0112 
0113 static void timbgpio_irq_enable(struct irq_data *d)
0114 {
0115     struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
0116     int offset = d->irq - tgpio->irq_base;
0117     unsigned long flags;
0118 
0119     spin_lock_irqsave(&tgpio->lock, flags);
0120     tgpio->last_ier |= 1UL << offset;
0121     iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
0122     spin_unlock_irqrestore(&tgpio->lock, flags);
0123 }
0124 
0125 static int timbgpio_irq_type(struct irq_data *d, unsigned trigger)
0126 {
0127     struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
0128     int offset = d->irq - tgpio->irq_base;
0129     unsigned long flags;
0130     u32 lvr, flr, bflr = 0;
0131     u32 ver;
0132     int ret = 0;
0133 
0134     if (offset < 0 || offset > tgpio->gpio.ngpio)
0135         return -EINVAL;
0136 
0137     ver = ioread32(tgpio->membase + TGPIO_VER);
0138 
0139     spin_lock_irqsave(&tgpio->lock, flags);
0140 
0141     lvr = ioread32(tgpio->membase + TGPIO_LVR);
0142     flr = ioread32(tgpio->membase + TGPIO_FLR);
0143     if (ver > 2)
0144         bflr = ioread32(tgpio->membase + TGPIO_BFLR);
0145 
0146     if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
0147         bflr &= ~(1 << offset);
0148         flr &= ~(1 << offset);
0149         if (trigger & IRQ_TYPE_LEVEL_HIGH)
0150             lvr |= 1 << offset;
0151         else
0152             lvr &= ~(1 << offset);
0153     }
0154 
0155     if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
0156         if (ver < 3) {
0157             ret = -EINVAL;
0158             goto out;
0159         } else {
0160             flr |= 1 << offset;
0161             bflr |= 1 << offset;
0162         }
0163     } else {
0164         bflr &= ~(1 << offset);
0165         flr |= 1 << offset;
0166         if (trigger & IRQ_TYPE_EDGE_FALLING)
0167             lvr &= ~(1 << offset);
0168         else
0169             lvr |= 1 << offset;
0170     }
0171 
0172     iowrite32(lvr, tgpio->membase + TGPIO_LVR);
0173     iowrite32(flr, tgpio->membase + TGPIO_FLR);
0174     if (ver > 2)
0175         iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
0176 
0177     iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
0178 
0179 out:
0180     spin_unlock_irqrestore(&tgpio->lock, flags);
0181     return ret;
0182 }
0183 
0184 static void timbgpio_irq(struct irq_desc *desc)
0185 {
0186     struct timbgpio *tgpio = irq_desc_get_handler_data(desc);
0187     struct irq_data *data = irq_desc_get_irq_data(desc);
0188     unsigned long ipr;
0189     int offset;
0190 
0191     data->chip->irq_ack(data);
0192     ipr = ioread32(tgpio->membase + TGPIO_IPR);
0193     iowrite32(ipr, tgpio->membase + TGPIO_ICR);
0194 
0195     /*
0196      * Some versions of the hardware trash the IER register if more than
0197      * one interrupt is received simultaneously.
0198      */
0199     iowrite32(0, tgpio->membase + TGPIO_IER);
0200 
0201     for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio)
0202         generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
0203 
0204     iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
0205 }
0206 
0207 static struct irq_chip timbgpio_irqchip = {
0208     .name       = "GPIO",
0209     .irq_enable = timbgpio_irq_enable,
0210     .irq_disable    = timbgpio_irq_disable,
0211     .irq_set_type   = timbgpio_irq_type,
0212 };
0213 
0214 static int timbgpio_probe(struct platform_device *pdev)
0215 {
0216     int err, i;
0217     struct device *dev = &pdev->dev;
0218     struct gpio_chip *gc;
0219     struct timbgpio *tgpio;
0220     struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
0221     int irq = platform_get_irq(pdev, 0);
0222 
0223     if (!pdata || pdata->nr_pins > 32) {
0224         dev_err(dev, "Invalid platform data\n");
0225         return -EINVAL;
0226     }
0227 
0228     tgpio = devm_kzalloc(dev, sizeof(*tgpio), GFP_KERNEL);
0229     if (!tgpio)
0230         return -EINVAL;
0231 
0232     tgpio->irq_base = pdata->irq_base;
0233 
0234     spin_lock_init(&tgpio->lock);
0235 
0236     tgpio->membase = devm_platform_ioremap_resource(pdev, 0);
0237     if (IS_ERR(tgpio->membase))
0238         return PTR_ERR(tgpio->membase);
0239 
0240     gc = &tgpio->gpio;
0241 
0242     gc->label = dev_name(&pdev->dev);
0243     gc->owner = THIS_MODULE;
0244     gc->parent = &pdev->dev;
0245     gc->direction_input = timbgpio_gpio_direction_input;
0246     gc->get = timbgpio_gpio_get;
0247     gc->direction_output = timbgpio_gpio_direction_output;
0248     gc->set = timbgpio_gpio_set;
0249     gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL;
0250     gc->dbg_show = NULL;
0251     gc->base = pdata->gpio_base;
0252     gc->ngpio = pdata->nr_pins;
0253     gc->can_sleep = false;
0254 
0255     err = devm_gpiochip_add_data(&pdev->dev, gc, tgpio);
0256     if (err)
0257         return err;
0258 
0259     platform_set_drvdata(pdev, tgpio);
0260 
0261     /* make sure to disable interrupts */
0262     iowrite32(0x0, tgpio->membase + TGPIO_IER);
0263 
0264     if (irq < 0 || tgpio->irq_base <= 0)
0265         return 0;
0266 
0267     for (i = 0; i < pdata->nr_pins; i++) {
0268         irq_set_chip_and_handler(tgpio->irq_base + i,
0269             &timbgpio_irqchip, handle_simple_irq);
0270         irq_set_chip_data(tgpio->irq_base + i, tgpio);
0271         irq_clear_status_flags(tgpio->irq_base + i, IRQ_NOREQUEST | IRQ_NOPROBE);
0272     }
0273 
0274     irq_set_chained_handler_and_data(irq, timbgpio_irq, tgpio);
0275 
0276     return 0;
0277 }
0278 
0279 static struct platform_driver timbgpio_platform_driver = {
0280     .driver = {
0281         .name           = DRIVER_NAME,
0282         .suppress_bind_attrs    = true,
0283     },
0284     .probe      = timbgpio_probe,
0285 };
0286 
0287 /*--------------------------------------------------------------------------*/
0288 
0289 builtin_platform_driver(timbgpio_platform_driver);