Lines Matching +full:data +full:- +full:shift

1 // SPDX-License-Identifier: GPL-2.0+
3 // S3C64xx specific support for pinctrl-samsung driver.
7 // Based on pinctrl-exynos.c, please see the file for original copyrights.
24 #include "pinctrl-samsung.h"
112 .eint_mask = (1 << (pins)) - 1, \
136 .eint_mask = (1 << (pins)) - 1, \
190 .eint_mask = (1 << (pins)) - 1, \
196 * struct s3c64xx_eint0_data - EINT0 common data
197 * @drvdata: pin controller driver data
208 * struct s3c64xx_eint0_domain_data - EINT0 per-domain data
218 * struct s3c64xx_eint_gpio_data - GPIO EINT data
219 * @drvdata: pin controller driver data
252 return -EINVAL; in s3c64xx_irq_get_trigger()
260 /* Edge- and level-triggered interrupts need different handlers */ in s3c64xx_irq_set_handler()
270 const struct samsung_pin_bank_type *bank_type = bank->type; in s3c64xx_irq_set_function()
273 u8 shift; in s3c64xx_irq_set_function() local
278 reg = d->virt_base + bank->pctl_offset; in s3c64xx_irq_set_function()
279 shift = pin; in s3c64xx_irq_set_function()
280 if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { in s3c64xx_irq_set_function()
281 /* 4-bit bank type with 2 con regs */ in s3c64xx_irq_set_function()
283 shift -= 8; in s3c64xx_irq_set_function()
286 shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC]; in s3c64xx_irq_set_function()
287 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; in s3c64xx_irq_set_function()
289 raw_spin_lock_irqsave(&bank->slock, flags); in s3c64xx_irq_set_function()
292 val &= ~(mask << shift); in s3c64xx_irq_set_function()
293 val |= bank->eint_func << shift; in s3c64xx_irq_set_function()
296 raw_spin_unlock_irqrestore(&bank->slock, flags); in s3c64xx_irq_set_function()
300 * Functions for EINT GPIO configuration (EINT groups 1-9)
306 struct samsung_pinctrl_drv_data *d = bank->drvdata; in s3c64xx_gpio_irq_set_mask()
307 unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; in s3c64xx_gpio_irq_set_mask()
308 void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); in s3c64xx_gpio_irq_set_mask()
332 struct samsung_pinctrl_drv_data *d = bank->drvdata; in s3c64xx_gpio_irq_ack()
333 unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; in s3c64xx_gpio_irq_ack()
334 void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); in s3c64xx_gpio_irq_ack()
342 struct samsung_pinctrl_drv_data *d = bank->drvdata; in s3c64xx_gpio_irq_set_type()
345 u8 shift; in s3c64xx_gpio_irq_set_type() local
351 return -EINVAL; in s3c64xx_gpio_irq_set_type()
357 reg = d->virt_base + EINTCON_REG(bank->eint_offset); in s3c64xx_gpio_irq_set_type()
358 shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; in s3c64xx_gpio_irq_set_type()
359 shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ in s3c64xx_gpio_irq_set_type()
362 val &= ~(EINT_CON_MASK << shift); in s3c64xx_gpio_irq_set_type()
363 val |= trigger << shift; in s3c64xx_gpio_irq_set_type()
366 s3c64xx_irq_set_function(d, bank, irqd->hwirq); in s3c64xx_gpio_irq_set_type()
385 struct samsung_pin_bank *bank = h->host_data; in s3c64xx_gpio_irq_map()
387 if (!(bank->eint_mask & (1 << hw))) in s3c64xx_gpio_irq_map()
388 return -EINVAL; in s3c64xx_gpio_irq_map()
408 struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc); in s3c64xx_eint_gpio_irq() local
409 struct samsung_pinctrl_drv_data *drvdata = data->drvdata; in s3c64xx_eint_gpio_irq()
419 svc = readl(drvdata->virt_base + SERVICE_REG); in s3c64xx_eint_gpio_irq()
431 pin -= 8; in s3c64xx_eint_gpio_irq()
434 ret = generic_handle_domain_irq(data->domains[group], pin); in s3c64xx_eint_gpio_irq()
446 * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
447 * @d: driver data of samsung pinctrl driver.
451 struct s3c64xx_eint_gpio_data *data; in s3c64xx_eint_gpio_init() local
453 struct device *dev = d->dev; in s3c64xx_eint_gpio_init()
457 if (!d->irq) { in s3c64xx_eint_gpio_init()
459 return -EINVAL; in s3c64xx_eint_gpio_init()
463 bank = d->pin_banks; in s3c64xx_eint_gpio_init()
464 for (i = 0; i < d->nr_banks; ++i, ++bank) { in s3c64xx_eint_gpio_init()
468 if (bank->eint_type != EINT_TYPE_GPIO) in s3c64xx_eint_gpio_init()
471 mask = bank->eint_mask; in s3c64xx_eint_gpio_init()
474 bank->irq_domain = irq_domain_create_linear(bank->fwnode, in s3c64xx_eint_gpio_init()
476 if (!bank->irq_domain) { in s3c64xx_eint_gpio_init()
478 return -ENXIO; in s3c64xx_eint_gpio_init()
484 data = devm_kzalloc(dev, struct_size(data, domains, nr_domains), in s3c64xx_eint_gpio_init()
486 if (!data) in s3c64xx_eint_gpio_init()
487 return -ENOMEM; in s3c64xx_eint_gpio_init()
488 data->drvdata = d; in s3c64xx_eint_gpio_init()
490 bank = d->pin_banks; in s3c64xx_eint_gpio_init()
492 for (i = 0; i < d->nr_banks; ++i, ++bank) { in s3c64xx_eint_gpio_init()
493 if (bank->eint_type != EINT_TYPE_GPIO) in s3c64xx_eint_gpio_init()
496 data->domains[nr_domains++] = bank->irq_domain; in s3c64xx_eint_gpio_init()
499 irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data); in s3c64xx_eint_gpio_init()
505 * Functions for configuration of EINT0 wake-up interrupts
512 struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; in s3c64xx_eint0_irq_set_mask()
515 val = readl(d->virt_base + EINT0MASK_REG); in s3c64xx_eint0_irq_set_mask()
517 val |= 1 << ddata->eints[irqd->hwirq]; in s3c64xx_eint0_irq_set_mask()
519 val &= ~(1 << ddata->eints[irqd->hwirq]); in s3c64xx_eint0_irq_set_mask()
520 writel(val, d->virt_base + EINT0MASK_REG); in s3c64xx_eint0_irq_set_mask()
537 struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; in s3c64xx_eint0_irq_ack()
539 writel(1 << ddata->eints[irqd->hwirq], in s3c64xx_eint0_irq_ack()
540 d->virt_base + EINT0PEND_REG); in s3c64xx_eint0_irq_ack()
547 struct samsung_pin_bank *bank = ddata->bank; in s3c64xx_eint0_irq_set_type()
548 struct samsung_pinctrl_drv_data *d = bank->drvdata; in s3c64xx_eint0_irq_set_type()
551 u8 shift; in s3c64xx_eint0_irq_set_type() local
557 return -EINVAL; in s3c64xx_eint0_irq_set_type()
563 reg = d->virt_base + EINT0CON0_REG; in s3c64xx_eint0_irq_set_type()
564 shift = ddata->eints[irqd->hwirq]; in s3c64xx_eint0_irq_set_type()
565 if (shift >= EINT_MAX_PER_REG) { in s3c64xx_eint0_irq_set_type()
567 shift -= EINT_MAX_PER_REG; in s3c64xx_eint0_irq_set_type()
569 shift = EINT_CON_LEN * (shift / 2); in s3c64xx_eint0_irq_set_type()
572 val &= ~(EINT_CON_MASK << shift); in s3c64xx_eint0_irq_set_type()
573 val |= trigger << shift; in s3c64xx_eint0_irq_set_type()
576 s3c64xx_irq_set_function(d, bank, irqd->hwirq); in s3c64xx_eint0_irq_set_type()
595 struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc); in s3c64xx_irq_demux_eint() local
596 struct samsung_pinctrl_drv_data *drvdata = data->drvdata; in s3c64xx_irq_demux_eint()
601 pend = readl(drvdata->virt_base + EINT0PEND_REG); in s3c64xx_irq_demux_eint()
602 mask = readl(drvdata->virt_base + EINT0MASK_REG); in s3c64xx_irq_demux_eint()
611 irq = fls(pend) - 1; in s3c64xx_irq_demux_eint()
613 ret = generic_handle_domain_irq(data->domains[irq], data->pins[irq]); in s3c64xx_irq_demux_eint()
654 struct s3c64xx_eint0_domain_data *ddata = h->host_data; in s3c64xx_eint0_irq_map()
655 struct samsung_pin_bank *bank = ddata->bank; in s3c64xx_eint0_irq_map()
657 if (!(bank->eint_mask & (1 << hw))) in s3c64xx_eint0_irq_map()
658 return -EINVAL; in s3c64xx_eint0_irq_map()
677 { .compatible = "samsung,s3c64xx-wakeup-eint", },
682 * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
683 * @d: driver data of samsung pinctrl driver.
687 struct device *dev = d->dev; in s3c64xx_eint_eint0_init()
691 struct s3c64xx_eint0_data *data; in s3c64xx_eint_eint0_init() local
694 for_each_child_of_node(dev->of_node, np) { in s3c64xx_eint_eint0_init()
701 return -ENODEV; in s3c64xx_eint_eint0_init()
703 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); in s3c64xx_eint_eint0_init()
704 if (!data) { in s3c64xx_eint_eint0_init()
706 return -ENOMEM; in s3c64xx_eint_eint0_init()
708 data->drvdata = d; in s3c64xx_eint_eint0_init()
717 return -ENXIO; in s3c64xx_eint_eint0_init()
722 data); in s3c64xx_eint_eint0_init()
726 bank = d->pin_banks; in s3c64xx_eint_eint0_init()
727 for (i = 0; i < d->nr_banks; ++i, ++bank) { in s3c64xx_eint_eint0_init()
734 if (bank->eint_type != EINT_TYPE_WKUP) in s3c64xx_eint_eint0_init()
737 mask = bank->eint_mask; in s3c64xx_eint_eint0_init()
743 return -ENOMEM; in s3c64xx_eint_eint0_init()
744 ddata->bank = bank; in s3c64xx_eint_eint0_init()
746 bank->irq_domain = irq_domain_create_linear(bank->fwnode, in s3c64xx_eint_eint0_init()
748 if (!bank->irq_domain) { in s3c64xx_eint_eint0_init()
750 return -ENXIO; in s3c64xx_eint_eint0_init()
753 irq = bank->eint_offset; in s3c64xx_eint_eint0_init()
754 mask = bank->eint_mask; in s3c64xx_eint_eint0_init()
758 data->domains[irq] = bank->irq_domain; in s3c64xx_eint_eint0_init()
759 data->pins[irq] = pin; in s3c64xx_eint_eint0_init()
760 ddata->eints[pin] = irq; in s3c64xx_eint_eint0_init()
768 /* pin banks of s3c64xx pin-controller 0 */
790 * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
791 * one gpio/pin-mux/pinconfig controller.
795 /* pin-controller instance 1 data */