lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241219173613.7f6572aa@jic23-huawei>
Date: Thu, 19 Dec 2024 17:36:13 +0000
From: Jonathan Cameron <jic23@...nel.org>
To: Robert Budai <robert.budai@...log.com>
Cc: Lars-Peter Clausen <lars@...afoo.de>, Michael Hennerich
 <Michael.Hennerich@...log.com>, Nuno Sa <nuno.sa@...log.com>, "Ramona
 Gradinariu" <ramona.gradinariu@...log.com>, Antoniu Miclaus
 <antoniu.miclaus@...log.com>, "Rob Herring" <robh@...nel.org>, Krzysztof
 Kozlowski <krzk+dt@...nel.org>, "Conor Dooley" <conor+dt@...nel.org>,
 Jonathan Corbet <corbet@....net>, Shen Jianping
 <Jianping.Shen@...bosch.com>, "Alex Lanzano" <lanzano.alex@...il.com>,
 <linux-iio@...r.kernel.org>, <devicetree@...r.kernel.org>,
 <linux-kernel@...r.kernel.org>, <linux-doc@...r.kernel.org>,
 <robi_budai@...oo.com>
Subject: Re: [PATCH v3 6/7] iio: imu: adis16550: add adis16550 support

On Mon, 16 Dec 2024 16:48:12 +0200
Robert Budai <robert.budai@...log.com> wrote:

> The ADIS16550 is a complete inertial system that includes a triaxis
> gyroscope and a triaxis accelerometer. Each inertial sensor in
> the ADIS16550 combines industry leading MEMS only technology
> with signal conditioning that optimizes dynamic performance. The
> factory calibration characterizes each sensor for sensitivity, bias,
> and alignment. As a result, each sensor has its own dynamic com-
> pensation formulas that provide accurate sensor measurements
> 
> Co-developed-by: Ramona Gradinariu <ramona.gradinariu@...log.com>
> Signed-off-by: Ramona Gradinariu <ramona.gradinariu@...log.com>
> Co-developed-by: Antoniu Miclaus <antoniu.miclaus@...log.com>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@...log.com>
> Signed-off-by: Nuno Sá <nuno.sa@...log.com>
> Signed-off-by: Robert Budai <robert.budai@...log.com>
> ---
> 
> v3:
> - freed xbuf
> - fixed code styling related issues
> - removed the sensor type enum and used separate structures for providing chip info data

Hi

A few comments inline to add to what Nuno noted.

Thanks

Jonathan


>  adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
> diff --git a/drivers/iio/imu/adis16550.c b/drivers/iio/imu/adis16550.c
> new file mode 100644
> index 000000000000..6e9d98dee0d8
> --- /dev/null
> +++ b/drivers/iio/imu/adis16550.c




> +static int adis16550_update_scan_mode(struct iio_dev *indio_dev,
> +				      const unsigned long *scan_mask)
> +{
> +	struct adis *adis = iio_device_get_drvdata(indio_dev);
> +	u16 burst_length = ADIS16550_BURST_DATA_LEN;
> +	u8 burst_cmd;
> +	u8 *tx;
> +
> +	if (*scan_mask & ADIS16550_BURST_DATA_GYRO_ACCEL_MASK)
> +		burst_cmd = ADIS16550_REG_BURST_GYRO_ACCEL;
> +	else
> +		burst_cmd = ADIS16550_REG_BURST_DELTA_ANG_VEL;
> +
> +	if (adis->xfer)
How would we be getting here if these weren't set?  Should be fine to
assume they are.

> +		memset(adis->xfer, 0, 2 * sizeof(*adis->xfer));
> +	if (adis->buffer)
> +		memset(adis->buffer, 0, burst_length + sizeof(u32));
> +
> +	tx = adis->buffer + burst_length;
> +	tx[0] = 0x00;
> +	tx[1] = 0x00;
> +	tx[2] = burst_cmd;
> +	/* crc4 is 0 on burst command */
> +	tx[3] = spi_crc4(get_unaligned_le32(tx));
> +
> +	adis->xfer[0].tx_buf = tx;
> +	adis->xfer[0].len = 4;
> +	adis->xfer[0].cs_change = 1;
> +	adis->xfer[0].delay.value = 8;
> +	adis->xfer[0].delay.unit = SPI_DELAY_UNIT_USECS;
> +	adis->xfer[1].rx_buf = adis->buffer;
> +	adis->xfer[1].len = burst_length;
> +
> +	spi_message_init_with_transfers(&adis->msg, adis->xfer, 2);
> +
> +	return 0;
> +}


...

> +static int adis16550_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct iio_dev *indio_dev;
> +	struct adis16550 *st;
> +	int ret;
> +
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	st = iio_priv(indio_dev);
> +	st->info = spi_get_device_match_data(spi);
> +	if (!st->info)
> +		return -EINVAL;
> +
> +	indio_dev->name = st->info->name;
> +	indio_dev->channels = st->info->channels;
> +	indio_dev->num_channels = st->info->num_channels;
> +	indio_dev->available_scan_masks = adis16550_channel_masks;
> +	indio_dev->info = &adis16550_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	st->adis.ops = &adis16550_ops;
> +
> +	struct spi_transfer *xfer_tmp = kcalloc(2, sizeof(*st->adis.xfer), GFP_KERNEL);
> +
> +	if (!xfer_tmp)
> +		return -ENOMEM;
> +
> +	void *buffer_tmp = kzalloc(ADIS16550_BURST_DATA_LEN + sizeof(u32),
> +				   GFP_KERNEL);
> +	if (!buffer_tmp) {
> +		kfree(st->adis.xfer);
> +		return -ENOMEM;
> +	}
> +
> +	ret = devm_regulator_get_enable(dev, "vdd");
> +	if (ret) {
> +		dev_err_probe(dev, ret,
> +			      "Failed to get vdd regulator\n");
> +		goto free_on_error;
> +	}
> +
> +	ret = adis_init(&st->adis, indio_dev, spi, &adis16550_data);
> +	if (ret)
> +		goto free_on_error;
> +
> +	ret = __adis_initial_startup(&st->adis);
> +	if (ret)
> +		goto free_on_error;
> +
> +	ret = adis16550_config_sync(st);
> +	if (ret)
> +		goto free_on_error;
> +
> +	ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev,
> +						 adis16550_trigger_handler);
> +	if (ret)
> +		goto free_on_error;
> +
> +	ret = devm_iio_device_register(dev, indio_dev);
> +	if (ret)
> +		goto free_on_error;
> +
> +	adis16550_debugfs_init(indio_dev);
> +
> +	st->adis.xfer = no_free_ptr(xfer_tmp);
> +	st->adis.buffer = no_free_ptr(buffer_tmp);
I guess this was me explaining something badly.
You need to look at all the infrastructure in cleanup.h.
This only makes sense if you are using auto freeing of the variables
That is
	void *buffer_tmp __free(kfree) =
		kzalloc(ADIS16550_BURST_DATA_LEN + sizeof(u32), GFP_KERNEL);
etc
Then get rid of the kfree below as they will be freed on exiting scope if
no_free_ptr() hasn't been called on them (which sets the pointer to NULL).
Then you can avoid the goto's.

However as Nuno pointed out, devm_kzalloc() may well be a better choice.
We need alignement for DMA, but dma_kzalloc does guarantee that so it is all fine.

That would also fix actually freeing these on driver remove which is currently
missing.


> +
> +	return 0;
> +
> +free_on_error:
> +	kfree(xfer_tmp);
> +	kfree(buffer_tmp);
> +
> +	return ret;
> +}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ