From patchwork Wed Oct 19 05:33:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "J, KEERTHY" X-Patchwork-Id: 9383611 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 801F360762 for ; Wed, 19 Oct 2016 05:34:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 72D2728DB1 for ; Wed, 19 Oct 2016 05:34:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6789728DE4; Wed, 19 Oct 2016 05:34:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3B3D28DB1 for ; Wed, 19 Oct 2016 05:34:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755503AbcJSFep (ORCPT ); Wed, 19 Oct 2016 01:34:45 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:52759 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754537AbcJSFeo (ORCPT ); Wed, 19 Oct 2016 01:34:44 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id u9J5Yfwx014962; Wed, 19 Oct 2016 00:34:41 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id u9J5Yfba024951; Wed, 19 Oct 2016 00:34:41 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.294.0; Wed, 19 Oct 2016 00:34:40 -0500 Received: from ula0393675.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id u9J5YQl0017393; Wed, 19 Oct 2016 00:34:38 -0500 From: Keerthy To: CC: , , , , , , , , Subject: [PATCH 3/5] gpio: davinci: irq support for multiple gpio controllers Date: Wed, 19 Oct 2016 11:03:57 +0530 Message-ID: <1476855239-32730-4-git-send-email-j-keerthy@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1476855239-32730-1-git-send-email-j-keerthy@ti.com> References: <1476855239-32730-1-git-send-email-j-keerthy@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Grygorii Strashko The Davinci GPIO driver is implemented to work with one monolithic Davinci GPIO platform device which may have up to Y(144) gpios. The Davinci GPIO driver instantiates number of GPIO chips with max 32 gpio pins per each during initialization and one IRQ domain. So, the current GPIO's opjects structure is: Davinci GPIO controller |- ------| ... |--- irq_domain (hwirq [0..143]) |- ------| The gpio2hwirq conversation is performing in the following way: hwirq = gpio0_chipX.base + gpio_offsetN where gpio_offsetN is gpio pin number inside gpio0_chipX and gpio0_chipX.base can have values 0..128 with step 32. Above will work properly only when one Davinci GPIO controller is present, but if second one (68 gpios) is added IRQs will not work for it, because gpio1_chipX.base will have values 144..208 with step 32 and above formula will not work any more. Hence, update Davinci GPIO driver to handle this situation properly: - add new field in struct davinci_gpio_controller.ctrl_base and save Linux GPIO number of the first GPIO assigned to the Davinci GPIO controller in .probe() - value of static variable "bank_base"; - correct gpio2hwirq conversation formula as below hwirq = (gpio0_chipX.base - gpio_controller.ctrl_base) + gpio_offsetN Signed-off-by: Grygorii Strashko [j-keerthy@ti.com added the ctrl_base to keep track of gpios per controller] Signed-off-by: Keerthy --- drivers/gpio/gpio-davinci.c | 28 ++++++++++++++++++++++------ include/linux/platform_data/gpio-davinci.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 2654dae..2bc308a 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -176,7 +176,7 @@ static int davinci_gpio_of_xlate(struct gpio_chip *gc, static int davinci_gpio_probe(struct platform_device *pdev) { - int i, base; + int i, base, temp_ctrl_base; unsigned ngpio, nbank; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; @@ -219,6 +219,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); + temp_ctrl_base = bank_base; + for (i = 0, base = 0; base < ngpio; i++, base += 32) { chips[i].chip.label = "DaVinci"; @@ -228,10 +230,13 @@ static int davinci_gpio_probe(struct platform_device *pdev) chips[i].chip.set = davinci_gpio_set; chips[i].chip.base = bank_base; + chips[i].ctrl_base = temp_ctrl_base; bank_base += 32; chips[i].chip.ngpio = ngpio - base; if (chips[i].chip.ngpio > 32) chips[i].chip.ngpio = 32; + else + bank_base = ngpio; #ifdef CONFIG_OF_GPIO chips[i].chip.of_gpio_n_cells = 2; @@ -329,6 +334,7 @@ static void gpio_irq_handler(struct irq_desc *desc) while (1) { u32 status; int bit; + irq_hw_number_t hw_irq; /* ack any irqs */ status = readl_relaxed(&g->intstat) & mask; @@ -341,9 +347,13 @@ static void gpio_irq_handler(struct irq_desc *desc) while (status) { bit = __ffs(status); status &= ~BIT(bit); + /* Max number of gpios per controller is 144 so + * hw_irq will be in [0..143] + */ + hw_irq = (d->chip.base - d->ctrl_base) + bit; + generic_handle_irq( - irq_find_mapping(d->irq_domain, - d->chip.base + bit)); + irq_find_mapping(d->irq_domain, hw_irq)); } } chained_irq_exit(irq_desc_get_chip(desc), desc); @@ -353,11 +363,17 @@ static void gpio_irq_handler(struct irq_desc *desc) static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *d = gpiochip_get_data(chip); + irq_hw_number_t hw_irq; - if (d->irq_domain) - return irq_create_mapping(d->irq_domain, d->chip.base + offset); - else + if (d->irq_domain) { + /* Max number of gpios per controller is 144 so + * hw_irq will be in [0..143] + */ + hw_irq = (d->chip.base - d->ctrl_base) + offset; + return irq_create_mapping(d->irq_domain, hw_irq); + } else { return -ENXIO; + } } static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) diff --git a/include/linux/platform_data/gpio-davinci.h b/include/linux/platform_data/gpio-davinci.h index 6ace3fd..0a0cdd7 100644 --- a/include/linux/platform_data/gpio-davinci.h +++ b/include/linux/platform_data/gpio-davinci.h @@ -38,6 +38,7 @@ struct davinci_gpio_controller { void __iomem *in_data; int gpio_unbanked; unsigned gpio_irq; + unsigned int ctrl_base; }; /*