From patchwork Thu Oct 26 15:28:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 830769 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yN9s94NbDz9s03 for ; Fri, 27 Oct 2017 02:29:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932506AbdJZP2S convert rfc822-to-8bit (ORCPT ); Thu, 26 Oct 2017 11:28:18 -0400 Received: from mail-oln040092070075.outbound.protection.outlook.com ([40.92.70.75]:58269 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932499AbdJZP2P (ORCPT ); Thu, 26 Oct 2017 11:28:15 -0400 Received: from AM5EUR03FT025.eop-EUR03.prod.protection.outlook.com (10.152.16.58) by AM5EUR03HT129.eop-EUR03.prod.protection.outlook.com (10.152.17.178) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.20.156.4; Thu, 26 Oct 2017 15:28:13 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com (10.152.16.60) by AM5EUR03FT025.mail.protection.outlook.com (10.152.16.157) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.20.156.4 via Frontend Transport; Thu, 26 Oct 2017 15:28:13 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::6432:5809:c70:3d63]) by AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::6432:5809:c70:3d63%17]) with mapi id 15.20.0197.004; Thu, 26 Oct 2017 15:28:13 +0000 From: Bernd Edlinger To: Linus Walleij CC: Rob Herring , Christian Lamparter , "linux-gpio@vger.kernel.org" , "devicetree@vger.kernel.org" Subject: [PATCHv5 1/2] Add device tree bindings for Altera FPGA Manager GPIO Thread-Topic: [PATCHv5 1/2] Add device tree bindings for Altera FPGA Manager GPIO Thread-Index: AQHTTm5meollfqP9S0eoO25uH9S8hA== Date: Thu, 26 Oct 2017 15:28:13 +0000 Message-ID: Accept-Language: de-DE, en-US Content-Language: de-DE X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: kernel.org; dkim=none (message not signed) header.d=none; kernel.org; dmarc=none action=none header.from=hotmail.de; x-incomingtopheadermarker: OriginalChecksum:C807278B748F6F186C39C2F260270373242BD9FC2CFDBA60172E105A22F128FB; UpperCasedChecksum:0CB533FAB6E952CD55F5E5B64E1B93CD19B1C789C8C1E7E74AC533067496CA9B; SizeAsReceived:7140; Count:45 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [MqDk5ocq13BY7vYdCIv5Fx0ANSjDqtvu] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM5EUR03HT129; 6:APngD2/QLjWTiC7TNQlDWNbMZFdXAVS6Pf9TWeo4r0cr5Hibq4zL209d1D8/UhkyHIVTkmV7P1V+1wwHN5EXIWlc9Q5/vouef5ufJZJ2fOM6DHTRa9ulTtIHOOen9rOCMk7lcl/GrEWfaZbzVNc7ubUTJcmXkvkeLslxhFEDbjMEByFkffztK3QJABOdjx23x/d0VB8R1F+xbA1PhsR5856roG1rUJJRQjd8cwVtWCnkBHkLq0LmaL1IvwNkOaUodE7NhlY5c/9SCG00Bm2biq4LP8knlB3C0HIJSnBaUw2eauoVm7SNebqPG/23P6DdWFHTrN60J7YOT8rYtdfR+g==; 5:Tl4iSPDqHdyvSQn2H6pSEgeqkIj1MTcyb/AwOqSMwCqZWrfx9CV65xvTYTxtdyNxbqS8p+3OcutncRm7uGFcPR930l/BnfLNAzjvic1LUG7mm65YdaNmkRuLLjqngD1lSN9SXy5K4ErhK71AwSdVeg==; 24:Qx9Fq8gmv0vBAa8ABcE564RDO2WCpNOFcWlowEpR0REnv9P8NRwT/GqaENXgbDsFSKZspPwHWa4kmIclMsMqVc4EAYc35N0SfRlVnU2C/Qo=; 7:+MTrt8NTH4qA/mDquexhvGut5u7xGzVWhTTvVwrY65rNyn8aaWwZOsQ7buOS38ThpuyZl3ctwWE2RfM+0iLMl2MNp/NmeV64rl+7KIs1cFmEI8fpXgFXMSlDOUdUhBoHUuDT07PKJFBW10ODj1/ilwUEh95l2DMV9rRIPYmOTYilRvUcIY/7/4c4o8jTPQs0GJnXKMNEBknV+vTbTBARlffs96yIeXflbuiqj+S2+8s= x-incomingheadercount: 45 x-eopattributedmessage: 0 x-ms-office365-filtering-correlation-id: 5283619f-7bdc-4f2f-c0a1-08d51c862c59 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201702061074)(5061506573)(5061507331)(1603103135)(2017031320274)(2017031324274)(2017031323274)(2017031322404)(1601125374)(1603101448)(1701031045); SRVR:AM5EUR03HT129; x-ms-traffictypediagnostic: AM5EUR03HT129: x-exchange-antispam-report-test: UriScan:(158256107679635); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(444000031); SRVR:AM5EUR03HT129; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM5EUR03HT129; x-forefront-prvs: 04724A515E x-forefront-antispam-report: SFV:NSPM; SFS:(7070007)(98901004); DIR:OUT; SFP:1901; SCL:1; SRVR:AM5EUR03HT129; H:AM5PR0701MB2657.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:; spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5283619f-7bdc-4f2f-c0a1-08d51c862c59 X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Oct 2017 15:28:13.7599 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5EUR03HT129 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Signed-off-by: Bernd Edlinger --- .../bindings/gpio/gpio-altera-fpgamgr.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-altera-fpgamgr.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-altera-fpgamgr.txt b/Documentation/devicetree/bindings/gpio/gpio-altera-fpgamgr.txt new file mode 100644 index 0000000..6e2ad47 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-altera-fpgamgr.txt @@ -0,0 +1,43 @@ +Altera FPGA Manager GPIO controller bindings + +Required controller properties: +- #address-cells : Should be 1 +- #size-cells : Should be 0 +- compatible: + - "altr,fpgamgr-gpio" +- reg: Physical base address and length of the controller's registers. + +The FPGA Manager has two 32-bit ports, one for input and one for output. + +Port properties: +- compatible: + - "altr,fpgamgr-gpio-output" + - "altr,fpgamgr-gpio-input" +- #gpio-cells : Should be 2 + - The first cell is the gpio offset number. + - The second cell is reserved and is currently unused. +- gpio-controller : Marks the device node as a GPIO controller. +- reg : Port number, 0 for output, 1 for input. + +Example: + +gpio3: gpio@ff706010 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "altr,fpgamgr-gpio"; + reg = <0xff706010 0x8>; + + portd: gpio-controller@0 { + compatible = "altr,fpgamgr-gpio-output"; + gpio-controller; + #gpio-cells = <2>; + reg = <0>; + }; + + porte: gpio-controller@1 { + compatible = "altr,fpgamgr-gpio-input"; + gpio-controller; + #gpio-cells = <2>; + reg = <1>; + }; +}; From patchwork Thu Oct 26 15:28:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 830766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yN9rk1bmvz9s03 for ; Fri, 27 Oct 2017 02:28:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932479AbdJZP2c convert rfc822-to-8bit (ORCPT ); Thu, 26 Oct 2017 11:28:32 -0400 Received: from mail-oln040092070019.outbound.protection.outlook.com ([40.92.70.19]:28145 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932345AbdJZP21 (ORCPT ); Thu, 26 Oct 2017 11:28:27 -0400 Received: from AM5EUR03FT025.eop-EUR03.prod.protection.outlook.com (10.152.16.57) by AM5EUR03HT227.eop-EUR03.prod.protection.outlook.com (10.152.17.190) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.20.156.4; Thu, 26 Oct 2017 15:28:25 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com (10.152.16.60) by AM5EUR03FT025.mail.protection.outlook.com (10.152.16.157) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.20.156.4 via Frontend Transport; Thu, 26 Oct 2017 15:28:25 +0000 Received: from AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::6432:5809:c70:3d63]) by AM5PR0701MB2657.eurprd07.prod.outlook.com ([fe80::6432:5809:c70:3d63%17]) with mapi id 15.20.0197.004; Thu, 26 Oct 2017 15:28:25 +0000 From: Bernd Edlinger To: Linus Walleij CC: Rob Herring , Christian Lamparter , "linux-gpio@vger.kernel.org" , "devicetree@vger.kernel.org" Subject: [PATCHv5 2/2] Add a GPIO driver for Altera FPGA Manager Fabric I/O Thread-Topic: [PATCHv5 2/2] Add a GPIO driver for Altera FPGA Manager Fabric I/O Thread-Index: AQHTTm7W8DH9Wffxlkqv93WwNAsmEw== Date: Thu, 26 Oct 2017 15:28:25 +0000 Message-ID: Accept-Language: de-DE, en-US Content-Language: de-DE X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: kernel.org; dkim=none (message not signed) header.d=none; kernel.org; dmarc=none action=none header.from=hotmail.de; x-incomingtopheadermarker: OriginalChecksum:2A6C0916C384FE8A0BD2EE3A1714C27AA2462E523FF049CBB105750775D72E09; UpperCasedChecksum:6A7381018AFB7E780C51E2A1429EA137C5E73503CD72ED10537FD5574E4FD9B1; SizeAsReceived:7138; Count:45 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [nT7FmphW/JndGV8RswoTC9UlKkZM5gCn] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM5EUR03HT227; 6:ywT3zNC9gQgOxzBKG0jjLRBlWKa9s0pSvVjkNBZRJ5HGtCctXczvo0VqTxOCckuaudC80ZYz9UGQENzfh4dqr0lLZCt66uBRjNYTVj3dq7O8ywZ/96yaejiKNP4G6qWz4fGJuixYkMuFZjHMA8eNDfbKaEAAQpBOMxhjl2Tg68p/D6tI0TfcMQsZP8pMcs6fExTl5L9Nw95p3hzZAfz2DiQyAP6G5h6yKhjeMo0O2B0ol95U8A114aF4OyR4DZGuyJcOfhhEZT0IcQ9GpQAI7Gn/nDsPs4gDNmxhhL3MIQ93PfMt4ZoYhRPbzcXnHpScRo19/1909M+PVKGgaZD9OA==; 5:Mh1KT8hoqd7g1/Huvw9QXfNZq/7/tzGOC5610ybz6BPf8uzkEI+jYwnI5wVUkD62GGDEwd1Jwtlyw8E8fGmVqSike6qr1vbnDHZ+a+EmOWs9T0lBIiO5zpkdfVxmbUrMCr0VFFzryhI2y3RaXWTvaw==; 24:KIekimGL92XrqX64ApQ5dHySznkjrmRYV9inZoWDJD55Fk8VdKfYEkUzZXBh+s2waaPLFuZ9nZzk3tySzoIcMsn/CQrStXkL+K6J3zn1aM8=; 7:TPYJ1fYe83e8i5dsN6N/kGO6Jluhj511q9gVDUJXOdTcy/k2A8RERVoNM5i7laJNsK4LZLNC/EZoVZT248GbpsONI/74qSEfWAgzoLyHgTiUaBOyqIffOEKmDaNmqIpLPjUx6ISKogrxSuLj+yMtDKV31LKNgvIH4kffQbQPH7uNpmqHhKwUQs01g2rpMfKF3PcLN24+t19xZgBxaNBeyUye+kmkvf3GtthZh4BVSvs= x-incomingheadercount: 45 x-eopattributedmessage: 0 x-ms-office365-filtering-correlation-id: 89073254-5f6c-4f22-5870-08d51c86338a x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201702061074)(5061506573)(5061507331)(1603103135)(2017031320274)(2017031324274)(2017031323274)(2017031322404)(1603101448)(1601125374)(1701031045); SRVR:AM5EUR03HT227; x-ms-traffictypediagnostic: AM5EUR03HT227: x-exchange-antispam-report-test: UriScan:(158256107679635); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(444000031); SRVR:AM5EUR03HT227; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM5EUR03HT227; x-forefront-prvs: 04724A515E x-forefront-antispam-report: SFV:NSPM; SFS:(7070007)(98901004); DIR:OUT; SFP:1901; SCL:1; SRVR:AM5EUR03HT227; H:AM5PR0701MB2657.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:; spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 89073254-5f6c-4f22-5870-08d51c86338a X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Oct 2017 15:28:25.8224 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5EUR03HT227 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This is an internal 32-bit input and 32-bit output port to the FPGA logic. Instantiate this in the device tree as: gpio3: gpio@ff706010 { #address-cells = <1>; #size-cells = <0>; compatible = "altr,fpgamgr-gpio"; reg = <0xff706010 0x8>; status = "okay"; portd: gpio-controller@0 { compatible = "altr,fpgamgr-gpio-output"; gpio-controller; #gpio-cells = <2>; reg = <0>; }; porte: gpio-controller@1 { compatible = "altr,fpgamgr-gpio-input"; gpio-controller; #gpio-cells = <2>; reg = <1>; }; }; Signed-off-by: Bernd Edlinger --- drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-altera-fpgamgr.c | 219 +++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 drivers/gpio/gpio-altera-fpgamgr.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3f80f16..6e01a31 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -97,6 +97,12 @@ config GPIO_ALTERA If driver is built as a module it will be called gpio-altera. +config GPIO_ALTERA_FPGAMGR + tristate "Altera FPGAMGR GPIO" + depends on OF_GPIO + help + Say yes here to support the Altera FPGAMGR GPIO device. + config GPIO_AMDPT tristate "AMD Promontory GPIO support" depends on ACPI diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index aeb70e9d..3eb73d4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o +obj-$(CONFIG_GPIO_ALTERA_FPGAMGR) += gpio-altera-fpgamgr.o obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o diff --git a/drivers/gpio/gpio-altera-fpgamgr.c b/drivers/gpio/gpio-altera-fpgamgr.c new file mode 100644 index 0000000..80eed6d --- /dev/null +++ b/drivers/gpio/gpio-altera-fpgamgr.c @@ -0,0 +1,219 @@ +/* + * This is a GPIO driver for the internal FPGA Manager I/O ports + * connecting the HPS to the FPGA logic on certain Altera parts. + * + * Copyright (c) 2015 Softing Industrial Automation GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct fpgamgr_port_property { + struct device_node *node; + const char *name; + unsigned int idx; +}; + +struct fpgamgr_platform_data { + struct fpgamgr_port_property *properties; + unsigned int nports; +}; + +struct fpgamgr_gpio_port { + struct gpio_chip bgc; + struct fpgamgr_gpio *gpio; + unsigned int idx; +}; + +struct fpgamgr_gpio { + struct device *dev; + void __iomem *regs; + struct fpgamgr_gpio_port *ports; + unsigned int nr_ports; +}; + +static int fpgamgr_gpio_add_port(struct fpgamgr_gpio *gpio, + struct fpgamgr_port_property *pp, + unsigned int offs) +{ + struct fpgamgr_gpio_port *port; + void __iomem *dat; + int err; + + port = &gpio->ports[offs]; + port->gpio = gpio; + port->idx = pp->idx; + + dat = gpio->regs + (pp->idx * 4); + + err = bgpio_init(&port->bgc, gpio->dev, 4, dat, NULL, NULL, + NULL, NULL, pp->idx ? BGPIOF_NO_OUTPUT : 0); + if (err) { + dev_err(gpio->dev, "failed to init gpio chip for %s\n", + pp->name); + return err; + } + + port->bgc.of_node = pp->node; + + err = devm_gpiochip_add_data(gpio->dev, &port->bgc, NULL); + if (err) + dev_err(gpio->dev, "failed to register gpiochip for %s\n", + pp->name); + + return err; +} + +static struct fpgamgr_platform_data * +fpgamgr_gpio_get_pdata_of(struct device *dev) +{ + struct device_node *np = dev->of_node, *port_np; + struct fpgamgr_platform_data *pdata; + struct fpgamgr_port_property *pp; + int nports; + int i; + + if (!np) + return ERR_PTR(-ENODEV); + + nports = of_get_child_count(np); + if (nports == 0) + return ERR_PTR(-ENODEV); + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->properties = kcalloc(nports, sizeof(*pp), GFP_KERNEL); + if (!pdata->properties) { + kfree(pdata); + return ERR_PTR(-ENOMEM); + } + + pdata->nports = nports; + + i = 0; + for_each_child_of_node(np, port_np) { + pp = &pdata->properties[i++]; + pp->node = port_np; + + if (of_property_read_u32(port_np, "reg", &pp->idx) || + pp->idx > 1) { + dev_err(dev, "missing/invalid port index for %s\n", + port_np->full_name); + kfree(pdata->properties); + kfree(pdata); + return ERR_PTR(-EINVAL); + } + + pp->name = port_np->full_name; + } + + return pdata; +} + +static inline void fpgamgr_free_pdata_of(struct fpgamgr_platform_data *pdata) +{ + if (!pdata) + return; + + kfree(pdata->properties); + kfree(pdata); +} + +static int fpgamgr_gpio_probe(struct platform_device *pdev) +{ + unsigned int i; + struct resource *res; + struct fpgamgr_gpio *fgpio; + int err; + struct device *dev = &pdev->dev; + struct fpgamgr_platform_data *pdata = dev_get_platdata(dev); + bool is_pdata_alloc = !pdata; + + if (is_pdata_alloc) { + pdata = fpgamgr_gpio_get_pdata_of(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } + + if (!pdata->nports) { + err = -ENODEV; + goto out_err; + } + + fgpio = devm_kzalloc(dev, sizeof(*fgpio), GFP_KERNEL); + if (!fgpio) { + err = -ENOMEM; + goto out_err; + } + fgpio->dev = dev; + fgpio->nr_ports = pdata->nports; + + fgpio->ports = devm_kcalloc(dev, fgpio->nr_ports, + sizeof(*fgpio->ports), GFP_KERNEL); + if (!fgpio->ports) { + err = -ENOMEM; + goto out_err; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + fgpio->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(fgpio->regs)) { + err = PTR_ERR(fgpio->regs); + goto out_err; + } + + for (i = 0; i < fgpio->nr_ports; i++) { + err = fpgamgr_gpio_add_port(fgpio, &pdata->properties[i], i); + if (err) + goto out_unregister; + } + platform_set_drvdata(pdev, fgpio); + + goto out_err; + +out_unregister: + while (i > 0) + devm_gpiochip_remove(dev, &fgpio->ports[--i].bgc); + +out_err: + if (is_pdata_alloc) + fpgamgr_free_pdata_of(pdata); + + return err; +} + +static const struct of_device_id fpgamgr_of_match[] = { + { .compatible = "altr,fpgamgr-gpio" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, fpgamgr_of_match); + +static struct platform_driver fpgamgr_gpio_driver = { + .driver = { + .name = "gpio-altera-fpgamgr", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(fpgamgr_of_match), + }, + .probe = fpgamgr_gpio_probe, +}; + +module_platform_driver(fpgamgr_gpio_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bernd Edlinger"); +MODULE_DESCRIPTION("Altera fpgamgr GPIO driver");