Lines Matching +full:stm32 +full:- +full:hwspinlock

1 // SPDX-License-Identifier: GPL-2.0
5 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
10 #include <linux/hwspinlock.h>
24 #include <dt-bindings/interrupt-controller/arm-gic.h>
63 struct hwspinlock *hwlock;
184 __diag_ignore_all("-Woverride-init",
189 [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ,
238 [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ,
297 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_exti_pending()
298 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_pending()
301 pending = irq_reg_readl(gc, stm32_bank->rpr_ofst); in stm32_exti_pending()
302 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_exti_pending()
303 pending |= irq_reg_readl(gc, stm32_bank->fpr_ofst); in stm32_exti_pending()
312 unsigned int nbanks = domain->gc->num_chips; in stm32_irq_handler()
334 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_set_type()
350 return -EINVAL; in stm32_exti_set_type()
359 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_set_type()
360 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_irq_set_type()
361 struct hwspinlock *hwlock = chip_data->host_data->hwlock; in stm32_irq_set_type()
370 pr_err("%s can't get hwspinlock (%d)\n", __func__, err); in stm32_irq_set_type()
375 rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst); in stm32_irq_set_type()
376 ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst); in stm32_irq_set_type()
382 irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst); in stm32_irq_set_type()
383 irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst); in stm32_irq_set_type()
397 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_chip_suspend()
398 void __iomem *base = chip_data->host_data->base; in stm32_chip_suspend()
401 chip_data->rtsr_cache = readl_relaxed(base + stm32_bank->rtsr_ofst); in stm32_chip_suspend()
402 chip_data->ftsr_cache = readl_relaxed(base + stm32_bank->ftsr_ofst); in stm32_chip_suspend()
404 writel_relaxed(wake_active, base + stm32_bank->imr_ofst); in stm32_chip_suspend()
410 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_chip_resume()
411 void __iomem *base = chip_data->host_data->base; in stm32_chip_resume()
414 writel_relaxed(chip_data->rtsr_cache, base + stm32_bank->rtsr_ofst); in stm32_chip_resume()
415 writel_relaxed(chip_data->ftsr_cache, base + stm32_bank->ftsr_ofst); in stm32_chip_resume()
417 writel_relaxed(mask_cache, base + stm32_bank->imr_ofst); in stm32_chip_resume()
422 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_suspend()
425 stm32_chip_suspend(chip_data, gc->wake_active); in stm32_irq_suspend()
431 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_resume()
434 stm32_chip_resume(chip_data, gc->mask_cache); in stm32_irq_resume()
444 hwirq = fwspec->param[0]; in stm32_exti_alloc()
469 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_ack()
470 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_irq_ack()
474 irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst); in stm32_irq_ack()
475 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_irq_ack()
476 irq_reg_writel(gc, d->mask, stm32_bank->fpr_ofst); in stm32_irq_ack()
485 void __iomem *base = chip_data->host_data->base; in stm32_exti_write_bit()
486 u32 val = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_write_bit()
494 void __iomem *base = chip_data->host_data->base; in stm32_exti_set_bit()
498 val |= BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_set_bit()
507 void __iomem *base = chip_data->host_data->base; in stm32_exti_clr_bit()
511 val &= ~BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_clr_bit()
520 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_eoi()
522 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_eoi()
524 stm32_exti_write_bit(d, stm32_bank->rpr_ofst); in stm32_exti_h_eoi()
525 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_exti_h_eoi()
526 stm32_exti_write_bit(d, stm32_bank->fpr_ofst); in stm32_exti_h_eoi()
528 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_eoi()
530 if (d->parent_data->chip) in stm32_exti_h_eoi()
537 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_mask()
539 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_mask()
540 chip_data->mask_cache = stm32_exti_clr_bit(d, stm32_bank->imr_ofst); in stm32_exti_h_mask()
541 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_mask()
543 if (d->parent_data->chip) in stm32_exti_h_mask()
550 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_unmask()
552 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_unmask()
553 chip_data->mask_cache = stm32_exti_set_bit(d, stm32_bank->imr_ofst); in stm32_exti_h_unmask()
554 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_unmask()
556 if (d->parent_data->chip) in stm32_exti_h_unmask()
563 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_set_type()
564 struct hwspinlock *hwlock = chip_data->host_data->hwlock; in stm32_exti_h_set_type()
565 void __iomem *base = chip_data->host_data->base; in stm32_exti_h_set_type()
569 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_set_type()
574 pr_err("%s can't get hwspinlock (%d)\n", __func__, err); in stm32_exti_h_set_type()
579 rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst); in stm32_exti_h_set_type()
580 ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst); in stm32_exti_h_set_type()
586 writel_relaxed(rtsr, base + stm32_bank->rtsr_ofst); in stm32_exti_h_set_type()
587 writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst); in stm32_exti_h_set_type()
593 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_set_type()
601 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_h_set_wake()
603 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_set_wake()
606 chip_data->wake_active |= mask; in stm32_exti_h_set_wake()
608 chip_data->wake_active &= ~mask; in stm32_exti_h_set_wake()
610 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_set_wake()
618 if (d->parent_data->chip) in stm32_exti_h_set_affinity()
629 for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) { in stm32_exti_h_suspend()
630 chip_data = &stm32_host_data->chips_data[i]; in stm32_exti_h_suspend()
631 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_suspend()
632 stm32_chip_suspend(chip_data, chip_data->wake_active); in stm32_exti_h_suspend()
633 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_suspend()
644 for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) { in stm32_exti_h_resume()
645 chip_data = &stm32_host_data->chips_data[i]; in stm32_exti_h_resume()
646 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_resume()
647 stm32_chip_resume(chip_data, chip_data->mask_cache); in stm32_exti_h_resume()
648 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_resume()
673 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_retrigger()
674 void __iomem *base = chip_data->host_data->base; in stm32_exti_h_retrigger()
675 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_h_retrigger()
677 writel_relaxed(mask, base + stm32_bank->swier_ofst); in stm32_exti_h_retrigger()
683 .name = "stm32-exti-h",
695 .name = "stm32-exti-h-direct",
711 struct stm32_exti_host_data *host_data = dm->host_data; in stm32_exti_h_domain_alloc()
721 hwirq = fwspec->param[0]; in stm32_exti_h_domain_alloc()
722 if (hwirq >= host_data->drv_data->bank_nr * IRQS_PER_BANK) in stm32_exti_h_domain_alloc()
723 return -EINVAL; in stm32_exti_h_domain_alloc()
726 chip_data = &host_data->chips_data[bank]; in stm32_exti_h_domain_alloc()
728 event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst); in stm32_exti_h_domain_alloc()
734 if (!host_data->drv_data->desc_irqs) in stm32_exti_h_domain_alloc()
735 return -EINVAL; in stm32_exti_h_domain_alloc()
737 desc_irq = host_data->drv_data->desc_irqs[hwirq]; in stm32_exti_h_domain_alloc()
739 p_fwspec.fwnode = dm->parent->fwnode; in stm32_exti_h_domain_alloc()
761 host_data->drv_data = dd; in stm32_exti_host_init()
762 host_data->chips_data = kcalloc(dd->bank_nr, in stm32_exti_host_init()
765 if (!host_data->chips_data) in stm32_exti_host_init()
768 host_data->base = of_iomap(node, 0); in stm32_exti_host_init()
769 if (!host_data->base) { in stm32_exti_host_init()
779 kfree(host_data->chips_data); in stm32_exti_host_init()
793 void __iomem *base = h_data->base; in stm32_exti_chip_init()
795 stm32_bank = h_data->drv_data->exti_banks[bank_idx]; in stm32_exti_chip_init()
796 chip_data = &h_data->chips_data[bank_idx]; in stm32_exti_chip_init()
797 chip_data->host_data = h_data; in stm32_exti_chip_init()
798 chip_data->reg_bank = stm32_bank; in stm32_exti_chip_init()
800 raw_spin_lock_init(&chip_data->rlock); in stm32_exti_chip_init()
806 writel_relaxed(0, base + stm32_bank->imr_ofst); in stm32_exti_chip_init()
807 if (stm32_bank->emr_ofst != UNDEF_REG) in stm32_exti_chip_init()
808 writel_relaxed(0, base + stm32_bank->emr_ofst); in stm32_exti_chip_init()
826 return -ENOMEM; in stm32_exti_init()
828 domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK, in stm32_exti_init()
833 ret = -ENOMEM; in stm32_exti_init()
845 for (i = 0; i < drv_data->bank_nr; i++) { in stm32_exti_init()
849 stm32_bank = drv_data->exti_banks[i]; in stm32_exti_init()
854 gc->reg_base = host_data->base; in stm32_exti_init()
855 gc->chip_types->type = IRQ_TYPE_EDGE_BOTH; in stm32_exti_init()
856 gc->chip_types->chip.irq_ack = stm32_irq_ack; in stm32_exti_init()
857 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; in stm32_exti_init()
858 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit; in stm32_exti_init()
859 gc->chip_types->chip.irq_set_type = stm32_irq_set_type; in stm32_exti_init()
860 gc->chip_types->chip.irq_set_wake = irq_gc_set_wake; in stm32_exti_init()
861 gc->suspend = stm32_irq_suspend; in stm32_exti_init()
862 gc->resume = stm32_irq_resume; in stm32_exti_init()
863 gc->wake_enabled = IRQ_MSK(IRQS_PER_BANK); in stm32_exti_init()
865 gc->chip_types->regs.mask = stm32_bank->imr_ofst; in stm32_exti_init()
866 gc->private = (void *)chip_data; in stm32_exti_init()
882 iounmap(host_data->base); in stm32_exti_init()
883 kfree(host_data->chips_data); in stm32_exti_init()
910 struct device *dev = &pdev->dev; in stm32_exti_probe()
911 struct device_node *np = dev->of_node; in stm32_exti_probe()
918 return -ENOMEM; in stm32_exti_probe()
920 /* check for optional hwspinlock which may be not available yet */ in stm32_exti_probe()
922 if (ret == -EPROBE_DEFER) in stm32_exti_probe()
923 /* hwspinlock framework not yet ready */ in stm32_exti_probe()
927 host_data->hwlock = devm_hwspin_lock_request_specific(dev, ret); in stm32_exti_probe()
928 if (!host_data->hwlock) { in stm32_exti_probe()
929 dev_err(dev, "Failed to request hwspinlock\n"); in stm32_exti_probe()
930 return -EINVAL; in stm32_exti_probe()
932 } else if (ret != -ENOENT) { in stm32_exti_probe()
933 /* note: ENOENT is a valid case (means 'no hwspinlock') */ in stm32_exti_probe()
934 dev_err(dev, "Failed to get hwspinlock\n"); in stm32_exti_probe()
942 return -ENODEV; in stm32_exti_probe()
944 host_data->drv_data = drv_data; in stm32_exti_probe()
946 host_data->chips_data = devm_kcalloc(dev, drv_data->bank_nr, in stm32_exti_probe()
947 sizeof(*host_data->chips_data), in stm32_exti_probe()
949 if (!host_data->chips_data) in stm32_exti_probe()
950 return -ENOMEM; in stm32_exti_probe()
952 host_data->base = devm_platform_ioremap_resource(pdev, 0); in stm32_exti_probe()
953 if (IS_ERR(host_data->base)) in stm32_exti_probe()
954 return PTR_ERR(host_data->base); in stm32_exti_probe()
956 for (i = 0; i < drv_data->bank_nr; i++) in stm32_exti_probe()
961 dev_err(dev, "GIC interrupt-parent not found\n"); in stm32_exti_probe()
962 return -EINVAL; in stm32_exti_probe()
966 drv_data->bank_nr * IRQS_PER_BANK, in stm32_exti_probe()
972 return -ENOMEM; in stm32_exti_probe()
986 { .compatible = "st,stm32mp1-exti", .data = &stm32mp1_drv_data},
987 { .compatible = "st,stm32mp13-exti", .data = &stm32mp13_drv_data},
1021 IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init);
1029 IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);