From patchwork Wed Feb 21 16:00:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 10233429 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 340B560209 for ; Wed, 21 Feb 2018 16:16:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B489289D3 for ; Wed, 21 Feb 2018 16:16:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1FB0A28A74; Wed, 21 Feb 2018 16:16:12 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7C4FB289D3 for ; Wed, 21 Feb 2018 16:16:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=U/I3ZkWihj1D/lXXHQzrpDPh+/gb2ypw3UOMEKvnOEI=; b=mn9E6v41SXAQiASOYn9Et7mamZ G/XRKZJ6YDreChkLv7xl8lmxm649uzRduYqtCf8epEw7qUj/mpiBErSPR9Tfpc8p6NiD4j4if1dbP 4YfoJdZNJvFln8dE+JbA4XJSV6o6kyRAZXkE76a3/avSZmuagKhrojGoFpaTyJd2Kuyhh8lwg3rYL cOo4uSKQ49ucrYRkau/Ca0zXRY9nSlM6gq9AMeHEjsIBJybJJnhHJ0zD024mAMoOIGQyDh3gDhgO8 bLycpMyrkJqmnrRDDZfVL2shL5/F5yNb0yRSWuSwdSDc5TbiqCX38eii76kJwnDo5SyqN/yWbhCf+ pNEn0Pgg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eoX3m-0006gg-Kb; Wed, 21 Feb 2018 16:15:58 +0000 Received: from casper.infradead.org ([85.118.1.10]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eoX3f-0006OP-RM for linux-arm-kernel@bombadil.infradead.org; Wed, 21 Feb 2018 16:15:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=9VUvw6ASmiGcXdK0Fr/Xz8hMRnF5k/TpJ9EiJPPHy88=; b=prCsutgsfa/7mNASaojzIJuHJ ItHAR6kOBOI71leSEvr1YxKmrI2969GuFhZhbLfH90LnhM+sZYaDsYT0l7lmJNzbuoOpucVFuYV0m a21afgBloJimlnty5RU4pnCwMFWbLE04CqDBIxxLDhwVCrKSFQjEQZnzVrCCsvwEwKmsbe6Mfz4uz onPkyX+Dw9xzX/DUB9BTJQeFP2Z+gwQNhkw6GXYZFiQ55KiIL71Ppd/wZACNP4fJpU/mewX7iSNqr CdPq8pwsVixg+KH1rm3HCy5ZiZRnRu4rGXVaqW5kM7KYqkn1e7Yn6DXXHdERNwUWEoWQpjKnEirhR myDPe4t3Q==; Received: from mail-pf0-x243.google.com ([2607:f8b0:400e:c00::243]) by casper.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eoWrs-0000Au-MV for linux-arm-kernel@lists.infradead.org; Wed, 21 Feb 2018 16:03:44 +0000 Received: by mail-pf0-x243.google.com with SMTP id z14so815064pfe.10 for ; Wed, 21 Feb 2018 08:03:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9VUvw6ASmiGcXdK0Fr/Xz8hMRnF5k/TpJ9EiJPPHy88=; b=bj+bNPll7eP7Ge7mdJj0I6cZxFrZoHezvyCjiX9ofOwfxGqIlapFHkMez88CY2xV/5 qXkmNJFy5UIVObpTfDq8Q3v8owdGlF4JRa1W//R+RR0U3OAMhNYgUEJGj8G6k0gZ7zVv oHoFOxejh6ZX7QD0Uhb9GQRncY4f5yyCPoQK0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9VUvw6ASmiGcXdK0Fr/Xz8hMRnF5k/TpJ9EiJPPHy88=; b=SDkmiAjYWnho4cqwSwhVrrni/zbRG232DyyMSAymMTR53sHHTaWyrOYno+2O29zqjn UqkzEYHMdhh9f3MIk7irZKW4MCgf/UJRmadR+nqhkYdoPTGat3MmSWf45Yrl0xxcrOLD oaijeRaQT5o0A64W1mDRC4sN4+SD+/s+nNKiLRrwBPohAzlejt/DCuOf4oSctY5jSLni 45vfxeh2vYNiTq5mOcfip/WEAdlPAfwVcs1BdL6pNSxQxJlfTijZF/oJbRoZ2WNAahf7 D1fv2fDtyi/GgYgTH+PNcfPVzGz7BfadAdPpK5bFYMkpj1kTXYwGa6hhP8qqcOj8qjXi CLHg== X-Gm-Message-State: APf1xPDRDHEZioAo0O/avNo9zT7jOs0zkU9ZMrmm3oPgg2MCTOyuab5V jwzGhWTABGiEnRPLnK/1QHrX X-Google-Smtp-Source: AH8x2260SuNL7Ul5PUvVEf1SEG7c90WO+6s7SZOOMhzbXjvfQB6D5sfMb3dxTY7XN0YbENYckqqK/Q== X-Received: by 10.98.93.87 with SMTP id r84mr3761800pfb.131.1519229008087; Wed, 21 Feb 2018 08:03:28 -0800 (PST) Received: from localhost.localdomain ([2405:204:7346:6848:3cb8:23ad:d761:239e]) by smtp.gmail.com with ESMTPSA id s67sm43068910pfg.104.2018.02.21.08.03.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 08:03:27 -0800 (PST) From: Manivannan Sadhasivam To: linus.walleij@linaro.org, robh+dt@kernel.org, afaerber@suse.de Subject: [PATCH v2 08/10] gpio: Add gpio driver for Actions OWL S900 SoC Date: Wed, 21 Feb 2018 21:30:42 +0530 Message-Id: <20180221160044.15089-9-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180221160044.15089-1-manivannan.sadhasivam@linaro.org> References: <20180221160044.15089-1-manivannan.sadhasivam@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180221_160340_729294_C00E381F X-CRM114-Status: GOOD ( 24.21 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, daniel.thompson@linaro.org, hzhang@ucrobotics.com, bdong@ucrobotics.com, liuwei@actions-semi.com, linux-kernel@vger.kernel.org, amit.kucheria@linaro.org, linux-gpio@vger.kernel.org, mp-cs@actions-semi.com, 96boards@ucrobotics.com, Manivannan Sadhasivam , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add gpio driver for Actions Semi OWL family S900 SoC. Set of registers controlling the gpio shares the same register range with pinctrl block. GPIO registers are organized as 6 banks and each bank controls the maximum of 32 gpios. Signed-off-by: Manivannan Sadhasivam --- drivers/gpio/Kconfig | 8 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-owl.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 drivers/gpio/gpio-owl.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8dbb2280538d..09ceb98e2434 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -364,6 +364,14 @@ config GPIO_OMAP help Say yes here to enable GPIO support for TI OMAP SoCs. +config GPIO_OWL + tristate "Actions OWL GPIO support" + default ARCH_ACTIONS + depends on ARCH_ACTIONS || COMPILE_TEST + depends on OF_GPIO + help + Say yes here to enable GPIO support for Actions OWL SoCs. + config GPIO_PL061 bool "PrimeCell PL061 GPIO support" depends on ARM_AMBA diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index cccb0d40846c..b2bb11d4675f 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o +obj-$(CONFIG_GPIO_OWL) += gpio-owl.o obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o obj-$(CONFIG_GPIO_PCH) += gpio-pch.o diff --git a/drivers/gpio/gpio-owl.c b/drivers/gpio/gpio-owl.c new file mode 100644 index 000000000000..0464c08e0422 --- /dev/null +++ b/drivers/gpio/gpio-owl.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * OWL SoC's GPIO driver + * + * Copyright (c) 2018 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_OUTEN 0x0000 +#define GPIO_INEN 0x0004 +#define GPIO_DAT 0x0008 + +#define OWL_GPIO_PORT_A 0 +#define OWL_GPIO_PORT_B 1 +#define OWL_GPIO_PORT_C 2 +#define OWL_GPIO_PORT_D 3 +#define OWL_GPIO_PORT_E 4 +#define OWL_GPIO_PORT_F 5 + +struct owl_gpio_port { + const char *name; + unsigned int offset; + unsigned int pins; +}; + +struct owl_gpio { + struct gpio_chip gpio; + const struct owl_gpio_port *port; + void __iomem *base; + int id; +}; + +static void owl_gpio_set_reg(void __iomem *base, unsigned int pin, int flag) +{ + u32 val; + + if (flag) { + val = readl(base); + val |= BIT(pin); + writel(val, base); + } else { + val = readl(base); + val &= ~BIT(pin); + writel(val, base); + } +} + +static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + + /* + * GPIOs have higher priority over other modules, so either setting + * them as OUT or IN is sufficient + */ + owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true); + + return 0; +} + +static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + + /* disable gpio output */ + owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false); + + /* disable gpio input */ + owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false); +} + +static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + u32 val; + + val = readl(gpio_base + GPIO_DAT); + + return !!(val & BIT(offset)); +} + +static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + u32 val; + + val = readl(gpio_base + GPIO_DAT); + + if (value) + val |= BIT(offset); + else + val &= ~BIT(offset); + + writel(val, gpio_base + GPIO_DAT); +} + +static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + + owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false); + owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, true); + + return 0; +} + +static int owl_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct owl_gpio *gpio = gpiochip_get_data(chip); + const struct owl_gpio_port *port = gpio->port; + void __iomem *gpio_base = gpio->base + port->offset; + + owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false); + owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true); + owl_gpio_set(chip, offset, value); + + return 0; +} + +#define OWL_GPIO_PORT(port, base, count) \ + [OWL_GPIO_PORT_##port] = { \ + .name = #port, \ + .offset = base, \ + .pins = count, \ + } + +static const struct owl_gpio_port s900_gpio_ports[] = { + OWL_GPIO_PORT(A, 0x0000, 32), + OWL_GPIO_PORT(B, 0x000C, 32), + OWL_GPIO_PORT(C, 0x0018, 12), + OWL_GPIO_PORT(D, 0x0024, 30), + OWL_GPIO_PORT(E, 0x0030, 32), + OWL_GPIO_PORT(F, 0x00F0, 8), +}; + +static int owl_gpio_probe(struct platform_device *pdev) +{ + struct owl_gpio *gpio; + const struct owl_gpio_port *port; + int ret; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->base = of_iomap(pdev->dev.of_node, 0); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); + + gpio->id = of_alias_get_id(pdev->dev.of_node, "gpio"); + if (gpio->id < 0) + return gpio->id; + + port = &s900_gpio_ports[gpio->id]; + + gpio->gpio.request = owl_gpio_request; + gpio->gpio.free = owl_gpio_free; + gpio->gpio.get = owl_gpio_get; + gpio->gpio.set = owl_gpio_set; + gpio->gpio.direction_input = owl_gpio_direction_input; + gpio->gpio.direction_output = owl_gpio_direction_output; + + gpio->gpio.base = -1; + gpio->gpio.parent = &pdev->dev; + gpio->gpio.label = port->name; + gpio->gpio.ngpio = port->pins; + + gpio->port = port; + + platform_set_drvdata(pdev, gpio); + + ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register gpiochip\n"); + return ret; + } + + return 0; +} + +static const struct of_device_id owl_gpio_of_match[] = { + { .compatible = "actions,s900-gpio", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, owl_gpio_of_match); + +static struct platform_driver owl_gpio_driver = { + .driver = { + .name = "owl-gpio", + .of_match_table = owl_gpio_of_match, + }, + .probe = owl_gpio_probe, +}; +module_platform_driver(owl_gpio_driver); + +MODULE_AUTHOR("Manivannan Sadhasivam "); +MODULE_DESCRIPTION("Actions Semi OWL SoCs GPIO driver"); +MODULE_LICENSE("GPL");