Received: by 10.223.185.116 with SMTP id b49csp159305wrg; Tue, 13 Feb 2018 18:50:22 -0800 (PST) X-Google-Smtp-Source: AH8x225esyzSyfCto8TRXfjpkadZ1GMMk2kRodbiRtxJoAomqpGsQkg+zRiI4SXvKFiTi832L/s6 X-Received: by 10.99.96.137 with SMTP id u131mr2701967pgb.103.1518576622632; Tue, 13 Feb 2018 18:50:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518576622; cv=none; d=google.com; s=arc-20160816; b=hkE9Ll5Ujo3J/xrvbhcc62CMPBOldvhSWaohpBt3rLAB/qXpQb5DSkjy5O/WLxckKm EO0GD0IE6hoVChFr2VYciP4Zim7NqaGUxuPxXAsCmYyVWquJN9A92qg3yAgtlct/A8Lj mIpZVOSVa4m8MyU9jrPXAZBBVI0y2cJ2hN2HZJQpgMchOiyBvCHpXiF0CJ52pl1zjrRH P0aBRoYvxpnXzyefzCeM49cfE8eTKbamOc1hHlTLp4jvYsqjpFqH+hh/6018bIuGYz9k WpCCPWXeqNLi5RYoYeMtfvrvY8V4sUrOzSsiaLiP6fkq6t7+z/KQHgrmhyDN0sECJtk0 c8Rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=z1B+aHY2DfwKqVScNXKdFl0naNNDDGPuwGXv2FmajDM=; b=cLDELo4HTCSnyO+XKr+p4UaeQyI32oK/9C1zrl0lla5iDtiAil44SThRPyCgq5/ht9 QJkpqDryEc6ftZrFeevo83Lgo6fXgfnxq4gpy3xf1ocgvYQhiyRm+4lB6K1sbpDUeslt 6rtBCQUhNcNjX72XCDryLtN2CtNYtPODpYKrjSCAeJHY8FkMeMKarnctdyYlLij3gIEz NVYBV8a+9gSK5KnO7aFXrtGacN2DTgZZlxVZWEOElpZ4eE/W2R0lKuUtLT6rbMevRBAk tfIyO2YAQefG7cT/pclPaIukbuVoB8zmR+fgoTX6JICW2UqQzRsXcq7Om1P1B3RycbAj HHfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DrjQhPwq; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 31-v6si6614181plk.532.2018.02.13.18.50.08; Tue, 13 Feb 2018 18:50:22 -0800 (PST) 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; dkim=pass header.i=@linaro.org header.s=google header.b=DrjQhPwq; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966627AbeBNCtB (ORCPT + 99 others); Tue, 13 Feb 2018 21:49:01 -0500 Received: from mail-ot0-f194.google.com ([74.125.82.194]:40677 "EHLO mail-ot0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966497AbeBNCtA (ORCPT ); Tue, 13 Feb 2018 21:49:00 -0500 Received: by mail-ot0-f194.google.com with SMTP id s4so19154406oth.7 for ; Tue, 13 Feb 2018 18:48:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=z1B+aHY2DfwKqVScNXKdFl0naNNDDGPuwGXv2FmajDM=; b=DrjQhPwq2IC7GpEszwW7gAF4ohLBf0ioVMc55X+EvkxBvjzZWmJ1pwFwJnXR0wx7Ph +uNbEtcgto+SpqKkwiJy5RLBfBLxAPGye9b//7z4gjkju3PNgKM2Bry/SFOj1cfqWut5 DZxSE5/xS8MfvEVWfIDplGUSdHUj/8uxQOWJk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=z1B+aHY2DfwKqVScNXKdFl0naNNDDGPuwGXv2FmajDM=; b=SyX7kEa2IHmgI8VXo1SBODnWwFLU/Lal8GGqUW3106ZxV2YNJi/sueKRWm1fJGBn/C 9XgOt9CsI0pqXQwl4BbgoPxindnXdta+uZ8PscZ4tLaIErqcVyDiFqKcGlYZIQShWMG9 Y9Jv/ftxOxK2npmEBxPX2Z5gMqRHhq86ptVd0oRSjMVpLsLXZujKpkFmMfDx3nFuiW9L Ku+wYqa7rhdJa5OkG63I0YbT8bPm0eUUH/Ikkppw9EeowURPQmTZ3K0FygKia4E+CiDd r9XqpfCv25nwYE5/Scz989VpQxOqr830Cmmk+MgMh1RD72eZ8U0sHTGtBmd9zDZusn0y tHrg== X-Gm-Message-State: APf1xPDV+2NMH8OiX7Ic/oUfgWk09KLAjXuZWayElwXiH2D3QcrAMkQG QsZ32XWrm9ysdStX/w0SXCizlfmgMtYMbLjjj7aqbQ== X-Received: by 10.157.14.163 with SMTP id 32mr2187951otj.396.1518576539365; Tue, 13 Feb 2018 18:48:59 -0800 (PST) MIME-Version: 1.0 Received: by 10.157.73.153 with HTTP; Tue, 13 Feb 2018 18:48:58 -0800 (PST) In-Reply-To: References: <2834309f69a1ec37b84a33f153a3d0b90336bcc6.1517795460.git.baolin.wang@linaro.org> From: Baolin Wang Date: Wed, 14 Feb 2018 10:48:58 +0800 Message-ID: Subject: Re: [PATCH v3 2/2] gpio: Add GPIO driver for Spreadtrum SC9860 platform To: Linus Walleij Cc: Rob Herring , Mark Rutland , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , "linux-kernel@vger.kernel.org" , "open list:GPIO SUBSYSTEM" , Mark Brown , Andy Shevchenko Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Linus, On 13 February 2018 at 16:13, Linus Walleij wrote: > On Mon, Feb 5, 2018 at 2:55 AM, Baolin Wang wrote: > >> The Spreadtrum SC9860 platform GPIO controller contains 16 groups and >> each group contains 16 GPIOs. Each GPIO can set input/output and has >> the interrupt capability. >> >> Signed-off-by: Baolin Wang >> Reviewed-by: Andy Shevchenko >> --- >> Changes since v2: > > Hi Baolin, > > sorry for taking so long to review :( > > I think you need to add > > depends on OF_GPIO to the dependencies. Else the build > will break on compile test on things like Usermode Linux > that doesn't have IOMEM. OK. > >> +/* GPIO registers definition */ >> +#define SPRD_GPIO_DATA 0x0 >> +#define SPRD_GPIO_DMSK 0x4 >> +#define SPRD_GPIO_DIR 0x8 >> +#define SPRD_GPIO_IS 0xc >> +#define SPRD_GPIO_IBE 0x10 >> +#define SPRD_GPIO_IEV 0x14 >> +#define SPRD_GPIO_IE 0x18 >> +#define SPRD_GPIO_RIS 0x1c >> +#define SPRD_GPIO_MIS 0x20 >> +#define SPRD_GPIO_IC 0x24 >> +#define SPRD_GPIO_INEN 0x28 > > So this is very simple. And the only reason we cannot use > GPIO_GENERIC is that we have these groups inside the controller > and a shared interrupt line :/ > > Hm yeah I cannot think of anything better anyway. > > Have you contemplated just putting them into the device tree > like this: > > ap_gpio0: gpio@40280000 { > compatible = "sprd,sc9860-gpio"; > reg = <0 0x40280000 0 0x80>; > gpio-controller; > #gpio-cells = <2>; > interrupt-controller; > #interrupt-cells = <2>; > interrupts = ; > }; > > ap_gpio1: gpio@40280080 { > compatible = "sprd,sc9860-gpio"; > reg = <0 0x40280080 0 0x80>; > gpio-controller; > #gpio-cells = <2>; > interrupt-controller; > #interrupt-cells = <2>; > interrupts = ; > }; > > ap_gpio2: gpio@40280100 { > compatible = "sprd,sc9860-gpio"; > reg = <0 0x40280100 0 0x80>; > gpio-controller; > #gpio-cells = <2>; > interrupt-controller; > #interrupt-cells = <2>; > interrupts = ; > }; > > (...) > > ? > > It is fine to have 16 driver instances if you grab the interrupt > with IRQF_SHARED and really just handle the IRQ if it is for > "your" instance. The upside is that you could then use > GPIO_GENERIC and get a very small and simple driver. > > I understand that the current approach is also appealing though > and I see why. I'm not gonna say no to it, so if you strongly > prefer this approach we can go for it. Just wanted to point out > alternatives. Thanks for pointing out another approach. But we only have one controller with multiple banks, so I think it is not easy to maintain if we split one GPIO controller into multiple ones. Moreover if we have more banks in future, there will be more device node to maintain. So I still would like to use one device node to describe the only one GPIO device. > >> +/* We have 16 groups GPIOs and each group contain 16 GPIOs */ >> +#define SPRD_GPIO_GROUP_NR 16 >> +#define SPRD_GPIO_NR 256 >> +#define SPRD_GPIO_GROUP_SIZE 0x80 >> +#define SPRD_GPIO_GROUP_MASK GENMASK(15, 0) >> +#define SPRD_GPIO_BIT(x) ((x) & (SPRD_GPIO_GROUP_NR - 1)) > > Please rename this from "groups" to "banks" because in the GPIO > subsystem everyone talks about "banks" not "groups". Sure. > > This last thing many drivers do like this: > > bit = x % 15; > > but it is up to you, either way works (and probably result in the > same assembly). OK. > >> +static inline void __iomem *sprd_gpio_group_base(struct sprd_gpio *sprd_gpio, >> + unsigned int group) >> +{ >> + return sprd_gpio->base + SPRD_GPIO_GROUP_SIZE * group; >> +} > > Since you're always using this like this: > > void __iomem *base = sprd_gpio_group_base(sprd_gpio, > offset / SPRD_GPIO_GROUP_NR); > > Why not simply have the offset as parameter to the function > instead of group number and do the division inside this > static inline? In sprd_gpio_irq_handler() function, we should pass the group number as parameter, so to consistent with them, I use group number as parameter. > >> +static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset, >> + unsigned int reg, unsigned int val) > > I would use u16 reg. Sure. > >> +{ >> + struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip); >> + void __iomem *base = sprd_gpio_group_base(sprd_gpio, >> + offset / SPRD_GPIO_GROUP_NR); >> + u32 shift = SPRD_GPIO_BIT(offset); >> + unsigned long flags; >> + u32 orig, tmp; >> + >> + spin_lock_irqsave(&sprd_gpio->lock, flags); >> + orig = readl_relaxed(base + reg); >> + >> + tmp = (orig & ~BIT(shift)) | (val << shift); >> + writel_relaxed(tmp, base + reg); >> + spin_unlock_irqrestore(&sprd_gpio->lock, flags); >> +} > > You don't need shift, orig and tmp variables here, I think it > gets hard to read. > > I would do it like this: > > u32 tmp; > > tmp = readl_relaxed(base + reg); > if (val) > tmp |= BIT(SPRD_GPIO_BIT(offset)); > else > tmp &= ~BIT(SPRD_GPIO_BIT(offset)); > writel_relaxed(tmp, base + reg); OK. This seems more simpler and clearer. > > I don't know if the macros really help much. Maybe just inline it: > > tmp = readl_relaxed(base + reg); > if (val) > tmp |= BIT(offset % 15); > else > tmp &= ~BIT(offset % 15); > writel_relaxed(tmp, base + reg); > > It depends on taste. Just consider my options. > (I'll go with what you feel is easiest to read.) OK. > >> +static int sprd_gpio_read(struct gpio_chip *chip, unsigned int offset, >> + unsigned int reg) >> +{ >> + struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip); >> + void __iomem *base = sprd_gpio_group_base(sprd_gpio, >> + offset / SPRD_GPIO_GROUP_NR); >> + u32 value = readl_relaxed(base + reg) & SPRD_GPIO_GROUP_MASK; >> + u32 shift = SPRD_GPIO_BIT(offset); >> + >> + return !!(value & BIT(shift)); > > I would just > > return !!(readl_relaxed(base + reg) & BIT(offset % 15)): > > But again it is a matter of taste. OK. Thanks for your useful comments. -- Baolin.wang Best Regards