]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/spi/spi.c
spi: Check we have a spi_device_id for each DT compatible
[mirror_ubuntu-jammy-kernel.git] / drivers / spi / spi.c
index aea037c65985e950a580eb0004adf3bad8559248..2a2f41b6df685e272d180de3be06a140c4c18617 100644 (file)
@@ -451,6 +451,47 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv)
 {
        sdrv->driver.owner = owner;
        sdrv->driver.bus = &spi_bus_type;
+
+       /*
+        * For Really Good Reasons we use spi: modaliases not of:
+        * modaliases for DT so module autoloading won't work if we
+        * don't have a spi_device_id as well as a compatible string.
+        */
+       if (sdrv->driver.of_match_table) {
+               const struct of_device_id *of_id;
+
+               for (of_id = sdrv->driver.of_match_table; of_id->compatible[0];
+                    of_id++) {
+                       const char *of_name;
+
+                       /* Strip off any vendor prefix */
+                       of_name = strnchr(of_id->compatible,
+                                         sizeof(of_id->compatible), ',');
+                       if (of_name)
+                               of_name++;
+                       else
+                               of_name = of_id->compatible;
+
+                       if (sdrv->id_table) {
+                               const struct spi_device_id *spi_id;
+
+                               for (spi_id = sdrv->id_table; spi_id->name[0];
+                                    spi_id++)
+                                       if (strcmp(spi_id->name, of_name) == 0)
+                                               break;
+
+                               if (spi_id->name[0])
+                                       continue;
+                       } else {
+                               if (strcmp(sdrv->driver.name, of_name) == 0)
+                                       continue;
+                       }
+
+                       pr_warn("SPI driver %s has no spi_device_id for %s\n",
+                               sdrv->driver.name, of_id->compatible);
+               }
+       }
+
        return driver_register(&sdrv->driver);
 }
 EXPORT_SYMBOL_GPL(__spi_register_driver);
@@ -478,12 +519,6 @@ static LIST_HEAD(spi_controller_list);
  */
 static DEFINE_MUTEX(board_lock);
 
-/*
- * Prevents addition of devices with same chip select and
- * addition of devices below an unregistering controller.
- */
-static DEFINE_MUTEX(spi_add_lock);
-
 /**
  * spi_alloc_device - Allocate a new SPI device
  * @ctlr: Controller to which device is connected
@@ -636,9 +671,9 @@ int spi_add_device(struct spi_device *spi)
         * chipselect **BEFORE** we call setup(), else we'll trash
         * its configuration.  Lock against concurrent add() calls.
         */
-       mutex_lock(&spi_add_lock);
+       mutex_lock(&ctlr->add_lock);
        status = __spi_add_device(spi);
-       mutex_unlock(&spi_add_lock);
+       mutex_unlock(&ctlr->add_lock);
        return status;
 }
 EXPORT_SYMBOL_GPL(spi_add_device);
@@ -658,7 +693,7 @@ static int spi_add_device_locked(struct spi_device *spi)
        /* Set the bus ID string */
        spi_dev_set_name(spi);
 
-       WARN_ON(!mutex_is_locked(&spi_add_lock));
+       WARN_ON(!mutex_is_locked(&ctlr->add_lock));
        return __spi_add_device(spi);
 }
 
@@ -2553,6 +2588,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
                return NULL;
 
        device_initialize(&ctlr->dev);
+       INIT_LIST_HEAD(&ctlr->queue);
+       spin_lock_init(&ctlr->queue_lock);
+       spin_lock_init(&ctlr->bus_lock_spinlock);
+       mutex_init(&ctlr->bus_lock_mutex);
+       mutex_init(&ctlr->io_mutex);
+       mutex_init(&ctlr->add_lock);
        ctlr->bus_num = -1;
        ctlr->num_chipselect = 1;
        ctlr->slave = slave;
@@ -2825,11 +2866,6 @@ int spi_register_controller(struct spi_controller *ctlr)
                        return id;
                ctlr->bus_num = id;
        }
-       INIT_LIST_HEAD(&ctlr->queue);
-       spin_lock_init(&ctlr->queue_lock);
-       spin_lock_init(&ctlr->bus_lock_spinlock);
-       mutex_init(&ctlr->bus_lock_mutex);
-       mutex_init(&ctlr->io_mutex);
        ctlr->bus_lock_flag = 0;
        init_completion(&ctlr->xfer_completion);
        if (!ctlr->max_dma_len)
@@ -2966,7 +3002,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
        /* Prevent addition of new devices, unregister existing ones */
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-               mutex_lock(&spi_add_lock);
+               mutex_lock(&ctlr->add_lock);
 
        device_for_each_child(&ctlr->dev, NULL, __unregister);
 
@@ -2997,7 +3033,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        mutex_unlock(&board_lock);
 
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-               mutex_unlock(&spi_add_lock);
+               mutex_unlock(&ctlr->add_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);