From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f170.google.com (mail-oi1-f170.google.com [209.85.167.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8BEC367296 for ; Wed, 13 May 2026 02:06:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778638019; cv=none; b=tgNa453vpy/bVsflAJQvja0pougrJy15t9TJv8zZal20SfgDPyRCBc6xAK6jUrnRvMqNl2GXMeHDZ39q9Aya0+qEqrdKIpii6ZUz8N4gAvnmIxo1GGcOL42fb9FGaNEWo2lLl5OrSStSzGeQKMUToctZ9xlc1dYBCYBEnDNjP2I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778638019; c=relaxed/simple; bh=vond2xIWWthhre52p1kIFAniJV4Kjqp9incPlq1jEgA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=MWH0eaxl7LecrJvjlJZnhNm7WuOPAdEGiM6DqLLs1FUOjqQPON/tEHFnjynia6U1Zhb1sZ5vx6fZpFYGSWYZpzNxMHOSlOzcmvjK5zcsUerbmHTZwskQYu53c4VMg7Sk91qNhMlpMRLD/FQIqxNILuqwVIvNec4ziBm/41wNLEI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Hh2ECuTP; arc=none smtp.client-ip=209.85.167.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Hh2ECuTP" Received: by mail-oi1-f170.google.com with SMTP id 5614622812f47-4645dde00a7so5803128b6e.1 for ; Tue, 12 May 2026 19:06:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778638017; x=1779242817; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=CDhy/x3DM4FisnOspwaroIeEW+Xi4GBI8y9aLOvUOX8=; b=Hh2ECuTPrYPkf3Wa4kf+scDIsUFCNdUIK4o+3Z9WB3fTJIqd3Qso4WaJqHzTBXydTN PrGWhPPkoGCTym2g82UgQSPMsCW9LK+zSXiRopSovdgEmzkk8/W6aQoA8c30ttBe2pFL cDJWzx350ugC67oKKMI6Dzod+npzuB7BSIur+uLh/bH72zMsU2GAXLM5eNTFRXrywSIQ hCgXg5wOUxdYvJGlioL3YmVF+GpwB0vEmX3BewAroufmFmMQj1UIQlnZR44KuJaTj1Ul z1kG4Rhwk48CfQBds6zIsLLmFqo6vtf1TASZKdksQlTKwBxvaqx7sezEzwLqUfcXFnlJ kVlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778638017; x=1779242817; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=CDhy/x3DM4FisnOspwaroIeEW+Xi4GBI8y9aLOvUOX8=; b=oLAW1tt12MX/Il4mbkdwvIe+h+X0mz/8NJ5X5iXm8gM2AaYafkzMkps+L3Rui/m30M orJyHaO5YsBqCZa/OXxhmYav5oIHJAAgKV+asY5uCQXCqnzsRfKW1/P5KXdjzsp92qkU aOl9OHoDj8VTo9ZD+mfQ4D8gs8rj5zuCYz9n2L45v6/VAwC2dEnwwVixjhRYbawA1aPE XH/b4sn4NmbXDoQPJYPTO+VrpGCqpNmqi6BmAJAjhYZjj1D0p9mpLBMa9f9VZIeH9SlY VEAwCeLwUszJnua09K/E6PItZCGkvW+2B6XvWxJB+gkLmmQjZ4gwobEE75GOfG/GKcOe HjWQ== X-Forwarded-Encrypted: i=1; AFNElJ9oo3c5x7ZV2kJkfZ/MluRDRw5s7P74ZLBY9BAHEsVs/kiF3YSpmu2BGUiSKaXxy+qZ+gqf40oNcr+Rcs4=@vger.kernel.org X-Gm-Message-State: AOJu0YzADo9jEwbB0QReUXlVck63RzkPh1IqPCMf9vl1T3Y24t6eM8E3 pd0stzBUodnUjGscvvzMwFdtrnfwKMQu1FTTi0eSOBagYrZv0JnRHTry X-Gm-Gg: Acq92OFOEX5kiYnDSml7Gqohk9pqtD9FoA1zSprJd9IKv4SXji1gFhXVmhptdk9V+7c SgxHJ5yf+BnOYDNY3r9Eqbs2/Ka3lkRd7tIDHMCE3z4xq0kXElhuJnEtpmv6jwNJ17KIdhYYLfD FHygPn0h2O1G9yVKlFuyL79iXtJ+CCLDEgBCMz3d2lMFMRRmceD6Fa10QOFNTquWJIeNrSJJIAF x7apkmgitzC+dn+jHmiS6cgKLbaa5/rem8ThIBevSl9ZHFgfwdz3BDrevRpaj0MlBgX2TMCfzvM TAp+9DwIBhc3bSgfw1p9ymWwq/kBdR1zsmJxFWrcXyFsiimabPUgPTMcxxzZs7FQjI746DMHH0f oBfcOq5rj3J3V0FHB8suK4uyI9UnV+cv0G9fQCGLSMOzURA7GE0xWWSB1yOkcSP7Se+4jOKVNPZ wlptynrMvOXm4sHo4XpetXwKx6XA5PjX+8YF77FwZxlVI7deIVKTpUzFRpEg== X-Received: by 2002:a05:6808:e401:b0:479:40d4:b140 with SMTP id 5614622812f47-482b2de0676mr726248b6e.21.1778638016806; Tue, 12 May 2026 19:06:56 -0700 (PDT) Received: from linuxescape.lan (23-88-128-2.fttp.usinternet.com. [23.88.128.2]) by smtp.gmail.com with ESMTPSA id 5614622812f47-47c76936271sm23449951b6e.9.2026.05.12.19.06.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 19:06:56 -0700 (PDT) From: Maxwell Doose To: jic23@kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-iio@vger.kernel.org (open list:IIO SUBSYSTEM AND DRIVERS), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v6] iio: imu: kmx61: Use guard(mutex)() over manual locking Date: Tue, 12 May 2026 21:06:54 -0500 Message-ID: <20260513020654.168071-1-m32285159@gmail.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Include linux/cleanup.h to take advantage of new macros. Replace manual mutex_lock() and mutex_unlock() calls across the file with guard(mutex)() and scoped_guard() where appropriate to simplify error paths and eliminate manual locking calls. Add new helper function kmx61_read_for_each_active_channel() to mitigate certain style issues and to prevent notifying that the IRQ is finished whilst holding the lock. Update certain returns, and add default case to return -EINVAL in kmx61_read_raw(). Remove now-redundant gotos and ret variables, as the new RAII macros make them unneeded. Signed-off-by: Maxwell Doose --- v2: - Remove redundant blank line per Andy. - Put kmx61_set_mode() function call in kmx61_runtime_suspend() on one line per Andy. v3: - Add dedicated scope for guards. v4: - Fix certain scoping in switch-case blocks. - Remove stray ret variable. - Used scoped_guard() in kmx61_trigger_handler() instead of guard()(). v5: - Added new helper function kmx61_read_for_each_active_channel() per Jonathan's suggestion. - Add default case to return -EINVAL in kmx61_read_raw() per Andy's suggestion. - Add blank lines between guard(mutex)() calls and regular code per Andy's suggestion. - Change last return statement of kmx61_write_event_config() to be 0 per Jonathan's suggestion. v6: - Rebased onto TOCTOU fix per Jonathan's suggestion. - (note: now dependent on said commit, link below) - link: https://lore.kernel.org/linux-iio/CAKqfh0GHVtAS6Uw3Bjo+B0PCpcfT8FogqEPCmt2x59zhmmh1Kg@mail.gmail.com/T/#t drivers/iio/imu/kmx61.c | 127 +++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 3afa369de3cf..b7bd2497fecd 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -7,6 +7,7 @@ * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F). */ +#include #include #include #include @@ -783,7 +784,7 @@ static int kmx61_read_raw(struct iio_dev *indio_dev, struct kmx61_data *data = kmx61_get_data(indio_dev); switch (mask) { - case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_RAW: { switch (chan->type) { case IIO_ACCEL: base_reg = KMX61_ACC_XOUT_L; @@ -794,28 +795,24 @@ static int kmx61_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } - mutex_lock(&data->lock); + guard(mutex)(&data->lock); ret = kmx61_set_power_state(data, true, chan->address); - if (ret) { - mutex_unlock(&data->lock); + if (ret) return ret; - } ret = kmx61_read_measurement(data, base_reg, chan->scan_index); if (ret < 0) { kmx61_set_power_state(data, false, chan->address); - mutex_unlock(&data->lock); return ret; } *val = sign_extend32(ret >> chan->scan_type.shift, chan->scan_type.realbits - 1); ret = kmx61_set_power_state(data, false, chan->address); - - mutex_unlock(&data->lock); if (ret) return ret; return IIO_VAL_INT; + } case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_ACCEL: @@ -834,41 +831,41 @@ static int kmx61_read_raw(struct iio_dev *indio_dev, if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) return -EINVAL; - mutex_lock(&data->lock); - ret = kmx61_get_odr(data, val, val2, chan->address); - mutex_unlock(&data->lock); + scoped_guard(mutex, &data->lock) + ret = kmx61_get_odr(data, val, val2, chan->address); if (ret) return -EINVAL; return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; } - return -EINVAL; + } static int kmx61_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - int ret; struct kmx61_data *data = kmx61_get_data(indio_dev); switch (mask) { - case IIO_CHAN_INFO_SAMP_FREQ: + case IIO_CHAN_INFO_SAMP_FREQ: { if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) return -EINVAL; - mutex_lock(&data->lock); - ret = kmx61_set_odr(data, val, val2, chan->address); - mutex_unlock(&data->lock); - return ret; + guard(mutex)(&data->lock); + + return kmx61_set_odr(data, val, val2, chan->address); + } case IIO_CHAN_INFO_SCALE: switch (chan->type) { - case IIO_ACCEL: + case IIO_ACCEL: { if (val != 0) return -EINVAL; - mutex_lock(&data->lock); - ret = kmx61_set_scale(data, val2); - mutex_unlock(&data->lock); - return ret; + guard(mutex)(&data->lock); + + return kmx61_set_scale(data, val2); + } default: return -EINVAL; } @@ -942,32 +939,29 @@ static int kmx61_write_event_config(struct iio_dev *indio_dev, struct kmx61_data *data = kmx61_get_data(indio_dev); int ret = 0; - mutex_lock(&data->lock); + guard(mutex)(&data->lock); if (state && data->ev_enable_state) - goto err_unlock; + return 0; if (!state && data->motion_trig_on) { data->ev_enable_state = false; - goto err_unlock; + return ret; } ret = kmx61_set_power_state(data, state, KMX61_ACC); if (ret < 0) - goto err_unlock; + return ret; ret = kmx61_setup_any_motion_interrupt(data, state); if (ret < 0) { kmx61_set_power_state(data, false, KMX61_ACC); - goto err_unlock; + return ret; } data->ev_enable_state = state; -err_unlock: - mutex_unlock(&data->lock); - - return ret; + return 0; } static int kmx61_acc_validate_trigger(struct iio_dev *indio_dev, @@ -1020,11 +1014,11 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig, struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct kmx61_data *data = kmx61_get_data(indio_dev); - mutex_lock(&data->lock); + guard(mutex)(&data->lock); if (!state && data->ev_enable_state && data->motion_trig_on) { data->motion_trig_on = false; - goto err_unlock; + return ret; } if (data->acc_dready_trig == trig || data->motion_trig == trig) @@ -1034,7 +1028,7 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig, ret = kmx61_set_power_state(data, state, device); if (ret < 0) - goto err_unlock; + return ret; if (data->acc_dready_trig == trig || data->mag_dready_trig == trig) ret = kmx61_setup_new_data_interrupt(data, state, device); @@ -1042,7 +1036,7 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig, ret = kmx61_setup_any_motion_interrupt(data, state); if (ret < 0) { kmx61_set_power_state(data, false, device); - goto err_unlock; + return ret; } if (data->acc_dready_trig == trig) @@ -1051,8 +1045,6 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig, data->mag_dready_trig_on = state; else data->motion_trig_on = state; -err_unlock: - mutex_unlock(&data->lock); return ret; } @@ -1181,30 +1173,52 @@ static irqreturn_t kmx61_data_rdy_trig_poll(int irq, void *private) return IRQ_HANDLED; } -static irqreturn_t kmx61_trigger_handler(int irq, void *p) +/** + * kmx61_read_for_each_active_channel - Read each active channel into a buffer + * + * @indio_dev: IIO Device struct to read from + * @buffer: Destination buffer to write to, the array must be of at least size 8 + * + * Intended only for use in kmx61_trigger_handler(). + * + * Return: + * 0 on success, negative errno on failure. + */ +static int kmx61_read_for_each_active_channel(struct iio_dev *indio_dev, s16 *buffer) { - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; struct kmx61_data *data = kmx61_get_data(indio_dev); - int bit, ret, i = 0; u8 base; - s16 buffer[8] = { }; + int ret, bit; + int i = 0; if (indio_dev == data->acc_indio_dev) base = KMX61_ACC_XOUT_L; else base = KMX61_MAG_XOUT_L; - mutex_lock(&data->lock); + guard(mutex)(&data->lock); + iio_for_each_active_channel(indio_dev, bit) { ret = kmx61_read_measurement(data, base, bit); if (ret < 0) { - mutex_unlock(&data->lock); - goto err; + return ret; } buffer[i++] = ret; } - mutex_unlock(&data->lock); + + return 0; +} + +static irqreturn_t kmx61_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + int ret; + s16 buffer[8] = { }; + + ret = kmx61_read_for_each_active_channel(indio_dev, buffer); + if (ret < 0) + goto err; iio_push_to_buffers(indio_dev, buffer); err: @@ -1419,22 +1433,18 @@ static void kmx61_remove(struct i2c_client *client) iio_trigger_unregister(data->motion_trig); } - mutex_lock(&data->lock); + guard(mutex)(&data->lock); + kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); - mutex_unlock(&data->lock); } static int kmx61_suspend(struct device *dev) { - int ret; struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev)); - mutex_lock(&data->lock); - ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, - false); - mutex_unlock(&data->lock); + guard(mutex)(&data->lock); - return ret; + return kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, false); } static int kmx61_resume(struct device *dev) @@ -1453,13 +1463,10 @@ static int kmx61_resume(struct device *dev) static int kmx61_runtime_suspend(struct device *dev) { struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev)); - int ret; - mutex_lock(&data->lock); - ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); - mutex_unlock(&data->lock); + guard(mutex)(&data->lock); - return ret; + return kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); } static int kmx61_runtime_resume(struct device *dev) -- 2.54.0