Thread (21 messages) 21 messages, 4 authors, 2023-03-31

Re: [PATCH v12 15/15] soc: amd: Add support for AMD Pensando SoC Controller

From: Andy Shevchenko <hidden>
Date: 2023-03-23 11:06:49
Also in: linux-arm-kernel, linux-mmc, linux-spi, lkml

On Thu, Mar 23, 2023 at 2:11 AM Brad Larson [off-list ref] wrote:
The Pensando SoC controller is a SPI connected companion device
that is present in all Pensando SoC board designs.  The essential
board management registers are accessed on chip select 0 with
board mgmt IO support accessed using additional chip selects.
...
+config AMD_PENSANDO_CTRL
+       tristate "AMD Pensando SoC Controller"
+       depends on SPI_MASTER=y
+       depends on (ARCH_PENSANDO && OF) || COMPILE_TEST
+       default y if ARCH_PENSANDO
       default ARCH_PENSANDO

?
+       select REGMAP_SPI
+       select MFD_SYSCON
...
+/*
+ * AMD Pensando SoC Controller
+ *
+ * Userspace interface and reset driver support for SPI connected Pensando SoC
+ * controller device.  This device is present in all Pensando SoC designs and
+ * contains board control/status regsiters and management IO support.
registers ?
+ *
+ * Copyright 2023 Advanced Micro Devices, Inc.
+ */
...
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
Seems semi-random. Are you sure you use this and not missing mod_devicetable.h?
+#include <linux/reset-controller.h>
+#include <linux/spi/spi.h>
...
+struct penctrl_device {
+       struct spi_device *spi_dev;
+       struct reset_controller_dev rcdev;
Perhaps swapping these two might provide a better code generation.
+};
...
+       struct spi_transfer t[2] = { 0 };
0 is not needed.

...
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               ret = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
+       else if (_IOC_DIR(cmd) & _IOC_WRITE)
+               ret = !access_ok((void __user *)arg, _IOC_SIZE(cmd));

Maybe you should create a temporary variable as

    void __user *in = ... arg;

?
+       if (ret)
+               return -EFAULT;
...
+       /* Verify and prepare spi message */
SPI
+       size = _IOC_SIZE(cmd);
+       if ((size % sizeof(struct penctrl_spi_xfer)) != 0) {
' != 0' is redundant.
+               ret = -EINVAL;
+               goto done;
+       }
+       num_msgs = size / sizeof(struct penctrl_spi_xfer);
+       if (num_msgs == 0) {
+               ret = -EINVAL;
+               goto done;
+       }
Can be unified with a previous check as

if (size == 0 || size % ...)
+       msg = memdup_user((struct penctrl_spi_xfer __user *)arg, size);
+       if (!msg) {
+               ret = PTR_ERR(msg);
+               goto done;
+       }
...
+       if (copy_from_user((void *)(uintptr_t)tx_buf,
+                          (void __user *)msg->tx_buf, msg->len)) {
Why are all these castings here?
+               ret = -EFAULT;
+               goto done;
+       }
...
+       if (copy_to_user((void __user *)msg->rx_buf,
+                        (void *)(uintptr_t)rx_buf, msg->len))
+               ret = -EFAULT;
Ditto.

...
+       struct spi_transfer t[2] = { 0 };
0 is redundant.

...
+       struct spi_transfer t[1] = { 0 };
Ditto.

Why is this an array?

...
+       ret = spi_sync(spi_dev, &m);
+       return ret;
return spi_sync(...);

...
+       np = spi_dev->dev.parent->of_node;
+       ret = of_property_read_u32(np, "num-cs", &num_cs);
Why not simply device_property_read_u32()?
+       if (ret)
+               return dev_err_probe(&spi_dev->dev, ret,
+                                    "number of chip-selects not defined");
...
+       cdev = cdev_alloc();
+       if (!cdev) {
+               dev_err(&spi_dev->dev, "allocation of cdev failed");
+               ret = -ENOMEM;
ret = dev_err_probe(...);
+               goto cdev_failed;
+       }
...
+       ret = cdev_add(cdev, penctrl_devt, num_cs);
+       if (ret) {
+               dev_err(&spi_dev->dev, "register of cdev failed");
dev_err_probe() ?
+               goto cdev_delete;
+       }
...
+       penctrl = kzalloc(sizeof(*penctrl), GFP_KERNEL);
+       if (!penctrl) {
+               ret = -ENOMEM;
+               dev_err(&spi_dev->dev, "allocate driver data failed");
ret = dev_err_probe();
But we do not print memory allocation failure messages.
+               goto cdev_delete;
+       }
...
+               if (IS_ERR(dev)) {
+                       ret = IS_ERR(dev);
+                       dev_err(&spi_dev->dev, "error creating device\n");
ret = dev_err_probe();
+                       goto cdev_delete;
+               }
+               dev_dbg(&spi_dev->dev, "created device major %u, minor %d\n",
+                       MAJOR(penctrl_devt), cs);
+       }
...
+       spi_set_drvdata(spi_dev, penctrl);
Is it in use?

...
+       penctrl->rcdev.of_node = spi_dev->dev.of_node;
device_set_node();

...
+       ret = reset_controller_register(&penctrl->rcdev);
+       if (ret)
+               return dev_err_probe(&spi_dev->dev, ret,
+                                    "failed to register reset controller\n");
+       return ret;
return 0;

...
+       device_destroy(penctrl_class, penctrl_devt);
Are you sure this is the correct API?
+       return ret;
...
+#include <linux/types.h>
+#include <linux/ioctl.h>
Sorted?

-- 
With Best Regards,
Andy Shevchenko
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help