mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
irqchip: sm1 support double-edge gpio irq trigger [1/1]
PD#SWPL-5395 Problem: sm1 support double-edge trigger, current code do not support. Solution: add relatvie bitmask to support this function. Verify: ptm & sm1_skt Change-Id: I48ebc9b38db868f946c49b6fd5f98d427b2669df Signed-off-by: Qianggui Song <qianggui.song@amlogic.com>
This commit is contained in:
committed by
Dongjin Kim
parent
c3ec245a76
commit
f0b50e854c
@@ -19,6 +19,7 @@ Required properties:
|
||||
“amlogic,meson-g12a-gpio-intc” for G12A SoCs (S905D2, S905X2, S905Y2)
|
||||
“amlogic,meson-txl-gpio-intc” for TXL SoCs (T950, T952, T960, T962)
|
||||
“amlogic,meson-tl1-gpio-intc” for TL1 SoCs (T962X2)
|
||||
“amlogic,meson-sm1-gpio-intc” for SM1 SoCs (S905D3, S905X3, S905Y3)
|
||||
- interrupt-parent : a phandle to the GIC the interrupts are routed to.
|
||||
Usually this is provided at the root level of the device tree as it is
|
||||
common to most of the SoC.
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
|
||||
gpio_intc: interrupt-controller@f080 {
|
||||
compatible = "amlogic,meson-gpio-intc",
|
||||
"amlogic,meson-g12a-gpio-intc";
|
||||
"amlogic,meson-sm1-gpio-intc";
|
||||
reg = <0xf080 0x10>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
|
||||
gpio_intc: interrupt-controller@f080 {
|
||||
compatible = "amlogic,meson-gpio-intc",
|
||||
"amlogic,meson-g12a-gpio-intc";
|
||||
"amlogic,meson-sm1-gpio-intc";
|
||||
reg = <0x0 0xf080 0x0 0x10>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
#define REG_EDGE_POL_MASK(x) (BIT(x) | BIT(16 + (x)))
|
||||
#define REG_EDGE_POL_EDGE(x) BIT(x)
|
||||
#define REG_EDGE_POL_LOW(x) BIT(16 + (x))
|
||||
#define REG_EDGE_BOTH_EDGE(x) BIT(8 + (x))
|
||||
#define REG_PIN_SEL_SHIFT(x) (((x) % 4) * 8)
|
||||
#define REG_FILTER_SEL_SHIFT(x) ((x) * 4)
|
||||
|
||||
struct meson_gpio_irq_params {
|
||||
unsigned int nr_hwirq;
|
||||
u8 support_double_edge;
|
||||
};
|
||||
|
||||
static const struct meson_gpio_irq_params meson8_params = {
|
||||
@@ -83,6 +85,11 @@ static const struct meson_gpio_irq_params tl1_params = {
|
||||
.nr_hwirq = 102,
|
||||
};
|
||||
|
||||
static const struct meson_gpio_irq_params sm1_params = {
|
||||
.nr_hwirq = 100,
|
||||
.support_double_edge = 1,
|
||||
};
|
||||
|
||||
static const struct of_device_id meson_irq_gpio_matches[] = {
|
||||
{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
|
||||
{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
|
||||
@@ -93,11 +100,13 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
|
||||
{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &g12a_params },
|
||||
{ .compatible = "amlogic,meson-txl-gpio-intc", .data = &txl_params },
|
||||
{ .compatible = "amlogic,meson-tl1-gpio-intc", .data = &tl1_params },
|
||||
{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
|
||||
{ }
|
||||
};
|
||||
|
||||
struct meson_gpio_irq_controller {
|
||||
unsigned int nr_hwirq;
|
||||
u8 support_double_edge;
|
||||
void __iomem *base;
|
||||
u32 channel_irqs[NUM_CHANNEL];
|
||||
DECLARE_BITMAP(channel_map, NUM_CHANNEL);
|
||||
@@ -200,8 +209,16 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
|
||||
*/
|
||||
type &= IRQ_TYPE_SENSE_MASK;
|
||||
|
||||
if (type == IRQ_TYPE_EDGE_BOTH)
|
||||
return -EINVAL;
|
||||
if (type == IRQ_TYPE_EDGE_BOTH) {
|
||||
if (!ctl->support_double_edge)
|
||||
return -EINVAL;
|
||||
val |= REG_EDGE_BOTH_EDGE(idx);
|
||||
spin_lock(&ctl->lock);
|
||||
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
|
||||
REG_EDGE_BOTH_EDGE(idx), val);
|
||||
spin_unlock(&ctl->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
|
||||
val |= REG_EDGE_POL_EDGE(idx);
|
||||
@@ -211,6 +228,14 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
|
||||
|
||||
spin_lock(&ctl->lock);
|
||||
|
||||
/* Double-edge has priority over all others. If a double-edge gpio
|
||||
* changes to another method's, we need to reset the corresponding bit
|
||||
* of double-edge register.
|
||||
*/
|
||||
if (ctl->support_double_edge)
|
||||
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
|
||||
REG_EDGE_BOTH_EDGE(idx), 0);
|
||||
|
||||
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
|
||||
REG_EDGE_POL_MASK(idx), val);
|
||||
|
||||
@@ -369,6 +394,7 @@ static int __init meson_gpio_irq_parse_dt(struct device_node *node,
|
||||
|
||||
params = match->data;
|
||||
ctl->nr_hwirq = params->nr_hwirq;
|
||||
ctl->support_double_edge = params->support_double_edge;
|
||||
|
||||
ret = of_property_read_variable_u32_array(node,
|
||||
"amlogic,channel-interrupts",
|
||||
|
||||
Reference in New Issue
Block a user