This is a test repository.
リビジョン | 6879c2d3b96039ff1668b4328a4d0dd3ea952cff (tree) |
---|---|
日時 | 2022-09-16 23:06:05 |
作者 | Linus Torvalds <torvalds@linu...> |
コミッター | Linus Torvalds |
Merge tag 'pinctrl-v6.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control fixes from Linus Walleij:
* tag 'pinctrl-v6.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
@@ -419,11 +419,11 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | ||
419 | 419 | goto out; |
420 | 420 | } else { |
421 | 421 | bank->toggle_edge_mode |= mask; |
422 | - level |= mask; | |
422 | + level &= ~mask; | |
423 | 423 | |
424 | 424 | /* |
425 | 425 | * Determine gpio state. If 1 next interrupt should be |
426 | - * falling otherwise rising. | |
426 | + * low otherwise high. | |
427 | 427 | */ |
428 | 428 | data = readl(bank->reg_base + bank->gpio_regs->ext_port); |
429 | 429 | if (data & mask) |
@@ -331,6 +331,7 @@ struct ocelot_pinctrl { | ||
331 | 331 | const struct ocelot_pincfg_data *pincfg_data; |
332 | 332 | struct ocelot_pmx_func func[FUNC_MAX]; |
333 | 333 | u8 stride; |
334 | + struct workqueue_struct *wq; | |
334 | 335 | }; |
335 | 336 | |
336 | 337 | struct ocelot_match_data { |
@@ -338,6 +339,11 @@ struct ocelot_match_data { | ||
338 | 339 | struct ocelot_pincfg_data pincfg_data; |
339 | 340 | }; |
340 | 341 | |
342 | +struct ocelot_irq_work { | |
343 | + struct work_struct irq_work; | |
344 | + struct irq_desc *irq_desc; | |
345 | +}; | |
346 | + | |
341 | 347 | #define LUTON_P(p, f0, f1) \ |
342 | 348 | static struct ocelot_pin_caps luton_pin_##p = { \ |
343 | 349 | .pin = p, \ |
@@ -1813,6 +1819,75 @@ static void ocelot_irq_mask(struct irq_data *data) | ||
1813 | 1819 | gpiochip_disable_irq(chip, gpio); |
1814 | 1820 | } |
1815 | 1821 | |
1822 | +static void ocelot_irq_work(struct work_struct *work) | |
1823 | +{ | |
1824 | + struct ocelot_irq_work *w = container_of(work, struct ocelot_irq_work, irq_work); | |
1825 | + struct irq_chip *parent_chip = irq_desc_get_chip(w->irq_desc); | |
1826 | + struct gpio_chip *chip = irq_desc_get_chip_data(w->irq_desc); | |
1827 | + struct irq_data *data = irq_desc_get_irq_data(w->irq_desc); | |
1828 | + unsigned int gpio = irqd_to_hwirq(data); | |
1829 | + | |
1830 | + local_irq_disable(); | |
1831 | + chained_irq_enter(parent_chip, w->irq_desc); | |
1832 | + generic_handle_domain_irq(chip->irq.domain, gpio); | |
1833 | + chained_irq_exit(parent_chip, w->irq_desc); | |
1834 | + local_irq_enable(); | |
1835 | + | |
1836 | + kfree(w); | |
1837 | +} | |
1838 | + | |
1839 | +static void ocelot_irq_unmask_level(struct irq_data *data) | |
1840 | +{ | |
1841 | + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
1842 | + struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
1843 | + struct irq_desc *desc = irq_data_to_desc(data); | |
1844 | + unsigned int gpio = irqd_to_hwirq(data); | |
1845 | + unsigned int bit = BIT(gpio % 32); | |
1846 | + bool ack = false, active = false; | |
1847 | + u8 trigger_level; | |
1848 | + int val; | |
1849 | + | |
1850 | + trigger_level = irqd_get_trigger_type(data); | |
1851 | + | |
1852 | + /* Check if the interrupt line is still active. */ | |
1853 | + regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val); | |
1854 | + if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) || | |
1855 | + (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH)) | |
1856 | + active = true; | |
1857 | + | |
1858 | + /* | |
1859 | + * Check if the interrupt controller has seen any changes in the | |
1860 | + * interrupt line. | |
1861 | + */ | |
1862 | + regmap_read(info->map, REG(OCELOT_GPIO_INTR, info, gpio), &val); | |
1863 | + if (val & bit) | |
1864 | + ack = true; | |
1865 | + | |
1866 | + /* Enable the interrupt now */ | |
1867 | + gpiochip_enable_irq(chip, gpio); | |
1868 | + regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), | |
1869 | + bit, bit); | |
1870 | + | |
1871 | + /* | |
1872 | + * In case the interrupt line is still active and the interrupt | |
1873 | + * controller has not seen any changes in the interrupt line, then it | |
1874 | + * means that there happen another interrupt while the line was active. | |
1875 | + * So we missed that one, so we need to kick the interrupt again | |
1876 | + * handler. | |
1877 | + */ | |
1878 | + if (active && !ack) { | |
1879 | + struct ocelot_irq_work *work; | |
1880 | + | |
1881 | + work = kmalloc(sizeof(*work), GFP_ATOMIC); | |
1882 | + if (!work) | |
1883 | + return; | |
1884 | + | |
1885 | + work->irq_desc = desc; | |
1886 | + INIT_WORK(&work->irq_work, ocelot_irq_work); | |
1887 | + queue_work(info->wq, &work->irq_work); | |
1888 | + } | |
1889 | +} | |
1890 | + | |
1816 | 1891 | static void ocelot_irq_unmask(struct irq_data *data) |
1817 | 1892 | { |
1818 | 1893 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); |
@@ -1836,13 +1911,12 @@ static void ocelot_irq_ack(struct irq_data *data) | ||
1836 | 1911 | |
1837 | 1912 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type); |
1838 | 1913 | |
1839 | -static struct irq_chip ocelot_eoi_irqchip = { | |
1914 | +static struct irq_chip ocelot_level_irqchip = { | |
1840 | 1915 | .name = "gpio", |
1841 | 1916 | .irq_mask = ocelot_irq_mask, |
1842 | - .irq_eoi = ocelot_irq_ack, | |
1843 | - .irq_unmask = ocelot_irq_unmask, | |
1844 | - .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | | |
1845 | - IRQCHIP_IMMUTABLE, | |
1917 | + .irq_ack = ocelot_irq_ack, | |
1918 | + .irq_unmask = ocelot_irq_unmask_level, | |
1919 | + .flags = IRQCHIP_IMMUTABLE, | |
1846 | 1920 | .irq_set_type = ocelot_irq_set_type, |
1847 | 1921 | GPIOCHIP_IRQ_RESOURCE_HELPERS |
1848 | 1922 | }; |
@@ -1859,14 +1933,9 @@ static struct irq_chip ocelot_irqchip = { | ||
1859 | 1933 | |
1860 | 1934 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type) |
1861 | 1935 | { |
1862 | - type &= IRQ_TYPE_SENSE_MASK; | |
1863 | - | |
1864 | - if (!(type & (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_HIGH))) | |
1865 | - return -EINVAL; | |
1866 | - | |
1867 | - if (type & IRQ_TYPE_LEVEL_HIGH) | |
1868 | - irq_set_chip_handler_name_locked(data, &ocelot_eoi_irqchip, | |
1869 | - handle_fasteoi_irq, NULL); | |
1936 | + if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | |
1937 | + irq_set_chip_handler_name_locked(data, &ocelot_level_irqchip, | |
1938 | + handle_level_irq, NULL); | |
1870 | 1939 | if (type & IRQ_TYPE_EDGE_BOTH) |
1871 | 1940 | irq_set_chip_handler_name_locked(data, &ocelot_irqchip, |
1872 | 1941 | handle_edge_irq, NULL); |
@@ -1996,6 +2065,10 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) | ||
1996 | 2065 | if (!info->desc) |
1997 | 2066 | return -ENOMEM; |
1998 | 2067 | |
2068 | + info->wq = alloc_ordered_workqueue("ocelot_ordered", 0); | |
2069 | + if (!info->wq) | |
2070 | + return -ENOMEM; | |
2071 | + | |
1999 | 2072 | info->pincfg_data = &data->pincfg_data; |
2000 | 2073 | |
2001 | 2074 | reset = devm_reset_control_get_optional_shared(dev, "switch"); |
@@ -2018,7 +2091,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) | ||
2018 | 2091 | dev_err(dev, "Failed to create regmap\n"); |
2019 | 2092 | return PTR_ERR(info->map); |
2020 | 2093 | } |
2021 | - dev_set_drvdata(dev, info->map); | |
2094 | + dev_set_drvdata(dev, info); | |
2022 | 2095 | info->dev = dev; |
2023 | 2096 | |
2024 | 2097 | /* Pinconf registers */ |
@@ -2043,6 +2116,15 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) | ||
2043 | 2116 | return 0; |
2044 | 2117 | } |
2045 | 2118 | |
2119 | +static int ocelot_pinctrl_remove(struct platform_device *pdev) | |
2120 | +{ | |
2121 | + struct ocelot_pinctrl *info = platform_get_drvdata(pdev); | |
2122 | + | |
2123 | + destroy_workqueue(info->wq); | |
2124 | + | |
2125 | + return 0; | |
2126 | +} | |
2127 | + | |
2046 | 2128 | static struct platform_driver ocelot_pinctrl_driver = { |
2047 | 2129 | .driver = { |
2048 | 2130 | .name = "pinctrl-ocelot", |
@@ -2050,6 +2132,7 @@ static struct platform_driver ocelot_pinctrl_driver = { | ||
2050 | 2132 | .suppress_bind_attrs = true, |
2051 | 2133 | }, |
2052 | 2134 | .probe = ocelot_pinctrl_probe, |
2135 | + .remove = ocelot_pinctrl_remove, | |
2053 | 2136 | }; |
2054 | 2137 | module_platform_driver(ocelot_pinctrl_driver); |
2055 | 2138 | MODULE_LICENSE("Dual MIT/GPL"); |
@@ -530,10 +530,10 @@ DECLARE_MSM_GPIO_PINS(187); | ||
530 | 530 | DECLARE_MSM_GPIO_PINS(188); |
531 | 531 | DECLARE_MSM_GPIO_PINS(189); |
532 | 532 | |
533 | -static const unsigned int sdc2_clk_pins[] = { 190 }; | |
534 | -static const unsigned int sdc2_cmd_pins[] = { 191 }; | |
535 | -static const unsigned int sdc2_data_pins[] = { 192 }; | |
536 | -static const unsigned int ufs_reset_pins[] = { 193 }; | |
533 | +static const unsigned int ufs_reset_pins[] = { 190 }; | |
534 | +static const unsigned int sdc2_clk_pins[] = { 191 }; | |
535 | +static const unsigned int sdc2_cmd_pins[] = { 192 }; | |
536 | +static const unsigned int sdc2_data_pins[] = { 193 }; | |
537 | 537 | |
538 | 538 | enum sc8180x_functions { |
539 | 539 | msm_mux_adsp_ext, |
@@ -1582,7 +1582,7 @@ static const int sc8180x_acpi_reserved_gpios[] = { | ||
1582 | 1582 | static const struct msm_gpio_wakeirq_map sc8180x_pdc_map[] = { |
1583 | 1583 | { 3, 31 }, { 5, 32 }, { 8, 33 }, { 9, 34 }, { 10, 100 }, { 12, 104 }, |
1584 | 1584 | { 24, 37 }, { 26, 38 }, { 27, 41 }, { 28, 42 }, { 30, 39 }, { 36, 43 }, |
1585 | - { 37, 43 }, { 38, 45 }, { 39, 118 }, { 39, 125 }, { 41, 47 }, | |
1585 | + { 37, 44 }, { 38, 45 }, { 39, 118 }, { 39, 125 }, { 41, 47 }, | |
1586 | 1586 | { 42, 48 }, { 46, 50 }, { 47, 49 }, { 48, 51 }, { 49, 53 }, { 50, 52 }, |
1587 | 1587 | { 51, 116 }, { 51, 123 }, { 53, 54 }, { 54, 55 }, { 55, 56 }, |
1588 | 1588 | { 56, 57 }, { 58, 58 }, { 60, 60 }, { 68, 62 }, { 70, 63 }, { 76, 86 }, |
@@ -99,7 +99,7 @@ MODULE_DEVICE_TABLE(of, a100_r_pinctrl_match); | ||
99 | 99 | static struct platform_driver a100_r_pinctrl_driver = { |
100 | 100 | .probe = a100_r_pinctrl_probe, |
101 | 101 | .driver = { |
102 | - .name = "sun50iw10p1-r-pinctrl", | |
102 | + .name = "sun50i-a100-r-pinctrl", | |
103 | 103 | .of_match_table = a100_r_pinctrl_match, |
104 | 104 | }, |
105 | 105 | }; |