From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934117AbcBQK3i (ORCPT ); Wed, 17 Feb 2016 05:29:38 -0500 Received: from mga04.intel.com ([192.55.52.120]:49214 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934102AbcBQK3g (ORCPT ); Wed, 17 Feb 2016 05:29:36 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,459,1449561600"; d="scan'208";a="916723964" From: Andy Shevchenko To: Stephen Boyd , Lee Jones , linux-kernel@vger.kernel.org Cc: Andy Shevchenko Subject: [PATCH v1 1/2] mfd: intel_quark_i2c_gpio: remove clock tree on error path Date: Wed, 17 Feb 2016 12:29:32 +0200 Message-Id: <1455704973-811-1-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.7.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Fixes: 60ae5b9f5cdd (mfd: intel_quark_i2c_gpio: Add Intel Quark X1000 I2C-GPIO MFD Driver) Signed-off-by: Andy Shevchenko --- drivers/mfd/intel_quark_i2c_gpio.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c index bdc5e27..43d8066 100644 --- a/drivers/mfd/intel_quark_i2c_gpio.c +++ b/drivers/mfd/intel_quark_i2c_gpio.c @@ -150,11 +150,10 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev) { struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev); - if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup) + clk_unregister(quark_mfd->i2c_clk); + if (!quark_mfd->i2c_clk_lookup) return; - clkdev_drop(quark_mfd->i2c_clk_lookup); - clk_unregister(quark_mfd->i2c_clk); } static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell) @@ -246,25 +245,33 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev, quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL); if (!quark_mfd) return -ENOMEM; + quark_mfd->pdev = pdev; + dev_set_drvdata(&pdev->dev, quark_mfd); ret = intel_quark_register_i2c_clk(quark_mfd); if (ret) - return ret; - - dev_set_drvdata(&pdev->dev, quark_mfd); + goto err_unregister_i2c_clk; ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]); if (ret) - return ret; + goto err_unregister_i2c_clk; ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]); if (ret) - return ret; + goto err_unregister_i2c_clk; + + ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells, + ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, + NULL); + if (ret) + goto err_unregister_i2c_clk; - return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells, - ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, - NULL); + return 0; + +err_unregister_i2c_clk: + intel_quark_unregister_i2c_clk(pdev); + return ret; } static void intel_quark_mfd_remove(struct pci_dev *pdev) -- 2.7.0