Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Copyright 2017-2018 Cadence
0005  *
0006  * Authors:
0007  *  Jan Kotas <jank@cadence.com>
0008  *  Boris Brezillon <boris.brezillon@free-electrons.com>
0009  */
0010 
0011 #include <linux/gpio/driver.h>
0012 #include <linux/clk.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/spinlock.h>
0018 
0019 #define CDNS_GPIO_BYPASS_MODE       0x00
0020 #define CDNS_GPIO_DIRECTION_MODE    0x04
0021 #define CDNS_GPIO_OUTPUT_EN     0x08
0022 #define CDNS_GPIO_OUTPUT_VALUE      0x0c
0023 #define CDNS_GPIO_INPUT_VALUE       0x10
0024 #define CDNS_GPIO_IRQ_MASK      0x14
0025 #define CDNS_GPIO_IRQ_EN        0x18
0026 #define CDNS_GPIO_IRQ_DIS       0x1c
0027 #define CDNS_GPIO_IRQ_STATUS        0x20
0028 #define CDNS_GPIO_IRQ_TYPE      0x24
0029 #define CDNS_GPIO_IRQ_VALUE     0x28
0030 #define CDNS_GPIO_IRQ_ANY_EDGE      0x2c
0031 
0032 struct cdns_gpio_chip {
0033     struct gpio_chip gc;
0034     struct clk *pclk;
0035     void __iomem *regs;
0036     u32 bypass_orig;
0037 };
0038 
0039 static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)
0040 {
0041     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0042     unsigned long flags;
0043 
0044     raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
0045 
0046     iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),
0047           cgpio->regs + CDNS_GPIO_BYPASS_MODE);
0048 
0049     raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
0050     return 0;
0051 }
0052 
0053 static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)
0054 {
0055     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0056     unsigned long flags;
0057 
0058     raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
0059 
0060     iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |
0061           (BIT(offset) & cgpio->bypass_orig),
0062           cgpio->regs + CDNS_GPIO_BYPASS_MODE);
0063 
0064     raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
0065 }
0066 
0067 static void cdns_gpio_irq_mask(struct irq_data *d)
0068 {
0069     struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
0070     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0071 
0072     iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_DIS);
0073 }
0074 
0075 static void cdns_gpio_irq_unmask(struct irq_data *d)
0076 {
0077     struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
0078     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0079 
0080     iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_EN);
0081 }
0082 
0083 static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
0084 {
0085     struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
0086     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0087     unsigned long flags;
0088     u32 int_value;
0089     u32 int_type;
0090     u32 mask = BIT(d->hwirq);
0091     int ret = 0;
0092 
0093     raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
0094 
0095     int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
0096     int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
0097 
0098     /*
0099      * The GPIO controller doesn't have an ACK register.
0100      * All interrupt statuses are cleared on a status register read.
0101      * Don't support edge interrupts for now.
0102      */
0103 
0104     if (type == IRQ_TYPE_LEVEL_HIGH) {
0105         int_type |= mask;
0106         int_value |= mask;
0107     } else if (type == IRQ_TYPE_LEVEL_LOW) {
0108         int_type |= mask;
0109     } else {
0110         ret = -EINVAL;
0111         goto err_irq_type;
0112     }
0113 
0114     iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE);
0115     iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
0116 
0117 err_irq_type:
0118     raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
0119     return ret;
0120 }
0121 
0122 static void cdns_gpio_irq_handler(struct irq_desc *desc)
0123 {
0124     struct gpio_chip *chip = irq_desc_get_handler_data(desc);
0125     struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
0126     struct irq_chip *irqchip = irq_desc_get_chip(desc);
0127     unsigned long status;
0128     int hwirq;
0129 
0130     chained_irq_enter(irqchip, desc);
0131 
0132     status = ioread32(cgpio->regs + CDNS_GPIO_IRQ_STATUS) &
0133         ~ioread32(cgpio->regs + CDNS_GPIO_IRQ_MASK);
0134 
0135     for_each_set_bit(hwirq, &status, chip->ngpio)
0136         generic_handle_domain_irq(chip->irq.domain, hwirq);
0137 
0138     chained_irq_exit(irqchip, desc);
0139 }
0140 
0141 static struct irq_chip cdns_gpio_irqchip = {
0142     .name       = "cdns-gpio",
0143     .irq_mask   = cdns_gpio_irq_mask,
0144     .irq_unmask = cdns_gpio_irq_unmask,
0145     .irq_set_type   = cdns_gpio_irq_set_type
0146 };
0147 
0148 static int cdns_gpio_probe(struct platform_device *pdev)
0149 {
0150     struct cdns_gpio_chip *cgpio;
0151     int ret, irq;
0152     u32 dir_prev;
0153     u32 num_gpios = 32;
0154 
0155     cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL);
0156     if (!cgpio)
0157         return -ENOMEM;
0158 
0159     cgpio->regs = devm_platform_ioremap_resource(pdev, 0);
0160     if (IS_ERR(cgpio->regs))
0161         return PTR_ERR(cgpio->regs);
0162 
0163     of_property_read_u32(pdev->dev.of_node, "ngpios", &num_gpios);
0164 
0165     if (num_gpios > 32) {
0166         dev_err(&pdev->dev, "ngpios must be less or equal 32\n");
0167         return -EINVAL;
0168     }
0169 
0170     /*
0171      * Set all pins as inputs by default, otherwise:
0172      * gpiochip_lock_as_irq:
0173      * tried to flag a GPIO set as output for IRQ
0174      * Generic GPIO driver stores the direction value internally,
0175      * so it needs to be changed before bgpio_init() is called.
0176      */
0177     dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
0178     iowrite32(GENMASK(num_gpios - 1, 0),
0179           cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
0180 
0181     ret = bgpio_init(&cgpio->gc, &pdev->dev, 4,
0182              cgpio->regs + CDNS_GPIO_INPUT_VALUE,
0183              cgpio->regs + CDNS_GPIO_OUTPUT_VALUE,
0184              NULL,
0185              NULL,
0186              cgpio->regs + CDNS_GPIO_DIRECTION_MODE,
0187              BGPIOF_READ_OUTPUT_REG_SET);
0188     if (ret) {
0189         dev_err(&pdev->dev, "Failed to register generic gpio, %d\n",
0190             ret);
0191         goto err_revert_dir;
0192     }
0193 
0194     cgpio->gc.label = dev_name(&pdev->dev);
0195     cgpio->gc.ngpio = num_gpios;
0196     cgpio->gc.parent = &pdev->dev;
0197     cgpio->gc.base = -1;
0198     cgpio->gc.owner = THIS_MODULE;
0199     cgpio->gc.request = cdns_gpio_request;
0200     cgpio->gc.free = cdns_gpio_free;
0201 
0202     cgpio->pclk = devm_clk_get(&pdev->dev, NULL);
0203     if (IS_ERR(cgpio->pclk)) {
0204         ret = PTR_ERR(cgpio->pclk);
0205         dev_err(&pdev->dev,
0206             "Failed to retrieve peripheral clock, %d\n", ret);
0207         goto err_revert_dir;
0208     }
0209 
0210     ret = clk_prepare_enable(cgpio->pclk);
0211     if (ret) {
0212         dev_err(&pdev->dev,
0213             "Failed to enable the peripheral clock, %d\n", ret);
0214         goto err_revert_dir;
0215     }
0216 
0217     /*
0218      * Optional irq_chip support
0219      */
0220     irq = platform_get_irq(pdev, 0);
0221     if (irq >= 0) {
0222         struct gpio_irq_chip *girq;
0223 
0224         girq = &cgpio->gc.irq;
0225         girq->chip = &cdns_gpio_irqchip;
0226         girq->parent_handler = cdns_gpio_irq_handler;
0227         girq->num_parents = 1;
0228         girq->parents = devm_kcalloc(&pdev->dev, 1,
0229                          sizeof(*girq->parents),
0230                          GFP_KERNEL);
0231         if (!girq->parents) {
0232             ret = -ENOMEM;
0233             goto err_disable_clk;
0234         }
0235         girq->parents[0] = irq;
0236         girq->default_type = IRQ_TYPE_NONE;
0237         girq->handler = handle_level_irq;
0238     }
0239 
0240     ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio);
0241     if (ret < 0) {
0242         dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
0243         goto err_disable_clk;
0244     }
0245 
0246     cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE);
0247 
0248     /*
0249      * Enable gpio outputs, ignored for input direction
0250      */
0251     iowrite32(GENMASK(num_gpios - 1, 0),
0252           cgpio->regs + CDNS_GPIO_OUTPUT_EN);
0253     iowrite32(0, cgpio->regs + CDNS_GPIO_BYPASS_MODE);
0254 
0255     platform_set_drvdata(pdev, cgpio);
0256     return 0;
0257 
0258 err_disable_clk:
0259     clk_disable_unprepare(cgpio->pclk);
0260 
0261 err_revert_dir:
0262     iowrite32(dir_prev, cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
0263 
0264     return ret;
0265 }
0266 
0267 static int cdns_gpio_remove(struct platform_device *pdev)
0268 {
0269     struct cdns_gpio_chip *cgpio = platform_get_drvdata(pdev);
0270 
0271     iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE);
0272     clk_disable_unprepare(cgpio->pclk);
0273 
0274     return 0;
0275 }
0276 
0277 static const struct of_device_id cdns_of_ids[] = {
0278     { .compatible = "cdns,gpio-r1p02" },
0279     { /* sentinel */ },
0280 };
0281 MODULE_DEVICE_TABLE(of, cdns_of_ids);
0282 
0283 static struct platform_driver cdns_gpio_driver = {
0284     .driver = {
0285         .name = "cdns-gpio",
0286         .of_match_table = cdns_of_ids,
0287     },
0288     .probe = cdns_gpio_probe,
0289     .remove = cdns_gpio_remove,
0290 };
0291 module_platform_driver(cdns_gpio_driver);
0292 
0293 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
0294 MODULE_DESCRIPTION("Cadence GPIO driver");
0295 MODULE_LICENSE("GPL v2");
0296 MODULE_ALIAS("platform:cdns-gpio");