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:
Qianggui Song
2019-03-08 15:40:42 +08:00
committed by Dongjin Kim
parent c3ec245a76
commit f0b50e854c
4 changed files with 31 additions and 4 deletions

View File

@@ -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.

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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",