Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'regmap-fix-v6.17-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap fixes from Mark Brown:
"These patches fix a lockdep issue Russell King reported with nested
regmap-irqs (unusual since regmap is generally for devices on slow
buses so devices don't get nested), plus add a missing mutex free
which I noticed while implementing a fix for that issue"

* tag 'regmap-fix-v6.17-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: irq: Avoid lockdep warnings with nested regmap-irq chips
regmap: irq: Free the regmap-irq mutex

+21 -9
+21 -9
drivers/base/regmap/regmap-irq.c
··· 21 21 22 22 struct regmap_irq_chip_data { 23 23 struct mutex lock; 24 + struct lock_class_key lock_key; 24 25 struct irq_chip irq_chip; 25 26 26 27 struct regmap *map; ··· 802 801 goto err_alloc; 803 802 } 804 803 805 - mutex_init(&d->lock); 804 + /* 805 + * If one regmap-irq is the parent of another then we'll try 806 + * to lock the child with the parent locked, use an explicit 807 + * lock_key so lockdep can figure out what's going on. 808 + */ 809 + lockdep_register_key(&d->lock_key); 810 + mutex_init_with_key(&d->lock, &d->lock_key); 806 811 807 812 for (i = 0; i < chip->num_irqs; i++) 808 813 d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] ··· 823 816 d->mask_buf[i], 824 817 chip->irq_drv_data); 825 818 if (ret) 826 - goto err_alloc; 819 + goto err_mutex; 827 820 } 828 821 829 822 if (chip->mask_base && !chip->handle_mask_sync) { ··· 834 827 if (ret) { 835 828 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", 836 829 reg, ret); 837 - goto err_alloc; 830 + goto err_mutex; 838 831 } 839 832 } 840 833 ··· 845 838 if (ret) { 846 839 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", 847 840 reg, ret); 848 - goto err_alloc; 841 + goto err_mutex; 849 842 } 850 843 } 851 844 ··· 862 855 if (ret != 0) { 863 856 dev_err(map->dev, "Failed to read IRQ status: %d\n", 864 857 ret); 865 - goto err_alloc; 858 + goto err_mutex; 866 859 } 867 860 } 868 861 ··· 886 879 if (ret != 0) { 887 880 dev_err(map->dev, "Failed to ack 0x%x: %d\n", 888 881 reg, ret); 889 - goto err_alloc; 882 + goto err_mutex; 890 883 } 891 884 } 892 885 } ··· 908 901 if (ret != 0) { 909 902 dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", 910 903 reg, ret); 911 - goto err_alloc; 904 + goto err_mutex; 912 905 } 913 906 } 914 907 } ··· 917 910 if (chip->status_is_level) { 918 911 ret = read_irq_data(d); 919 912 if (ret < 0) 920 - goto err_alloc; 913 + goto err_mutex; 921 914 922 915 memcpy(d->prev_status_buf, d->status_buf, 923 916 array_size(d->chip->num_regs, sizeof(d->prev_status_buf[0]))); ··· 925 918 926 919 ret = regmap_irq_create_domain(fwnode, irq_base, chip, d); 927 920 if (ret) 928 - goto err_alloc; 921 + goto err_mutex; 929 922 930 923 ret = request_threaded_irq(irq, NULL, regmap_irq_thread, 931 924 irq_flags | IRQF_ONESHOT, ··· 942 935 943 936 err_domain: 944 937 /* Should really dispose of the domain but... */ 938 + err_mutex: 939 + mutex_destroy(&d->lock); 940 + lockdep_unregister_key(&d->lock_key); 945 941 err_alloc: 946 942 kfree(d->type_buf); 947 943 kfree(d->type_buf_def); ··· 1037 1027 kfree(d->config_buf[i]); 1038 1028 kfree(d->config_buf); 1039 1029 } 1030 + mutex_destroy(&d->lock); 1031 + lockdep_unregister_key(&d->lock_key); 1040 1032 kfree(d); 1041 1033 } 1042 1034 EXPORT_SYMBOL_GPL(regmap_del_irq_chip);