Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3043344imm; Sun, 5 Aug 2018 19:33:21 -0700 (PDT) X-Google-Smtp-Source: AAOMgpepTglGOdaARG0RgpVtlH8yfKPmN4NF27HZ+XhIlt15jek4sgFmdH3YHbx2lw+aAfVA744f X-Received: by 2002:a17:902:a58b:: with SMTP id az11-v6mr11968103plb.36.1533522801937; Sun, 05 Aug 2018 19:33:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533522801; cv=none; d=google.com; s=arc-20160816; b=LpacQxCBgIc/GDmPxFZHsQxxsZ3Zm+vBO8H0wsilQEl8Rj7ar6+8DqQI0LheasHduK KsMWpQTrHYC5aZJV9QgVllZf0yZnOjP5NrsgVwWBZzRoWA4tAkhoNyAB0M+yynybPdMX i4ntjVbQgRXn7kEHVLJN3PfaGgaEA0tS26P5QTgz3od7tLXYYE8KzX8Iq0p0ue8CugO4 WGXEyt23swItyhiRfGzMRyfwjbg5+u8wpJiD1Cn5sCT5kQpLWGly4wQQd4VlLSWXtIIe JUb/rfdrw2dttWZD9GgFPkgl44j/K6FqaR9ftdytKk0kdWCm4vEqbBuWOaVfKSSOn1zC THTg== 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=G0tNEwb+SWTIKGc3pYGleCgZ3pAhaZNPtPVjRf0E+ThA9h4dlpsBwABCPgzFml/YJZ hYlthtdtD8/hmqu4a9uIKxV+KFxy9uWN3k+PYUzbsTHMnhniHQuVSWi1xU7Ea5op1xdY Ue8vkQKmH0yx45Xb7vyh8tYhNGTgGqk0jmloieXS/HskOc7IpGPRTjmeB0O3NY5tzpWW fH+mpTQoMhz/CNR1SkqvCSY5WW3cH9OHGDqlPvCeFB7u7vOI2tOYQ2M9S5eYK8u7jDeQ dl+baUwE4Qga8TJBEpyD/xWCacFziqJUxl81SVsziVaLjN29Ce3cjW4ze3xv2ngeDWhl p19A== 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 y6-v6si12490369pfy.140.2018.08.05.19.32.51; Sun, 05 Aug 2018 19:33:21 -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 S1726988AbeHFEi0 (ORCPT + 99 others); Mon, 6 Aug 2018 00:38:26 -0400 Received: from relay6-d.mail.gandi.net ([217.70.183.198]:53861 "EHLO relay6-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726143AbeHFEi0 (ORCPT ); Mon, 6 Aug 2018 00:38:26 -0400 X-Originating-IP: 112.215.208.161 Received: from ubuntuVM.localdomain (unknown [112.215.208.161]) (Authenticated sender: aditya@kobol.io) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 5A760C0002; Mon, 6 Aug 2018 02:31:26 +0000 (UTC) From: Aditya Prayoga To: linux-gpio@vger.kernel.org Cc: Richard Genoud , Gregory CLEMENT , Gauthier Provost , Alban Browaeys , Thierry Reding , Linus Walleij , linux-pwm@vger.kernel.org, linux-kernel@vger.kernel.org, Dennis Gilmore , Ralph Sennhauser , Andrew Lunn , Aditya Prayoga Subject: [PATCH RESEND 1/2] gpio: mvebu: Add support for multiple PWM lines per GPIO chip Date: Mon, 6 Aug 2018 10:29:15 +0800 Message-Id: <1533522556-55055-2-git-send-email-aditya@kobol.io> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1533522556-55055-1-git-send-email-aditya@kobol.io> References: <1533522556-55055-1-git-send-email-aditya@kobol.io> 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