Message ID | 1421202745.27675.148.camel@mtksdaap41 (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jan 14, 2015 at 3:32 AM, Yingjoe Chen <yingjoe.chen@mediatek.com> wrote: > Let's me describe my problem more clearly. On our SoC, if a pin support > interrupt it will have 2 different numbers for it. For examples, here's > a partial list for the gpio and EINT number mappings on mt8135: > > gpio EINT > 0 49 > 1 48 > ........... > 36 97 > 37 19 > ........... > > To control interrupt related function, we'll need EINT number to locate > corresponding register bits. When interrupt occurs, the interrupt > handler will know which EINT interrupt occurs. In irq_chip functions, > only .irq_request_resources and .irq_release_resources use gpio number > to set pinmux to EINT mode and all the others need EINT number. > > Because EINT number is used more frequently in interrupt related > functions, it make sense to use EINT number as hwirq instead of gpio > number. That means irq_domain will translate EINT number to virq. > So what mtk_gpio_to_irq actually do is translate gpio number to EINT > number and use irq domain to translate it to virq. But the EINT is not a hardware number is it? That sounds like an abuse of the irqdomain framework. The purpose of that code is to map hardware IRQs to Linux IRQs nothing else. This sounds more like mapping a Linux IRQ (the EINT) to another Linux IRQ (whatever the irqdomain allocates for you). Since the EINTs are already Linux IRQs, these should be used directly. I would solve this by just having some cross-reference table for mapping GPIOs to EINTs without involving the irqdomain at all. struct eint_map { int gpio_offset; int eint; }; But also check with the irqdomain people. Yours, Linus Walleij
On Thu, 2015-01-15 at 18:30 +0100, Linus Walleij wrote: > On Wed, Jan 14, 2015 at 3:32 AM, Yingjoe Chen <yingjoe.chen@mediatek.com> wrote: > > > Let's me describe my problem more clearly. On our SoC, if a pin support > > interrupt it will have 2 different numbers for it. For examples, here's > > a partial list for the gpio and EINT number mappings on mt8135: > > > > gpio EINT > > 0 49 > > 1 48 > > ........... > > 36 97 > > 37 19 > > ........... > > > > To control interrupt related function, we'll need EINT number to locate > > corresponding register bits. When interrupt occurs, the interrupt > > handler will know which EINT interrupt occurs. In irq_chip functions, > > only .irq_request_resources and .irq_release_resources use gpio number > > to set pinmux to EINT mode and all the others need EINT number. > > > > Because EINT number is used more frequently in interrupt related > > functions, it make sense to use EINT number as hwirq instead of gpio > > number. That means irq_domain will translate EINT number to virq. > > So what mtk_gpio_to_irq actually do is translate gpio number to EINT > > number and use irq domain to translate it to virq. > > But the EINT is not a hardware number is it? It is a hardware number. eg, to mask irq for the gpio 0 above, we have to set bit49 in EINT mask_set register. When this irq triggered, it is reported using EINT status register bit49. We can find out EINT number for a GPIO using mtk_desc_pin tables. In drivers/pinctrl/mediatek/pinctrl-mtk-mt8135.h, for GPIO0, we can see its EINT is 49 and must set to function 2 for EINT. I believe this is similar to sunxi. MTK_PIN( PINCTRL_PIN(0, "MSDC0_DAT7"), "D21", "mt8135", MTK_EINT_FUNCTION(2, 49), MTK_FUNCTION(0, "GPIO0"), MTK_FUNCTION(1, "MSDC0_DAT7"), MTK_FUNCTION(2, "EINT49"), MTK_FUNCTION(3, "I2SOUT_DAT"), MTK_FUNCTION(4, "DAC_DAT_OUT"), MTK_FUNCTION(5, "PCM1_DO"), MTK_FUNCTION(6, "SPI1_MO"), MTK_FUNCTION(7, "NALE") ), Joe.C
On Fri, Jan 16, 2015 at 3:50 AM, Yingjoe Chen <yingjoe.chen@mediatek.com> wrote: > On Thu, 2015-01-15 at 18:30 +0100, Linus Walleij wrote: >> But the EINT is not a hardware number is it? > > It is a hardware number. eg, to mask irq for the gpio 0 above, we have > to set bit49 in EINT mask_set register. When this irq triggered, it is > reported using EINT status register bit49. OK I get it (finally) then you should indeed use the irqdomain for it... It's just a bit confusing that it begins at offset 49... Yours, Linus Walleij
======================= --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -567,11 +567,14 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) * the pins on the gpiochip can generate a unique IRQ. Everything else * need to be open coded. */ -int gpiochip_irqchip_add(struct gpio_chip *gpiochip, - struct irq_chip *irqchip, - unsigned int first_irq, - irq_flow_handler_t handler, - unsigned int type) +int gpiochip_irqchip_add_with_map(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + unsigned int first_irq, + irq_flow_handler_t handler, + unsigned int type, + unsigned int size, + int (*to_irq_func)(struct gpio_chip *chip, + unsigned offset)) { struct device_node *of_node;