Lines Matching +full:qoriq +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIOs on MPC512x/8349/8572/8610/QorIQ and compatible
11 #include <linux/gpio/driver.h>
50 * This hardware has a big endian bit assignment such that GPIO line 0 is
56 return BIT(31 - offset); in mpc_pin2mask()
59 /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
64 static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) in mpc8572_gpio_get() argument
70 out_mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_DIR); in mpc8572_gpio_get()
71 val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask; in mpc8572_gpio_get()
72 out_shadow = gc->bgpio_data & out_mask; in mpc8572_gpio_get()
74 return !!((val | out_shadow) & mpc_pin2mask(gpio)); in mpc8572_gpio_get()
78 unsigned int gpio, int val) in mpc5121_gpio_dir_out() argument
81 /* GPIO 28..31 are input only on MPC5121 */ in mpc5121_gpio_dir_out()
82 if (gpio >= 28) in mpc5121_gpio_dir_out()
83 return -EINVAL; in mpc5121_gpio_dir_out()
85 return mpc8xxx_gc->direction_output(gc, gpio, val); in mpc5121_gpio_dir_out()
89 unsigned int gpio, int val) in mpc5125_gpio_dir_out() argument
92 /* GPIO 0..3 are input only on MPC5125 */ in mpc5125_gpio_dir_out()
93 if (gpio <= 3) in mpc5125_gpio_dir_out()
94 return -EINVAL; in mpc5125_gpio_dir_out()
96 return mpc8xxx_gc->direction_output(gc, gpio, val); in mpc5125_gpio_dir_out()
103 if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) in mpc8xxx_gpio_to_irq()
104 return irq_create_mapping(mpc8xxx_gc->irq, offset); in mpc8xxx_gpio_to_irq()
106 return -ENXIO; in mpc8xxx_gpio_to_irq()
112 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc8xxx_gpio_irq_cascade()
116 mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER) in mpc8xxx_gpio_irq_cascade()
117 & gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR); in mpc8xxx_gpio_irq_cascade()
119 generic_handle_domain_irq(mpc8xxx_gc->irq, 31 - i); in mpc8xxx_gpio_irq_cascade()
127 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc8xxx_irq_unmask()
130 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_unmask()
132 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, in mpc8xxx_irq_unmask()
133 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) in mpc8xxx_irq_unmask()
136 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_unmask()
142 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc8xxx_irq_mask()
145 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_mask()
147 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, in mpc8xxx_irq_mask()
148 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) in mpc8xxx_irq_mask()
151 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_mask()
157 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc8xxx_irq_ack()
159 gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, in mpc8xxx_irq_ack()
166 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc8xxx_irq_set_type()
172 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_set_type()
173 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, in mpc8xxx_irq_set_type()
174 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) in mpc8xxx_irq_set_type()
176 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_set_type()
180 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_set_type()
181 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, in mpc8xxx_irq_set_type()
182 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) in mpc8xxx_irq_set_type()
184 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc8xxx_irq_set_type()
188 return -EINVAL; in mpc8xxx_irq_set_type()
197 struct gpio_chip *gc = &mpc8xxx_gc->gc; in mpc512x_irq_set_type()
198 unsigned long gpio = irqd_to_hwirq(d); in mpc512x_irq_set_type() local
203 if (gpio < 16) { in mpc512x_irq_set_type()
204 reg = mpc8xxx_gc->regs + GPIO_ICR; in mpc512x_irq_set_type()
205 shift = (15 - gpio) * 2; in mpc512x_irq_set_type()
207 reg = mpc8xxx_gc->regs + GPIO_ICR2; in mpc512x_irq_set_type()
208 shift = (15 - (gpio % 16)) * 2; in mpc512x_irq_set_type()
214 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
215 gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift)) in mpc512x_irq_set_type()
217 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
222 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
223 gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift)) in mpc512x_irq_set_type()
225 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
229 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
230 gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift))); in mpc512x_irq_set_type()
231 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); in mpc512x_irq_set_type()
235 return -EINVAL; in mpc512x_irq_set_type()
242 .name = "mpc8xxx-gpio",
253 irq_set_chip_data(irq, h->host_data); in mpc8xxx_gpio_irq_map()
289 { .compatible = "fsl,mpc8349-gpio", },
290 { .compatible = "fsl,mpc8572-gpio", .data = &mpc8572_gpio_devtype, },
291 { .compatible = "fsl,mpc8610-gpio", },
292 { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, },
293 { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, },
294 { .compatible = "fsl,pq3-gpio", },
295 { .compatible = "fsl,ls1028a-gpio", },
296 { .compatible = "fsl,ls1088a-gpio", },
297 { .compatible = "fsl,qoriq-gpio", },
303 struct device_node *np = pdev->dev.of_node; in mpc8xxx_probe()
310 mpc8xxx_gc = devm_kzalloc(&pdev->dev, sizeof(*mpc8xxx_gc), GFP_KERNEL); in mpc8xxx_probe()
312 return -ENOMEM; in mpc8xxx_probe()
316 raw_spin_lock_init(&mpc8xxx_gc->lock); in mpc8xxx_probe()
318 mpc8xxx_gc->regs = devm_platform_ioremap_resource(pdev, 0); in mpc8xxx_probe()
319 if (IS_ERR(mpc8xxx_gc->regs)) in mpc8xxx_probe()
320 return PTR_ERR(mpc8xxx_gc->regs); in mpc8xxx_probe()
322 gc = &mpc8xxx_gc->gc; in mpc8xxx_probe()
323 gc->parent = &pdev->dev; in mpc8xxx_probe()
325 if (device_property_read_bool(&pdev->dev, "little-endian")) { in mpc8xxx_probe()
326 ret = bgpio_init(gc, &pdev->dev, 4, in mpc8xxx_probe()
327 mpc8xxx_gc->regs + GPIO_DAT, in mpc8xxx_probe()
329 mpc8xxx_gc->regs + GPIO_DIR, NULL, in mpc8xxx_probe()
333 dev_dbg(&pdev->dev, "GPIO registers are LITTLE endian\n"); in mpc8xxx_probe()
335 ret = bgpio_init(gc, &pdev->dev, 4, in mpc8xxx_probe()
336 mpc8xxx_gc->regs + GPIO_DAT, in mpc8xxx_probe()
338 mpc8xxx_gc->regs + GPIO_DIR, NULL, in mpc8xxx_probe()
343 dev_dbg(&pdev->dev, "GPIO registers are BIG endian\n"); in mpc8xxx_probe()
346 mpc8xxx_gc->direction_output = gc->direction_output; in mpc8xxx_probe()
348 devtype = device_get_match_data(&pdev->dev); in mpc8xxx_probe()
353 * It's assumed that only a single type of gpio controller is available in mpc8xxx_probe()
356 if (devtype->irq_set_type) in mpc8xxx_probe()
357 mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type; in mpc8xxx_probe()
359 if (devtype->gpio_dir_out) in mpc8xxx_probe()
360 gc->direction_output = devtype->gpio_dir_out; in mpc8xxx_probe()
361 if (devtype->gpio_get) in mpc8xxx_probe()
362 gc->get = devtype->gpio_get; in mpc8xxx_probe()
364 gc->to_irq = mpc8xxx_gpio_to_irq; in mpc8xxx_probe()
367 * The GPIO Input Buffer Enable register(GPIO_IBE) is used to control in mpc8xxx_probe()
368 * the input enable of each individual GPIO port. When an individual in mpc8xxx_probe()
369 * GPIO port’s direction is set to input (GPIO_GPDIR[DRn=0]), the in mpc8xxx_probe()
371 * the port value to the GPIO Data Register. in mpc8xxx_probe()
373 fwnode = dev_fwnode(&pdev->dev); in mpc8xxx_probe()
374 if (of_device_is_compatible(np, "fsl,qoriq-gpio") || in mpc8xxx_probe()
375 of_device_is_compatible(np, "fsl,ls1028a-gpio") || in mpc8xxx_probe()
376 of_device_is_compatible(np, "fsl,ls1088a-gpio") || in mpc8xxx_probe()
378 gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff); in mpc8xxx_probe()
380 gc->bgpio_data = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & in mpc8xxx_probe()
381 gc->read_reg(mpc8xxx_gc->regs + GPIO_DIR); in mpc8xxx_probe()
384 ret = devm_gpiochip_add_data(&pdev->dev, gc, mpc8xxx_gc); in mpc8xxx_probe()
386 dev_err(&pdev->dev, in mpc8xxx_probe()
387 "GPIO chip registration failed with status %d\n", ret); in mpc8xxx_probe()
391 mpc8xxx_gc->irqn = platform_get_irq(pdev, 0); in mpc8xxx_probe()
392 if (mpc8xxx_gc->irqn < 0) in mpc8xxx_probe()
393 return mpc8xxx_gc->irqn; in mpc8xxx_probe()
395 mpc8xxx_gc->irq = irq_domain_create_linear(fwnode, in mpc8xxx_probe()
400 if (!mpc8xxx_gc->irq) in mpc8xxx_probe()
404 gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff); in mpc8xxx_probe()
405 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0); in mpc8xxx_probe()
407 ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn, in mpc8xxx_probe()
409 IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", in mpc8xxx_probe()
412 dev_err(&pdev->dev, in mpc8xxx_probe()
414 mpc8xxx_gc->irqn, ret); in mpc8xxx_probe()
418 device_init_wakeup(&pdev->dev, true); in mpc8xxx_probe()
422 irq_domain_remove(mpc8xxx_gc->irq); in mpc8xxx_probe()
430 if (mpc8xxx_gc->irq) { in mpc8xxx_remove()
431 irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, NULL, NULL); in mpc8xxx_remove()
432 irq_domain_remove(mpc8xxx_gc->irq); in mpc8xxx_remove()
440 if (mpc8xxx_gc->irqn && device_may_wakeup(dev)) in mpc8xxx_suspend()
441 enable_irq_wake(mpc8xxx_gc->irqn); in mpc8xxx_suspend()
450 if (mpc8xxx_gc->irqn && device_may_wakeup(dev)) in mpc8xxx_resume()
451 disable_irq_wake(mpc8xxx_gc->irqn); in mpc8xxx_resume()
471 .name = "gpio-mpc8xxx",