From patchwork Fri Apr 29 00:53:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christian Lamparter X-Patchwork-Id: 616550 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 3qwwG65JJPz9snm for ; Fri, 29 Apr 2016 10:54:54 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=googlemail.com header.i=@googlemail.com header.b=HrM0/UkO; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753027AbcD2Ayi (ORCPT ); Thu, 28 Apr 2016 20:54:38 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:35737 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752692AbcD2Axj (ORCPT ); Thu, 28 Apr 2016 20:53:39 -0400 Received: by mail-wm0-f65.google.com with SMTP id e201so1730006wme.2; Thu, 28 Apr 2016 17:53:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references:mime-version:content-transfer-encoding; bh=vMZJzltxOpBBvU9ZdYly6epfxMu0YnQN3GVWneoEC+M=; b=HrM0/UkOYZO9i+wZBWurm74okBm+BN0ZpiHi0GH8JXlVECalmGdanB2NLnRP+hkD6n EHAI7W5fIbbQvUWXFyJvCbCP9JI/yVx8C6VlnUbs4yXDmeKeWdzf5XFOjBhcw3JxTcog lg3bBeS0NpNIRu/eIaAKl4gUA2DV9YSpR4nIMayes3n/3+O3Mv9xdlwhi69NgpfBIuj0 xpEdcA4sIYjyuJSDl9XQRj/hDEjXyWTwb2/mO0auYv4tYlh2mSOGaV9M6m6QjzdfNOSk mWTHMywKdlJ7ILkcVpcn159Ndk1gIDB1HowClq9WrRUEmBlSORgsfvlnSRIJcypmBd1n u1GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references:mime-version :content-transfer-encoding; bh=vMZJzltxOpBBvU9ZdYly6epfxMu0YnQN3GVWneoEC+M=; b=kzkYxQPda1usI68iBii3AUN5VaT02AfYYQVrxfFyaFB8OIyOr8a3HFG0rT9h7+Aljp /V9VS9AafN+BMVKBbBZKMJK5DJBTQQQmOe+ImkQUErxnMyW7TygHYxAf/65ihKhr79PH aGeAEWroieYMxRBtph1D/lC9diwPBkmwbhpRHN9MCPF/4g9t8CAUfIgIDUCaut7AMAoV UJzqDTmoJj7GXdGtnQLco3Kg64KqKSDLEQBuad3wwkAFTtJEWaZJGjEajzCLFViC5p1j IGJ2x7SN93WC6HYx8i35sxYkIY9LfGFkkBo/xGl0Tvruly2t0SzFLT7KuCnljhOzJ3y1 /Khw== X-Gm-Message-State: AOPr4FV4M+4y5JyZ9fBvtNHeooxeSrRaUKo6eau5vCRP9qAUcfWsEXQ94uBR3jvy8cKlJg== X-Received: by 10.194.61.2 with SMTP id l2mr21003131wjr.169.1461891217748; Thu, 28 Apr 2016 17:53:37 -0700 (PDT) Received: from debian64.daheim (p5B2E6CB2.dip0.t-ipconnect.de. [91.46.108.178]) by smtp.googlemail.com with ESMTPSA id e12sm657035wma.15.2016.04.28.17.53.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Apr 2016 17:53:36 -0700 (PDT) Received: from chuck by debian64.daheim with local (Exim 4.87) (envelope-from ) id 1avwgY-0007QE-Mb; Fri, 29 Apr 2016 02:53:34 +0200 From: Christian Lamparter To: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= , Kumar Gala , Alexander Shiyan , Ian Campbell , Mark Rutland , Pawel Moll , Rob Herring , Alexandre Courbot , Linus Walleij , Christian Lamparter Subject: [RFC v5 2/4] gpio: generic: add DT support for generic memory-mapped GPIOs Date: Fri, 29 Apr 2016 02:53:15 +0200 Message-Id: <240c85fbbedbe3fa3c4b23da9a804e4ece98786d.1461888822.git.chunkeey@googlemail.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: References: In-Reply-To: References: MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Álvaro Fernández Rojas This patch adds support for defining memory-mapped GPIOs which provide a compatible interface for the existing generic-gpio driver. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Christian Lamparter --- drivers/gpio/gpio-generic.c | 98 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 6c1cb3b..129c3ba 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -61,6 +61,8 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` #include #include #include +#include +#include static void bgpio_write8(void __iomem *reg, unsigned long data) { @@ -569,6 +571,88 @@ static void __iomem *bgpio_map(struct platform_device *pdev, return devm_ioremap_resource(&pdev->dev, r); } +#ifdef CONFIG_OF +static int bgpio_basic_mmio_parse_dt(struct platform_device *pdev, + struct bgpio_pdata *pdata, + unsigned long *flags) +{ + struct device *dev = &pdev->dev; + int err; + + /* If ngpio property is not specified, of_property_read_u32 + * will return -EINVAL. In this case the number of GPIOs is + * automatically determined by the register width. Any + * other error of of_property_read_u32 is due bad data and + * needs to be dealt with. + */ + err = of_property_read_u32(dev->of_node, "ngpio", &pdata->ngpio); + if (err && err != -EINVAL) + return err; + + if (of_device_is_big_endian(dev->of_node)) + *flags |= BGPIOF_BIG_ENDIAN_BYTE_ORDER; + + if (of_property_read_bool(dev->of_node, "unreadable-reg-set")) + *flags |= BGPIOF_UNREADABLE_REG_SET; + + if (of_property_read_bool(dev->of_node, "unreadable-reg-dir")) + *flags |= BGPIOF_UNREADABLE_REG_DIR; + + if (of_property_read_bool(dev->of_node, "big-endian-byte-order")) + *flags |= BGPIOF_BIG_ENDIAN; + + if (of_property_read_bool(dev->of_node, "read-output-reg-set")) + *flags |= BGPIOF_READ_OUTPUT_REG_SET; + + if (of_property_read_bool(dev->of_node, "no-output")) + *flags |= BGPIOF_NO_OUTPUT; + return 0; +} + +#define ADD(_name, _func) { .compatible = _name, .data = _func } + +static const struct of_device_id bgpio_of_match[] = { + ADD("linux,gpio-mmio", bgpio_basic_mmio_parse_dt), + { } +}; +#undef ADD +MODULE_DEVICE_TABLE(of, bgpio_of_match); + +static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, + unsigned long *flags) +{ + int (*parse_dt)(struct platform_device *, + struct bgpio_pdata *, unsigned long *); + const struct device_node *node = pdev->dev.of_node; + const struct of_device_id *of_id; + struct bgpio_pdata *pdata; + int err = -ENODEV; + + of_id = of_match_node(bgpio_of_match, node); + if (!of_id) + return NULL; + + pdata = devm_kzalloc(&pdev->dev, sizeof(struct bgpio_pdata), + GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + parse_dt = of_id->data; + if (parse_dt) + err = parse_dt(pdev, pdata, flags); + if (err) + return ERR_PTR(err); + + return pdata; +} +#else +static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, + unsigned long *flags) +{ + return NULL; +} +#endif /* CONFIG_OF */ + static int bgpio_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -579,10 +663,19 @@ 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 = 0; int err; struct gpio_chip *gc; - struct bgpio_pdata *pdata = dev_get_platdata(dev); + struct bgpio_pdata *pdata; + + pdata = bgpio_parse_dt(pdev, &flags); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + + if (!pdata) { + pdata = dev_get_platdata(dev); + flags = pdev->id_entry->driver_data; + } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); if (!r) @@ -646,6 +739,7 @@ MODULE_DEVICE_TABLE(platform, bgpio_id_table); static struct platform_driver bgpio_driver = { .driver = { .name = "basic-mmio-gpio", + .of_match_table = of_match_ptr(bgpio_of_match), }, .id_table = bgpio_id_table, .probe = bgpio_pdev_probe,