Commit 7f0c5ae1 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Lee Jones

mfd: intel_quark_i2c_gpio: Remove clock tree on error path

There is a potential resource leak in case when ->probe() fails. We have to
unregister and remove clock tree which is done here.

This is a follow up to previously pushed commit c4726abc ("mfd:
intel_quark_i2c_gpio: Use clkdev_create()") that prevents double free() when
clkdev_drop() followed by kfree() in devm_kcalloc() release stage.

I leave Fixes tag here, but the backporting will require to backport the commit
c4726abc ("mfd: intel_quark_i2c_gpio: Use clkdev_create()") first.

Cc: stable@vger.kernel.org
Fixes: 60ae5b9f (mfd: intel_quark_i2c_gpio: Add Intel Quark X1000 I2C-GPIO MFD Driver)
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 65433fd5
...@@ -139,6 +139,7 @@ static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd) ...@@ -139,6 +139,7 @@ static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
INTEL_QUARK_I2C_CONTROLLER_CLK); INTEL_QUARK_I2C_CONTROLLER_CLK);
if (!quark_mfd->i2c_clk_lookup) { if (!quark_mfd->i2c_clk_lookup) {
clk_unregister(quark_mfd->i2c_clk);
dev_err(&pdev->dev, "Fixed clk register failed\n"); dev_err(&pdev->dev, "Fixed clk register failed\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -150,7 +151,7 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev) ...@@ -150,7 +151,7 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
{ {
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev); struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup) if (!quark_mfd->i2c_clk_lookup)
return; return;
clkdev_drop(quark_mfd->i2c_clk_lookup); clkdev_drop(quark_mfd->i2c_clk_lookup);
...@@ -246,25 +247,33 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev, ...@@ -246,25 +247,33 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL); quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
if (!quark_mfd) if (!quark_mfd)
return -ENOMEM; return -ENOMEM;
quark_mfd->pdev = pdev; quark_mfd->pdev = pdev;
dev_set_drvdata(&pdev->dev, quark_mfd);
ret = intel_quark_register_i2c_clk(quark_mfd); ret = intel_quark_register_i2c_clk(quark_mfd);
if (ret) if (ret)
return ret; return ret;
dev_set_drvdata(&pdev->dev, quark_mfd);
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]); ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
if (ret) if (ret)
return ret; goto err_unregister_i2c_clk;
ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]); ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
if (ret) if (ret)
return ret; goto err_unregister_i2c_clk;
return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells, ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
NULL); NULL);
if (ret)
goto err_unregister_i2c_clk;
return 0;
err_unregister_i2c_clk:
intel_quark_unregister_i2c_clk(pdev);
return ret;
} }
static void intel_quark_mfd_remove(struct pci_dev *pdev) static void intel_quark_mfd_remove(struct pci_dev *pdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment