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>
23 #include <dt-bindings/interrupt-controller/arm-gic.h>
68 struct hwspinlock *hwlock;
224 if (!drv_data->desc_irqs) in stm32_exti_get_desc()
227 for (i = 0; i < drv_data->irq_nr; i++) { in stm32_exti_get_desc()
228 desc = &drv_data->desc_irqs[i]; in stm32_exti_get_desc()
229 if (desc->exti == hwirq) in stm32_exti_get_desc()
238 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_exti_pending()
239 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_pending()
242 pending = irq_reg_readl(gc, stm32_bank->rpr_ofst); in stm32_exti_pending()
243 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_exti_pending()
244 pending |= irq_reg_readl(gc, stm32_bank->fpr_ofst); in stm32_exti_pending()
253 unsigned int virq, nbanks = domain->gc->num_chips; in stm32_irq_handler()
277 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_set_type()
293 return -EINVAL; in stm32_exti_set_type()
302 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_set_type()
303 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_irq_set_type()
304 struct hwspinlock *hwlock = chip_data->host_data->hwlock; in stm32_irq_set_type()
313 pr_err("%s can't get hwspinlock (%d)\n", __func__, err); in stm32_irq_set_type()
318 rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst); in stm32_irq_set_type()
319 ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst); in stm32_irq_set_type()
325 irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst); in stm32_irq_set_type()
326 irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst); in stm32_irq_set_type()
340 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_chip_suspend()
341 void __iomem *base = chip_data->host_data->base; in stm32_chip_suspend()
344 chip_data->rtsr_cache = readl_relaxed(base + stm32_bank->rtsr_ofst); in stm32_chip_suspend()
345 chip_data->ftsr_cache = readl_relaxed(base + stm32_bank->ftsr_ofst); in stm32_chip_suspend()
347 writel_relaxed(wake_active, base + stm32_bank->imr_ofst); in stm32_chip_suspend()
353 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_chip_resume()
354 void __iomem *base = chip_data->host_data->base; in stm32_chip_resume()
357 writel_relaxed(chip_data->rtsr_cache, base + stm32_bank->rtsr_ofst); in stm32_chip_resume()
358 writel_relaxed(chip_data->ftsr_cache, base + stm32_bank->ftsr_ofst); in stm32_chip_resume()
360 writel_relaxed(mask_cache, base + stm32_bank->imr_ofst); in stm32_chip_resume()
365 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_suspend()
368 stm32_chip_suspend(chip_data, gc->wake_active); in stm32_irq_suspend()
374 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_resume()
377 stm32_chip_resume(chip_data, gc->mask_cache); in stm32_irq_resume()
387 hwirq = fwspec->param[0]; in stm32_exti_alloc()
411 struct stm32_exti_chip_data *chip_data = gc->private; in stm32_irq_ack()
412 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_irq_ack()
416 irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst); in stm32_irq_ack()
417 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_irq_ack()
418 irq_reg_writel(gc, d->mask, stm32_bank->fpr_ofst); in stm32_irq_ack()
427 void __iomem *base = chip_data->host_data->base; in stm32_exti_write_bit()
428 u32 val = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_write_bit()
436 void __iomem *base = chip_data->host_data->base; in stm32_exti_set_bit()
440 val |= BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_set_bit()
449 void __iomem *base = chip_data->host_data->base; in stm32_exti_clr_bit()
453 val &= ~BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_clr_bit()
462 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_eoi()
464 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_eoi()
466 stm32_exti_write_bit(d, stm32_bank->rpr_ofst); in stm32_exti_h_eoi()
467 if (stm32_bank->fpr_ofst != UNDEF_REG) in stm32_exti_h_eoi()
468 stm32_exti_write_bit(d, stm32_bank->fpr_ofst); in stm32_exti_h_eoi()
470 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_eoi()
472 if (d->parent_data->chip) in stm32_exti_h_eoi()
479 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_mask()
481 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_mask()
482 chip_data->mask_cache = stm32_exti_clr_bit(d, stm32_bank->imr_ofst); in stm32_exti_h_mask()
483 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_mask()
485 if (d->parent_data->chip) in stm32_exti_h_mask()
492 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_unmask()
494 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_unmask()
495 chip_data->mask_cache = stm32_exti_set_bit(d, stm32_bank->imr_ofst); in stm32_exti_h_unmask()
496 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_unmask()
498 if (d->parent_data->chip) in stm32_exti_h_unmask()
505 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_set_type()
506 struct hwspinlock *hwlock = chip_data->host_data->hwlock; in stm32_exti_h_set_type()
507 void __iomem *base = chip_data->host_data->base; in stm32_exti_h_set_type()
511 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_set_type()
516 pr_err("%s can't get hwspinlock (%d)\n", __func__, err); in stm32_exti_h_set_type()
521 rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst); in stm32_exti_h_set_type()
522 ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst); in stm32_exti_h_set_type()
528 writel_relaxed(rtsr, base + stm32_bank->rtsr_ofst); in stm32_exti_h_set_type()
529 writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst); in stm32_exti_h_set_type()
535 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_set_type()
543 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_h_set_wake()
545 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_set_wake()
548 chip_data->wake_active |= mask; in stm32_exti_h_set_wake()
550 chip_data->wake_active &= ~mask; in stm32_exti_h_set_wake()
552 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_set_wake()
560 if (d->parent_data->chip) in stm32_exti_h_set_affinity()
563 return -EINVAL; in stm32_exti_h_set_affinity()
571 for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) { in stm32_exti_h_suspend()
572 chip_data = &stm32_host_data->chips_data[i]; in stm32_exti_h_suspend()
573 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_suspend()
574 stm32_chip_suspend(chip_data, chip_data->wake_active); in stm32_exti_h_suspend()
575 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_suspend()
586 for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) { in stm32_exti_h_resume()
587 chip_data = &stm32_host_data->chips_data[i]; in stm32_exti_h_resume()
588 raw_spin_lock(&chip_data->rlock); in stm32_exti_h_resume()
589 stm32_chip_resume(chip_data, chip_data->mask_cache); in stm32_exti_h_resume()
590 raw_spin_unlock(&chip_data->rlock); in stm32_exti_h_resume()
615 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; in stm32_exti_h_retrigger()
616 void __iomem *base = chip_data->host_data->base; in stm32_exti_h_retrigger()
617 u32 mask = BIT(d->hwirq % IRQS_PER_BANK); in stm32_exti_h_retrigger()
619 writel_relaxed(mask, base + stm32_bank->swier_ofst); in stm32_exti_h_retrigger()
625 .name = "stm32-exti-h",
637 .name = "stm32-exti-h-direct",
653 struct stm32_exti_host_data *host_data = dm->host_data; in stm32_exti_h_domain_alloc()
661 hwirq = fwspec->param[0]; in stm32_exti_h_domain_alloc()
663 chip_data = &host_data->chips_data[bank]; in stm32_exti_h_domain_alloc()
666 desc = stm32_exti_get_desc(host_data->drv_data, hwirq); in stm32_exti_h_domain_alloc()
668 return -EINVAL; in stm32_exti_h_domain_alloc()
670 irq_domain_set_hwirq_and_chip(dm, virq, hwirq, desc->chip, in stm32_exti_h_domain_alloc()
672 if (desc->irq_parent) { in stm32_exti_h_domain_alloc()
673 p_fwspec.fwnode = dm->parent->fwnode; in stm32_exti_h_domain_alloc()
676 p_fwspec.param[1] = desc->irq_parent; in stm32_exti_h_domain_alloc()
695 host_data->drv_data = dd; in stm32_exti_host_init()
696 host_data->chips_data = kcalloc(dd->bank_nr, in stm32_exti_host_init()
699 if (!host_data->chips_data) in stm32_exti_host_init()
702 host_data->base = of_iomap(node, 0); in stm32_exti_host_init()
703 if (!host_data->base) { in stm32_exti_host_init()
713 kfree(host_data->chips_data); in stm32_exti_host_init()
727 void __iomem *base = h_data->base; in stm32_exti_chip_init()
729 stm32_bank = h_data->drv_data->exti_banks[bank_idx]; in stm32_exti_chip_init()
730 chip_data = &h_data->chips_data[bank_idx]; in stm32_exti_chip_init()
731 chip_data->host_data = h_data; in stm32_exti_chip_init()
732 chip_data->reg_bank = stm32_bank; in stm32_exti_chip_init()
734 raw_spin_lock_init(&chip_data->rlock); in stm32_exti_chip_init()
740 writel_relaxed(0, base + stm32_bank->imr_ofst); in stm32_exti_chip_init()
741 writel_relaxed(0, base + stm32_bank->emr_ofst); in stm32_exti_chip_init()
759 return -ENOMEM; in stm32_exti_init()
761 domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK, in stm32_exti_init()
766 ret = -ENOMEM; in stm32_exti_init()
778 for (i = 0; i < drv_data->bank_nr; i++) { in stm32_exti_init()
782 stm32_bank = drv_data->exti_banks[i]; in stm32_exti_init()
787 gc->reg_base = host_data->base; in stm32_exti_init()
788 gc->chip_types->type = IRQ_TYPE_EDGE_BOTH; in stm32_exti_init()
789 gc->chip_types->chip.irq_ack = stm32_irq_ack; in stm32_exti_init()
790 gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; in stm32_exti_init()
791 gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit; in stm32_exti_init()
792 gc->chip_types->chip.irq_set_type = stm32_irq_set_type; in stm32_exti_init()
793 gc->chip_types->chip.irq_set_wake = irq_gc_set_wake; in stm32_exti_init()
794 gc->suspend = stm32_irq_suspend; in stm32_exti_init()
795 gc->resume = stm32_irq_resume; in stm32_exti_init()
796 gc->wake_enabled = IRQ_MSK(IRQS_PER_BANK); in stm32_exti_init()
798 gc->chip_types->regs.mask = stm32_bank->imr_ofst; in stm32_exti_init()
799 gc->private = (void *)chip_data; in stm32_exti_init()
815 iounmap(host_data->base); in stm32_exti_init()
816 kfree(host_data->chips_data); in stm32_exti_init()
843 struct device *dev = &pdev->dev; in stm32_exti_probe()
844 struct device_node *np = dev->of_node; in stm32_exti_probe()
852 return -ENOMEM; in stm32_exti_probe()
854 /* check for optional hwspinlock which may be not available yet */ in stm32_exti_probe()
856 if (ret == -EPROBE_DEFER) in stm32_exti_probe()
857 /* hwspinlock framework not yet ready */ in stm32_exti_probe()
861 host_data->hwlock = devm_hwspin_lock_request_specific(dev, ret); in stm32_exti_probe()
862 if (!host_data->hwlock) { in stm32_exti_probe()
863 dev_err(dev, "Failed to request hwspinlock\n"); in stm32_exti_probe()
864 return -EINVAL; in stm32_exti_probe()
866 } else if (ret != -ENOENT) { in stm32_exti_probe()
867 /* note: ENOENT is a valid case (means 'no hwspinlock') */ in stm32_exti_probe()
868 dev_err(dev, "Failed to get hwspinlock\n"); in stm32_exti_probe()
876 return -ENODEV; in stm32_exti_probe()
878 host_data->drv_data = drv_data; in stm32_exti_probe()
880 host_data->chips_data = devm_kcalloc(dev, drv_data->bank_nr, in stm32_exti_probe()
881 sizeof(*host_data->chips_data), in stm32_exti_probe()
883 if (!host_data->chips_data) in stm32_exti_probe()
884 return -ENOMEM; in stm32_exti_probe()
887 host_data->base = devm_ioremap_resource(dev, res); in stm32_exti_probe()
888 if (IS_ERR(host_data->base)) { in stm32_exti_probe()
890 return PTR_ERR(host_data->base); in stm32_exti_probe()
893 for (i = 0; i < drv_data->bank_nr; i++) in stm32_exti_probe()
898 dev_err(dev, "GIC interrupt-parent not found\n"); in stm32_exti_probe()
899 return -EINVAL; in stm32_exti_probe()
903 drv_data->bank_nr * IRQS_PER_BANK, in stm32_exti_probe()
909 return -ENOMEM; in stm32_exti_probe()
923 { .compatible = "st,stm32mp1-exti", .data = &stm32mp1_drv_data},
957 IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init);
965 IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init);