Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp821571imm; Fri, 3 Aug 2018 12:10:00 -0700 (PDT) X-Google-Smtp-Source: AAOMgpeLY6d40nJSSgMz41X/q4rYsnAnPV5AT0AOLn2bC8kfDq+aFSyDJcCStoJy1W1biaHtOWOz X-Received: by 2002:a65:6110:: with SMTP id z16-v6mr5099240pgu.412.1533323399967; Fri, 03 Aug 2018 12:09:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533323399; cv=none; d=google.com; s=arc-20160816; b=jNgaI5ySsHRYlgOXtdgnTaPPWWJZMJwjt1/pDvddOPlj4FV/I1Cb1nBQG023FsFIIC cm7eZBn3uBJSe/cZ6A1CU93sj2olV1uFPSJh2/E05tXNq+Hnjy7jwr/nE7E9w2aQ/ibf fcQ52iTO88vPI5/oM3FvCxQ72SqVk5c/Otg2py3D9MAOqNkWCaVThZy3+NQ83US0+MTq g4PdfjaENl7dRYr+lheZNGdWUjG0740HDJE5ImKQV3POS01O7rsVz5Y+6mlUT14FuC/E F6MuSY+cCApTiKF2g5FKdlCyeix8DsmduvZekB7WyoURuR1rSXCkPmqH53o1oPFlkVO+ zPPA== 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=kpZlL+/y/Ez120raHr4T6F8c+6ia3San6SaxWsGsYec=; b=p9Rieqgap4lyfTRWLdrYRAmV1Lc3W/v4L5ffaLRMvUSw2tZCuY9S9bI+i6iJ4fBEzd mRbC05KV9x1TqMZkaihbikpYUZupV15XtrZrlmA9+2bNxhgWAWB6vR989ADfvhS4JF4T w1uucKIeN36TLqR610/xTGpcPOHf1RfGvGCpOgt/aMxPwDcNfAazoQmG2ktUaHbwEZ1t UEz5iaGh2VhnKTK7gSPWPMfWZn6MWV05UpMjghn47O3Bqzx3rcK2tD+C7e3M9Sa3wJHM veYB7J5gj8xsphe9UvAWqL5CCpxSMciRCTw377YxWygxkf+32EezfUkkjpZ5A6R7hke+ 4a3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Z8rILXTE; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i2-v6si4458260pgs.432.2018.08.03.12.09.45; Fri, 03 Aug 2018 12:09:59 -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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Z8rILXTE; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732106AbeHCVGC (ORCPT + 99 others); Fri, 3 Aug 2018 17:06:02 -0400 Received: from mail-ua0-f194.google.com ([209.85.217.194]:34883 "EHLO mail-ua0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729034AbeHCVGC (ORCPT ); Fri, 3 Aug 2018 17:06:02 -0400 Received: by mail-ua0-f194.google.com with SMTP id q12-v6so5541668ual.2; Fri, 03 Aug 2018 12:08:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=kpZlL+/y/Ez120raHr4T6F8c+6ia3San6SaxWsGsYec=; b=Z8rILXTEN7hSh/B2uc0lPd9xfIUiHgFNY869K0az5GRaWtPNOSVQutQXwxbiQHeVeo Icn9gNBuxsQ0fq7eym+TzjcnxHAsM4BtecRvG+Xpin7/GFyM5b3+RWmqA16zxTUPU2FY CPN+cLa1VQ5E8uWLXemvhKRI7+VbHNFaI7r1pWt1qIES4rLHWYaFS/iqHrXo5uIqpIaE pT17h+l1B2xwtqdiHkP8AP2ZF+QObK4jLkrLN1cqiejeHw7n3Fg73qUdAEMWJPWBqZz5 eUHRecf/mjpySuxPHL+s6pOsUWfSadQGMQSFnhGhMkaJPANkhonU7oDvbyxKQ/NCSPMv bCkA== 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=kpZlL+/y/Ez120raHr4T6F8c+6ia3San6SaxWsGsYec=; b=c9jYurJxe4UrhCVT8OitBvwTCXFisHZbVIqgZysGMMIm9vp6sLfsp4KB9gV5ARfnzO 0PslEi029ThiWnuRHEqmLBYaLYg0mmk8TIvY5l2I3wR8MX16A7V1oDPZWO3nV7CEplBI swS6A0l3BrmvobEWiLoVs910Tzj2O+6nYPRxGnJSOVoRKkod3mCVCeEpzVL8szctDPI5 cgGjBUMBJB+qrx64nKEiq0NoXyiH7bmMyOjbRxPVUR9hEkXNQ6I2dZRhHTL4Ujt2kJp+ s/T81NwwtmGgt5dvMhlRrO2zKnJp2MTaTgwWDm41k584m3dAyW32rmPlB3lrf+lL1Y05 iFEQ== X-Gm-Message-State: AOUpUlEVEq7bCFqfWlB5EhsRmYYFAD4oaeNXeO9AHsRLnZ3mhAh6aW0D uaYyp3JaFyS84LrWjiEaqBATICHMbEZ2Uazbq3s= X-Received: by 2002:ab0:70a9:: with SMTP id q9-v6mr3619080ual.141.1533323307571; Fri, 03 Aug 2018 12:08:27 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a67:2149:0:0:0:0:0 with HTTP; Fri, 3 Aug 2018 12:08:26 -0700 (PDT) In-Reply-To: <20180801111243.2848-1-fe@dev.tdt.de> References: <20180801111243.2848-1-fe@dev.tdt.de> From: Andy Shevchenko Date: Fri, 3 Aug 2018 22:08:26 +0300 Message-ID: Subject: Re: [PATCH] gpio: Add driver for PC Engines APU2/APU3 GPIOs To: Florian Eckert Cc: "open list:GPIO SUBSYSTEM" , Linus Walleij , Linux Kernel Mailing List 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 On Wed, Aug 1, 2018 at 2:12 PM, Florian Eckert wrote: Thanks for the patch, my comments below. > Add a new device driver "gpio-apu" which will now handle the GPIOs on > APU2 and APU3 devices from PC Engines. > - APU2/APU3 -> front button reset support > - APU3 -> SIM switch support Good. Can we see some specification for those platforms? > +/* PC Engines APU2/APU3 GPIO device driver > + * > + * Copyright (C) 2018 Florian Eckert > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version > + * > + * This program is distributed in the hope that it will be useful > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, see SPDX, please! > + */ > +#include > +#include These both looks very strange in here. > +#define APU_FCH_ACPI_MMIO_BASE 0xFED80000 > +#define APU_FCH_GPIO_BASE (APU_FCH_ACPI_MMIO_BASE + 0x1500) Wow! Can we see ACPI tables for these boards? Care to share (via some file share service) output of `acpidump -o tables.dat` ? > +#define APU_GPIO_BIT_WRITE 22 > +#define APU_GPIO_BIT_READ 16 > +#define APU_GPIO_BIT_DIR 23 WR and RD looks shorter, And please keep them sorted by value. > +#define APU_IOSIZE sizeof(u32) This is usual for x86 stuff, no need to have a definition, I think. > +struct apu_gpio_pdata { > + struct platform_device *pdev; > + struct gpio_chip *chip; > + unsigned long *offset; > + void __iomem **addr; > + int iosize; /* for devm_ioremap() */ > + spinlock_t lock; > +}; > + > +static struct apu_gpio_pdata *apu_gpio; > +static struct platform_device *keydev; > + > +/* APU2 */ > +static unsigned long apu2_gpio_offset[APU2_NUM_GPIO] = { > + APU_FCH_GPIO_BASE + 89 * APU_IOSIZE, //KEY > +}; > +static void __iomem *apu2_gpio_addr[APU2_NUM_GPIO] = {NULL}; > + > +/* APU3 */ > +static unsigned long apu3_gpio_offset[APU3_NUM_GPIO] = { > + APU_FCH_GPIO_BASE + 89 * APU_IOSIZE, //KEY > + APU_FCH_GPIO_BASE + 90 * APU_IOSIZE, //SIM > +}; > +static void __iomem *apu3_gpio_addr[APU3_NUM_GPIO] = {NULL, NULL}; > + > +static int gpio_apu_get_dir (struct gpio_chip *chip, unsigned offset) Style! We do not use space between func and its parameter list. > +{ > + u32 val; > + > + spin_lock(&apu_gpio->lock); > + > + val = ~ioread32(apu_gpio->addr[offset]); This is unusual (I mean ~). Better to leave IO alone and do bits manipulations latter on. > + val = (val >> APU_GPIO_BIT_DIR) & 1; Do you need this under spin lock? > + > + spin_unlock(&apu_gpio->lock); > + > + return val; > +} > +static int gpio_apu_get_data (struct gpio_chip *chip, unsigned offset) > +{ > + u32 val; > + > + spin_lock(&apu_gpio->lock); > + > + val = ioread32(apu_gpio->addr[offset]); > + val = (val >> APU_GPIO_BIT_READ) & 1; > + > + spin_unlock(&apu_gpio->lock); > + > + return val; > +} Similar comments as per _get_dir(). > +static struct gpio_keys_button apu_gpio_keys[] = { > +}; > + > +static void register_gpio_keys_polled(int id, unsigned poll_interval, > + unsigned nbuttons, > + struct gpio_keys_button *buttons) > +{ > +} Above must not be here. > + if (dmi_match(DMI_PRODUCT_NAME, "APU3")) { > + apu_gpio->offset = apu3_gpio_offset; > + apu_gpio->addr = apu3_gpio_addr; > + apu_gpio->iosize = APU_IOSIZE; > + apu_gpio->chip->ngpio = ARRAY_SIZE(apu3_gpio_offset); > + for( i = 0; i < ARRAY_SIZE(apu3_gpio_offset); i++) { > + apu3_gpio_addr[i] = devm_ioremap(&pdev->dev, > + apu_gpio->offset[i], apu_gpio->iosize); > + if (!apu3_gpio_addr[i]) { > + return -ENOMEM; > + } > + } > + } else if (dmi_match(DMI_BOARD_NAME, "APU2") || > + dmi_match(DMI_BOARD_NAME, "apu2") || > + dmi_match(DMI_BOARD_NAME, "PC Engines apu2")) { > + apu_gpio->offset = apu2_gpio_offset; > + apu_gpio->addr = apu2_gpio_addr; > + apu_gpio->iosize = APU_IOSIZE; > + apu_gpio->chip->ngpio = ARRAY_SIZE(apu2_gpio_offset); > + for( i = 0; i < ARRAY_SIZE(apu2_gpio_offset); i++) { > + apu2_gpio_addr[i] = devm_ioremap(&pdev->dev, > + apu_gpio->offset[i], apu_gpio->iosize); > + if (!apu2_gpio_addr[i]) { > + return -ENOMEM; > + } > + } > + } The above should be part either as callback or driver_data of DMI entries. > + ret = gpiochip_add(&gpio_apu_chip); devm_ > + if (ret) { > + pr_err("Adding gpiochip failed\n"); dev_err(), but I consider this message completely useless. > + } > + > + register_gpio_keys_polled(-1, 20, ARRAY_SIZE(apu_gpio_keys), apu_gpio_keys); > + Not part of this driver. Remove. > + return ret; > +} > +module_init(apu_gpio_init); > +module_exit(apu_gpio_exit); Consider to use module_platform_driver() and accompanying data structures and functions. -- With Best Regards, Andy Shevchenko