summaryrefslogtreecommitdiff
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2020-05-29 12:59:48 +0300
committerMarcel Holtmann <marcel@holtmann.org>2020-06-03 19:55:33 +0200
commit4c07a5d7aeb39f559b29aa58ec9a8a5ab4282cb0 (patch)
tree071539ee304faaa2c20ea2391cda92461709d805 /drivers/bluetooth
parent30965242268c39eaaa4e845e0559cd2635d016a6 (diff)
Bluetooth: hci_qca: Fix an error pointer dereference
When a function like devm_clk_get_optional() function returns both error pointers on error and NULL then the NULL return means that the optional feature is deliberately disabled. It is a special sort of success and should not trigger an error message. The surrounding code should be written to check for NULL and not crash. On the other hand, if we encounter an error, then the probe from should clean up and return a failure. In this code, if devm_clk_get_optional() returns an error pointer then the kernel will crash inside the call to: clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); The error handling must be updated to prevent that. Fixes: 77131dfec6af ("Bluetooth: hci_qca: Replace devm_gpiod_get() with devm_gpiod_get_optional()") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/hci_qca.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 81c3c38baba1..836949d827ee 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1962,17 +1962,17 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
- if (!qcadev->susclk) {
+ if (IS_ERR(qcadev->susclk)) {
dev_warn(&serdev->dev, "failed to acquire clk\n");
- } else {
- err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
- if (err)
- return err;
-
- err = clk_prepare_enable(qcadev->susclk);
- if (err)
- return err;
+ return PTR_ERR(qcadev->susclk);
}
+ err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(qcadev->susclk);
+ if (err)
+ return err;
err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
if (err) {