From patchwork Tue Jul 5 05:10:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sekhar Nori X-Patchwork-Id: 943412 Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p655DEAr030899 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 5 Jul 2011 05:13:34 GMT Received: from dlep34.itg.ti.com ([157.170.170.115]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id p655CAXE028663 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 5 Jul 2011 00:12:10 -0500 Received: from linux.omap.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep34.itg.ti.com (8.13.7/8.13.8) with ESMTP id p655C9WY003466; Tue, 5 Jul 2011 00:12:09 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 8130B80626; Tue, 5 Jul 2011 00:12:09 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dbdp20.itg.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by linux.omap.com (Postfix) with ESMTP id 186CC80628 for ; Tue, 5 Jul 2011 00:11:13 -0500 (CDT) Received: from dbde70.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id p655B768025177; Tue, 5 Jul 2011 10:41:12 +0530 (IST) Received: from dbdp31.itg.ti.com (172.24.170.98) by DBDE70.ent.ti.com (172.24.170.148) with Microsoft SMTP Server id 8.3.106.1; Tue, 5 Jul 2011 10:41:07 +0530 Received: from psplinux051.india.ti.com (psplinux051.india.ti.com [172.24.162.244]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id p655B1Gk020953; Tue, 5 Jul 2011 10:41:02 +0530 (IST) Received: from psplinux051.india.ti.com (localhost [127.0.0.1]) by psplinux051.india.ti.com (8.13.1/8.13.1) with ESMTP id p655B1VG016843; Tue, 5 Jul 2011 10:41:01 +0530 Received: (from a0875516@localhost) by psplinux051.india.ti.com (8.13.1/8.13.1/Submit) id p655B1i5016840; Tue, 5 Jul 2011 10:41:01 +0530 From: Sekhar Nori To: Subject: [RFC/RFT 1/2] gpio/basic_mmio: add support for enable register Date: Tue, 5 Jul 2011 10:40:59 +0530 Message-ID: <83915224c24e43224272b1bf570cddb9545279a6.1309840042.git.nsekhar@ti.com> X-Mailer: git-send-email 1.6.2.4 In-Reply-To: References: MIME-Version: 1.0 Cc: davinci-linux-open-source@linux.davincidsp.com, Grant Likely , linux-arm-kernel@lists.infradead.org X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Greylist: Sender succeeded STARTTLS authentication, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Tue, 05 Jul 2011 05:13:34 +0000 (UTC) Some GPIO controllers have an enable register which needs to be written to before a GPIO can be used. Add support for enabling the GPIO. At this time inverted logic for enabling the GPIO is not supported. This can be done by adding a disable register as and when a controller with this comes along. Signed-off-by: Sekhar Nori --- drivers/gpio/gpio-ep93xx.c | 2 +- drivers/gpio/gpio-generic.c | 45 ++++++++++++++++++++++++++++++++++++++- drivers/gpio/gpio-mxc.c | 2 +- drivers/gpio/gpio-mxs.c | 2 +- include/linux/basic_mmio_gpio.h | 5 ++++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 3bfd341..8ed498a 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -314,7 +314,7 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, void __iomem *dir = mmio_base + bank->dir; int err; - err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false); + err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, NULL, false); if (err) return err; diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 231714d..cf7d596 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -247,6 +247,34 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } +static int bgpio_request(struct gpio_chip *gc, unsigned int gpio) +{ + struct bgpio_chip *bgc = to_bgpio_chip(gc); + unsigned long flags; + + spin_lock_irqsave(&bgc->lock, flags); + + bgc->en |= bgc->pin2mask(bgc, gpio); + bgc->write_reg(bgc->reg_en, bgc->en); + + spin_unlock_irqrestore(&bgc->lock, flags); + + return 0; +} + +static void bgpio_free(struct gpio_chip *gc, unsigned int gpio) +{ + struct bgpio_chip *bgc = to_bgpio_chip(gc); + unsigned long flags; + + spin_lock_irqsave(&bgc->lock, flags); + + bgc->en &= ~bgc->pin2mask(bgc, gpio); + bgc->write_reg(bgc->reg_en, bgc->en); + + spin_unlock_irqrestore(&bgc->lock, flags); +} + static int bgpio_setup_accessors(struct device *dev, struct bgpio_chip *bgc, bool be) @@ -302,6 +330,10 @@ static int bgpio_setup_accessors(struct device *dev, * indicates the GPIO is an output. * - an input direction register (named "dirin") where a 1 bit indicates * the GPIO is an input. + * + * To enable and disable a GPIO at the time of requesting it there is a + * a simple enable register supported where a 1 bit indicates that the GPIO + * is enabled. */ static int bgpio_setup_io(struct bgpio_chip *bgc, void __iomem *dat, @@ -369,6 +401,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc, void __iomem *clr, void __iomem *dirout, void __iomem *dirin, + void __iomem *en, bool big_endian) { int ret; @@ -398,6 +431,11 @@ int __devinit bgpio_init(struct bgpio_chip *bgc, if (ret) return ret; + if (en) { + bgc->gc.request = bgpio_request; + bgc->gc.free = bgpio_free; + } + bgc->data = bgc->read_reg(bgc->reg_dat); return ret; @@ -453,6 +491,7 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev) void __iomem *clr; void __iomem *dirout; void __iomem *dirin; + void __iomem *en; unsigned long sz; bool be; int err; @@ -485,13 +524,17 @@ static int __devinit bgpio_pdev_probe(struct platform_device *pdev) if (err) return err; + en = bgpio_map(pdev, "en", sz, &err); + if (err) + return err; + be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be"); bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL); if (!bgc) return -ENOMEM; - err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be); + err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, en, be); if (err) return err; diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 2f6a81b..5ce98c6 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -300,7 +300,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + GPIO_PSR, port->base + GPIO_DR, NULL, - port->base + GPIO_GDIR, NULL, false); + port->base + GPIO_GDIR, NULL, NULL, false); if (err) goto out_iounmap; diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index d8cafba..f3b78bf 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -241,7 +241,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + PINCTRL_DIN(port->id), port->base + PINCTRL_DOUT(port->id), NULL, - port->base + PINCTRL_DOE(port->id), NULL, false); + port->base + PINCTRL_DOE(port->id), NULL, NULL, false); if (err) goto out_iounmap; diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index 98999cf..fc2e1cc 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h @@ -35,6 +35,7 @@ struct bgpio_chip { void __iomem *reg_set; void __iomem *reg_clr; void __iomem *reg_dir; + void __iomem *reg_en; /* Number of bits (GPIOs): * 8. */ int bits; @@ -56,6 +57,9 @@ struct bgpio_chip { /* Shadowed direction registers to clear/set direction safely. */ unsigned long dir; + + /* Shadowed enable register to enable/disable safely. */ + unsigned long en; }; static inline struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) @@ -72,6 +76,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc, void __iomem *clr, void __iomem *dirout, void __iomem *dirin, + void __iomem *en, bool big_endian); #endif /* __BASIC_MMIO_GPIO_H */