Merge tag 'spi-fix-v5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brooni...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Nov 2021 22:35:41 +0000 (14:35 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Nov 2021 22:35:41 +0000 (14:35 -0800)
Pull spi fixes from Mark Brown:
 "A few small fixes for v5.16, one in the core for an issue with
  handling of controller unregistration that was introduced with the
  fixes for registering nested SPI controllers and a few more minor
  device specific ones"

* tag 'spi-fix-v5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: fix use-after-free of the add_lock mutex
  spi: spi-geni-qcom: fix error handling in spi_geni_grab_gpi_chan()
  spi: lpspi: Silence error message upon deferred probe
  spi: cadence-quadspi: fix write completion support

1  2 
drivers/spi/spi.c

diff --combined drivers/spi/spi.c
@@@ -450,47 -450,6 +450,47 @@@ int __spi_register_driver(struct modul
  {
        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);
@@@ -3099,12 -3058,6 +3099,6 @@@ void spi_unregister_controller(struct s
  
        device_del(&ctlr->dev);
  
-       /* Release the last reference on the controller if its driver
-        * has not yet been converted to devm_spi_alloc_master/slave().
-        */
-       if (!ctlr->devm_allocated)
-               put_device(&ctlr->dev);
        /* free bus id */
        mutex_lock(&board_lock);
        if (found == ctlr)
  
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
                mutex_unlock(&ctlr->add_lock);
+       /* Release the last reference on the controller if its driver
+        * has not yet been converted to devm_spi_alloc_master/slave().
+        */
+       if (!ctlr->devm_allocated)
+               put_device(&ctlr->dev);
  }
  EXPORT_SYMBOL_GPL(spi_unregister_controller);