Lines Matching +full:gpio +full:- +full:r1p02

1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright 2017-2018 Cadence
8 * Boris Brezillon <boris.brezillon@free-electrons.com>
13 #include <linux/gpio/driver.h>
15 #include <linux/gpio/generic.h>
44 guard(gpio_generic_lock)(&cgpio->gen_gc); in cdns_gpio_request()
46 iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset), in cdns_gpio_request()
47 cgpio->regs + CDNS_GPIO_BYPASS_MODE); in cdns_gpio_request()
56 guard(gpio_generic_lock)(&cgpio->gen_gc); in cdns_gpio_free()
58 iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) | in cdns_gpio_free()
59 (BIT(offset) & cgpio->bypass_orig), in cdns_gpio_free()
60 cgpio->regs + CDNS_GPIO_BYPASS_MODE); in cdns_gpio_free()
68 iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_DIS); in cdns_gpio_irq_mask()
78 iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_EN); in cdns_gpio_irq_unmask()
87 u32 mask = BIT(d->hwirq); in cdns_gpio_irq_set_type()
90 guard(gpio_generic_lock)(&cgpio->gen_gc); in cdns_gpio_irq_set_type()
92 int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask; in cdns_gpio_irq_set_type()
93 int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask; in cdns_gpio_irq_set_type()
96 * The GPIO controller doesn't have an ACK register. in cdns_gpio_irq_set_type()
107 return -EINVAL; in cdns_gpio_irq_set_type()
110 iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE); in cdns_gpio_irq_set_type()
111 iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE); in cdns_gpio_irq_set_type()
126 status = ioread32(cgpio->regs + CDNS_GPIO_IRQ_STATUS) & in cdns_gpio_irq_handler()
127 ~ioread32(cgpio->regs + CDNS_GPIO_IRQ_MASK); in cdns_gpio_irq_handler()
129 for_each_set_bit(hwirq, &status, chip->ngpio) in cdns_gpio_irq_handler()
130 generic_handle_domain_irq(chip->irq.domain, hwirq); in cdns_gpio_irq_handler()
136 .name = "cdns-gpio",
153 cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL); in cdns_gpio_probe()
155 return -ENOMEM; in cdns_gpio_probe()
157 cgpio->regs = devm_platform_ioremap_resource(pdev, 0); in cdns_gpio_probe()
158 if (IS_ERR(cgpio->regs)) in cdns_gpio_probe()
159 return PTR_ERR(cgpio->regs); in cdns_gpio_probe()
161 of_property_read_u32(pdev->dev.of_node, "ngpios", &num_gpios); in cdns_gpio_probe()
164 dev_err(&pdev->dev, "ngpios must be less or equal 32\n"); in cdns_gpio_probe()
165 return -EINVAL; in cdns_gpio_probe()
171 * tried to flag a GPIO set as output for IRQ in cdns_gpio_probe()
172 * Generic GPIO driver stores the direction value internally, in cdns_gpio_probe()
175 dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE); in cdns_gpio_probe()
176 iowrite32(GENMASK(num_gpios - 1, 0), in cdns_gpio_probe()
177 cgpio->regs + CDNS_GPIO_DIRECTION_MODE); in cdns_gpio_probe()
179 config.dev = &pdev->dev; in cdns_gpio_probe()
181 config.dat = cgpio->regs + CDNS_GPIO_INPUT_VALUE; in cdns_gpio_probe()
182 config.set = cgpio->regs + CDNS_GPIO_OUTPUT_VALUE; in cdns_gpio_probe()
183 config.dirin = cgpio->regs + CDNS_GPIO_DIRECTION_MODE; in cdns_gpio_probe()
186 ret = gpio_generic_chip_init(&cgpio->gen_gc, &config); in cdns_gpio_probe()
188 dev_err(&pdev->dev, "Failed to register generic gpio, %d\n", in cdns_gpio_probe()
193 cgpio->gen_gc.gc.label = dev_name(&pdev->dev); in cdns_gpio_probe()
194 cgpio->gen_gc.gc.ngpio = num_gpios; in cdns_gpio_probe()
195 cgpio->gen_gc.gc.parent = &pdev->dev; in cdns_gpio_probe()
196 cgpio->gen_gc.gc.base = -1; in cdns_gpio_probe()
197 cgpio->gen_gc.gc.owner = THIS_MODULE; in cdns_gpio_probe()
198 cgpio->gen_gc.gc.request = cdns_gpio_request; in cdns_gpio_probe()
199 cgpio->gen_gc.gc.free = cdns_gpio_free; in cdns_gpio_probe()
201 clk = devm_clk_get_enabled(&pdev->dev, NULL); in cdns_gpio_probe()
204 dev_err(&pdev->dev, in cdns_gpio_probe()
216 girq = &cgpio->gen_gc.gc.irq; in cdns_gpio_probe()
218 girq->parent_handler = cdns_gpio_irq_handler; in cdns_gpio_probe()
219 girq->num_parents = 1; in cdns_gpio_probe()
220 girq->parents = devm_kcalloc(&pdev->dev, 1, in cdns_gpio_probe()
221 sizeof(*girq->parents), in cdns_gpio_probe()
223 if (!girq->parents) { in cdns_gpio_probe()
224 ret = -ENOMEM; in cdns_gpio_probe()
227 girq->parents[0] = irq; in cdns_gpio_probe()
228 girq->default_type = IRQ_TYPE_NONE; in cdns_gpio_probe()
229 girq->handler = handle_level_irq; in cdns_gpio_probe()
232 ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gen_gc.gc, cgpio); in cdns_gpio_probe()
234 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); in cdns_gpio_probe()
238 cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE); in cdns_gpio_probe()
241 * Enable gpio outputs, ignored for input direction in cdns_gpio_probe()
243 iowrite32(GENMASK(num_gpios - 1, 0), in cdns_gpio_probe()
244 cgpio->regs + CDNS_GPIO_OUTPUT_EN); in cdns_gpio_probe()
245 iowrite32(0, cgpio->regs + CDNS_GPIO_BYPASS_MODE); in cdns_gpio_probe()
251 iowrite32(dir_prev, cgpio->regs + CDNS_GPIO_DIRECTION_MODE); in cdns_gpio_probe()
260 iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE); in cdns_gpio_remove()
264 { .compatible = "cdns,gpio-r1p02" },
271 .name = "cdns-gpio",
280 MODULE_DESCRIPTION("Cadence GPIO driver");
282 MODULE_ALIAS("platform:cdns-gpio");