mtk kernel 设置EINT中断响应

本文环境

  • mt6797
  • kernel 3.18
  • android 6.0

DTS设置

&eintc {
    irq_my_irq@3 {
        compatible = "eint, my-irq";
        interrupt-parent = <&eintc>;
        interrupts = <65 IRQ_TYPE_EDGE_RISING>;
        debounce = <65 0>;
    };
    irq_my_gpio@3 {
        compatible = "eint, my-gpio";
        interrupt-parent = <&eintc>;
        interrupts = <179 IRQ_TYPE_EDGE_RISING>;
        debounce = <179 0>;
    };
};

{
    //...
    pinctrl-names = "default", "my_irq_as_int", "nor_irq_as_gpio";
    pinctrl-0 = <&pins_default>;
    pinctrl-1 = <&pins_my_irq_as_int>;
    pinctrl-2 = <&pins_normal_irq_as_gpio>;
};

&pio {
    pins_default: eint0default {
    };
    pins_my_irq_as_int: eint@0 {
        pins_cmd_dat {
            pins = ;
            slew-rate = <0>;
            bias-disable;
        };
    };
    pins_normal_irq_as_gpio: normal_irq_as_gpio@0 {
        pins_cmd_dat {
            pins = ;
            slew-rate = <0>;
            bias-disable;
        };
    };
};

driver配置


struct pinctrl *my_pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *my_irq_as_int, *nor_irq_as_gpio;

int parse_dt(struct platform_device *pdev)
{
    //...
    my_pinctrl = devm_pinctrl_get(&pdev->dev);
    if (IS_ERR(my_pinctrl)) {
        ret = PTR_ERR(my_pinctrl);
        dev_err(&pdev->dev, "failed to find pinctrl!\n");
        return ret;
    }
    pins_default = pinctrl_lookup_state(my_pinctrl, "default");
    if (IS_ERR(pins_default)) {
        ret = PTR_ERR(pins_default);
        dev_err(&pdev->dev, "cannot find default: %d!\n", ret);
    }
    my_irq_as_int= pinctrl_lookup_state(my_pinctrl, "my_irq_as_int");
    if (IS_ERR(my_irq_as_int)) {
        ret = PTR_ERR(my_irq_as_int);
        dev_err(&pdev->dev, "cannot find my_irq_as_int\n");
        return ret;
    }
    nor_irq_as_gpio = pinctrl_lookup_state(my_pinctrl, "nor_irq_as_gpio");
}
// 设置INT
int my_probe(*dev)
{
    // ...
    pinctrl_select_state(my_pinctrl, eint_as_int);
    pinctrl_select_state(my_pinctrl, nor_irq_as_gpio);
    // ...
}

static struct of_device_id my_irq_match[] = {
    {.compatible = "eint,my-irq", },
};
static struct of_device_id my_gpio_match[] = {
    {.compatible = "eint,my-gpio", },
};
// 中断响应函数
static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
    //...
    return IRQ_HANDLED;
}
// 关联注册中断响应函数
int my_register_irq(void)
{
    struct device_node *node = NULL;
    int ret = 0;
    int irq;

    node = of_find_matching_node(node, my_irq_match);
    if (NULL == node) {
        pr_err("Can not find eint node!");
        return -ENODATA;
    }

    irq = irq_of_parse_and_map(node, 0); 
    pr_debug("%s irq: %d", my_irq_match->compatible, irq);

    ret = request_irq(irq, my_irq_handler,
                      IRQF_TRIGGER_FALLING, "my-irq", NULL);
    return ret;
}
#define GPIO_MY_IRQ_GPIO (GPIO179)
int my_register_irq_gpio(void)
{
    struct device_node *node = NULL;
    int ret = 0;
    int irq;
    int gpio = GPIO_MY_IRQ_GPIO;

    /* request irq gpio */
    if (gpio_is_valid(gpio)) {
        ret = gpio_request(gpio, "irq_gpio");
        if (ret) {
            pr_err("irq gpio request failed");
        }

        ret = gpio_direction_input(gpio);
        if (ret) {
            pr_err("set_direction for irq gpio failed");
        }
    } else {
        pr_err("gpio: %d invalid", gpio);
    }

    node = of_find_matching_node(node, my_gpio_match);
    if (NULL == node) {
        pr_err("Can not find eint node!");
        return -ENODATA;
    }

    irq = irq_of_parse_and_map(node, 0); 
    pr_debug("%s irq: %d", my_gpio_match->compatible, irq);

    ret = request_irq(irq, my_irq_handler,
                      IRQF_TRIGGER_FALLING, "my-gpio-irq", NULL);
    return ret;
}

你可能感兴趣的:(Linux,Android)