summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-10-12 15:28:18 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-23 11:25:48 +0200
commit978d6fac5d0617c9722ae1db1accee46776f4400 (patch)
tree3c1153ded6911d27552cdec2c0edf978ada8f92d /drivers/tty
parent08fcee289f341786eb3b44e5f2d1dc850943238e (diff)
downloadlinux-978d6fac5d0617c9722ae1db1accee46776f4400.tar.gz
linux-978d6fac5d0617c9722ae1db1accee46776f4400.tar.bz2
linux-978d6fac5d0617c9722ae1db1accee46776f4400.zip
serdev: fix controller-allocation error handling
Reorder controller initialisation so that in the unlikely event that id allocation fails, we don't end up releasing id 0 in the destructor. Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serdev/core.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index dde2ddc5967d..4d662d1f4784 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -358,26 +358,31 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent,
if (!ctrl)
return NULL;
- device_initialize(&ctrl->dev);
- ctrl->dev.type = &serdev_ctrl_type;
- ctrl->dev.bus = &serdev_bus_type;
- ctrl->dev.parent = parent;
- ctrl->dev.of_node = parent->of_node;
- serdev_controller_set_drvdata(ctrl, &ctrl[1]);
-
id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
dev_err(parent,
"unable to allocate serdev controller identifier.\n");
- serdev_controller_put(ctrl);
- return NULL;
+ goto err_free;
}
ctrl->nr = id;
+
+ device_initialize(&ctrl->dev);
+ ctrl->dev.type = &serdev_ctrl_type;
+ ctrl->dev.bus = &serdev_bus_type;
+ ctrl->dev.parent = parent;
+ ctrl->dev.of_node = parent->of_node;
+ serdev_controller_set_drvdata(ctrl, &ctrl[1]);
+
dev_set_name(&ctrl->dev, "serial%d", id);
dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
return ctrl;
+
+err_free:
+ kfree(ctrl);
+
+ return NULL;
}
EXPORT_SYMBOL_GPL(serdev_controller_alloc);