Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3273266imm; Fri, 20 Jul 2018 13:20:54 -0700 (PDT) X-Google-Smtp-Source: AAOMgpf8CfjZ6+9NQMU3IWuYvrqkR9t1oEQ8VR1Fxy1Gb+PqEXfBWiUPqqZ42AU7FzAM6WAzhRdo X-Received: by 2002:a65:58c8:: with SMTP id e8-v6mr3327116pgu.96.1532118054407; Fri, 20 Jul 2018 13:20:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532118054; cv=none; d=google.com; s=arc-20160816; b=PaAzWqUhFFrfv9f7e/COKraIaINbbL2dmQhVrJnKqMK3sFJDKjzbIDvA4cYDzmg14r 3H4maLRkb1oS9dy0+Gr51GMKePbVTLY4LKeITEggAAJiKj+/Sq1O69LiTBL4ONUP3ETU BNNDABdySc76SIgjREZQuCUKkw7tTDQOkMP7oN9sXG1WLsYwZJhm0QbVeE3ci+Gm5gdn mYgC+1oW3r1glNbxLm3EcGElMX/PkmZkCDr0DqZVpv/KTh5MM4Hd0Z3bfux5c5R4vu0o FpEVlNm12JaUx5hMWOTCq7ht7TGvcgUuHQmChKW/U1mHJyZg6PHclmP+pXsaZODQtWCQ yGsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=B4tYwA4GiZ6JFz4WaS5NGtHyrv4AUzGPl4VrUbZM/pk=; b=EkzoHhpwOEC64SX4TSG1u+C2zWC7rsbBe8ElrBjDR1InAlcDPFxDld1nu+V0AXx+zS 2CrRDSo3TP5gG09jLXXukg6yP0mp7QAW3ly1V4km2w3Oo1/eI3cipuWPVnj7uprVSb9t Tq8zPK3buWF/ysAlYWc/v74m2xKNi3QovYrvteA4LmjDSBLhjzGouCtingtoDL6dVGOM xLkwjfNwlSn62gqnDr9R8Z7XvYGamc3O/3YjaKaHogbq/3dz6vbjhNcK3Y+4Z1KWR7dF 4WIE/vN2EzEYrNPzoZ2K0NQ6Y6pW60z+aVZ1TeKlTBowx+ilnpZWwwEKB7Oj5KsxAiZn pQOA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 200-v6si2596706pgf.378.2018.07.20.13.20.16; Fri, 20 Jul 2018 13:20:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728305AbeGTVIl (ORCPT + 99 others); Fri, 20 Jul 2018 17:08:41 -0400 Received: from mslow2.mail.gandi.net ([217.70.178.242]:49052 "EHLO slow1-d.mail.gandi.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727383AbeGTVIl (ORCPT ); Fri, 20 Jul 2018 17:08:41 -0400 Received: from relay6-d.mail.gandi.net (unknown [217.70.183.198]) by slow1-d.mail.gandi.net (Postfix) with ESMTP id CE5AB3A5A76; Fri, 20 Jul 2018 21:24:11 +0200 (CEST) X-Originating-IP: 140.213.19.3 Received: from ubuntuVM.localdomain (unknown [140.213.19.3]) (Authenticated sender: aditya@kobol.io) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 5CB0BC000A; Fri, 20 Jul 2018 19:24:05 +0000 (UTC) From: Aditya Prayoga To: linux-gpio@vger.kernel.org Cc: Gauthier Provost , Alban Browaeys , Thierry Reding , Linus Walleij , linux-pwm@vger.kernel.org, linux-kernel@vger.kernel.org, Aditya Prayoga Subject: [PATCH 1/2] gpio: mvebu: Add support for multiple PWM lines per GPIO chip Date: Sat, 21 Jul 2018 03:23:42 +0800 Message-Id: <1532114623-81911-2-git-send-email-aditya@kobol.io> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532114623-81911-1-git-send-email-aditya@kobol.io> References: <1532114623-81911-1-git-send-email-aditya@kobol.io> X-Spam-Level: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow more than 1 PWM request (eg. PWM fan) on the same GPIO chip. based on initial work on LK4.4 by Alban Browaeys. URL: https://github.com/helios-4/linux-marvell/commit/743ae97 [Aditya Prayoga: forward port, cleanup] Signed-off-by: Aditya Prayoga --- drivers/gpio/gpio-mvebu.c | 63 ++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 6e02148..0617e66 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -92,10 +92,17 @@ #define MVEBU_MAX_GPIO_PER_BANK 32 +struct mvebu_pwm_item { + struct gpio_desc *gpiod; + struct pwm_device *device; + struct list_head node; +}; + struct mvebu_pwm { void __iomem *membase; unsigned long clk_rate; - struct gpio_desc *gpiod; + int id; + struct list_head pwms; struct pwm_chip chip; spinlock_t lock; struct mvebu_gpio_chip *mvchip; @@ -599,29 +606,31 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; struct gpio_desc *desc; + struct mvebu_pwm_item *item; unsigned long flags; int ret = 0; - spin_lock_irqsave(&mvpwm->lock, flags); - - if (mvpwm->gpiod) { - ret = -EBUSY; - } else { - desc = gpiochip_request_own_desc(&mvchip->chip, - pwm->hwpwm, "mvebu-pwm"); - if (IS_ERR(desc)) { - ret = PTR_ERR(desc); - goto out; - } + item = kzalloc(sizeof(*item), GFP_KERNEL); + if (!item) + return -ENODEV; - ret = gpiod_direction_output(desc, 0); - if (ret) { - gpiochip_free_own_desc(desc); - goto out; - } + spin_lock_irqsave(&mvpwm->lock, flags); + desc = gpiochip_request_own_desc(&mvchip->chip, + pwm->hwpwm, "mvebu-pwm"); + if (IS_ERR(desc)) { + ret = PTR_ERR(desc); + goto out; + } - mvpwm->gpiod = desc; + ret = gpiod_direction_output(desc, 0); + if (ret) { + gpiochip_free_own_desc(desc); + goto out; } + item->gpiod = desc; + item->device = pwm; + INIT_LIST_HEAD(&item->node); + list_add_tail(&item->node, &mvpwm->pwms); out: spin_unlock_irqrestore(&mvpwm->lock, flags); return ret; @@ -630,12 +639,20 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); + struct mvebu_pwm_item *item, *tmp; unsigned long flags; - spin_lock_irqsave(&mvpwm->lock, flags); - gpiochip_free_own_desc(mvpwm->gpiod); - mvpwm->gpiod = NULL; - spin_unlock_irqrestore(&mvpwm->lock, flags); + list_for_each_entry_safe(item, tmp, &mvpwm->pwms, node) { + if (item->device == pwm) { + spin_lock_irqsave(&mvpwm->lock, flags); + gpiochip_free_own_desc(item->gpiod); + item->gpiod = NULL; + item->device = NULL; + list_del(&item->node); + spin_unlock_irqrestore(&mvpwm->lock, flags); + kfree(item); + } + } } static void mvebu_pwm_get_state(struct pwm_chip *chip, @@ -804,6 +821,8 @@ static int mvebu_pwm_probe(struct platform_device *pdev, return -ENOMEM; mvchip->mvpwm = mvpwm; mvpwm->mvchip = mvchip; + mvpwm->id = id; + INIT_LIST_HEAD(&mvpwm->pwms); mvpwm->membase = devm_ioremap_resource(dev, res); if (IS_ERR(mvpwm->membase)) -- 2.7.4