From patchwork Fri Jun 5 06:51:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Romain Baeriswyl X-Patchwork-Id: 481077 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0A6C0140218 for ; Fri, 5 Jun 2015 17:15:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753518AbbFEHPe (ORCPT ); Fri, 5 Jun 2015 03:15:34 -0400 Received: from nopam.alitech.com ([202.3.176.31]:36277 "EHLO nopam.alitech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751634AbbFEHPd (ORCPT ); Fri, 5 Jun 2015 03:15:33 -0400 X-Greylist: delayed 1454 seconds by postgrey-1.27 at vger.kernel.org; Fri, 05 Jun 2015 03:15:32 EDT Received: from localhost (localhost [127.0.0.1]) by nopam.alitech.com (Postfix) with ESMTP id 1C43072C0D92; Fri, 5 Jun 2015 14:53:10 +0800 (CST) split_mail: 1 Received: from twalins2.ali.net (unknown [192.168.200.12]) by nopam.alitech.com (Postfix) with ESMTP id 54DD772C0D1F; Fri, 5 Jun 2015 14:53:09 +0800 (CST) Received: from ab24.lan ([10.41.22.152]) by twalins2 (Lotus Domino Release 8.0.2FP6) with ESMTP id 2015060514524980-1287 ; Fri, 5 Jun 2015 14:52:49 +0800 From: Romain Baeriswyl To: Linus Walleij , Alexandre Courbot , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Christian Ruppert , Anton Vorontsov , Rojhalat Ibrahim , abdoulaye berthe , Anthony Fee , Alexander Shiyan Cc: Romain Baeriswyl Subject: [PATCH] added device tree support to gpio-generic driver Date: Fri, 5 Jun 2015 08:51:02 +0200 Message-Id: <1433487062-10647-1-git-send-email-romain.baeriswyl@alitech.com> X-Mailer: git-send-email 1.7.1 X-MIMETrack: =?Big5?B?SXRlbWl6ZSBieSBTTVRQIFNlcnZlciBvbiBUV0FMSU5TMi9BTElfVFBFL0FMaSg=?= =?Big5?B?UmVsZWFzZSA4LjAuMkZQNnxKdWx5IDE1LCAyMDEwKSBhdCAyMDE1LzA2LzA1IKRV?= =?Big5?B?pMggMDI6NTI6NTA=?=, =?Big5?B?U2VyaWFsaXplIGJ5IFJvdXRlciBvbiBUV0FMSU5TMi9BTElfVFBFL0FMaSg=?= =?Big5?B?UmVsZWFzZSA4LjAuMkZQNnxKdWx5IDE1LCAyMDEwKSBhdCAyMDE1LzA2LzA1IKRV?= =?Big5?B?pMggMDI6NTI6NTE=?=, =?Big5?B?U2VyaWFsaXplIGNvbXBsZXRlIGF0IDIwMTUvMDYvMDUgpFWkyCAwMjo1Mjo1MQ==?= X-TNEFEvaluated: 1 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org --- .../devicetree/bindings/gpio/gpio-generic.txt | 19 +++++ drivers/gpio/gpio-generic.c | 81 ++++++++++++++----- 2 files changed, 78 insertions(+), 22 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-generic.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-generic.txt b/Documentation/devicetree/bindings/gpio/gpio-generic.txt new file mode 100644 index 0000000..c2c4b98 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-generic.txt @@ -0,0 +1,19 @@ +Bindings for gpio-generic + +Required properties: +- compatible : "basic-mmio-gpio" for little endian register access or + "basic-mmio-gpio-be" for big endian register access +- ngpios: Specifies the number of gpio mapped in the register. The value is + limited to the number of bits of the LONG type. + +Optional properties: +- base: Allows to forces the gpio number base offset used to index the gpio in + the device. If it is not see then the driver search autonoumously for + valid index range. + +Examples: + + gpio_a { + compatible = "basic-mmio-gpio"; + ngpios = <32>; + }; diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index b92a690..9a4354c 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -15,11 +15,11 @@ * `.just a single "data" register, where GPIO state can be read and/or ` * `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.``````` * ````````` - ___ -_/~~|___/~| . ```~~~~~~ ___/___\___ ,~.`.`.`.`````.~~...,,,,... -__________|~$@~~~ %~ /o*o*o*o*o*o\ .. Implementing such a GPIO . -o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` - `....trivial..'~`.```.``` + * ___ + * _/~~|___/~| . ```~~~~~~ ___/___\___ ,~.`.`.`.`````.~~...,,,,... + * __________|~$@~~~ %~ /o*o*o*o*o*o\ .. Implementing such a GPIO . + * o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` + * `....trivial..'~`.```.``` * ``````` * .```````~~~~`..`.``.``. * . The driver supports `... ,..```.`~~~```````````````....````.``,, @@ -61,6 +61,8 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` #include #include #include +#include +#include static void bgpio_write8(void __iomem *reg, unsigned long data) { @@ -375,10 +377,9 @@ static int bgpio_setup_accessors(struct device *dev, dev_err(dev, "64 bit big endian byte order unsupported\n"); return -EINVAL; - } else { - bgc->read_reg = bgpio_read64; - bgc->write_reg = bgpio_write64; } + bgc->read_reg = bgpio_read64; + bgc->write_reg = bgpio_write64; break; #endif /* BITS_PER_LONG >= 64 */ default: @@ -564,6 +565,27 @@ static void __iomem *bgpio_map(struct platform_device *pdev, return ret; } +static const struct platform_device_id bgpio_id_table[] = { + { "basic-mmio-gpio", + .driver_data = 0, + }, { "basic-mmio-gpio-be", + .driver_data = BGPIOF_BIG_ENDIAN + }, + { }, +}; +MODULE_DEVICE_TABLE(platform, bgpio_id_table); + +static const struct of_device_id bgpio_dt_ids[] = { + { .compatible = "basic-mmio-gpio", + .data = bgpio_id_table + 0 + }, + { .compatible = "basic-mmio-gpio-be", + .data = bgpio_id_table + 1 + }, + { } +}; +MODULE_DEVICE_TABLE(of, bgpio_dt_ids); + static int bgpio_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -574,10 +596,37 @@ static int bgpio_pdev_probe(struct platform_device *pdev) void __iomem *dirout; void __iomem *dirin; unsigned long sz; - unsigned long flags = pdev->id_entry->driver_data; + unsigned long flags; int err; struct bgpio_chip *bgc; - struct bgpio_pdata *pdata = dev_get_platdata(dev); + struct bgpio_pdata *pdata; + + if (of_have_populated_dt()) { + const struct of_device_id *of_id = + of_match_device(bgpio_dt_ids, dev); + + pdata = devm_kzalloc(dev, sizeof(struct bgpio_pdata), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + if (of_property_read_u32(dev->of_node, "ngpio", + &pdata->ngpio)) { + dev_err(dev, "Failed to get field ngpio"); + return -EINVAL; + } + if (of_property_read_u32(dev->of_node, "base", &pdata->base)) + pdata->base = -1; + + dev->platform_data = pdata; + + if (of_id) + pdev->id_entry = of_id->data; + } + + pdata = dev_get_platdata(dev); + + flags = pdev->id_entry->driver_data; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); if (!r) @@ -633,18 +682,6 @@ static int bgpio_pdev_remove(struct platform_device *pdev) return bgpio_remove(bgc); } -static const struct platform_device_id bgpio_id_table[] = { - { - .name = "basic-mmio-gpio", - .driver_data = 0, - }, { - .name = "basic-mmio-gpio-be", - .driver_data = BGPIOF_BIG_ENDIAN, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, bgpio_id_table); - static struct platform_driver bgpio_driver = { .driver = { .name = "basic-mmio-gpio",