Skip to content

Commit 6879c2d

Browse files
committed
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: "Nothing special, just driver fixes: - Fix IRQ wakeup and pins for UFS and SDC2 issues on the Qualcomm SC8180x - Fix the Rockchip driver to support interrupt on both rising and falling edges. - Name the Allwinner A100 R_PIO properly - Fix several issues with the Ocelot interrupts" * tag 'pinctrl-v6.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: pinctrl: ocelot: Fix interrupt controller pinctrl: sunxi: Fix name for A100 R_PIO pinctrl: rockchip: Enhance support for IRQ_TYPE_EDGE_BOTH pinctrl: qcom: sc8180x: Fix wrong pin numbers pinctrl: qcom: sc8180x: Fix gpio_wakeirq_map
2 parents 68e777e + c297561 commit 6879c2d

File tree

4 files changed

+105
-22
lines changed

4 files changed

+105
-22
lines changed

drivers/gpio/gpio-rockchip.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,11 +419,11 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
419419
goto out;
420420
} else {
421421
bank->toggle_edge_mode |= mask;
422-
level |= mask;
422+
level &= ~mask;
423423

424424
/*
425425
* Determine gpio state. If 1 next interrupt should be
426-
* falling otherwise rising.
426+
* low otherwise high.
427427
*/
428428
data = readl(bank->reg_base + bank->gpio_regs->ext_port);
429429
if (data & mask)

drivers/pinctrl/pinctrl-ocelot.c

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,19 @@ struct ocelot_pinctrl {
331331
const struct ocelot_pincfg_data *pincfg_data;
332332
struct ocelot_pmx_func func[FUNC_MAX];
333333
u8 stride;
334+
struct workqueue_struct *wq;
334335
};
335336

336337
struct ocelot_match_data {
337338
struct pinctrl_desc desc;
338339
struct ocelot_pincfg_data pincfg_data;
339340
};
340341

342+
struct ocelot_irq_work {
343+
struct work_struct irq_work;
344+
struct irq_desc *irq_desc;
345+
};
346+
341347
#define LUTON_P(p, f0, f1) \
342348
static struct ocelot_pin_caps luton_pin_##p = { \
343349
.pin = p, \
@@ -1813,6 +1819,75 @@ static void ocelot_irq_mask(struct irq_data *data)
18131819
gpiochip_disable_irq(chip, gpio);
18141820
}
18151821

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+
18161891
static void ocelot_irq_unmask(struct irq_data *data)
18171892
{
18181893
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
@@ -1836,13 +1911,12 @@ static void ocelot_irq_ack(struct irq_data *data)
18361911

18371912
static int ocelot_irq_set_type(struct irq_data *data, unsigned int type);
18381913

1839-
static struct irq_chip ocelot_eoi_irqchip = {
1914+
static struct irq_chip ocelot_level_irqchip = {
18401915
.name = "gpio",
18411916
.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,
18461920
.irq_set_type = ocelot_irq_set_type,
18471921
GPIOCHIP_IRQ_RESOURCE_HELPERS
18481922
};
@@ -1859,14 +1933,9 @@ static struct irq_chip ocelot_irqchip = {
18591933

18601934
static int ocelot_irq_set_type(struct irq_data *data, unsigned int type)
18611935
{
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);
18701939
if (type & IRQ_TYPE_EDGE_BOTH)
18711940
irq_set_chip_handler_name_locked(data, &ocelot_irqchip,
18721941
handle_edge_irq, NULL);
@@ -1996,6 +2065,10 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
19962065
if (!info->desc)
19972066
return -ENOMEM;
19982067

2068+
info->wq = alloc_ordered_workqueue("ocelot_ordered", 0);
2069+
if (!info->wq)
2070+
return -ENOMEM;
2071+
19992072
info->pincfg_data = &data->pincfg_data;
20002073

20012074
reset = devm_reset_control_get_optional_shared(dev, "switch");
@@ -2018,7 +2091,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
20182091
dev_err(dev, "Failed to create regmap\n");
20192092
return PTR_ERR(info->map);
20202093
}
2021-
dev_set_drvdata(dev, info->map);
2094+
dev_set_drvdata(dev, info);
20222095
info->dev = dev;
20232096

20242097
/* Pinconf registers */
@@ -2043,13 +2116,23 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
20432116
return 0;
20442117
}
20452118

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+
20462128
static struct platform_driver ocelot_pinctrl_driver = {
20472129
.driver = {
20482130
.name = "pinctrl-ocelot",
20492131
.of_match_table = of_match_ptr(ocelot_pinctrl_of_match),
20502132
.suppress_bind_attrs = true,
20512133
},
20522134
.probe = ocelot_pinctrl_probe,
2135+
.remove = ocelot_pinctrl_remove,
20532136
};
20542137
module_platform_driver(ocelot_pinctrl_driver);
20552138
MODULE_LICENSE("Dual MIT/GPL");

drivers/pinctrl/qcom/pinctrl-sc8180x.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,10 @@ DECLARE_MSM_GPIO_PINS(187);
530530
DECLARE_MSM_GPIO_PINS(188);
531531
DECLARE_MSM_GPIO_PINS(189);
532532

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 };
537537

538538
enum sc8180x_functions {
539539
msm_mux_adsp_ext,
@@ -1582,7 +1582,7 @@ static const int sc8180x_acpi_reserved_gpios[] = {
15821582
static const struct msm_gpio_wakeirq_map sc8180x_pdc_map[] = {
15831583
{ 3, 31 }, { 5, 32 }, { 8, 33 }, { 9, 34 }, { 10, 100 }, { 12, 104 },
15841584
{ 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 },
15861586
{ 42, 48 }, { 46, 50 }, { 47, 49 }, { 48, 51 }, { 49, 53 }, { 50, 52 },
15871587
{ 51, 116 }, { 51, 123 }, { 53, 54 }, { 54, 55 }, { 55, 56 },
15881588
{ 56, 57 }, { 58, 58 }, { 60, 60 }, { 68, 62 }, { 70, 63 }, { 76, 86 },

drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ MODULE_DEVICE_TABLE(of, a100_r_pinctrl_match);
9999
static struct platform_driver a100_r_pinctrl_driver = {
100100
.probe = a100_r_pinctrl_probe,
101101
.driver = {
102-
.name = "sun50iw10p1-r-pinctrl",
102+
.name = "sun50i-a100-r-pinctrl",
103103
.of_match_table = a100_r_pinctrl_match,
104104
},
105105
};

0 commit comments

Comments
 (0)