From patchwork Thu May 18 06:36:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 100046 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp577334qge; Wed, 17 May 2017 23:36:36 -0700 (PDT) X-Received: by 10.98.139.21 with SMTP id j21mr2742838pfe.5.1495089396089; Wed, 17 May 2017 23:36:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1495089396; cv=none; d=google.com; s=arc-20160816; b=ytQIUn2fE8rtz4/Aa4n8o11luk7efYEsMxI+Nq4nXmTA9PiYqPasqRdXgzU8LRw0JH hJmTejNgZVKmK0Vx7jW3yHmXmjIkdv2ncmSx9Z21a7xOmmA4JiEXC+3nYMSU3F6DIV5E OJrrs+9cjl/adNVdBtkhZfBN/Vlzfl5CJs1Dujk+t6PffZkAfqopLpKSj0+4DEbd/w2c FddXYP78//Q+/jy2lnm0Jxq4d9kwBgZNwnfH4JW0nr26YBGuE/xpllWC0mRa8LjRwsEm +kSNXdDnkjPrtsP3orTKGXfox/neBtOBNVTm8DfLMzHMdMv0gv11wzMrapXW4M4cJXME LK4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=wFL7I4+vAcWakVhZb5+Ocgtppd7BOww9jTd/J7UeXrc=; b=PrWC1YH/B8ZB7pfXtKmuZoXJmJdeMzK0kz8MSfpOPurcbhhYvBU6+I++6jkDi3ykOp 9+j6JzjY7bXW++i6slEqjfzgzjpwUoL3Zr5r6DAuypXn9uk4YU5DZdQ8bKChUEs+fduu RVxfqEeC34II+u6rAcEFNBSDqLwqqPLD6WKF2ZOSaWFc7sj8B7EXKxtRPSxb9AlJ3ZLl akWGebKVs2laVFijEzboc4JrlN36gADbIo/Bfwz2XAQyhOq97BuSVszS2mNAvGf3IZ0U d7G1N+kvc0TKUuDVflAWcqjipTOnnGBdkkKL2KflHOx6E3xreQTU+WXQJB+Xcyi0TWp5 fC0g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b15si4293703pfh.381.2017.05.17.23.36.35; Wed, 17 May 2017 23:36:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753520AbdERGgW (ORCPT + 25 others); Thu, 18 May 2017 02:36:22 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:46288 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751348AbdERGgU (ORCPT ); Thu, 18 May 2017 02:36:20 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id E019120822; Thu, 18 May 2017 08:36:17 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 920EE2080F; Thu, 18 May 2017 08:36:17 +0200 (CEST) From: Quentin Schulz To: jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, maxime.ripard@free-electrons.com, wens@csie.org Cc: Quentin Schulz , clabbe.montjoie@gmail.com, linux-iio@vger.kernel.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] iio: adc: sun4i-gpadc-iio: fix parent device being used in devm function Date: Thu, 18 May 2017 08:36:07 +0200 Message-Id: <20170518063607.11069-1-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For the sake of DT binding stability, this IIO driver is a child of an MFD driver for Allwinner A10, A13 and A31 because there already exists a DT binding for this IP. The MFD driver has a DT node but the IIO driver does not. The IIO device registers the temperature sensor in the thermal framework using the DT node of the parent, the MFD device, so the thermal framework could match the phandle to the MFD device in the DT and the struct device used to register in the thermal framework. devm_thermal_zone_of_sensor_register was previously used to register the thermal sensor with the parent struct device of the IIO device, representing the MFD device. By doing so, we registered actually the parent in the devm routine and not the actual IIO device. This lead to the devm unregister function not being called when the IIO module driver is removed. It resulted in the thermal framework still polling the get_temp function of the IIO module while the device doesn't exist anymore, thus generated a kernel panic. Use the non-devm function instead and do the unregister manually in the remove function. Fixes: d1caa9905538 ("iio: adc: add support for Allwinner SoCs ADC") Signed-off-by: Quentin Schulz Reported-by: Corentin Labbe --- v2: - save struct device used to register in thermal framework in sun4i_gpadc_iio, - use this struct device to unregister from thermal framework instead of doing a condition on pdev->dev.of_node, - check if CONFIG_THERMAL_OF is enabled before unregistering from thermal, drivers/iio/adc/sun4i-gpadc-iio.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) -- 2.11.0 Reviewed-by: Maxime Ripard Tested-by: Corentin Labbe diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index b23527309088..11f7d7745614 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -105,6 +105,8 @@ struct sun4i_gpadc_iio { bool no_irq; /* prevents concurrent reads of temperature and ADC */ struct mutex mutex; + struct thermal_zone_device *tzd; + struct device *sensor_device; }; #define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) { \ @@ -502,7 +504,6 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, { struct sun4i_gpadc_iio *info = iio_priv(indio_dev); const struct of_device_id *of_dev; - struct thermal_zone_device *tzd; struct resource *mem; void __iomem *base; int ret; @@ -532,13 +533,14 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, if (!IS_ENABLED(CONFIG_THERMAL_OF)) return 0; - tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info, - &sun4i_ts_tz_ops); - if (IS_ERR(tzd)) + info->sensor_device = &pdev->dev; + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, 0, + info, &sun4i_ts_tz_ops); + if (IS_ERR(info->tzd)) dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(tzd)); + PTR_ERR(info->tzd)); - return PTR_ERR_OR_ZERO(tzd); + return PTR_ERR_OR_ZERO(info->tzd); } static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, @@ -584,15 +586,15 @@ static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, * of_node, and the device from this driver as third argument to * return the temperature. */ - struct thermal_zone_device *tzd; - tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, - info, - &sun4i_ts_tz_ops); - if (IS_ERR(tzd)) { + info->sensor_device = pdev->dev.parent; + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, + 0, info, + &sun4i_ts_tz_ops); + if (IS_ERR(info->tzd)) { dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(tzd)); - return PTR_ERR(tzd); + PTR_ERR(info->tzd)); + return PTR_ERR(info->tzd); } } else { indio_dev->num_channels = @@ -688,7 +690,13 @@ static int sun4i_gpadc_remove(struct platform_device *pdev) pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF)) + + if (!IS_ENABLED(CONFIG_THERMAL_OF)) + return 0; + + thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd); + + if (!info->no_irq) iio_map_array_unregister(indio_dev); return 0;