Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2600830imu; Sun, 23 Dec 2018 03:36:42 -0800 (PST) X-Google-Smtp-Source: ALg8bN6domwofzNgF3mAvPqQYu6IGFJIT8jNaO5f/gWaFdkV7FniQMwrGhVVvEXD2nShYprhB4UT X-Received: by 2002:a63:4611:: with SMTP id t17mr8809347pga.119.1545565002416; Sun, 23 Dec 2018 03:36:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545565002; cv=none; d=google.com; s=arc-20160816; b=Dn3UtE3hJ+gPdX5f/BwQ6925K1glP9kerOTRqZiLMGRl5vOMwJ2aJhidYht4zfPiCG xKjkShHaXbx8kstQBG72V+Uj5WJu1X/AmlqiLcxA6iaoI+9wjURZfpy6NbJfhq0PFgEC 6d0qiqgc80yEnqHWIwbSPwbefZY4TKRRvLF4gv63gU4hKiLjAhXRB0CNDQwe3GiS7v0I RrWikY1RTTL3l9GgTX9TwvjWmmmeLVZpT4JM9isTOKNmj+ym8lEZewpL/tYx7Ztqr9Lh GwsvYp44nZCQRkzSIrAcZsjARr6nrERD8UY4VgpoJ7hMmnJYV3XlpST26Z9ZhyLOmSn4 GErg== 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=Yc+e0+untcPTPHab8p8Jd6Rt1ATT/XlKwFZRgabf6Yk=; b=slPc1idh5fli/Xdfj9P6cMYbbVStiaLUtgUFB8gFdGndaUe2mgMRFX2Q7jSoZWkPlF ZJCtGD6hJUx7g4mZOzl3c12UIf2gByhP6zS2l4XcGVwmFO5MNmZp0s0dc3zGBt1uFmgB aMZwf8UMf2JOSFDIFHYoQTvYDaPxt7iIIf6uYlhha3d+Gmjpkzwj7GqE+MtsrvE1Zl08 9HtoX0YHoN+qpAw/XfkG4e0PTvlbRkfCGtCVgCso4mc6UtfWCH8tFeDz6TQuFOcmZpYd aZaGjQoauffmnArvWj8wSPNnLvxIA6GPac780y47lHjAktLCD9TM12QSyeFv8fOYeTtM O82A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=UTjiCEos; 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 p16si825445pff.272.2018.12.23.03.36.26; Sun, 23 Dec 2018 03:36:42 -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=UTjiCEos; 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 S1732428AbeLVRKK (ORCPT + 99 others); Sat, 22 Dec 2018 12:10:10 -0500 Received: from mail.kernel.org ([198.145.29.99]:48332 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726475AbeLVRKK (ORCPT ); Sat, 22 Dec 2018 12:10:10 -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 D01A721939; Sat, 22 Dec 2018 17:10:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1545498609; bh=heE9cdDdVflVrUYAD6lddllPD7KExb0gXVcTvbvfv1E=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=UTjiCEosMQn6+8B57DzUz2mgRYdgVX10vRgXW/6+mwbRBDbLBXCpfSU6YhsBs7VuD GzK86xB65RLNP5//+BXbegzSBgd9YyW8thP+qxpuyiYb1PfwIMXNaBykYsltjFqtC9 5lqntcLv2533177zBlf6zbNP48csnTrtB3D6KLCM= Date: Sat, 22 Dec 2018 17:10:02 +0000 From: Jonathan Cameron To: Anson Huang Cc: "knaack.h@gmx.de" , "lars@metafoo.de" , "pmeerw@pmeerw.net" , "robh+dt@kernel.org" , "mark.rutland@arm.com" , "olivier.moysan@st.com" , "masneyb@onstation.org" , "broonie@kernel.org" , "peda@axentia.se" , "rtresidd@electromag.com.au" , "linux-iio@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "festevam@gmail.com" , "preid@electromag.com.au" , dl-linux-imx Subject: Re: [PATCH V5 2/2] iio: magnetometer: mag3110: add vdd/vddio regulator operation support Message-ID: <20181222171002.2261bc97@archlinux> In-Reply-To: <1545021679-4025-2-git-send-email-Anson.Huang@nxp.com> References: <1545021679-4025-1-git-send-email-Anson.Huang@nxp.com> <1545021679-4025-2-git-send-email-Anson.Huang@nxp.com> X-Mailer: Claws Mail 3.17.2 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 17 Dec 2018 04:47:49 +0000 Anson Huang wrote: > The magnetometer's power supplies could be controllable on some platforms, > such as i.MX6Q-SABRESD board, the mag3110's power supplies are controlled > by a GPIO fixed regulator, need to make sure the regulators are enabled > before any communication with mag3110, this patch adds vdd/vddio regulator > operation support. > > Signed-off-by: Anson Huang > --- > ChangeLog since V4: > - using devm_regulator_get() instead of devm_regulator_get_optional() since the regulator is > there always, if dtb does NOT specify one, regulator framework will assign dummy regulator for it > --- > drivers/iio/magnetometer/mag3110.c | 92 ++++++++++++++++++++++++++++++++++---- > 1 file changed, 84 insertions(+), 8 deletions(-) > > diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c > index f063355..32660ce 100644 > --- a/drivers/iio/magnetometer/mag3110.c > +++ b/drivers/iio/magnetometer/mag3110.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > > #define MAG3110_STATUS 0x00 > #define MAG3110_OUT_X 0x01 /* MSB first */ > @@ -56,6 +57,8 @@ struct mag3110_data { > struct mutex lock; > u8 ctrl_reg1; > int sleep_val; > + struct regulator *vdd_reg; > + struct regulator *vddio_reg; > }; > > static int mag3110_request(struct mag3110_data *data) > @@ -469,17 +472,48 @@ static int mag3110_probe(struct i2c_client *client, > struct iio_dev *indio_dev; > int ret; > > - ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I); > - if (ret < 0) > - return ret; > - if (ret != MAG3110_DEVICE_ID) > - return -ENODEV; > - > indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); > if (!indio_dev) > return -ENOMEM; > > data = iio_priv(indio_dev); > + > + data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); > + if (IS_ERR(data->vdd_reg)) { > + ret = PTR_ERR(data->vdd_reg); > + if (ret != -EPROBE_DEFER) > + dev_err(&client->dev, "failed to get VDD regulator!\n"); > + return ret; > + } > + > + ret = regulator_enable(data->vdd_reg); > + if (ret) { > + dev_err(&client->dev, "failed to enable VDD regulator!\n"); > + return ret; > + } Please don't mix managed unwinding (devm) with the manual version. It makes it harder to reason about any races. Here there aren't any but in general please don't do it. The easy solution here is to reorder so both regulators are acquired before either is turned on. Jonathan > + > + data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); > + if (IS_ERR(data->vddio_reg)) { > + ret = PTR_ERR(data->vddio_reg); > + if (ret != -EPROBE_DEFER) > + dev_err(&client->dev, "failed to get VDDIO regulator!\n"); > + goto disable_regulator_vdd; > + } > + > + ret = regulator_enable(data->vddio_reg); > + if (ret) { > + dev_err(&client->dev, "failed to enable VDDIO regulator!\n"); > + goto disable_regulator_vdd; > + } > + > + ret = i2c_smbus_read_byte_data(client, MAG3110_WHO_AM_I); > + if (ret < 0) > + goto disable_regulators; > + if (ret != MAG3110_DEVICE_ID) { > + ret = -ENODEV; > + goto disable_regulators; > + } > + > data->client = client; > mutex_init(&data->lock); > > @@ -499,7 +533,7 @@ static int mag3110_probe(struct i2c_client *client, > > ret = mag3110_change_config(data, MAG3110_CTRL_REG1, data->ctrl_reg1); > if (ret < 0) > - return ret; > + goto disable_regulators; > > ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG2, > MAG3110_CTRL_AUTO_MRST_EN); > @@ -520,16 +554,24 @@ static int mag3110_probe(struct i2c_client *client, > iio_triggered_buffer_cleanup(indio_dev); > standby_on_error: > mag3110_standby(iio_priv(indio_dev)); > +disable_regulators: > + regulator_disable(data->vddio_reg); > +disable_regulator_vdd: > + regulator_disable(data->vdd_reg); > + > return ret; > } > > static int mag3110_remove(struct i2c_client *client) > { > struct iio_dev *indio_dev = i2c_get_clientdata(client); > + struct mag3110_data *data = iio_priv(indio_dev); > > iio_device_unregister(indio_dev); > iio_triggered_buffer_cleanup(indio_dev); > mag3110_standby(iio_priv(indio_dev)); > + regulator_disable(data->vddio_reg); > + regulator_disable(data->vdd_reg); > > return 0; > } > @@ -537,14 +579,48 @@ static int mag3110_remove(struct i2c_client *client) > #ifdef CONFIG_PM_SLEEP > static int mag3110_suspend(struct device *dev) > { > - return mag3110_standby(iio_priv(i2c_get_clientdata( > + struct mag3110_data *data = iio_priv(i2c_get_clientdata( > + to_i2c_client(dev))); > + int ret; > + > + ret = mag3110_standby(iio_priv(i2c_get_clientdata( > to_i2c_client(dev)))); > + if (ret) > + return ret; > + > + ret = regulator_disable(data->vddio_reg); > + if (ret) { > + dev_err(dev, "failed to disable VDDIO regulator\n"); > + return ret; > + } > + > + ret = regulator_disable(data->vdd_reg); > + if (ret) { > + dev_err(dev, "failed to disable VDD regulator\n"); > + return ret; > + } > + > + return 0; > } > > static int mag3110_resume(struct device *dev) > { > struct mag3110_data *data = iio_priv(i2c_get_clientdata( > to_i2c_client(dev))); > + int ret; > + > + ret = regulator_enable(data->vdd_reg); > + if (ret) { > + dev_err(dev, "failed to enable VDD regulator\n"); > + return ret; > + } > + > + ret = regulator_enable(data->vddio_reg); > + if (ret) { > + dev_err(dev, "failed to enable VDDIO regulator\n"); > + regulator_disable(data->vdd_reg); > + return ret; > + } > > return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, > data->ctrl_reg1);