0001
0002
0003
0004
0005
0006
0007
0008
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
0100
0101
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
0172
0173
0174
0175
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
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
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 { },
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");