]> Git Repo - linux.git/commitdiff
Merge tag 'devicetree-fixes-for-6.2-3' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <[email protected]>
Thu, 13 Apr 2023 22:21:56 +0000 (15:21 -0700)
committerLinus Torvalds <[email protected]>
Thu, 13 Apr 2023 22:21:56 +0000 (15:21 -0700)
Pull devicetree fixes from Rob Herring:

 - Fix interaction between fw_devlink and DT overlays causing devices to
   not be probed

 - Fix the compatible string for loongson,cpu-interrupt-controller

* tag 'devicetree-fixes-for-6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux:
  treewide: Fix probing of devices in DT overlays
  dt-bindings: interrupt-controller: loongarch: Fix mismatched compatible

1  2 
drivers/bus/imx-weim.c
drivers/i2c/i2c-core-of.c
drivers/of/dynamic.c
drivers/of/platform.c
drivers/spi/spi.c

diff --combined drivers/bus/imx-weim.c
index 36d42484142aede2a409279f3626f3ffc3e959e9,a8dfe94491fd7094e156d1a8a6e89194544fd3f6..cf463c1d2102c6fb9bb13bbaea33f1844c9daa17
@@@ -204,8 -204,8 +204,8 @@@ static int weim_parse_dt(struct platfor
        const struct of_device_id *of_id = of_match_device(weim_id_table,
                                                           &pdev->dev);
        const struct imx_weim_devtype *devtype = of_id->data;
 +      int ret = 0, have_child = 0;
        struct device_node *child;
 -      int ret, have_child = 0;
        struct weim_priv *priv;
        void __iomem *base;
        u32 reg;
  static int weim_probe(struct platform_device *pdev)
  {
        struct weim_priv *priv;
 -      struct resource *res;
        struct clk *clk;
        void __iomem *base;
        int ret;
                return -ENOMEM;
  
        /* get the resource */
 -      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      base = devm_ioremap_resource(&pdev->dev, res);
 +      base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
        if (IS_ERR(base))
                return PTR_ERR(base);
  
@@@ -329,6 -331,12 +329,12 @@@ static int of_weim_notify(struct notifi
                                 "Failed to setup timing for '%pOF'\n", rd->dn);
  
                if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
+                       /*
+                        * Clear the flag before adding the device so that
+                        * fw_devlink doesn't skip adding consumers to this
+                        * device.
+                        */
+                       rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                        if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
                                dev_err(&pdev->dev,
                                        "Failed to create child device '%pOF'\n",
index bce6b796e04c2ca0523bf1fc83117b13b4bc2c43,1073f82d5dd47fc36dc4a34999cc5989d988b67a..545436b7dd5355a5505f1c4348241d58a6157470
@@@ -113,6 -113,72 +113,6 @@@ void of_i2c_register_devices(struct i2c
        of_node_put(bus);
  }
  
 -static int of_dev_or_parent_node_match(struct device *dev, const void *data)
 -{
 -      if (dev->of_node == data)
 -              return 1;
 -
 -      if (dev->parent)
 -              return dev->parent->of_node == data;
 -
 -      return 0;
 -}
 -
 -/* must call put_device() when done with returned i2c_client device */
 -struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
 -{
 -      struct device *dev;
 -      struct i2c_client *client;
 -
 -      dev = bus_find_device_by_of_node(&i2c_bus_type, node);
 -      if (!dev)
 -              return NULL;
 -
 -      client = i2c_verify_client(dev);
 -      if (!client)
 -              put_device(dev);
 -
 -      return client;
 -}
 -EXPORT_SYMBOL(of_find_i2c_device_by_node);
 -
 -/* must call put_device() when done with returned i2c_adapter device */
 -struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
 -{
 -      struct device *dev;
 -      struct i2c_adapter *adapter;
 -
 -      dev = bus_find_device(&i2c_bus_type, NULL, node,
 -                            of_dev_or_parent_node_match);
 -      if (!dev)
 -              return NULL;
 -
 -      adapter = i2c_verify_adapter(dev);
 -      if (!adapter)
 -              put_device(dev);
 -
 -      return adapter;
 -}
 -EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
 -
 -/* must call i2c_put_adapter() when done with returned i2c_adapter device */
 -struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
 -{
 -      struct i2c_adapter *adapter;
 -
 -      adapter = of_find_i2c_adapter_by_node(node);
 -      if (!adapter)
 -              return NULL;
 -
 -      if (!try_module_get(adapter->owner)) {
 -              put_device(&adapter->dev);
 -              adapter = NULL;
 -      }
 -
 -      return adapter;
 -}
 -EXPORT_SYMBOL(of_get_i2c_adapter_by_node);
 -
  static const struct of_device_id*
  i2c_of_match_device_sysfs(const struct of_device_id *matches,
                                  struct i2c_client *client)
@@@ -178,6 -244,11 +178,11 @@@ static int of_i2c_notify(struct notifie
                        return NOTIFY_OK;
                }
  
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                client = of_i2c_register_device(adap, rd->dn);
                if (IS_ERR(client)) {
                        dev_err(&adap->dev, "failed to create client for '%pOF'\n",
diff --combined drivers/of/dynamic.c
index 07d93753b12f5f4d2ccc0b6f00fa1e2aefef5bd6,788c77b257b38369584e040c6a360418eb16be18..e311d406b17053065b2f0699e92cda1c2e5db481
@@@ -226,6 -226,7 +226,7 @@@ static void __of_attach_node(struct dev
        np->sibling = np->parent->child;
        np->parent->child = np;
        of_node_clear_flag(np, OF_DETACHED);
+       np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
  }
  
  /**
@@@ -329,30 -330,10 +330,30 @@@ void of_node_release(struct kobject *ko
  {
        struct device_node *node = kobj_to_device_node(kobj);
  
 +      /*
 +       * can not use '"%pOF", node' in pr_err() calls from this function
 +       * because an of_node_get(node) when refcount is already zero
 +       * will result in an error and a stack dump
 +       */
 +
        /* We should never be releasing nodes that haven't been detached. */
        if (!of_node_check_flag(node, OF_DETACHED)) {
 -              pr_err("ERROR: Bad of_node_put() on %pOF\n", node);
 -              dump_stack();
 +
 +              pr_err("ERROR: %s() detected bad of_node_put() on %pOF/%s\n",
 +                      __func__, node->parent, node->full_name);
 +
 +              /*
 +               * of unittests will test this path.  Do not print the stack
 +               * trace when the error is caused by unittest so that we do
 +               * not display what a normal developer might reasonably
 +               * consider a real bug.
 +               */
 +              if (!IS_ENABLED(CONFIG_OF_UNITTEST) ||
 +                  strcmp(node->parent->full_name, "testcase-data")) {
 +                      dump_stack();
 +                      pr_err("ERROR: next of_node_put() on this node will result in a kobject warning 'refcount_t: underflow; use-after-free.'\n");
 +              }
 +
                return;
        }
        if (!of_node_check_flag(node, OF_DYNAMIC))
                               __func__, node);
        }
  
 +      if (node->child)
 +              pr_err("ERROR: %s() unexpected children for %pOF/%s\n",
 +                      __func__, node->parent, node->full_name);
 +
        property_list_free(node->properties);
        property_list_free(node->deadprops);
        fwnode_links_purge(of_fwnode_handle(node));
@@@ -443,8 -420,7 +444,8 @@@ struct property *__of_prop_dup(const st
   * another node.  The node data are dynamically allocated and all the node
   * flags have the OF_DYNAMIC & OF_DETACHED bits set.
   *
 - * Return: The newly allocated node or NULL on out of memory error.
 + * Return: The newly allocated node or NULL on out of memory error.  Use
 + * of_node_put() on it when done to free the memory allocated for it.
   */
  struct device_node *__of_node_dup(const struct device_node *np,
                                  const char *full_name)
diff --combined drivers/of/platform.c
index b2bd2e783445dd78e40beefb31d83bfa8c7eac6d,daf2acf7dad5af08971fe66f9356469056c511c8..78ae8418744905c9b038378e78699a1aeb111a1c
@@@ -222,6 -222,7 +222,6 @@@ static struct amba_device *of_amba_devi
                                                 struct device *parent)
  {
        struct amba_device *dev;
 -      const void *prop;
        int ret;
  
        pr_debug("Creating amba device %pOF\n", node);
                of_device_make_bus_id(&dev->dev);
  
        /* Allow the HW Peripheral ID to be overridden */
 -      prop = of_get_property(node, "arm,primecell-periphid", NULL);
 -      if (prop)
 -              dev->periphid = of_read_ulong(prop, 1);
 +      of_property_read_u32(node, "arm,primecell-periphid", &dev->periphid);
  
        ret = of_address_to_resource(node, 0, &dev->res);
        if (ret) {
@@@ -526,7 -529,7 +526,7 @@@ static int __init of_platform_default_p
                int ret;
  
                /* Check if we have a MacOS display without a node spec */
 -              if (of_get_property(of_chosen, "linux,bootx-noscreen", NULL)) {
 +              if (of_property_present(of_chosen, "linux,bootx-noscreen")) {
                        /*
                         * The old code tried to work out which node was the MacOS
                         * display based on the address. I'm dropping that since the
@@@ -737,6 -740,11 +737,11 @@@ static int of_platform_notify(struct no
                if (of_node_check_flag(rd->dn, OF_POPULATED))
                        return NOTIFY_OK;
  
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                /* pdev_parent may be NULL when no bus platform device */
                pdev_parent = of_find_device_by_node(rd->dn->parent);
                pdev = of_platform_device_create(rd->dn, NULL,
diff --combined drivers/spi/spi.c
index 44b85a8d47f112f795fb0a8a46397daff7999bcf,94f60f7561d4c6c15ca061665e994018a09c3f93..7bc14fb309a69970ea92902e4f1ec88b32a41e8c
@@@ -395,7 -395,7 +395,7 @@@ static int spi_match_device(struct devi
        return strcmp(spi->modalias, drv->name) == 0;
  }
  
 -static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
 +static int spi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
        const struct spi_device         *spi = to_spi_device(dev);
        int rc;
@@@ -604,7 -604,7 +604,7 @@@ static void spi_dev_set_name(struct spi
        }
  
        dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev),
 -                   spi->chip_select);
 +                   spi_get_chipselect(spi, 0));
  }
  
  static int spi_dev_check(struct device *dev, void *data)
        struct spi_device *new_spi = data;
  
        if (spi->controller == new_spi->controller &&
 -          spi->chip_select == new_spi->chip_select)
 +          spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0))
                return -EBUSY;
        return 0;
  }
@@@ -638,7 -638,7 +638,7 @@@ static int __spi_add_device(struct spi_
        status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
        if (status) {
                dev_err(dev, "chipselect %d already in use\n",
 -                              spi->chip_select);
 +                              spi_get_chipselect(spi, 0));
                return status;
        }
  
        }
  
        if (ctlr->cs_gpiods)
 -              spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
 +              spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]);
  
        /*
         * Drivers may modify this initial i/o setup, but will
@@@ -692,8 -692,8 +692,8 @@@ int spi_add_device(struct spi_device *s
        int status;
  
        /* Chipselects are numbered 0..max; validate. */
 -      if (spi->chip_select >= ctlr->num_chipselect) {
 -              dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
 +      if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
 +              dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
                        ctlr->num_chipselect);
                return -EINVAL;
        }
@@@ -714,8 -714,8 +714,8 @@@ static int spi_add_device_locked(struc
        struct device *dev = ctlr->dev.parent;
  
        /* Chipselects are numbered 0..max; validate. */
 -      if (spi->chip_select >= ctlr->num_chipselect) {
 -              dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
 +      if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
 +              dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
                        ctlr->num_chipselect);
                return -EINVAL;
        }
@@@ -761,7 -761,7 +761,7 @@@ struct spi_device *spi_new_device(struc
  
        WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
  
 -      proxy->chip_select = chip->chip_select;
 +      spi_set_chipselect(proxy, 0, chip->chip_select);
        proxy->max_speed_hz = chip->max_speed_hz;
        proxy->mode = chip->mode;
        proxy->irq = chip->irq;
@@@ -970,23 -970,24 +970,23 @@@ static void spi_set_cs(struct spi_devic
         * Avoid calling into the driver (or doing delays) if the chip select
         * isn't actually changing from the last time this was called.
         */
 -      if (!force && ((enable && spi->controller->last_cs == spi->chip_select) ||
 -                              (!enable && spi->controller->last_cs != spi->chip_select)) &&
 +      if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) ||
 +                     (!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) &&
            (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
                return;
  
        trace_spi_set_cs(spi, activate);
  
 -      spi->controller->last_cs = enable ? spi->chip_select : -1;
 +      spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1;
        spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
  
 -      if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) {
 +      if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate)
                spi_delay_exec(&spi->cs_hold, NULL);
 -      }
  
        if (spi->mode & SPI_CS_HIGH)
                enable = !enable;
  
 -      if (spi->cs_gpiod) {
 +      if (spi_get_csgpiod(spi, 0)) {
                if (!(spi->mode & SPI_NO_CS)) {
                        /*
                         * Historically ACPI has no means of the GPIO polarity and
                         * into account.
                         */
                        if (has_acpi_companion(&spi->dev))
 -                              gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
 +                              gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable);
                        else
                                /* Polarity handled by GPIO library */
 -                              gpiod_set_value_cansleep(spi->cs_gpiod, activate);
 +                              gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate);
                }
                /* Some SPI masters need both GPIO CS & slave_select */
                if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
                spi->controller->set_cs(spi, !enable);
        }
  
 -      if (spi->cs_gpiod || !spi->controller->set_cs_timing) {
 +      if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) {
                if (activate)
                        spi_delay_exec(&spi->cs_setup, NULL);
                else
@@@ -1483,13 -1484,6 +1483,13 @@@ static void _spi_transfer_cs_change_del
        }
  }
  
 +void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
 +                                                struct spi_transfer *xfer)
 +{
 +      _spi_transfer_cs_change_delay(msg, xfer);
 +}
 +EXPORT_SYMBOL_GPL(spi_transfer_cs_change_delay_exec);
 +
  /*
   * spi_transfer_one_message - Default implementation of transfer_one_message()
   *
@@@ -1927,7 -1921,7 +1927,7 @@@ void spi_take_timestamp_post(struct spi
        /* Capture the resolution of the timestamp */
        xfer->ptp_sts_word_post = progress;
  
 -      xfer->timestamped = true;
 +      xfer->timestamped = 1;
  }
  EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
  
@@@ -2226,26 -2220,11 +2226,26 @@@ void spi_flush_queue(struct spi_control
  /*-------------------------------------------------------------------------*/
  
  #if defined(CONFIG_OF)
 +static void of_spi_parse_dt_cs_delay(struct device_node *nc,
 +                                   struct spi_delay *delay, const char *prop)
 +{
 +      u32 value;
 +
 +      if (!of_property_read_u32(nc, prop, &value)) {
 +              if (value > U16_MAX) {
 +                      delay->value = DIV_ROUND_UP(value, 1000);
 +                      delay->unit = SPI_DELAY_UNIT_USECS;
 +              } else {
 +                      delay->value = value;
 +                      delay->unit = SPI_DELAY_UNIT_NSECS;
 +              }
 +      }
 +}
 +
  static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
                           struct device_node *nc)
  {
        u32 value;
 -      u16 cs_setup;
        int rc;
  
        /* Mode (clock phase/polarity/etc.) */
                        nc, rc);
                return rc;
        }
 -      spi->chip_select = value;
 +      spi_set_chipselect(spi, 0, value);
  
        /* Device speed */
        if (!of_property_read_u32(nc, "spi-max-frequency", &value))
                spi->max_speed_hz = value;
  
 -      if (!of_property_read_u16(nc, "spi-cs-setup-ns", &cs_setup)) {
 -              spi->cs_setup.value = cs_setup;
 -              spi->cs_setup.unit = SPI_DELAY_UNIT_NSECS;
 -      }
 +      /* Device CS delays */
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns");
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns");
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns");
  
        return 0;
  }
@@@ -2444,7 -2423,7 +2444,7 @@@ struct spi_device *spi_new_ancillary_de
        strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias));
  
        /* Use provided chip-select for ancillary device */
 -      ancillary->chip_select = chip_select;
 +      spi_set_chipselect(ancillary, 0, chip_select);
  
        /* Take over SPI mode/speed from SPI main device */
        ancillary->max_speed_hz = spi->max_speed_hz;
@@@ -2691,7 -2670,7 +2691,7 @@@ struct spi_device *acpi_spi_device_allo
        spi->mode               |= lookup.mode;
        spi->irq                = lookup.irq;
        spi->bits_per_word      = lookup.bits_per_word;
 -      spi->chip_select        = lookup.chip_select;
 +      spi_set_chipselect(spi, 0, lookup.chip_select);
  
        return spi;
  }
@@@ -3072,14 -3051,15 +3072,14 @@@ static int spi_controller_check_ops(str
         * The controller may implement only the high-level SPI-memory like
         * operations if it does not support regular SPI transfers, and this is
         * valid use case.
 -       * If ->mem_ops is NULL, we request that at least one of the
 -       * ->transfer_xxx() method be implemented.
 +       * If ->mem_ops or ->mem_ops->exec_op is NULL, we request that at least
 +       * one of the ->transfer_xxx() method be implemented.
         */
 -      if (ctlr->mem_ops) {
 -              if (!ctlr->mem_ops->exec_op)
 -                      return -EINVAL;
 -      } else if (!ctlr->transfer && !ctlr->transfer_one &&
 +      if (!ctlr->mem_ops || (ctlr->mem_ops && !ctlr->mem_ops->exec_op)) {
 +              if (!ctlr->transfer && !ctlr->transfer_one &&
                   !ctlr->transfer_one_message) {
 -              return -EINVAL;
 +                      return -EINVAL;
 +              }
        }
  
        return 0;
@@@ -3652,7 -3632,7 +3652,7 @@@ static int spi_set_cs_timing(struct spi
        struct device *parent = spi->controller->dev.parent;
        int status = 0;
  
 -      if (spi->controller->set_cs_timing && !spi->cs_gpiod) {
 +      if (spi->controller->set_cs_timing && !spi_get_csgpiod(spi, 0)) {
                if (spi->controller->auto_runtime_pm) {
                        status = pm_runtime_get_sync(parent);
                        if (status < 0) {
@@@ -3857,7 -3837,7 +3857,7 @@@ static int __spi_validate(struct spi_de
         * cs_change is set for each transfer.
         */
        if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
 -                                        spi->cs_gpiod)) {
 +                                        spi_get_csgpiod(spi, 0))) {
                size_t maxsize;
                int ret;
  
@@@ -4456,6 -4436,11 +4456,11 @@@ static int of_spi_notify(struct notifie
                        return NOTIFY_OK;
                }
  
+               /*
+                * Clear the flag before adding the device so that fw_devlink
+                * doesn't skip adding consumers to this device.
+                */
+               rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
                spi = of_register_spi_device(ctlr, rd->dn);
                put_device(&ctlr->dev);
  
This page took 0.093179 seconds and 4 git commands to generate.