Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1757815pxf; Fri, 26 Mar 2021 14:15:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJywWegMJcxI7WTAfEk33WnrIe3GO/WXyu04xQeqlKRBC2MVyVCh/ZYn1KcNqgpBvastd+v0 X-Received: by 2002:a17:906:38da:: with SMTP id r26mr17876641ejd.251.1616793322655; Fri, 26 Mar 2021 14:15:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616793322; cv=none; d=google.com; s=arc-20160816; b=PXN+NLVfR3ofRhrJ/oFCwCxfeF3BZhXIHkkXLtxLuagBGmOHTSwzBNLqXlH7r1rSD8 ld1635qIc17Sa0CeeCBzBrglbvaHENqA5ZseHhjgfhXgWlM/pIpUzfp3m66t6gI7/0I/ fwwdRd8PqPeIK2IHmLwGP3PdEcY/spXTMsCav/lsVtmkCfd7cv2s7482PLNn+Mfcb5l4 j0uPWLL1Ds3xykkc8UyiDDRDKv1O4O+wV8ivPOjEdxfH/pkQeq+ktnyaGwoLcFIpO8LZ aj9nbhQhbKdtl11chzDFhy0WFryObVobWf33fdEYn10/lU2HmRCOSqbo9UfeS3uig1s3 3aYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:cc:to:from:subject :message-id:dkim-signature; bh=khl5Z4oSNwve2yBva/20MyIhKiwGzIOzGG+zJupOXk4=; b=V++wZ/wff2Ec0OER2KZIhIC/eP5TLBpqTZWtCzktikrOqt0dv9VutlB9PUF4kpMSZy KLvG5dXwdYvlF5rkRRVsXuE1+4BArnQughpSzN1kpVW9tIj8FbrxA8XCFXKH3Ilmvsll teiJwZP4dm8rziFTRZ95koDvXwlFe9eQX1GU3IOaj9OXEfyAmeqTElqthnZsiAaNYT6L AOspAlhOhKngfJKPOYQiwLPyj8oMGLdBtEZAx99JlyXGDWEb4NgKKlu2WnKG5qvy8irg ltvZoRQwE0oV5SaJzGGNyO2DcG6QLbY1LIFARmpsFbFkDampAAvvLq3BJ4K+mQxPKTYE yOeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@svanheule.net header.s=mail1707 header.b=X3V+AeuP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=svanheule.net Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id oy25si2121290ejb.563.2021.03.26.14.15.00; Fri, 26 Mar 2021 14:15:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@svanheule.net header.s=mail1707 header.b=X3V+AeuP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=svanheule.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230308AbhCZVMC (ORCPT + 99 others); Fri, 26 Mar 2021 17:12:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230259AbhCZVLm (ORCPT ); Fri, 26 Mar 2021 17:11:42 -0400 Received: from polaris.svanheule.net (polaris.svanheule.net [IPv6:2a00:c98:2060:a004:1::200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94053C0613AA for ; Fri, 26 Mar 2021 14:11:41 -0700 (PDT) Received: from [IPv6:2a02:a03f:eaff:9f01:cce8:c5ff:8b8d:f8cb] (unknown [IPv6:2a02:a03f:eaff:9f01:cce8:c5ff:8b8d:f8cb]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id A100F1E60C4; Fri, 26 Mar 2021 22:11:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1616793099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=khl5Z4oSNwve2yBva/20MyIhKiwGzIOzGG+zJupOXk4=; b=X3V+AeuP13VDXyEH+N82jg44PnDNS8o0dktTnMEjqx8dYruxKDQJQ6sGJA0VEMGPBlGPCV 4c6QRItCVn5X9lrB6cN6SGC8Lut1BFWRUSYlAyobmhn7mj3KoGDYx2wMipNttig4fd+X7F eRWiRITj842aW6EIsCSoaPuHQ0osrzudltXn+soEs4V3p7F1ipyGmJOOKHA/n9GV3eBj/W 04dyogUCzTocon2Bdw+RUBsSCwfVodZ4ThTUTu1kjRdfLM3/ph9Whkh4MkYxOilIRMK/JQ hTBZ6YliDm5I/+DDK3hFb4y/s+bQrIHNTftbcNaVMF/3fikkYtIKlCh3bnoCmQ== Message-ID: Subject: Re: [PATCH v4 2/2] gpio: Add Realtek Otto GPIO support From: Sander Vanheule To: Andy Shevchenko Cc: devicetree , "open list:GPIO SUBSYSTEM" , Bert Vermeulen , Bartosz Golaszewski , Linus Walleij , Linux Kernel Mailing List , Marc Zyngier , Rob Herring , Thomas Gleixner Date: Fri, 26 Mar 2021 22:11:36 +0100 In-Reply-To: References: <31e5a5aeb833c43c07daafcf939864497ff1c349.1616760183.git.sander@svanheule.net> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.38.4 (3.38.4-1.fc33) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Andy, Replies inline below. On Fri, 2021-03-26 at 20:19 +0200, Andy Shevchenko wrote: > On Fri, Mar 26, 2021 at 2:05 PM Sander Vanheule > wrote: > > > +config GPIO_REALTEK_OTTO > > +       bool "Realtek Otto GPIO support" > > Why not module? This driver is only useful on a few specific MIPS SoCs, where this GPIO peripheral is a part of that SoC. What would be the point of providing this driver as a module? > > > +       depends on MACH_REALTEK_RTL > > +       default MACH_REALTEK_RTL > > +       select GPIO_GENERIC > > +       select GPIOLIB_IRQCHIP > > > +       help > > +         The GPIO controller on the Otto MIPS platform supports up > > to two > > +         banks of 32 GPIOs, with edge triggered interrupts. The 32 > > GPIOs > > +         are grouped in four 8-bit wide ports. > > When allowing module build, here you may add what will be the name of > it. > > ... > > > +/* > > + * Total register block size is 0x1C for four ports. > > + * On the RTL8380/RLT8390 platforms port A, B, and C are > > implemented. > > D? No port D on 8380/8390. Only 24 GPIO lines are present on these platforms. I'll rephrase this comment. > > > + * RTL8389 and RTL8328 implement a second bank with ports E, F, G, > > and H. > > + * > > + * Port information is stored with the first port at offset 0, > > followed by the > > + * second, etc. Most registers store one bit per GPIO and should be > > read out in > > + * reversed endian order. The two interrupt mask registers store two > > bits per > > + * GPIO, and should be manipulated with swahw32, if required. > > + */ This reference to swahw32 and the include of linux/swab.h will be dropped. > > > +/* > > Seems like kernel doc format with missed ** header and properly formed > summary and description. I'll reformat. > > > + * Realtek GPIO driver data > > + * Because the interrupt mask register (IMR) combines the function > > of > > + * IRQ type selection and masking, two extra values are stored. > > + * intr_mask is used to mask/unmask the interrupts for certain > > GPIO, > > + * and intr_type is used to store the selected interrupt types. > > The > > + * logical AND of these values is written to IMR on changes. > > + * > > + * @gc Associated gpio_chip instance > > + * @base Base address of the register block > > + * @lock Lock for accessing the IRQ registers and values > > + * @intr_mask Mask for GPIO interrupts > > + * @intr_type GPIO interrupt type selection > > + */ > > +struct realtek_gpio_ctrl { > > +       struct gpio_chip gc; > > +       void __iomem *base; > > +       raw_spinlock_t lock; > > +       u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK]; > > +       u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK]; > > +}; > > + > > +enum realtek_gpio_flags { > > +       GPIO_INTERRUPTS = BIT(0), > > +}; > > ... See below. I'll add a comment. > > > +static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data > > *data) > > +{ > > +       struct gpio_chip *gc = irq_data_get_irq_chip_data(data); > > + > > +       return container_of(gc, struct realtek_gpio_ctrl, gc); > > +} > > > +static unsigned int line_to_port(unsigned int line) > > +{ > > +       return line / 8; > > +} > > + > > +static unsigned int line_to_port_pin(unsigned int line) > > +{ > > +       return line % 8; > > +} > > These are useless. Just use them inline. I added these as the alternative of the /16 and %16 I had for the IMR offsets in v2. The function names tell the reader _why_ I'm doing the division and modulo operations, but I guess a properly named variable would do the same. > > > +static u8 read_u8_reg(void __iomem *reg, unsigned int port) > > +{ > > +       return ioread8(reg + port); > > +} > > + > > +static void write_u8_reg(void __iomem *reg, unsigned int port, u8 > > value) > > +{ > > +       iowrite8(value, reg + port); > > +} > > + > > +static void write_u16_reg(void __iomem *reg, unsigned int port, u16 > > value) > > +{ > > +       iowrite16(value, reg + 2 * port); > > +} > > What's the point? You better provide a controller structure as a > parameter. Look into other drivers. There are plenty of examples how > to provide IO accessors in smarter way. Since these are currently only really used for IMR and ISR, I'll fold them into their accessor functions for v5. > > > +static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl, > > +       unsigned int port, u16 irq_type, u16 irq_mask) > > +{ > > +       write_u16_reg(ctrl->base + REALTEK_GPIO_REG_IMR, port, > > +                  irq_type & irq_mask); > > Can be one line. > > > +} > > ... > > > +static int realtek_gpio_irq_set_type(struct irq_data *data, > > +       unsigned int flow_type) > > One line? I thought checkpatch.pl would complain, but it doesn't. Folded onto one line. > > +       chained_irq_enter(irq_chip, desc); > > + > > +       for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) > > { > > +               port = line_to_port(lines_done); > > +               status = read_u8_reg(reg_isr, port); > > +               port_pin_count = min(gc->ngpio - lines_done, 8U); > > +               for_each_set_bit(offset, &status, port_pin_count) { > > +                       irq = irq_find_mapping(gc->irq.domain, > > offset); > > +                       generic_handle_irq(irq); > > > +                       write_u8_reg(reg_isr, port, BIT(offset)); > > Shouldn't it be in the ->irq_ack() callback? I think I added this line to deal with handle_bad_irq during development. Like you say, handle_edge_irq() has it's specific ACK logic, so this is probably even a bug. Will be removed. > > > +               } > > +       } > > ... > > > +static const struct of_device_id realtek_gpio_of_match[] = { > > +       { .compatible = "realtek,otto-gpio" }, > > +       { > > +               .compatible = "realtek,rtl8380-gpio", > > +               .data = (void *)GPIO_INTERRUPTS > > Not sure why this flag is needed right now. Drop it completely for > good. > > +       }, > > +       { > > +               .compatible = "realtek,rtl8390-gpio", > > +               .data = (void *)GPIO_INTERRUPTS > > Ditto Linus Walleij asked this question too after v1: https://lore.kernel.org/linux-gpio/e9f0651e5fb52b7d56361ceb30b41759b6f2ec13.camel@svanheule.net/ Note that the fall-back compatible doesn't have this flag set. > . > > > +       }, > > +       {} > > +}; > > > + > > Extra blank line. Add or drop? I see other drivers using no empty line between the of_match table and the MODULE_DEVICE_TABLE macro. > > > +MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); > > > ... > > > +               iowrite32(GENMASK(31, 0), ctrl->base + > > REALTEK_GPIO_REG_ISR); > > This one perhaps needs a comment like "cleaning all IRQ states". > Note, we have a proper callback for this, i.e. hw_init. Consider to use > it. Which "hw_init" are you referring too? I can't really find much, aside from drivers implementing it themselves to differentiate between driver and hardware set-up. Since this is normally only called once, I can turn it into the more readable: for (port = 0; (port * 8) < ngpios; port++) { realtek_gpio_write_imr(ctrl, port, 0, 0); realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0)); } > > > +}; > > > + > > Extra blank line. I see the same use of one blank line in other drivers. > > +builtin_platform_driver(realtek_gpio_driver); > > ... > > So, looking into the code, I think you may easily get rid of 30-50 > LOCs. > So, expecting <= 300 LOCs in v5. After trimming the file, sloccount puts me at 224, but the total line count is still 310. :-) Best, Sander