summaryrefslogtreecommitdiff
authorQianggui Song <qianggui.song@amlogic.com>2019-03-08 07:40:42 (GMT)
committer Jianxiong Pan <jianxiong.pan@amlogic.com>2019-03-29 12:24:31 (GMT)
commitf3c9ff52051f476e7038caff81bd80d220f4532a (patch)
tree7dc1d202670d8eaee3a0e44115917761785ffef3
parent633cfac2e02742b5b181f2f9282fb399358f2f9d (diff)
downloadcommon-f3c9ff52051f476e7038caff81bd80d220f4532a.zip
common-f3c9ff52051f476e7038caff81bd80d220f4532a.tar.gz
common-f3c9ff52051f476e7038caff81bd80d220f4532a.tar.bz2
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>
Diffstat
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt1
-rw-r--r--arch/arm/boot/dts/amlogic/mesonsm1.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/mesonsm1.dtsi2
-rw-r--r--drivers/amlogic/irqchip/irq-meson-gpio.c30
4 files changed, 31 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 4dfe69f..3f305fd 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -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.
diff --git a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
index 61d5b1f..9cb9d78 100644
--- a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
+++ b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
@@ -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>;
diff --git a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
index a3bddfe..906622a 100644
--- a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
@@ -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>;
diff --git a/drivers/amlogic/irqchip/irq-meson-gpio.c b/drivers/amlogic/irqchip/irq-meson-gpio.c
index a875b21..d353df4 100644
--- a/drivers/amlogic/irqchip/irq-meson-gpio.c
+++ b/drivers/amlogic/irqchip/irq-meson-gpio.c
@@ -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",