From patchwork Tue Jan 29 13:35:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 10786255 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D043313B4 for ; Tue, 29 Jan 2019 13:35:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE2ED2AB2D for ; Tue, 29 Jan 2019 13:35:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B20422B32B; Tue, 29 Jan 2019 13:35:58 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21C1D29C88 for ; Tue, 29 Jan 2019 13:35:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727868AbfA2Nf4 (ORCPT ); Tue, 29 Jan 2019 08:35:56 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:50358 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727681AbfA2Nfz (ORCPT ); Tue, 29 Jan 2019 08:35:55 -0500 Received: by mail-wm1-f67.google.com with SMTP id n190so17903269wmd.0 for ; Tue, 29 Jan 2019 05:35:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yxFrfAYs+THFoK5Dj2J2xzQ1ZkkvkOfk5WjbVRfiZK4=; b=acfBjB/G/RGT2SiXbA6dD6Mds2mD+gtD4cqfVmUgyVla4N42BywgZ2JpU+aXnDuqcB l3AP8KTcOl2uatjScbns0xMXSP+Ab1ZfRPmNEbYP4Jp+dK9zTxuMGGRCBi19ZgocPIL5 DVyBSn8ZSxM/xnK/CKWVgPrNaNuGib7gHwFnXO0tp2u+iHOa3HQhnMi7sNzwwp+UxzaB s/Jv4MrnQwlSi2SHu3N464Y3voMCgUuYZ4ZIEqCM6FRvFxU0g7l4Hyzmi6JMTrSnSzLa 2jVEzQrEQ2jr19GuGPIoeqi5ON1TVWbtuNb0uT4PS7kOWsHlF45BiYlaUGPjW2aJ8IzG QmWg== 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:mime-version:content-transfer-encoding; bh=yxFrfAYs+THFoK5Dj2J2xzQ1ZkkvkOfk5WjbVRfiZK4=; b=e4o7XokuQaZXYb8AAiOSqDCCZYG/x/Yz3CkHdM89bVjAZ4Es3bctrX1iNctTLq5Ijp +/h7LLOWsYQwEkgJ2EVmf3+9hHVz6LT1YbwutprNMlAiR/pMH3Zcc3v0/J5GnfUlQDG3 GFcPtwcqapUX60uoF7QPtJ5i3a8JsGCqDUq5cVnXzJu46t4YNwE94fYJElB4U5NZBwkQ hdYTyZ1ifzBFk3Cpu2FGYqljSsfXlTXMUyGEH/ltrWlwpq9ek6iLO/0QfYCnAA0FG+7R HefcB41jy5WXQJDd2Yb+5x/Uy9gmHHy9TBDEqofqjAxXT+pmm0VqYMPx+Menx8zIQOtT 4Rig== X-Gm-Message-State: AJcUukcpktjZBJE2+ghAyaP4j6POHPBBRMzi/rq3JCoT7GySnyvOPrEk igWsPXoSC5hsqIEGUE27uYb5fDIr+o3CZA== X-Google-Smtp-Source: ALg8bN7/l7shoWwiyIuCMtOXzlzQfq3jbt1FE3Oa72Nkp0woPkqn1e7eQl5apQCjXt4L5dAkBFY9/w== X-Received: by 2002:a1c:f112:: with SMTP id p18mr20055471wmh.83.1548768953782; Tue, 29 Jan 2019 05:35:53 -0800 (PST) Received: from debian-brgl.home ([2a01:cb1d:af:5b00:6d6c:8493:1ab5:dad7]) by smtp.gmail.com with ESMTPSA id k128sm4367891wmd.37.2019.01.29.05.35.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 05:35:53 -0800 (PST) From: Bartosz Golaszewski To: Rob Herring , Mark Rutland , Linus Walleij , Dmitry Torokhov , Jacek Anaszewski , Pavel Machek , Lee Jones , Sebastian Reichel , Liam Girdwood , Mark Brown , Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH] gpio fixup domain Date: Tue, 29 Jan 2019 14:35:33 +0100 Message-Id: <20190129133545.1931-3-brgl@bgdev.pl> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129133545.1931-1-brgl@bgdev.pl> References: <20190129133545.1931-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bartosz Golaszewski --- arch/arm/boot/dts/am335x-bone-common.dtsi | 4 + drivers/gpio/gpio-max77650.c | 138 +++++++++++++++++++++- 2 files changed, 136 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 62f7f2ac191c..320b4c21fdf3 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -276,6 +276,10 @@ gpio-controller; #gpio-cells = <2>; + + interrupt-parent = <&pmic>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "GPI"; }; leds { diff --git a/drivers/gpio/gpio-max77650.c b/drivers/gpio/gpio-max77650.c index 3f03f4e8956c..03a5a2ed07f8 100644 --- a/drivers/gpio/gpio-max77650.c +++ b/drivers/gpio/gpio-max77650.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,8 @@ struct max77650_gpio_chip { struct regmap *map; struct gpio_chip gc; - int irq; + struct fwnode_handle *fwnode; + struct irq_domain *domain; }; static int max77650_gpio_direction_input(struct gpio_chip *gc, @@ -130,20 +132,114 @@ static int max77650_gpio_set_config(struct gpio_chip *gc, } } +static struct irq_chip max77650_gpio_irq_chip = { + .name = "max77650-gpio", + .irq_ack = irq_chip_ack_parent, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_set_type = irq_chip_set_type_parent, +}; + +static int max77650_gpio_irq_domain_activate(struct irq_domain *domain, + struct irq_data *data, + bool reserve) +{ + struct max77650_gpio_chip *chip = domain->host_data; + + return gpiochip_lock_as_irq(&chip->gc, data->hwirq); +} + +static void max77650_gpio_irq_domain_deactivate(struct irq_domain *domain, + struct irq_data *data) +{ + struct max77650_gpio_chip *chip = domain->host_data; + + return gpiochip_unlock_as_irq(&chip->gc, data->hwirq); +} + +static int max77650_gpio_domain_translate(struct irq_domain *domain, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + struct max77650_gpio_chip *chip = domain->host_data; + + if (fwspec->param_count != 2 || fwspec->param[0] >= chip->gc.ngpio) + return -EINVAL; + + *hwirq = fwspec->param[0]; + *type = fwspec->param[1]; + + return 0; +} + +static int max77650_gpio_domain_alloc(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs, void *data) +{ + struct max77650_gpio_chip *chip = domain->host_data; + struct irq_fwspec *fwspec = data; + struct irq_fwspec parent_fwspec; + irq_hw_number_t hwirq; + unsigned int type; + int ret; + + if (nr_irqs != 1) + return -EINVAL; + + ret = max77650_gpio_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + irq_domain_set_info(domain, virq, hwirq, + &max77650_gpio_irq_chip, chip, + handle_level_irq, NULL, NULL); + + parent_fwspec.fwnode = domain->parent->fwnode; + parent_fwspec.param_count = 4; + parent_fwspec.param[0] = 0; + parent_fwspec.param[1] = hwirq; + parent_fwspec.param[2] = 0; + parent_fwspec.param[3] = fwspec->param[1]; + + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, + &parent_fwspec); + + return 0; +} + +static const struct irq_domain_ops max77650_gpio_irq_domain_ops = { + .activate = max77650_gpio_irq_domain_activate, + .deactivate = max77650_gpio_irq_domain_deactivate, + .alloc = max77650_gpio_domain_alloc, + .free = irq_domain_free_irqs_common, + .translate = max77650_gpio_domain_translate, +}; + static int max77650_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) { struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + struct irq_fwspec fwspec; + + fwspec.fwnode = chip->fwnode; + fwspec.param_count = 2; + fwspec.param[0] = 0; + fwspec.param[1] = IRQ_TYPE_LEVEL_LOW; - return chip->irq; + return irq_create_fwspec_mapping(&fwspec); } static int max77650_gpio_probe(struct platform_device *pdev) { + struct device_node *of_node, *parent_node; + struct irq_domain *parent_domain; struct max77650_gpio_chip *chip; struct device *dev, *parent; struct i2c_client *i2c; + int rv; dev = &pdev->dev; + of_node = dev->of_node; parent = dev->parent; i2c = to_i2c_client(parent); @@ -151,13 +247,29 @@ static int max77650_gpio_probe(struct platform_device *pdev) if (!chip) return -ENOMEM; + chip->fwnode = dev->fwnode; + platform_set_drvdata(pdev, chip); + chip->map = dev_get_regmap(parent, NULL); if (!chip->map) return -ENODEV; - chip->irq = platform_get_irq_byname(pdev, "GPI"); - if (chip->irq < 0) - return chip->irq; + parent_node = of_irq_find_parent(of_node); + if (!parent_node) + return -ENXIO; + + parent_domain = irq_find_host(parent_node); + of_node_put(parent_node); + if (!parent_domain) + return -ENXIO; + + chip->fwnode = of_node_to_fwnode(of_node); + chip->domain = irq_domain_create_hierarchy(parent_domain, 0, 1, + chip->fwnode, + &max77650_gpio_irq_domain_ops, + chip); + if (!chip->domain) + return -ENODEV; chip->gc.base = -1; chip->gc.ngpio = 1; @@ -174,7 +286,20 @@ static int max77650_gpio_probe(struct platform_device *pdev) chip->gc.set_config = max77650_gpio_set_config; chip->gc.to_irq = max77650_gpio_to_irq; - return devm_gpiochip_add_data(dev, &chip->gc, chip); + rv = devm_gpiochip_add_data(dev, &chip->gc, chip); + if (rv) + irq_domain_remove(chip->domain); + + return rv; +} + +static int max77650_gpio_remove(struct platform_device *pdev) +{ + struct max77650_gpio_chip *chip = platform_get_drvdata(pdev); + + irq_domain_remove(chip->domain); + + return 0; } static struct platform_driver max77650_gpio_driver = { @@ -182,6 +307,7 @@ static struct platform_driver max77650_gpio_driver = { .name = "max77650-gpio", }, .probe = max77650_gpio_probe, + .remove = max77650_gpio_remove, }; module_platform_driver(max77650_gpio_driver);