aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2016-02-19 03:42:10 -0500
committerLee Jones <lee.jones@linaro.org>2016-04-11 08:31:39 -0400
commit7f0c5ae18d649ed2f4978cbf07c02a0ff732f23e (patch)
treed2ab98dbce17b3209fc465c919ba8b6658985245 /drivers/mfd
parent65433fd561f089f232758efc2c6566b6b6febb47 (diff)
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 c4726abce63b ("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 c4726abce63b ("mfd: intel_quark_i2c_gpio: Use clkdev_create()") first. Cc: stable@vger.kernel.org Fixes: 60ae5b9f5cdd (mfd: intel_quark_i2c_gpio: Add Intel Quark X1000 I2C-GPIO MFD Driver) Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/intel_quark_i2c_gpio.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index bdc5e27222c0..7450f5d8770c 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -139,6 +139,7 @@ static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
139 INTEL_QUARK_I2C_CONTROLLER_CLK); 139 INTEL_QUARK_I2C_CONTROLLER_CLK);
140 140
141 if (!quark_mfd->i2c_clk_lookup) { 141 if (!quark_mfd->i2c_clk_lookup) {
142 clk_unregister(quark_mfd->i2c_clk);
142 dev_err(&pdev->dev, "Fixed clk register failed\n"); 143 dev_err(&pdev->dev, "Fixed clk register failed\n");
143 return -ENOMEM; 144 return -ENOMEM;
144 } 145 }
@@ -150,7 +151,7 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
150{ 151{
151 struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev); 152 struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
152 153
153 if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup) 154 if (!quark_mfd->i2c_clk_lookup)
154 return; 155 return;
155 156
156 clkdev_drop(quark_mfd->i2c_clk_lookup); 157 clkdev_drop(quark_mfd->i2c_clk_lookup);
@@ -246,25 +247,33 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
246 quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL); 247 quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
247 if (!quark_mfd) 248 if (!quark_mfd)
248 return -ENOMEM; 249 return -ENOMEM;
250
249 quark_mfd->pdev = pdev; 251 quark_mfd->pdev = pdev;
252 dev_set_drvdata(&pdev->dev, quark_mfd);
250 253
251 ret = intel_quark_register_i2c_clk(quark_mfd); 254 ret = intel_quark_register_i2c_clk(quark_mfd);
252 if (ret) 255 if (ret)
253 return ret; 256 return ret;
254 257
255 dev_set_drvdata(&pdev->dev, quark_mfd);
256
257 ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]); 258 ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
258 if (ret) 259 if (ret)
259 return ret; 260 goto err_unregister_i2c_clk;
260 261
261 ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]); 262 ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
262 if (ret) 263 if (ret)
263 return ret; 264 goto err_unregister_i2c_clk;
264 265
265 return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells, 266 ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
266 ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, 267 ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
267 NULL); 268 NULL);
269 if (ret)
270 goto err_unregister_i2c_clk;
271
272 return 0;
273
274err_unregister_i2c_clk:
275 intel_quark_unregister_i2c_clk(pdev);
276 return ret;
268} 277}
269 278
270static void intel_quark_mfd_remove(struct pci_dev *pdev) 279static void intel_quark_mfd_remove(struct pci_dev *pdev)