Message ID | 1598070473-46624-1-git-send-email-dingtianhong@huawei.com |
---|---|
State | New |
Headers | show |
Series | gpio: dwapb: add support for new hisilicon ascend soc | expand |
Hello Ding, Thanks for the patch. My comments are below. On Sat, Aug 22, 2020 at 12:27:53PM +0800, Ding Tianhong wrote: > The hisilicon ascend soc's gpio is based on the synopsys DW gpio, > and expand the register to support for INTCOMB_MASK, the new > register is used to enable/disable the interrupt combine features. I am wondering what does the "Interrupt Combine" feature do? Is it the same as the GPIO_INTR_IO pre-synthesize parameter of the DW_apb_gpio IP-core? Is it possible to tune the DW APB GPIO controller at runtime sending up to the IRQ controller either combined or individual interrupts? If the later is true, then probably having the "Interrupt Combine" feature enabled must depend on whether an individual or combined interrupts are supplied in dts, etc... Could you explain the way the feature works and the corresponding layout register in more details? > > Both support for ACPI and Device Tree. > > Signed-off-by: Ding Tianhong <dingtianhong@huawei.com> > --- > drivers/gpio/gpio-dwapb.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c > index 1d8d55b..923b381 100644 > --- a/drivers/gpio/gpio-dwapb.c > +++ b/drivers/gpio/gpio-dwapb.c > @@ -49,6 +49,8 @@ > #define GPIO_EXT_PORTC 0x58 > #define GPIO_EXT_PORTD 0x5c > > +#define GPIO_INTCOMB_MASK 0xffc If the register is the HiSilicon Ascend SoC specific, then I'd suggest to add the vendor-specific prefix like: GPIO_HS_INTCOMB_MASK. Also pay attention to the register naming. Here you define it as "INTCOMB", later as "INT_COMB". It's better to have the same references everywhere: either with underscore or without it. Also please move the new register definition to be after the corresponding feature macro definition (see the next comment for detailts). > + > #define DWAPB_DRIVER_NAME "gpio-dwapb" > #define DWAPB_MAX_PORTS 4 > > @@ -58,6 +60,10 @@ > > #define GPIO_REG_OFFSET_V2 1 > > +#define GPIO_REG_INT_COMB 2 Please move this macro to be define after the "GPIO_PORTA_EOI_V2" one, so to make the blocked-like macro definitions order. Like this: #define GPIO_REG_OFFSET_V2 BIT(0) // Reg V2 Feature macro #define GPIO_INTMASK_V2 0x44 // Reg V2-specific macro ... #define GPIO_PORTA_EOI_V2 0x40 // Reg V2-specific macro + #define GPIO_REG_HS_INTCOMB BIT(1) // HiSilicon Feature macro + + #define GPIO_HS_INTCOMB_MASK 0xffc // HiSilicon-specific macro + I missed that in my series, but having the flags defined as decimals isn't good. Could you convert GPIO_REG_HS_INTCOMB and GPIO_REG_OFFSET_V2 to be defined as BIT(x)? The same comment about HS_-prefixing. Perhaps GPIO_REG_HS_INTCOMB? > +#define ENABLE_INT_COMB 1 > +#define DISABLE_INT_COMB 0 I don't really see a point in having these two macros defined. They are basically just the boolean flags. Please see my next comment. > + > #define GPIO_INTMASK_V2 0x44 > #define GPIO_INTTYPE_LEVEL_V2 0x34 > #define GPIO_INT_POLARITY_V2 0x38 > @@ -354,6 +360,20 @@ static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id) > return IRQ_RETVAL(dwapb_do_irq(dev_id)); > } > > +static void dwapb_enable_inq_combine(struct dwapb_gpio *gpio, unsigned int enable) inq_combine or int_combine? "enable" is used here as boolean, then it should be declared as one. > +{ > + u32 val; > + > + if (gpio->flags & GPIO_REG_INT_COMB) { > + val = dwapb_read(gpio, GPIO_INTCOMB_MASK); > + if (enable) > + val |= BIT(0); > + else > + val &= BIT(0); > + dwapb_write(gpio, GPIO_INTCOMB_MASK, val); > + } > +} > + Do you need to preserve the register content by using the read-modify-write procedure here? If not, then inlining something like this should be fine: if (gpio->flags & GPIO_REG_HS_INTCOMB) dwapb_write(gpio, GPIO_HS_INTCOMB_MASK, 1); > static void dwapb_configure_irqs(struct dwapb_gpio *gpio, > struct dwapb_gpio_port *port, > struct dwapb_port_property *pp) > @@ -446,6 +466,8 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, > irq_create_mapping(gpio->domain, hwirq); > > port->gc.to_irq = dwapb_gpio_to_irq; > + > + dwapb_enable_inq_combine(gpio, ENABLE_INT_COMB); > } > > static void dwapb_irq_teardown(struct dwapb_gpio *gpio) > @@ -618,6 +640,7 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) > static const struct of_device_id dwapb_of_match[] = { > { .compatible = "snps,dw-apb-gpio", .data = (void *)0}, > { .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2}, > + { .compatible = "hisi,ascend-gpio", .data = (void *)GPIO_REG_INT_COMB}, > { /* Sentinel */ } > }; > MODULE_DEVICE_TABLE(of, dwapb_of_match); > @@ -626,6 +649,7 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) > {"HISI0181", 0}, > {"APMC0D07", 0}, > {"APMC0D81", GPIO_REG_OFFSET_V2}, > + {"HISI19XX", GPIO_REG_INT_COMB}, > { } > }; > MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match); > @@ -713,6 +737,8 @@ static int dwapb_gpio_remove(struct platform_device *pdev) > reset_control_assert(gpio->rst); > clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); > > + dwapb_enable_inq_combine(gpio, DISABLE_INT_COMB); > + > return 0; > } Note the dwapb_gpio_remove method will be discarded from the driver in the framework of the next series: https://patchwork.ozlabs.org/project/linux-gpio/list/?series=193334 So if you really need to revert the GPIO_HS_INTCOMB_MASK flag setting, then you'd need to create and register a dedicated devm-action (see 8 and 9 patch in my series for example). BTW Linus, could you take a look at my series? Andy and Rob have finished reviewing it almost a month ago. -Sergey > > @@ -794,6 +820,8 @@ static int dwapb_gpio_resume(struct device *dev) > dwapb_write(gpio, GPIO_INTEN, ctx->int_en); > dwapb_write(gpio, GPIO_INTMASK, ctx->int_mask); > > + dwapb_enable_inq_combine(gpio, ENABLE_INT_COMB); > + > /* Clear out spurious interrupts */ > dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff); > } > -- > 1.8.3.1 >
On Tue, Aug 25, 2020 at 12:58 PM Serge Semin <fancer.lancer@gmail.com> wrote: > On Sat, Aug 22, 2020 at 12:27:53PM +0800, Ding Tianhong wrote: > BTW Linus, could you take a look at my series? Andy and Rob have finished reviewing > it almost a month ago. I was wondering the same, but in normal cases (not closer to the merge window) Bart is taking care of drivers/gpio (AFAIU). -- With Best Regards, Andy Shevchenko
On Thu, Aug 27, 2020 at 10:20 AM Andy Shevchenko <andy.shevchenko@gmail.com> wrote: > On Tue, Aug 25, 2020 at 12:58 PM Serge Semin <fancer.lancer@gmail.com> wrote: > > On Sat, Aug 22, 2020 at 12:27:53PM +0800, Ding Tianhong wrote: > > > BTW Linus, could you take a look at my series? Andy and Rob have finished reviewing > > it almost a month ago. > > I was wondering the same, but in normal cases (not closer to the merge > window) Bart is taking care of drivers/gpio (AFAIU). I just had too much to do, sorry folks :/ It is queued now. Yours, Linus Walleij
On Thu, Aug 27, 2020 at 10:20 AM Andy Shevchenko <andy.shevchenko@gmail.com> wrote: > > On Tue, Aug 25, 2020 at 12:58 PM Serge Semin <fancer.lancer@gmail.com> wrote: > > On Sat, Aug 22, 2020 at 12:27:53PM +0800, Ding Tianhong wrote: > > > BTW Linus, could you take a look at my series? Andy and Rob have finished reviewing > > it almost a month ago. > > I was wondering the same, but in normal cases (not closer to the merge > window) Bart is taking care of drivers/gpio (AFAIU). > > Yeah, normally I'd have queued it by now but I'm only coming back to 100% activity on Tuesday - I was on a leave since July so I was rather inactive lately. Bartosz
On Sun, Sep 06, 2020 at 06:18:07AM +0000, Dingtianhong wrote: [...] > > On Sat, Aug 22, 2020 at 12:27:53PM +0800, Ding Tianhong wrote: > >> The hisilicon ascend soc's gpio is based on the synopsys DW gpio, > >> and expand the register to support for INTCOMB_MASK, the new > >> register is used to enable/disable the interrupt combine features. > > > > I am wondering what does the "Interrupt Combine" feature do? Is it the same as > > the GPIO_INTR_IO pre-synthesize parameter of the DW_apb_gpio IP-core? Is it > > possible to tune the DW APB GPIO controller at runtime sending up to the IRQ > > controller either combined or individual interrupts? > > > > looks like the same. > > > If the later is true, then probably having the "Interrupt Combine" feature > > enabled must depend on whether an individual or combined interrupts are supplied > > in dts, etc... > > > > needed. > > > Could you explain the way the feature works and the corresponding layout > > register in more details? > > > > Ok > The hisilicon chip use the register called GPIO_INTCOMB_MASK (offset is 0xffc) to enable the combien interrupt. > it is very simple, if GPIO_INTCOMB_MASK.bit0 is 0, then all combine interrupte could not be used (default > setting), otherwise if 1, then the 32 ports could use the same irq line, that is all. The main question is whether your hardware is capable of working with both combined and individual interrupts. Is your version of the DW APB GPIO controller able to generate both types of them? How is it connected to the parental interrupt controller? So If the GPIO and IRQ controllers are attached to each other with a single lane gpio_intr_flag, then indeed it's pure combined IRQ design and we'll have to make sure that GPIO_INTCOMB_MASK.bit0 is set to one before using the DW GPIO block. If they are also connected with each other by 32 individual GPIO-IRQ gpio_intr{_n}N lanes, then setting or clearing of the GPIO_INTCOMB_MASK.bit0 flag will for example depend on the number IRQ lanes specified in a dts file. In the later case the patch needs to be altered, but it would provide a better support of the hisilicon ascend soc's GPIO capabilities. -Sergey
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 1d8d55b..923b381 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -49,6 +49,8 @@ #define GPIO_EXT_PORTC 0x58 #define GPIO_EXT_PORTD 0x5c +#define GPIO_INTCOMB_MASK 0xffc + #define DWAPB_DRIVER_NAME "gpio-dwapb" #define DWAPB_MAX_PORTS 4 @@ -58,6 +60,10 @@ #define GPIO_REG_OFFSET_V2 1 +#define GPIO_REG_INT_COMB 2 +#define ENABLE_INT_COMB 1 +#define DISABLE_INT_COMB 0 + #define GPIO_INTMASK_V2 0x44 #define GPIO_INTTYPE_LEVEL_V2 0x34 #define GPIO_INT_POLARITY_V2 0x38 @@ -354,6 +360,20 @@ static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id) return IRQ_RETVAL(dwapb_do_irq(dev_id)); } +static void dwapb_enable_inq_combine(struct dwapb_gpio *gpio, unsigned int enable) +{ + u32 val; + + if (gpio->flags & GPIO_REG_INT_COMB) { + val = dwapb_read(gpio, GPIO_INTCOMB_MASK); + if (enable) + val |= BIT(0); + else + val &= BIT(0); + dwapb_write(gpio, GPIO_INTCOMB_MASK, val); + } +} + static void dwapb_configure_irqs(struct dwapb_gpio *gpio, struct dwapb_gpio_port *port, struct dwapb_port_property *pp) @@ -446,6 +466,8 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, irq_create_mapping(gpio->domain, hwirq); port->gc.to_irq = dwapb_gpio_to_irq; + + dwapb_enable_inq_combine(gpio, ENABLE_INT_COMB); } static void dwapb_irq_teardown(struct dwapb_gpio *gpio) @@ -618,6 +640,7 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) static const struct of_device_id dwapb_of_match[] = { { .compatible = "snps,dw-apb-gpio", .data = (void *)0}, { .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2}, + { .compatible = "hisi,ascend-gpio", .data = (void *)GPIO_REG_INT_COMB}, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, dwapb_of_match); @@ -626,6 +649,7 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) {"HISI0181", 0}, {"APMC0D07", 0}, {"APMC0D81", GPIO_REG_OFFSET_V2}, + {"HISI19XX", GPIO_REG_INT_COMB}, { } }; MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match); @@ -713,6 +737,8 @@ static int dwapb_gpio_remove(struct platform_device *pdev) reset_control_assert(gpio->rst); clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); + dwapb_enable_inq_combine(gpio, DISABLE_INT_COMB); + return 0; } @@ -794,6 +820,8 @@ static int dwapb_gpio_resume(struct device *dev) dwapb_write(gpio, GPIO_INTEN, ctx->int_en); dwapb_write(gpio, GPIO_INTMASK, ctx->int_mask); + dwapb_enable_inq_combine(gpio, ENABLE_INT_COMB); + /* Clear out spurious interrupts */ dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff); }
The hisilicon ascend soc's gpio is based on the synopsys DW gpio, and expand the register to support for INTCOMB_MASK, the new register is used to enable/disable the interrupt combine features. Both support for ACPI and Device Tree. Signed-off-by: Ding Tianhong <dingtianhong@huawei.com> --- drivers/gpio/gpio-dwapb.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) -- 1.8.3.1