linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Paul Osmialowski <p.osmialowsk@samsung.com>,
	Krzysztof Kozlowski <k.kozlowski@samsung.com>,
	Wolfram Sang <wsa@the-dreams.de>
Subject: [PATCH 3.18 25/57] i2c: s3c2410: fix ABBA deadlock by keeping clock prepared
Date: Tue,  3 Feb 2015 15:14:16 -0800	[thread overview]
Message-ID: <20150203231215.619724976@linuxfoundation.org> (raw)
In-Reply-To: <20150203231211.486950145@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Paul Osmialowski <p.osmialowsk@samsung.com>

commit 34e81ad5f0b60007c95995eb7803da7e00c6c611 upstream.

This patch solves deadlock between clock prepare mutex and regmap mutex reported
by Tomasz Figa in [1] by implementing solution from [2]: "always leave the clock
of the i2c controller in a prepared state".

[1] https://lkml.org/lkml/2014/7/2/171
[2] https://lkml.org/lkml/2014/7/2/207

On each i2c transfer handled by s3c24xx_i2c_xfer(), clk_prepare_enable() was
called, which calls clk_prepare() then clk_enable(). clk_prepare() takes
prepare_lock mutex before proceeding. Note that i2c transfer functions are
invoked from many places in kernel, typically with some other additional lock
held.

It may happen that function on CPU1 (e.g. regmap_update_bits()) has taken a
mutex (i.e. regmap lock mutex) then it attempts i2c communication in order to
proceed (so it needs to obtain clock related prepare_lock mutex during transfer
preparation stage due to clk_prepare() call). At the same time other task on
CPU0 wants to operate on clock (e.g. to (un)prepare clock for some other reason)
so it has taken prepare_lock mutex.

CPU0:                        CPU1:
clk_disable_unused()         regulator_disable()
  clk_prepare_lock()           map->lock(map->lock_arg)
  regmap_read()                s3c24xx_i2c_xfer()
    map->lock(map->lock_arg)     clk_prepare_lock()

Implemented solution from [2] leaves i2c clock prepared. Preparation is done in
s3c24xx_i2c_probe() function. Without this patch, it is immediately unprepared
by clk_disable_unprepare() call. I've replaced this call with clk_disable() and
I've added clk_unprepare() call in s3c24xx_i2c_remove().

The s3c24xx_i2c_xfer() function now uses clk_enable() instead of
clk_prepare_enable() (and clk_disable() instead of clk_unprepare_disable()).

Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/i2c/busses/i2c-s3c2410.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -778,14 +778,16 @@ static int s3c24xx_i2c_xfer(struct i2c_a
 	int ret;
 
 	pm_runtime_get_sync(&adap->dev);
-	clk_prepare_enable(i2c->clk);
+	ret = clk_enable(i2c->clk);
+	if (ret)
+		return ret;
 
 	for (retry = 0; retry < adap->retries; retry++) {
 
 		ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
 
 		if (ret != -EAGAIN) {
-			clk_disable_unprepare(i2c->clk);
+			clk_disable(i2c->clk);
 			pm_runtime_put(&adap->dev);
 			return ret;
 		}
@@ -795,7 +797,7 @@ static int s3c24xx_i2c_xfer(struct i2c_a
 		udelay(100);
 	}
 
-	clk_disable_unprepare(i2c->clk);
+	clk_disable(i2c->clk);
 	pm_runtime_put(&adap->dev);
 	return -EREMOTEIO;
 }
@@ -1174,7 +1176,7 @@ static int s3c24xx_i2c_probe(struct plat
 
 	clk_prepare_enable(i2c->clk);
 	ret = s3c24xx_i2c_init(i2c);
-	clk_disable_unprepare(i2c->clk);
+	clk_disable(i2c->clk);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "I2C controller init failed\n");
 		return ret;
@@ -1187,6 +1189,7 @@ static int s3c24xx_i2c_probe(struct plat
 		i2c->irq = ret = platform_get_irq(pdev, 0);
 		if (ret <= 0) {
 			dev_err(&pdev->dev, "cannot find IRQ\n");
+			clk_unprepare(i2c->clk);
 			return ret;
 		}
 
@@ -1195,6 +1198,7 @@ static int s3c24xx_i2c_probe(struct plat
 
 		if (ret != 0) {
 			dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
+			clk_unprepare(i2c->clk);
 			return ret;
 		}
 	}
@@ -1202,6 +1206,7 @@ static int s3c24xx_i2c_probe(struct plat
 	ret = s3c24xx_i2c_register_cpufreq(i2c);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
+		clk_unprepare(i2c->clk);
 		return ret;
 	}
 
@@ -1218,6 +1223,7 @@ static int s3c24xx_i2c_probe(struct plat
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to add bus to i2c core\n");
 		s3c24xx_i2c_deregister_cpufreq(i2c);
+		clk_unprepare(i2c->clk);
 		return ret;
 	}
 
@@ -1239,6 +1245,8 @@ static int s3c24xx_i2c_remove(struct pla
 {
 	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
 
+	clk_unprepare(i2c->clk);
+
 	pm_runtime_disable(&i2c->adap.dev);
 	pm_runtime_disable(&pdev->dev);
 
@@ -1267,10 +1275,13 @@ static int s3c24xx_i2c_resume_noirq(stru
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+	int ret;
 
-	clk_prepare_enable(i2c->clk);
+	ret = clk_enable(i2c->clk);
+	if (ret)
+		return ret;
 	s3c24xx_i2c_init(i2c);
-	clk_disable_unprepare(i2c->clk);
+	clk_disable(i2c->clk);
 	i2c->suspended = 0;
 
 	return 0;



  parent reply	other threads:[~2015-02-03 23:15 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-03 23:13 [PATCH 3.18 00/57] 3.18.6-stable review Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 01/57] x86, build: replace Perl script with Shell script Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 02/57] spi: dw: Fix detecting FIFO depth Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 03/57] spi: dw-mid: fix FIFO size Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 04/57] vm: add VM_FAULT_SIGSEGV handling support Greg Kroah-Hartman
2015-02-10  8:22   ` Konstantin Khlebnikov
2015-02-11  3:43     ` Greg Kroah-Hartman
2015-02-11  3:49       ` Linus Torvalds
2015-02-11  4:16         ` Greg Kroah-Hartman
2015-02-11  5:34       ` Konstantin Khlebnikov
2015-02-16  9:50     ` Luis Henriques
2015-02-03 23:13 ` [PATCH 3.18 05/57] arc: mm: Fix build failure Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 06/57] vm: make stack guard page errors return VM_FAULT_SIGSEGV rather than SIGBUS Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 07/57] ASoC: wm8960: Fix capture sample rate from 11250 to 11025 Greg Kroah-Hartman
2015-02-03 23:13 ` [PATCH 3.18 08/57] ASoC: pcm512x: Fix DSP program selection Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 09/57] ASoC: fsl_esai: Fix incorrect xDC field width of xCCR registers Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 10/57] ASoC: soc-compress.c: fix NULL dereference Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 11/57] ASoC: simple-card: Fix crash in asoc_simple_card_unref() Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 12/57] ASoC: omap-mcbsp: Correct CBM_CFS dai format configuration Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 13/57] udf: Release preallocation on last writeable close Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 14/57] can: kvaser_usb: Do not sleep in atomic context Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 15/57] can: kvaser_usb: Send correct context to URB completion Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 16/57] can: kvaser_usb: Retry the first bulk transfer on -ETIMEDOUT Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 17/57] can: kvaser_usb: Fix state handling upon BUS_ERROR events Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 18/57] powerpc/xmon: Fix another endiannes issue in RTAS call from xmon Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 19/57] ALSA: seq-dummy: remove deadlock-causing events on close Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 20/57] rbd: drop parent_ref in rbd_dev_unprobe() unconditionally Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 21/57] rbd: fix rbd_dev_parent_get() when parent_overlap == 0 Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 22/57] USB: Add OTG PET device to TPL Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 23/57] usb-storage/SCSI: blacklist FUA on JMicron 152d:2566 USB-SATA controller Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 24/57] uas: Add no-report-opcodes quirk for Simpletech devices with id 4971:8017 Greg Kroah-Hartman
2015-02-03 23:14 ` Greg Kroah-Hartman [this message]
2015-02-03 23:14 ` [PATCH 3.18 26/57] Input: synaptics - adjust min/max for Lenovo ThinkPad X1 Carbon 2nd Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 27/57] Input: elantech - add more Fujtisu notebooks to force crc_enabled Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 28/57] Input: i8042 - add noloop quirk for Medion Akoya E7225 (MD98857) Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 29/57] nfs: fix dio deadlock when O_DIRECT flag is flipped Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 30/57] NFSv4.1: Fix an Oops in nfs41_walk_client_list Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 31/57] mac80211: properly set CCK flag in radiotap Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 32/57] mac80211: only roll back station states for WDS when suspending Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 33/57] nl80211: fix per-station group key get/del and memory leak Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 34/57] pinctrl: at91: allow to have disabled gpio bank Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 35/57] ARM: mvebu: dont set the PL310 in I/O coherency mode when I/O coherency is disabled Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 36/57] dm thin: dont allow messages to be sent to a pool target in READ_ONLY or FAIL mode Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 37/57] dm cache: fix missing ERR_PTR returns and handling Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 38/57] drm/vmwgfx: Replace the hw mutex with a hw spinlock Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 41/57] spi/pxa2xx: Clear cur_chip pointer before starting next message Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 42/57] drivers/rtc/rtc-s5m.c: terminate s5m_rtc_id array with empty element Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 43/57] regulator: core: fix race condition in regulator_put() Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 44/57] drivers: net: cpsw: discard dual emac default vlan configuration Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 45/57] drm: fix fb-helper vs MST dangling connector ptrs (v2) Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 46/57] drm/i915: Only fence tiled region of object Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 47/57] drm/i915: BDW Fix Halo PCI IDs marked as ULT Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 48/57] drm/i915: Init PPGTT before context enable Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 49/57] drm/i915: fix inconsistent brightness after resume Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 50/57] quota: Switch ->get_dqblk() and ->set_dqblk() to use bytes as space units Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 51/57] memcg: remove extra newlines from memcg oom kill log Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 52/57] perf/x86/intel: Add model number for Airmont Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 53/57] perf/rapl: Fix crash in rapl_scale() Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 54/57] HID: rmi: Check for additional ACM registers appended to F11 data report Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 55/57] can: c_can: end pending transmission on network stop (ifdown) Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 56/57] clocksource: arch_timer: Only use the virtual counter (CNTVCT) on arm64 Greg Kroah-Hartman
2015-02-03 23:14 ` [PATCH 3.18 57/57] xen/arm/arm64: introduce xen_arch_need_swiotlb Greg Kroah-Hartman
2015-02-04 14:03 ` [PATCH 3.18 00/57] 3.18.6-stable review Guenter Roeck
2015-02-04 19:22   ` Greg Kroah-Hartman
2015-02-04 17:30 ` Shuah Khan
2015-02-04 19:22   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150203231215.619724976@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=k.kozlowski@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.osmialowsk@samsung.com \
    --cc=stable@vger.kernel.org \
    --cc=wsa@the-dreams.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).