Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1999966imu; Sat, 12 Jan 2019 12:39:22 -0800 (PST) X-Google-Smtp-Source: ALg8bN7Xpj8OPLWk9DOMPYaETU5gER8Uk11jL4g7AecJJMgJjRXab0WLbB+OiEFw23JFEf7lJRFA X-Received: by 2002:a17:902:8ec9:: with SMTP id x9mr19956722plo.27.1547325562686; Sat, 12 Jan 2019 12:39:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547325562; cv=none; d=google.com; s=arc-20160816; b=Ec+8TzgAZTsKb8rvKQeZ40f6n+wiV2IlN7uoa62Uw7DRih5IiNQph7Te9zE8PVd08t U2jl+gBlNWau1QIYTui+LZc+3n/WwOuG++GgfaBlfSmviUNyKjog3yqYELfYlYRibFWt 2tYxa7Vizjc1TppuBDQFKQ+IlPHDL9QTID5ZcbhjexK8Tba4f5TFxk64Ub1VNaauGls6 rIzMSTaz8lAyXXaWe9mGQXNiUakZqBmfWmb3b9rZG3ic+cGwSCtiB8YOe25smHIOlrvv JsqRgTAX6DxmkuyV0dcUIFHv1HWQL+AwOjIlkh35c9fEUMrSn7xMeyZp35v91f+MNtVC /Big== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :dkim-signature; bh=bp+pDcjTZ9yXYKgzQaEuSNtChlx61uTxfKRNhvkIMcU=; b=dD7T7A96eQ46NVPyAYwAMXvFdKjiXuNuqCmYuRLKamV4eigi9bwSt6Je+6y52MTuF1 dmcOzYsZho0EJxeyW5u+QmpcSXPW2Oi+IYuWwsycZcGdpny++nQGeHoOnc0c0TwgjDLx VdhGG+NueXWcBbsvWByslG2xXhDUGAe26U4CIRte+ki0InqAZmds3HUptQjvooo5LGOz C/Cs5G7f/ebdHYHyLFYUppWpReowY3XRaALP1jxg2hFFXeg+iZPe+mN9nlIarwqV7Pt7 EdqMqdGE5PKu7tYhdbK0+QvYPcukemNJFat0HQqUZAlbagOR/1GM+wGAOItJ4DcEE9oY MAxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="sF7/mTE5"; 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=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ay4si6085221plb.235.2019.01.12.12.38.38; Sat, 12 Jan 2019 12:39: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=@kernel.org header.s=default header.b="sF7/mTE5"; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726747AbfALTLU (ORCPT + 99 others); Sat, 12 Jan 2019 14:11:20 -0500 Received: from mail.kernel.org ([198.145.29.99]:43826 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725855AbfALTLU (ORCPT ); Sat, 12 Jan 2019 14:11:20 -0500 Received: from archlinux (cpc91196-cmbg18-2-0-cust659.5-4.cable.virginm.net [81.96.234.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D7A6920835; Sat, 12 Jan 2019 19:11:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1547320278; bh=SpepeSHh9N1o3YLZ5wdEJrtRvOAfS9wkfugOIOLhJwc=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=sF7/mTE5e341Fo4rwkKoyf/tJvUThCVQFGLduiNR+EU9OvbQTG9r0BvoQYroYIOV2 P7+2Vhjchs2v0xhHINiT82y2e59O97LHDnuoQYjk21oiX3BurUWVA8kPZIqKSwlJ6q 0QTNeK14GqFO7YkqYCJ0mY0yJk1iZNihnJKOzyrY= Date: Sat, 12 Jan 2019 19:11:11 +0000 From: Jonathan Cameron To: Anson Huang Cc: Martin Kepplinger , "knaack.h@gmx.de" , "lars@metafoo.de" , "pmeerw@pmeerw.net" , "robh+dt@kernel.org" , "mark.rutland@arm.com" , "gustavo@embeddedor.com" , "gregkh@linuxfoundation.org" , Leonard Crestez , "rtresidd@electromag.com.au" , "linux-iio@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-kernel@vger.kernel.org" , dl-linux-imx Subject: Re: [PATCH V7 2/2] iio: accell: mma8452: add vdd/vddio regulator operation support Message-ID: <20190112191111.4909e254@archlinux> In-Reply-To: <4CB70D1B-06A6-4E34-B701-58E72B1AC9D9@nxp.com> References: <1546938556-26969-1-git-send-email-Anson.Huang@nxp.com> <1546938556-26969-2-git-send-email-Anson.Huang@nxp.com> <84c2971b-29d5-a0d0-c830-11504c381dd2@posteo.de> <4CB70D1B-06A6-4E34-B701-58E72B1AC9D9@nxp.com> X-Mailer: Claws Mail 3.17.3 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 8 Jan 2019 14:48:48 +0000 Anson Huang wrote: > Hi, Martin >=20 > From Anson's iPhone 6 >=20 >=20 > > =E5=9C=A8 2019=E5=B9=B41=E6=9C=888=E6=97=A5=EF=BC=8C19:41=EF=BC=8CMarti= n Kepplinger =E5=86=99=E9=81=93=EF=BC=9A > > =20 > >> On 08.01.19 10:14, Anson Huang wrote: > >> The accelerometer's power supply could be controllable on some > >> platforms, such as i.MX6Q-SABRESD board, the mma8451's power supplies > >> are controlled by a GPIO fixed regulator, need to make sure the > >> regulators are enabled before any communication with mma8451, this > >> patch adds vdd/vddio regulator operation support. > >>=20 > >> Signed-off-by: Anson Huang > >> Acked-by: Martin Kepplinger > >> --- > >> ChangeLog Since V6: > >> - separate the error handling of regulators get to make code easy to = read. > >> --- > >> drivers/iio/accel/mma8452.c | 105 ++++++++++++++++++++++++++++++++++--= -------- > >> 1 file changed, 83 insertions(+), 22 deletions(-) > >>=20 > >> diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c > >> index 421a0a8..3027811 100644 > >> --- a/drivers/iio/accel/mma8452.c > >> +++ b/drivers/iio/accel/mma8452.c > >> @@ -31,6 +31,7 @@ > >> #include > >> #include > >> #include > >> +#include > >>=20 > >> #define MMA8452_STATUS 0x00 > >> #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) > >> @@ -107,6 +108,8 @@ struct mma8452_data { > >> u8 data_cfg; > >> const struct mma_chip_info *chip_info; > >> int sleep_val; > >> + struct regulator *vdd_reg; > >> + struct regulator *vddio_reg; > >> }; > >>=20 > >> /** > >> @@ -1534,9 +1537,39 @@ static int mma8452_probe(struct i2c_client *cli= ent, > >> mutex_init(&data->lock); > >> data->chip_info =3D match->data; > >>=20 > >> + data->vdd_reg =3D devm_regulator_get(&client->dev, "vdd"); > >> + if (IS_ERR(data->vdd_reg)) { > >> + if (PTR_ERR(data->vdd_reg) =3D=3D -EPROBE_DEFER) > >> + return -EPROBE_DEFER; > >> + > >> + dev_err(&client->dev, "failed to get VDD regulator!\n"); > >> + return PTR_ERR(data->vdd_reg); > >> + } > >> + > >> + data->vddio_reg =3D devm_regulator_get(&client->dev, "vddio"); > >> + if (IS_ERR(data->vddio_reg)) { > >> + if (PTR_ERR(data->vddio_reg) =3D=3D -EPROBE_DEFER) > >> + return -EPROBE_DEFER; > >> + > >> + dev_err(&client->dev, "failed to get VDDIO regulator!\n"); > >> + return PTR_ERR(data->vddio_reg); > >> + } > >> + > >> + ret =3D regulator_enable(data->vdd_reg); > >> + if (ret) { > >> + dev_err(&client->dev, "failed to enable VDD regulator!\n"); > >> + return ret; > >> + } > >> + > >> + ret =3D regulator_enable(data->vddio_reg); > >> + if (ret) { > >> + dev_err(&client->dev, "failed to enable VDDIO regulator!\n"); > >> + goto disable_regulator_vdd; > >> + } > >> + > >> ret =3D i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> switch (ret) { > >> case MMA8451_DEVICE_ID: > >> @@ -1549,7 +1582,8 @@ static int mma8452_probe(struct i2c_client *clie= nt, > >> break; > >> /* else: fall through */ > >> default: > >> - return -ENODEV; > >> + ret =3D -ENODEV; > >> + goto disable_regulators; > >> } > >>=20 > >> dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n", > >> @@ -1566,13 +1600,13 @@ static int mma8452_probe(struct i2c_client *cl= ient, > >>=20 > >> ret =3D mma8452_reset(client); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> data->data_cfg =3D MMA8452_DATA_CFG_FS_2G; > >> ret =3D i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG, > >> data->data_cfg); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> /* > >> * By default set transient threshold to max to avoid events if > >> @@ -1581,7 +1615,7 @@ static int mma8452_probe(struct i2c_client *clie= nt, > >> ret =3D i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS, > >> MMA8452_TRANSIENT_THS_MASK); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> if (client->irq) { > >> int irq2; > >> @@ -1595,7 +1629,7 @@ static int mma8452_probe(struct i2c_client *clie= nt, > >> MMA8452_CTRL_REG5, > >> data->chip_info->all_events); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> dev_dbg(&client->dev, "using interrupt line INT1\n"); > >> } > >> @@ -1604,11 +1638,11 @@ static int mma8452_probe(struct i2c_client *cl= ient, > >> MMA8452_CTRL_REG4, > >> data->chip_info->enabled_events); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >>=20 > >> ret =3D mma8452_trigger_setup(indio_dev); > >> if (ret < 0) > >> - return ret; > >> + goto disable_regulators; > >> } > >>=20 > >> data->ctrl_reg1 =3D MMA8452_CTRL_ACTIVE | > >> @@ -1661,12 +1695,19 @@ static int mma8452_probe(struct i2c_client *cl= ient, > >> trigger_cleanup: > >> mma8452_trigger_cleanup(indio_dev); > >>=20 > >> +disable_regulators: > >> + regulator_disable(data->vddio_reg); > >> + > >> +disable_regulator_vdd: > >> + regulator_disable(data->vdd_reg); > >> + > >> return ret; > >> } > >>=20 > >> static int mma8452_remove(struct i2c_client *client) > >> { > >> struct iio_dev *indio_dev =3D i2c_get_clientdata(client); > >> + struct mma8452_data *data =3D iio_priv(indio_dev); > >>=20 > >> iio_device_unregister(indio_dev); > >>=20 > >> @@ -1678,6 +1719,9 @@ static int mma8452_remove(struct i2c_client *cli= ent) > >> mma8452_trigger_cleanup(indio_dev); > >> mma8452_standby(iio_priv(indio_dev)); > >>=20 > >> + regulator_disable(data->vddio_reg); > >> + regulator_disable(data->vdd_reg); > >> + > >> return 0; > >> } > >>=20 > >> @@ -1696,6 +1740,18 @@ static int mma8452_runtime_suspend(struct devic= e *dev) > >> return -EAGAIN; > >> } > >>=20 > >> + ret =3D regulator_disable(data->vddio_reg); > >> + if (ret) { > >> + dev_err(dev, "failed to disable VDDIO regulator\n"); > >> + return ret; > >> + } > >> + > >> + ret =3D regulator_disable(data->vdd_reg); > >> + if (ret) { > >> + dev_err(dev, "failed to disable VDD regulator\n"); > >> + return ret; > >> + } > >> + > >> return 0; > >> } > >>=20 > >> @@ -1705,9 +1761,22 @@ static int mma8452_runtime_resume(struct device= *dev) > >> struct mma8452_data *data =3D iio_priv(indio_dev); > >> int ret, sleep_val; > >>=20 > >> + ret =3D regulator_enable(data->vdd_reg); > >> + if (ret) { > >> + dev_err(dev, "failed to enable VDD regulator\n"); > >> + return ret; > >> + } > >> + > >> + ret =3D regulator_enable(data->vddio_reg); > >> + if (ret) { > >> + dev_err(dev, "failed to enable VDDIO regulator\n"); > >> + regulator_disable(data->vdd_reg); > >> + return ret; > >> + } > >> + > >> ret =3D mma8452_active(data); > >> if (ret < 0) > >> - return ret; > >> + goto runtime_resume_failed; > >>=20 > >> ret =3D mma8452_get_odr_index(data); > >> sleep_val =3D 1000 / mma8452_samp_freq[ret][0]; > >> @@ -1717,25 +1786,17 @@ static int mma8452_runtime_resume(struct devic= e *dev) > >> msleep_interruptible(sleep_val); > >>=20 > >> return 0; > >> -} > >> -#endif > >>=20 > >> -#ifdef CONFIG_PM_SLEEP > >> -static int mma8452_suspend(struct device *dev) > >> -{ > >> - return mma8452_standby(iio_priv(i2c_get_clientdata( > >> - to_i2c_client(dev)))); > >> -} > >> +runtime_resume_failed: > >> + regulator_disable(data->vddio_reg); > >> + regulator_disable(data->vdd_reg); > >>=20 > >> -static int mma8452_resume(struct device *dev) > >> -{ > >> - return mma8452_active(iio_priv(i2c_get_clientdata( > >> - to_i2c_client(dev)))); > >> + return ret; > >> } > >> #endif > >>=20 > >> static const struct dev_pm_ops mma8452_pm_ops =3D { > >> - SET_SYSTEM_SLEEP_PM_OPS(mma8452_suspend, mma8452_resume) > >> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_forc= e_resume) =20 > >=20 > > Just a quesion: Isn't it semantically a different change to replace > > mma8452_suspend() and mma8452_resume()? If not, why is it needed here? > >=20 > > other than that, lgtm. =20 >=20 > It is because with regulator operation added, before system suspend, driv= er is in runtime suspend already, the suspend/resume callback need to deal = with regulator again including error handling etc., and also need to disabl= e runtime pm and re-enable it etc., this introduces too many complicated co= de/logic, also, the things suspend/resume callback does are actually same a= s runtime suspend/ resume, so just using pm_runtime_force_suspend/resume ca= n save these duplicated operations and make code easy/clean. >=20 Anson, please wrap below 80 chars. Some of us have old old old laptops, (though I admit I still have more than 80 chars ;) I 'think' Anson is correct that these end up running the same code, but with considerably less complexity an this is the reason the force functions exist. Often the runtime case is very similar to the full pm case so you can avoid the whole runtime resume then suspend dance by doing this. Anyhow I've applied it to the togreg branch of iio.git and pushed it out as testing. Hopefully we haven't missed any corner cases. Runtime PM always gives me a headache when I dig into exactly what the various dances are that go on. Thanks Jonathan > Anson. >=20 >=20 >=20 >=20 > > =20 > >> SET_RUNTIME_PM_OPS(mma8452_runtime_suspend, > >> mma8452_runtime_resume, NULL) > >> }; > >> =20 > > =20