mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Arnd Bergmann" <arnd@arndb.de>
To: "Manjunatha Venkatesh" <manjunatha.venkatesh@nxp.com>,
	linux-kernel@vger.kernel.org,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Will Deacon" <will@kernel.org>, "Jens Axboe" <axboe@kernel.dk>,
	robh+dt@kernel.org
Cc: mb@lightnvm.io, ckeepax@opensource.cirrus.com, arnd@arndb.d,
	mst@redhat.com, javier@javigon.com, mikelley@microsoft.com,
	jasowang@redhat.com, sunilmut@microsoft.com,
	bjorn.andersson@linaro.org, krzysztof.kozlowski+dt@linaro.org,
	devicetree@vger.kernel.org, ashish.deshpande@nxp.com,
	rvmanjumce@gmail.com
Subject: Re: [PATCH v5 2/2] misc: nxp-sr1xx: UWB driver support for sr1xx series chip
Date: Wed, 14 Sep 2022 17:09:28 +0200	[thread overview]
Message-ID: <0b2da6f2-62f8-41a3-bf07-b6895a2dedee@www.fastmail.com> (raw)
In-Reply-To: <20220914142944.576482-3-manjunatha.venkatesh@nxp.com>

On Wed, Sep 14, 2022, at 4:29 PM, Manjunatha Venkatesh wrote:

> NXP has SR1XX family of UWB Subsystems (UWBS) devices. SR1XX SOCs
> are FiRa Compliant. SR1XX SOCs are flash less devices and they need
> Firmware Download on every device boot. More details on the SR1XX Family
> can be found at https://www.nxp.com/products/:UWB-TRIMENSION
> 
> The sr1xx driver work the SR1XX Family of UWBS, and uses UWB Controller
> Interface (UCI).  The corresponding details are available in the FiRa
> Consortium Website (https://www.firaconsortium.org/).

I know nothing about UWB, so I have no idea if the user interface
you propose here makes sense. My guess is that there is a good chance
that there are other implementations of UWB that would not work
with this specific driver interface, so you probably need a
slightly higher-level abstraction.

We had an older subsystem that was called UWB and that got removed
a while ago:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/staging/uwb?id=caa6772db4c1deb5d9add48e95d6eab50699ee5e

Is that the same UWB or something completely different?

> +#define SR1XX_MAGIC 0xEA
> +#define SR1XX_SET_PWR _IOW(SR1XX_MAGIC, 0x01, long)
> +#define SR1XX_SET_FWD _IOW(SR1XX_MAGIC, 0x02, long)

This should be in a uapi header.

> +static int sr1xx_dev_open(struct inode *inode, struct file *filp)
> +{
> +	struct sr1xx_dev *sr1xx_dev =
> +	    container_of(filp->private_data, struct sr1xx_dev, sr1xx_device);
> +
> +	filp->private_data = sr1xx_dev;

This looks dangerous if the file gets opened more than once
and filp->private_data can have two different values.

> +static long sr1xx_dev_ioctl(struct file *filp, unsigned int cmd,
> +			    unsigned long arg)
> +{
> +	int ret = 0;
> +	struct sr1xx_dev *sr1xx_dev = NULL;
> +
> +	sr1xx_dev = filp->private_data;
> +
> +	switch (cmd) {
> +	case SR1XX_SET_PWR:
> +		if (arg == PWR_ENABLE) {
> +			gpio_set_value(sr1xx_dev->ce_gpio, 1);
> +			usleep_range(10000, 12000);

The usage of 'arg' does not match the definition of the command
number, which expects a pointer to 'long'. If you want to keep
the behavior, I suggest changing the #define.

> +static void sr1xx_wait_for_irq_gpio_low(struct sr1xx_dev *sr1xx_dev)
> +{
> +	int retry_count = 0;
> +
> +	do {
> +		udelay(10);
> +		retry_count++;
> +		if (retry_count == MAX_RETRY_COUNT_FOR_HANDSHAKE) {
> +			dev_info(&sr1xx_dev->spi->dev,
> +				 "Slave not released the IRQ even after 10ms");
> +			break;
> +		}
> +	} while (gpio_get_value(sr1xx_dev->irq_gpio));
> +}

The way to wait for a timeout is to compare against the timestamp
before the loop, using e.g. "time_before(jiffies, timeout)"
or possibly using ktime_get() instead of jiffies if you want to
be more accurate.

10ms is really too long for a busy-loop anyway, so better use
usleep_range() from a non-atomic context.

> +/* Possible fops on the sr1xx device */
> +static const struct file_operations sr1xx_dev_fops = {
> +	.owner = THIS_MODULE,
> +	.read = sr1xx_dev_read,
> +	.write = sr1xx_dev_write,
> +	.open = sr1xx_dev_open,
> +	.unlocked_ioctl = sr1xx_dev_ioctl,
> +};

There should be a .compat_ioctl callback, either using the
same sr1xx_dev_ioctl function if you keep using the 'arg'
value directly, or 'compat_ptr_ioctl()' if you move to
pointers to arguments, or a custom function if you have
a mix of the two.

> +static int sr1xx_probe(struct spi_device *spi)
...
> +	ret = sr1xx_hw_setup(&spi->dev, &platform_data);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "Failed hw_setup\n");
> +		goto err_setup;
> +	}
....
> +
> +	sr1xx_dev->spi = spi;
> +	sr1xx_dev->sr1xx_device.minor = MISC_DYNAMIC_MINOR;
> +	sr1xx_dev->sr1xx_device.name = "sr1xx";
> +	sr1xx_dev->sr1xx_device.fops = &sr1xx_dev_fops;
> +	sr1xx_dev->sr1xx_device.parent = &spi->dev;
> +	sr1xx_dev->irq_gpio = desc_to_gpio(platform_data.gpiod_irq);
> +	sr1xx_dev->ce_gpio = desc_to_gpio(platform_data.gpiod_ce);
> +	sr1xx_dev->spi_handshake_gpio =
> +	    desc_to_gpio(platform_data.gpiod_spi_handshake);

The temporary 'platform_data' structure seems useless here,
just fold its members into the sr1xx_dev structure itself.
No need to store both a gpio descriptor and a number, you
can simplify this to always use the descriptor.

> +	sr1xx_dev->tx_buffer = kzalloc(SR1XX_TXBUF_SIZE, GFP_KERNEL);
> +	sr1xx_dev->rx_buffer = kzalloc(SR1XX_RXBUF_SIZE, GFP_KERNEL);
> +	if (!sr1xx_dev->tx_buffer) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +	if (!sr1xx_dev->rx_buffer) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +
> +	sr1xx_dev->spi->irq = gpio_to_irq(sr1xx_dev->irq_gpio);
> +	if (sr1xx_dev->spi->irq < 0) {
> +		dev_err(&spi->dev, "gpio_to_irq request failed gpio = 0x%x\n",
> +			sr1xx_dev->irq_gpio);
> +		goto err_exit;
> +	}

Instead of gpio_to_irq(), the DT binding should probably
list the interrupt directly using the "interrupts" property
pointing to the gpio controller.

> +
> +static const struct acpi_device_id sr1xx_acpi_match[] = {
> +	{"PRP0001", 0},
> +	{"", 0},
> +};

As far as I understand, you are not supposed to list
compatiblity with PRP0001 when using this on a PC, the
ACPI subsystem will instead look at the of_device_id
table.

> +static const struct dev_pm_ops sr1xx_dev_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(sr1xx_dev_suspend, sr1xx_dev_resume)
> +};

Use SYSTEM_SLEEP_PM_OPS() instead of SET_SYSTEM_SLEEP_PM_OPS()
to avoid a warning about unused functions.

> +static int __init sr1xx_dev_init(void)
> +{
> +	return spi_register_driver(&sr1xx_driver);
> +}
> +
> +module_init(sr1xx_dev_init);
> +
> +static void __exit sr1xx_dev_exit(void)
> +{
> +	spi_unregister_driver(&sr1xx_driver);
> +}
> +
> +module_exit(sr1xx_dev_exit);

module_spi_driver()

  parent reply	other threads:[~2022-09-14 15:09 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-14 14:29 [PATCH v5 0/2] Uwb: Nxp: Driver for SR1XX SOCs Patch Series Manjunatha Venkatesh
2022-09-14 14:29 ` [PATCH v5 1/2] dt-bindings: uwb: Device tree information for Nxp SR1XX SOCs Manjunatha Venkatesh
2022-09-14 14:36   ` Arnd Bergmann
2022-10-07 11:39     ` [EXT] " Manjunatha Venkatesh
2022-10-07 12:30       ` Krzysztof Kozlowski
2022-09-16 19:26   ` Rob Herring
2022-09-14 14:29 ` [PATCH v5 2/2] misc: nxp-sr1xx: UWB driver support for sr1xx series chip Manjunatha Venkatesh
2022-09-14 14:53   ` Greg KH
2022-11-30  3:40     ` [EXT] " Manjunatha Venkatesh
2022-11-30  7:27       ` Greg KH
2022-12-20 14:09         ` Manjunatha Venkatesh
2022-12-20 14:30           ` Greg KH
2022-12-20 14:43             ` Manjunatha Venkatesh
2022-09-14 14:55   ` Greg KH
2022-10-07 14:19     ` [EXT] " Manjunatha Venkatesh
2022-09-14 15:09   ` Arnd Bergmann [this message]
     [not found]     ` <cd397721-f549-5c65-2c65-35b09c3ea7f9@nxp.com>
2022-10-07 14:11       ` Arnd Bergmann
2022-11-30  3:55         ` Manjunatha Venkatesh
2022-10-07 14:57       ` Greg Kroah-Hartman
2022-11-30  4:09         ` Manjunatha Venkatesh
2022-11-30  7:23           ` Greg Kroah-Hartman
2022-12-20 14:33             ` Manjunatha Venkatesh
2022-12-20 14:51               ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0b2da6f2-62f8-41a3-bf07-b6895a2dedee@www.fastmail.com \
    --to=arnd@arndb.de \
    --cc=arnd@arndb.d \
    --cc=ashish.deshpande@nxp.com \
    --cc=axboe@kernel.dk \
    --cc=bjorn.andersson@linaro.org \
    --cc=ckeepax@opensource.cirrus.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jasowang@redhat.com \
    --cc=javier@javigon.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=manjunatha.venkatesh@nxp.com \
    --cc=mb@lightnvm.io \
    --cc=mikelley@microsoft.com \
    --cc=mst@redhat.com \
    --cc=robh+dt@kernel.org \
    --cc=rvmanjumce@gmail.com \
    --cc=sunilmut@microsoft.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®