Message ID | 454a58f998b0d16847d72a97b32192829fab2c8c.1627273794.git.viresh.kumar@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | virtio: Add virtio-device bindings | expand |
On 26/07/2021 14:51, Viresh Kumar wrote: > Bind the virtio devices with their of_node. This will help users of the > virtio devices to mention their dependencies on the device in the DT > itself. Like GPIO pin users can use the phandle of the device node, or > the node may contain more subnodes to add i2c or spi eeproms and other > users. > > Reviewed-by: Arnd Bergmann <arnd@arndb.de> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > --- > drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 54 insertions(+), 3 deletions(-) > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c > index 4b15c00c0a0a..d001e84a5b23 100644 > --- a/drivers/virtio/virtio.c > +++ b/drivers/virtio/virtio.c > @@ -4,6 +4,7 @@ > #include <linux/virtio_config.h> > #include <linux/module.h> > #include <linux/idr.h> > +#include <linux/of.h> > #include <uapi/linux/virtio_ids.h> > > /* Unique numbering for virtio devices. */ > @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d) > > /* Acknowledge the device's existence again. */ > virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); > + > + of_node_put(dev->dev.of_node); > + > return 0; > } > > @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver) > } > EXPORT_SYMBOL_GPL(unregister_virtio_driver); > > +static int virtio_device_of_init(struct virtio_device *dev) > +{ > + struct device_node *np, *pnode = dev_of_node(dev->dev.parent); > + char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */ > + int ret, count; > + > + if (!pnode) > + return 0; > + > + count = of_get_available_child_count(pnode); > + if (!count) > + return 0; > + > + /* There can be only 1 child node */ > + if (WARN_ON(count > 1)) > + return -EINVAL; > + > + np = of_get_next_available_child(pnode, NULL); > + if (WARN_ON(!np)) > + return -ENODEV; > + > + BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >= > + sizeof(compat)); > + > + if (!of_device_is_compatible(np, compat)) { This broke powerpc/pseries as there these virtio devices are PCI so there is no "compat" - PCI vendor id/device ids play role of "compat". Thanks, > + ret = -EINVAL; > + goto out; > + } > + > + dev->dev.of_node = np; > + return 0; > + > +out: > + of_node_put(np); > + return ret; > +} > + > /** > * register_virtio_device - register virtio device > * @dev : virtio device to be registered > @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev) > dev->index = err; > dev_set_name(&dev->dev, "virtio%u", dev->index); > > + err = virtio_device_of_init(dev); > + if (err) > + goto out_ida_remove; > + > spin_lock_init(&dev->config_lock); > dev->config_enabled = false; > dev->config_change_pending = false; > @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev) > */ > err = device_add(&dev->dev); > if (err) > - ida_simple_remove(&virtio_index_ida, dev->index); > + goto out_of_node_put; > + > + return 0; > + > +out_of_node_put: > + of_node_put(dev->dev.of_node); > +out_ida_remove: > + ida_simple_remove(&virtio_index_ida, dev->index); > out: > - if (err) > - virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); > return err; > } > EXPORT_SYMBOL_GPL(register_virtio_device); > -- Alexey
On Mon, Sep 13, 2021 at 07:19:17PM +1000, Alexey Kardashevskiy wrote: > > > On 26/07/2021 14:51, Viresh Kumar wrote: > > Bind the virtio devices with their of_node. This will help users of the > > virtio devices to mention their dependencies on the device in the DT > > itself. Like GPIO pin users can use the phandle of the device node, or > > the node may contain more subnodes to add i2c or spi eeproms and other > > users. > > > > Reviewed-by: Arnd Bergmann <arnd@arndb.de> > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > > --- > > drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++--- > > 1 file changed, 54 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c > > index 4b15c00c0a0a..d001e84a5b23 100644 > > --- a/drivers/virtio/virtio.c > > +++ b/drivers/virtio/virtio.c > > @@ -4,6 +4,7 @@ > > #include <linux/virtio_config.h> > > #include <linux/module.h> > > #include <linux/idr.h> > > +#include <linux/of.h> > > #include <uapi/linux/virtio_ids.h> > > > > /* Unique numbering for virtio devices. */ > > @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d) > > > > /* Acknowledge the device's existence again. */ > > virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); > > + > > + of_node_put(dev->dev.of_node); > > + > > return 0; > > } > > > > @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver) > > } > > EXPORT_SYMBOL_GPL(unregister_virtio_driver); > > > > +static int virtio_device_of_init(struct virtio_device *dev) > > +{ > > + struct device_node *np, *pnode = dev_of_node(dev->dev.parent); > > + char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */ > > + int ret, count; > > + > > + if (!pnode) > > + return 0; > > + > > + count = of_get_available_child_count(pnode); > > + if (!count) > > + return 0; > > + > > + /* There can be only 1 child node */ > > + if (WARN_ON(count > 1)) > > + return -EINVAL; > > + > > + np = of_get_next_available_child(pnode, NULL); > > + if (WARN_ON(!np)) > > + return -ENODEV; > > + > > + BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >= > > + sizeof(compat)); > > + > > + if (!of_device_is_compatible(np, compat)) { > > > This broke powerpc/pseries as there these virtio devices are PCI so > there is no "compat" - PCI vendor id/device ids play role of "compat". > Thanks, Hmm now that you say this I wonder why do we bother with this check, too. When can this be invoked for something that is not a virtio device? And is it enough to just skip of_node initialization then? > > > > > + ret = -EINVAL; So basically ret = 0 above? > > + goto out; > > + } > > + > > + dev->dev.of_node = np; > > + return 0; > > + > > +out: > > + of_node_put(np); > > + return ret; > > +} > > + > > /** > > * register_virtio_device - register virtio device > > * @dev : virtio device to be registered > > @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev) > > dev->index = err; > > dev_set_name(&dev->dev, "virtio%u", dev->index); > > > > + err = virtio_device_of_init(dev); > > + if (err) > > + goto out_ida_remove; > > + > > spin_lock_init(&dev->config_lock); > > dev->config_enabled = false; > > dev->config_change_pending = false; > > @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev) > > */ > > err = device_add(&dev->dev); > > if (err) > > - ida_simple_remove(&virtio_index_ida, dev->index); > > + goto out_of_node_put; > > + > > + return 0; > > + > > +out_of_node_put: > > + of_node_put(dev->dev.of_node); > > +out_ida_remove: > > + ida_simple_remove(&virtio_index_ida, dev->index); > > out: > > - if (err) > > - virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); > > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); > > return err; > > } > > EXPORT_SYMBOL_GPL(register_virtio_device); > > > > -- > Alexey
On 13/09/2021 19:45, Michael S. Tsirkin wrote: > On Mon, Sep 13, 2021 at 07:19:17PM +1000, Alexey Kardashevskiy wrote: >> >> >> On 26/07/2021 14:51, Viresh Kumar wrote: >>> Bind the virtio devices with their of_node. This will help users of the >>> virtio devices to mention their dependencies on the device in the DT >>> itself. Like GPIO pin users can use the phandle of the device node, or >>> the node may contain more subnodes to add i2c or spi eeproms and other >>> users. >>> >>> Reviewed-by: Arnd Bergmann <arnd@arndb.de> >>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> >>> --- >>> drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++--- >>> 1 file changed, 54 insertions(+), 3 deletions(-) >>> >>> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c >>> index 4b15c00c0a0a..d001e84a5b23 100644 >>> --- a/drivers/virtio/virtio.c >>> +++ b/drivers/virtio/virtio.c >>> @@ -4,6 +4,7 @@ >>> #include <linux/virtio_config.h> >>> #include <linux/module.h> >>> #include <linux/idr.h> >>> +#include <linux/of.h> >>> #include <uapi/linux/virtio_ids.h> >>> >>> /* Unique numbering for virtio devices. */ >>> @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d) >>> >>> /* Acknowledge the device's existence again. */ >>> virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); >>> + >>> + of_node_put(dev->dev.of_node); >>> + >>> return 0; >>> } >>> >>> @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver) >>> } >>> EXPORT_SYMBOL_GPL(unregister_virtio_driver); >>> >>> +static int virtio_device_of_init(struct virtio_device *dev) >>> +{ >>> + struct device_node *np, *pnode = dev_of_node(dev->dev.parent); >>> + char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */ >>> + int ret, count; >>> + >>> + if (!pnode) >>> + return 0; >>> + >>> + count = of_get_available_child_count(pnode); >>> + if (!count) >>> + return 0; >>> + >>> + /* There can be only 1 child node */ >>> + if (WARN_ON(count > 1)) >>> + return -EINVAL; >>> + >>> + np = of_get_next_available_child(pnode, NULL); >>> + if (WARN_ON(!np)) >>> + return -ENODEV; >>> + >>> + BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >= >>> + sizeof(compat)); >>> + >>> + if (!of_device_is_compatible(np, compat)) { >> >> >> This broke powerpc/pseries as there these virtio devices are PCI so >> there is no "compat" - PCI vendor id/device ids play role of "compat". >> Thanks, > > Hmm now that you say this I wonder why do we bother > with this check, too. When can this be invoked for something > that is not a virtio device? And is it enough to just > skip of_node initialization then? I am not following here, the problem device is virtio-scsi which is virtio-derived, or you meant that virtio which hosts virtio-bus? > >> >> >> >>> + ret = -EINVAL; > > > So basically ret = 0 above? Yup, this does fix it. Thanks, > > >>> + goto out; >>> + } >>> + >>> + dev->dev.of_node = np; >>> + return 0; >>> + >>> +out: >>> + of_node_put(np); >>> + return ret; >>> +} >>> + >>> /** >>> * register_virtio_device - register virtio device >>> * @dev : virtio device to be registered >>> @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev) >>> dev->index = err; >>> dev_set_name(&dev->dev, "virtio%u", dev->index); >>> >>> + err = virtio_device_of_init(dev); >>> + if (err) >>> + goto out_ida_remove; >>> + >>> spin_lock_init(&dev->config_lock); >>> dev->config_enabled = false; >>> dev->config_change_pending = false; >>> @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev) >>> */ >>> err = device_add(&dev->dev); >>> if (err) >>> - ida_simple_remove(&virtio_index_ida, dev->index); >>> + goto out_of_node_put; >>> + >>> + return 0; >>> + >>> +out_of_node_put: >>> + of_node_put(dev->dev.of_node); >>> +out_ida_remove: >>> + ida_simple_remove(&virtio_index_ida, dev->index); >>> out: >>> - if (err) >>> - virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); >>> + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); >>> return err; >>> } >>> EXPORT_SYMBOL_GPL(register_virtio_device); >>> >> >> -- >> Alexey > -- Alexey
On Mon, Jul 26, 2021 at 10:21:45AM +0530, Viresh Kumar wrote: > Bind the virtio devices with their of_node. This will help users of the > virtio devices to mention their dependencies on the device in the DT > itself. Like GPIO pin users can use the phandle of the device node, or > the node may contain more subnodes to add i2c or spi eeproms and other > users. > > Reviewed-by: Arnd Bergmann <arnd@arndb.de> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> This patch causes a boot failure on sparc64: The virtio device no longer instantiates. Reverting this patch fixes the problem. Bisect log attached. Guenter --- # bad: [6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f] Linux 5.15-rc1 # good: [926de8c4326c14fcf35f1de142019043597a4fac] Merge tag 'acpi-5.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm git bisect start 'HEAD' '926de8c4326c' # good: [8177a5c96229ff24da1e362789e359b68b4f34f5] Merge tag 'libata-5.15-2021-09-11' of git://git.kernel.dk/linux-block git bisect good 8177a5c96229ff24da1e362789e359b68b4f34f5 # bad: [78e709522d2c012cb0daad2e668506637bffb7c2] Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost git bisect bad 78e709522d2c012cb0daad2e668506637bffb7c2 # bad: [7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca] Documentation: Add documentation for VDUSE git bisect bad 7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca # bad: [41116599a0731f4cd451e9d191d879ab45e31945] virtio/vsock: add 'VIRTIO_VSOCK_SEQ_EOR' bit. git bisect bad 41116599a0731f4cd451e9d191d879ab45e31945 # good: [5262912ef3cfc5e518892c3d67fb36412cb813e2] vdpa/mlx5: Add support for control VQ and MAC setting git bisect good 5262912ef3cfc5e518892c3d67fb36412cb813e2 # good: [7f815fce08d563006e43d1b7d2f9a0a4f3b832f3] dt-bindings: i2c: Add bindings for i2c-virtio git bisect good 7f815fce08d563006e43d1b7d2f9a0a4f3b832f3 # good: [d5a8680dfab0547a4ecd708b1fe9de48598a6757] uapi: virtio_ids: Sync ids with specification git bisect good d5a8680dfab0547a4ecd708b1fe9de48598a6757 # bad: [9af8f1061646e8e22b66413bedf7b3e2ab3d69e5] virtio/vsock: rename 'EOR' to 'EOM' bit. git bisect bad 9af8f1061646e8e22b66413bedf7b3e2ab3d69e5 # bad: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node git bisect bad 694a1116b405d887c893525a6766b390989c8606 # first bad commit: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node
On Mon, Sep 13, 2021 at 07:49:07AM -0700, Guenter Roeck wrote: > On Mon, Jul 26, 2021 at 10:21:45AM +0530, Viresh Kumar wrote: > > Bind the virtio devices with their of_node. This will help users of the > > virtio devices to mention their dependencies on the device in the DT > > itself. Like GPIO pin users can use the phandle of the device node, or > > the node may contain more subnodes to add i2c or spi eeproms and other > > users. > > > > Reviewed-by: Arnd Bergmann <arnd@arndb.de> > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > > This patch causes a boot failure on sparc64: The virtio device no longer > instantiates. Reverting this patch fixes the problem. Bisect log attached. > In case it matters: The problem is here: + if (!of_device_is_compatible(np, compat)) { + ret = -EINVAL; + goto out; + } Guenter > Guenter > > --- > # bad: [6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f] Linux 5.15-rc1 > # good: [926de8c4326c14fcf35f1de142019043597a4fac] Merge tag 'acpi-5.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm > git bisect start 'HEAD' '926de8c4326c' > # good: [8177a5c96229ff24da1e362789e359b68b4f34f5] Merge tag 'libata-5.15-2021-09-11' of git://git.kernel.dk/linux-block > git bisect good 8177a5c96229ff24da1e362789e359b68b4f34f5 > # bad: [78e709522d2c012cb0daad2e668506637bffb7c2] Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost > git bisect bad 78e709522d2c012cb0daad2e668506637bffb7c2 > # bad: [7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca] Documentation: Add documentation for VDUSE > git bisect bad 7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca > # bad: [41116599a0731f4cd451e9d191d879ab45e31945] virtio/vsock: add 'VIRTIO_VSOCK_SEQ_EOR' bit. > git bisect bad 41116599a0731f4cd451e9d191d879ab45e31945 > # good: [5262912ef3cfc5e518892c3d67fb36412cb813e2] vdpa/mlx5: Add support for control VQ and MAC setting > git bisect good 5262912ef3cfc5e518892c3d67fb36412cb813e2 > # good: [7f815fce08d563006e43d1b7d2f9a0a4f3b832f3] dt-bindings: i2c: Add bindings for i2c-virtio > git bisect good 7f815fce08d563006e43d1b7d2f9a0a4f3b832f3 > # good: [d5a8680dfab0547a4ecd708b1fe9de48598a6757] uapi: virtio_ids: Sync ids with specification > git bisect good d5a8680dfab0547a4ecd708b1fe9de48598a6757 > # bad: [9af8f1061646e8e22b66413bedf7b3e2ab3d69e5] virtio/vsock: rename 'EOR' to 'EOM' bit. > git bisect bad 9af8f1061646e8e22b66413bedf7b3e2ab3d69e5 > # bad: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node > git bisect bad 694a1116b405d887c893525a6766b390989c8606 > # first bad commit: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 4b15c00c0a0a..d001e84a5b23 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -4,6 +4,7 @@ #include <linux/virtio_config.h> #include <linux/module.h> #include <linux/idr.h> +#include <linux/of.h> #include <uapi/linux/virtio_ids.h> /* Unique numbering for virtio devices. */ @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d) /* Acknowledge the device's existence again. */ virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); + + of_node_put(dev->dev.of_node); + return 0; } @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver) } EXPORT_SYMBOL_GPL(unregister_virtio_driver); +static int virtio_device_of_init(struct virtio_device *dev) +{ + struct device_node *np, *pnode = dev_of_node(dev->dev.parent); + char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */ + int ret, count; + + if (!pnode) + return 0; + + count = of_get_available_child_count(pnode); + if (!count) + return 0; + + /* There can be only 1 child node */ + if (WARN_ON(count > 1)) + return -EINVAL; + + np = of_get_next_available_child(pnode, NULL); + if (WARN_ON(!np)) + return -ENODEV; + + BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >= + sizeof(compat)); + + if (!of_device_is_compatible(np, compat)) { + ret = -EINVAL; + goto out; + } + + dev->dev.of_node = np; + return 0; + +out: + of_node_put(np); + return ret; +} + /** * register_virtio_device - register virtio device * @dev : virtio device to be registered @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev) dev->index = err; dev_set_name(&dev->dev, "virtio%u", dev->index); + err = virtio_device_of_init(dev); + if (err) + goto out_ida_remove; + spin_lock_init(&dev->config_lock); dev->config_enabled = false; dev->config_change_pending = false; @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev) */ err = device_add(&dev->dev); if (err) - ida_simple_remove(&virtio_index_ida, dev->index); + goto out_of_node_put; + + return 0; + +out_of_node_put: + of_node_put(dev->dev.of_node); +out_ida_remove: + ida_simple_remove(&virtio_index_ida, dev->index); out: - if (err) - virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED); return err; } EXPORT_SYMBOL_GPL(register_virtio_device);