From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B080DC4727E for ; Fri, 25 Sep 2020 21:41:01 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 36C2320659 for ; Fri, 25 Sep 2020 21:41:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Tgc6M9bu"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=gmx.net header.i=@gmx.net header.b="K+z3Yz1D" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 36C2320659 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gmx.net Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: In-Reply-To:MIME-Version:References:Message-ID:Subject:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+CsEgT1IwibbESL2LH0ujmUBNRNmV7gwQfpFxNtYgxU=; b=Tgc6M9buWVq5PG/K7PpiX9W2v 9fbuMGtXdYBxrt09H3NoGNzwdF3GI/T+7Jc15YZ9fNSIpVdgfiy/AJDZon3IOnEe9L+4exKCZn32C nVqRzj8G+uQbWE8mgOnMMzC6USt5/TQKB31vHSa7i/lwpDNzJIT2F8UJH2LApE/pvCHhIQP9tBXZH 969W2M33sxowBHLGYK/I8W5m5NggsF/PAAasbPitS3KkEsxhCIk++DkCiNykdTe4n9YLZQ6PFcvpF HPqyuceCsuB1pIO7F6EHjQe0o42KNMFkbBWPh/W53b9FvISpNnVytat3aCeClDkR+9B5JCWr9C193 0nrZBm9VA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLvQz-0005c9-17; Fri, 25 Sep 2020 21:39:17 +0000 Received: from mout.gmx.net ([212.227.15.15]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLvQv-0005bW-9r for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 21:39:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1601069949; bh=fOmj3zQts7kybefgEaY4WROeVIrinhK+N1GjZXrXArI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:References:In-Reply-To; b=K+z3Yz1DphSBa9tvghkjG1rVmf8roaG8FmF1BpMAyoDK83tRwfnefQGb0k7BcTnPi pkEk6a+gOekchEPDUesuVIzCL2nILiuBDCixUDuPpUNPSTZR8OgWrv2P/i4jenHK0Z cYBmaGl37iSiGNyyyrw/PMIkx5Slf/tLtBfYVBPo= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from longitude ([5.146.195.151]) by mail.gmx.com (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MAfYw-1kAtmB1wcK-00B3BS; Fri, 25 Sep 2020 23:32:15 +0200 Date: Fri, 25 Sep 2020 23:32:07 +0200 From: Jonathan =?utf-8?Q?Neusch=C3=A4fer?= To: Andy Shevchenko Subject: Re: [PATCH v3 3/7] mfd: Add base driver for Netronix embedded controller Message-ID: <20200925213207.GA2510@latitude> References: <20200924192455.2484005-1-j.neuschaefer@gmx.net> <20200924192455.2484005-4-j.neuschaefer@gmx.net> MIME-Version: 1.0 In-Reply-To: X-Provags-ID: V03:K1:d7YI7q9xhqyMeuCoSJ1xFCTdK3X2pL7XIlrg4rAzNabthB/psZt nXMDjOk/jQqamXBNOiQn+Q9P/JBxwgKqMPnGhCESNzmn/7qeT/HCVTXZbyiJPLI9hO/5rn4 oAtweDKzKff+8CCCRxQaxU80sSIQLQ3jaZ5dA/H5+LfE3EBYhMWvXNot8fkeZDzIaPikYuM R03MmlsYcbs8UG8yEJ+fw== X-UI-Out-Filterresults: notjunk:1;V03:K0:y11aiQxOcDo=:8lSowFlYjZI2/ZrPysDrz9 ltW+aANke4idTFy5zxSE/oQPIPom4cYbGDLYvrfny+t5lDxCu9mresMsXfzfFRVVpD3smVk2Y xfEexMYT1YsSYQ8jfKqC+O90ot0Yxxge1NywJIGiKACloVETJdpqZDfpsQxjme3U4m5FuCm84 4VL8TJynNo5aEMjGhyooZ0hBT9YM/LFakKQWV3nUqY/u8g0EcCENyQm5I/9b8hzot9OKJWXy3 pVMIEhhYZDBH4kRMr6KDPsCXBsMdjDDGLMumtWTkL0WCnW9y9dO3F7MrYCKHvEv3GllYk3ulq TvaMVElXEQCtl6blVuRhhUZyzmi+FCQ965uDSSL+iDQK71JBp4VBTYlMkcWNKQqAZfVECnOHO NWe/FqD6QhAzeO+EujN65tw5uPJGvZQmpneUVdnJ61EvFDmk6wbCxvdphGDCHipsv2byyA8lS pOYgB8e1yAAxNMy2ch6hlOto1TnlP/JEecll+puS9FHP1fygL/VVCFQbyv4WTtlapQnhv12CL WAuRMZQhgWmBtmHxMwWmQLG5XXC45Tm4OshJVNC5YaIx+UTbAYleuCuwtT29oStArCnCfUW8x aX9QoqU3I6UL5wPd3yGWPzYJ+/UHQbsJZbMwPq3o5qHfk4bHglHwlgIrWkQKdEgKwoyRR8Aat dGJafUGP9zUmbLadABwWs3LWixvbSvt7CUvw82+bQ05Q5t8Pze0X2akCJaKLrEyZiL9Za95ZQ aY3kRcmDOcVEj2SBeMfAJVSClfmVpj8rmh8Cca7lniFosagS7MvJKDueJv8ypkAF9z+GxPo6C xvgrPX0JhMxCSbb+lD3z5vDah+YmwY6e6HRQjmjSNDvVcJAEjk5m90hZ6kUPHO6HB35JXi8Ox /jrxP2DkakAgVRWZ1KrTH76a1sgfp6/0Wx6IA+8hplQnCl9spVAznz2EOO79HHQMITEjSobLw DSrGLI3lGrL5bvhdDdFwFUF5/PH/iP3SG8H8qVnv2PDzqWkfED70w17S8MdpT6rR8r5Q7xm5Z QPlh1c7HRc9RjOHmjK/x+bLQd+RGP/HvMC3C4kPjmiJ4h0exx7nq85OyqzyPiONjMZhkAnudy rtqhxs9xp4PlVkPJqyRZEcZhVwwb4pLndZfCJL0Zy5QARSdEfv91j961Hv8f9a0tp5ylsbJql A7mVWB2ti4JM0u/OAShMGm+P/SC0b81YjOGZVnFhXDUj/L5dUNCRjSTn5m6FATxlF4QCt1cmd thBowk5Ebvk8H3/opR6MAZEO4+iBOLqcH9spT3A== X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_173913_577636_013F7647 X-CRM114-Status: GOOD ( 49.88 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexandre Belloni , Heiko Stuebner , linux-pwm@vger.kernel.org, Linus Walleij , Thierry Reding , Fabio Estevam , "open list:REAL TIME CLOCK \(RTC\) SUBSYSTEM" , Arnd Bergmann , Mauro Carvalho Chehab , Sam Ravnborg , Daniel Palmer , Andreas Kemnade , NXP Linux Team , Uwe =?utf-8?Q?Kleine-K=C3=B6nig?= , devicetree , Stephan Gerhold , allen , Sascha Hauer , Jonathan =?utf-8?Q?Neusch=C3=A4fer?= , Lubomir Rintel , Rob Herring , Lee Jones , linux-arm Mailing List , Alessandro Zummo , Linux Kernel Mailing List , Mark Brown , Pengutronix Kernel Team , Heiko Stuebner , Josua Mayer , Shawn Guo , "David S. Miller" Content-Type: multipart/mixed; boundary="===============0088736298739940221==" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org --===============0088736298739940221== Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="Kj7319i9nmIyA2yE" Content-Disposition: inline --Kj7319i9nmIyA2yE Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Sep 25, 2020 at 12:29:45PM +0300, Andy Shevchenko wrote: > On Thu, Sep 24, 2020 at 10:26 PM Jonathan Neusch=C3=A4fer > wrote: > > > > The Netronix embedded controller is a microcontroller found in some > > e-book readers designed by the ODM Netronix, Inc. It contains RTC, > > battery monitoring, system power management, and PWM functionality. > > > > This driver implements register access and version detection. > > > > Third-party hardware documentation is available at: > > > > https://github.com/neuschaefer/linux/wiki/Netronix-MSP430-embedded-co= ntroller > > > > The EC supports interrupts, but the driver doesn't make use of them so > > far. >=20 > ... >=20 > > +#include >=20 > This usually goes after linux/*.h > (and actually not visible how it's being used, but see below first) I think it was a leftover from v1 before I used regmap for general access to the registers. Will fix the ordering. > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include >=20 > ... >=20 > > +static void ntxec_poweroff(void) > > +{ > > + int res; > > + u8 buf[] =3D { > > + NTXEC_REG_POWEROFF, >=20 > > + (NTXEC_POWEROFF_VALUE >> 8) & 0xff, > > + NTXEC_POWEROFF_VALUE & 0xff, >=20 > '& 0xff' parts are redundant. *u8 implies that. Fix in all cases. > Also I would rather see something like >=20 > buf[0] =3D _POWEROFF; > put_unaligned_be16(_VALUE, &buf[1]); >=20 > to explicitly show the endianess of the register values. Good idea. > > + }; > > + struct i2c_msg msgs[] =3D { > > + { > > + .addr =3D poweroff_restart_client->addr, > > + .flags =3D 0, > > + .len =3D sizeof(buf), >=20 > > + .buf =3D buf >=20 > It's slightly better to keep trailing commas in cases like this. Ok. >=20 > > + } > > + }; > > + > > + res =3D i2c_transfer(poweroff_restart_client->adapter, msgs, AR= RAY_SIZE(msgs)); > > + if (res < 0) >=20 > > + dev_alert(&poweroff_restart_client->dev, > > + "Failed to power off (err =3D %d)\n", res); >=20 > alert? This needs to be explained. I copied the dev_alert from drivers/mfd/rn5t618.c. Upon reconsideration, I'm not sure what the correct log level would be, but _warn seems enough, or maybe _err is better > > + /* > > + * The time from the register write until the host CPU is power= ed off > > + * has been observed to be about 2.5 to 3 seconds. Sleep long e= nough to > > + * safely avoid returning from the poweroff handler. > > + */ > > + msleep(5000); > > +} > > + > > +static int ntxec_restart(struct notifier_block *nb, > > + unsigned long action, void *data) > > +{ > > + int res; > > + /* > > + * NOTE: The lower half of the reset value is not sent, because= sending > > + * it causes an error >=20 > Why? Any root cause? Perhaps you need to send 0xffff ? Unknown, because I don't have the EC firmware for analysis. The vendor kernel sends 0xff00 and gets an error. Sending 0xffff doesn't help. > > + */ > > + u8 buf[] =3D { > > + NTXEC_REG_RESET, >=20 > > + (NTXEC_RESET_VALUE >> 8) & 0xff, >=20 > Here you may still use put_unaligned_be16() but move the comment to be > before len hardcoded to sizeof(buf) - 1. Okay, will do. >=20 > > + }; > > + struct i2c_msg msgs[] =3D { > > + { > > + .addr =3D poweroff_restart_client->addr, > > + .flags =3D 0, > > + .len =3D sizeof(buf), > > + .buf =3D buf > > + } > > + }; > > + > > + res =3D i2c_transfer(poweroff_restart_client->adapter, msgs, AR= RAY_SIZE(msgs)); > > + if (res < 0) > > + dev_alert(&poweroff_restart_client->dev, > > + "Failed to restart (err =3D %d)\n", res); > > + > > + return NOTIFY_DONE; > > +} >=20 > ... An error in the i2c transfer here is an abnormal situation that should in my opinion be logged, but I don't see what else the code can do here to handle the error. >=20 > > +static int ntxec_probe(struct i2c_client *client) > > +{ > > + struct ntxec *ec; > > + unsigned int version; > > + int res; > > + > > + ec =3D devm_kmalloc(&client->dev, sizeof(*ec), GFP_KERNEL); > > + if (!ec) > > + return -ENOMEM; > > + > > + ec->dev =3D &client->dev; > > + > > + ec->regmap =3D devm_regmap_init_i2c(client, ®map_config); > > + if (IS_ERR(ec->regmap)) { > > + dev_err(ec->dev, "Failed to set up regmap for device\n"= ); > > + return res; > > + } > > + > > + /* Determine the firmware version */ > > + res =3D regmap_read(ec->regmap, NTXEC_REG_VERSION, &version); > > + if (res < 0) { > > + dev_err(ec->dev, "Failed to read firmware version numbe= r\n"); > > + return res; > > + } >=20 > > + dev_info(ec->dev, > > + "Netronix embedded controller version %04x detected.\n= ", > > + version); >=20 > This info level may confuse users if followed by an error path. Right. I suppose printing incompatible versions is still useful, so how about something like the following? /* Bail out if we encounter an unknown firmware version */ switch (version) { case 0xd726: /* found in Kobo Aura */ dev_info(ec->dev, "Netronix embedded controller version %04x detected.\n", version); break; default: dev_err(ec->dev, "Netronix embedded controller version %04x is not supported.\n", version); return -ENODEV; } > > + > > + if (of_device_is_system_power_controller(ec->dev->of_node)) { > > + /* > > + * Set the 'powerkeep' bit. This is necessary on some b= oards > > + * in order to keep the system running. > > + */ > > + res =3D regmap_write(ec->regmap, NTXEC_REG_POWERKEEP, > > + NTXEC_POWERKEEP_VALUE); > > + if (res < 0) > > + return res; >=20 > > + WARN_ON(poweroff_restart_client); >=20 > WARN_ON? All these alerts, WARNs, BUGs must be explained. Screaming to > the user is not good if it wasn't justified. poweroff_restart_client being already set is not a situation that should happen (and would indicate a bug in this driver, AFAICT), but I guess the log message could be better in that case... > > + poweroff_restart_client =3D client; > > + if (pm_power_off) > > + dev_err(ec->dev, "pm_power_off already assigned= \n"); > > + else > > + pm_power_off =3D ntxec_poweroff; > > + > > + res =3D register_restart_handler(&ntxec_restart_handler= ); > > + if (res) > > + dev_err(ec->dev, > > + "Failed to register restart handler: %d= \n", res); > > + } > > + > > + i2c_set_clientdata(client, ec); > > + > > + res =3D devm_mfd_add_devices(ec->dev, PLATFORM_DEVID_NONE, ntxe= c_subdevices, > > + ARRAY_SIZE(ntxec_subdevices), NULL, = 0, NULL); > > + if (res) >=20 > > + dev_warn(ec->dev, "Failed to add subdevices: %d\n", res= ); >=20 > 'warn' is inconsistent with 'return err'. Either do not return an > error, or mark a message as an error one. Okay, I'll change it to dev_err. >=20 > And above with the restart handler has the same issue. >=20 > > + return res; > > +} > > + > > +static int ntxec_remove(struct i2c_client *client) > > +{ >=20 > > + if (client =3D=3D poweroff_restart_client) { >=20 > When it's not the case? The EC doesn't always need to provide poweroff/restart functionality, and AFAIK, in some systems it doesn't. In those systems, ntxec_remove would run with poweroff_restart_client =3D=3D NULL. In theory, there might also be two of it in the same system, of which only one controls system poweroff/restart, but I'm not sure if that is actually the case on any existing board design. > > + poweroff_restart_client =3D NULL; > > + pm_power_off =3D NULL; > > + unregister_restart_handler(&ntxec_restart_handler); > > + } > > + > > + return 0; > > +} >=20 > ... >=20 > > +#include > > + >=20 > Missed >=20 > struct device; > struct regmap; >=20 > here. I'll add them. > > +struct ntxec { > > + struct device *dev; > > + struct regmap *regmap; > > +}; >=20 > > +/* > > + * Some registers, such as the battery status register (0x41), are in > > + * big-endian, but others only have eight significant bits, which are = in the > > + * first byte transmitted over I2C (the MSB of the big-endian value). > > + * This convenience function converts an 8-bit value to 16-bit for use= in the > > + * second kind of register. > > + */ > > +static inline u16 ntxec_reg8(u8 value) > > +{ > > + return value << 8; > > +} >=20 > I'm wondering why __be16 is not used as returned type. I didn't think of it, but it's a good idea. Will do. Thanks, Jonathan Neusch=C3=A4fer --Kj7319i9nmIyA2yE Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEvHAHGBBjQPVy+qvDCDBEmo7zX9sFAl9uYckACgkQCDBEmo7z X9tfeA/+PcBI/xMedlMauddT3snjDWczk7NDO6pSKs9Z+FgLKmNM7VjP8KZ8BlSy hZhYOCMqvnzPOTv+CR474Yn6sO4mzScSm2BRTo7k6CTOVO5BCKN1QvXRjkD6eCJ6 U2aUw4hssBJs/lJrbsejJDZA++/3o4AKPpZa2ZKgERbNCUaSL4osxgzh4n23qS4J 8NXyUKFzKOGtmVAek7FDfUMeqKVeVnfvtQ8baNJ6KKjHNBItK7LIAZ6Qfj5RKirT dPmtkPKJnniw/pIsandzQcPk+6KOK+DTpu+xqR1X9jOF58pM33u8lviKsMzeIpYn b9sMZrut9d/bJ+S8lhtw40KfjpFczabkd74T3IrCwSw242sTYoJDq+nMHkFr8YFG EMItgLfmVvgodLNar6Xr/2I3820oyejrt4S6QAuRIe9e6KKLN3J/ltVKv7PChEU5 9tVfD2+5j72MZu25Gqvh0EKY6Jj7VirKqnqK/I3WgcK52EY4/hx6UHkaHKhGrdmX kpQ4xx/dHijgC/7/D/1aJjSvGOwLHf87PYgfiH7E23F9WXZ5XtWzN3wiq87OgWY8 MOeXnX5Io2b3Zuts7lo+XNAZfKlzgX5B5xEPKtpdF5PGc6aqZ4Qxs/jwednvs7R4 4C3e/bll5qi8es1ap7ofnsswjMOMYKXv0WxrEc0/JEekBv7RKQA= =+7Ew -----END PGP SIGNATURE----- --Kj7319i9nmIyA2yE-- --===============0088736298739940221== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel --===============0088736298739940221==--