summaryrefslogtreecommitdiff
path: root/drivers/input/serio/hp_sdc_mlc.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2007-03-16 07:59:29 +0300
committerDmitry Torokhov <dtor@insightbb.com>2007-03-16 07:59:29 +0300
commit9575499dfebc0f0fbbf122223f02e9e92630661d (patch)
treed43f958bec192f127907ba393762a0a4728fea4c /drivers/input/serio/hp_sdc_mlc.c
parent5a90e5bca96696f1daa0bb0a9db299eb40241ada (diff)
downloadlinux-9575499dfebc0f0fbbf122223f02e9e92630661d.tar.xz
Input: HIL - fix rwlock recursion bug
The following bug happens when insmoding hp_sdc_mlc.ko: HP SDC MLC: Registering the System Domain Controller's HIL MLC. BUG: rwlock recursion on CPU#0, hotplug/1814, 00854734 Backtrace: [<10267560>] _raw_write_lock+0x50/0x88 [<10104008>] _write_lock_irqsave+0x14/0x24 [<008537d4>] hp_sdc_mlc_out+0x38/0x25c [hp_sdc_mlc] [<0084ebd8>] hilse_donode+0x308/0x470 [hil_mlc] [<0084ed80>] hil_mlcs_process+0x40/0x6c [hil_mlc] [<10130f80>] tasklet_action+0x78/0xb8 [<10130cec>] __do_softirq+0x60/0xcc [<1010428c>] __lock_text_end+0x38/0x48 [<10108348>] do_cpu_irq_mask+0xf0/0x11c [<1010b068>] intr_return+0x0/0xc Signed-off-by: Helge Deller <deller@gmx.de> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/serio/hp_sdc_mlc.c')
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c19
1 files changed, 2 insertions, 17 deletions
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index cb0b28877e05..c45ea74d53e4 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -142,14 +142,11 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id,
static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout)
{
- unsigned long flags;
struct hp_sdc_mlc_priv_s *priv;
int rc = 2;
priv = mlc->priv;
- write_lock_irqsave(&mlc->lock, flags);
-
/* Try to down the semaphore */
if (down_trylock(&mlc->isem)) {
struct timeval tv;
@@ -178,21 +175,16 @@ static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout)
wasup:
up(&mlc->isem);
rc = 0;
- goto done;
done:
- write_unlock_irqrestore(&mlc->lock, flags);
return rc;
}
static int hp_sdc_mlc_cts(hil_mlc *mlc)
{
struct hp_sdc_mlc_priv_s *priv;
- unsigned long flags;
priv = mlc->priv;
- write_lock_irqsave(&mlc->lock, flags);
-
/* Try to down the semaphores -- they should be up. */
BUG_ON(down_trylock(&mlc->isem));
BUG_ON(down_trylock(&mlc->osem));
@@ -221,26 +213,21 @@ static int hp_sdc_mlc_cts(hil_mlc *mlc)
priv->tseq[2] = 1;
priv->tseq[3] = 0;
priv->tseq[4] = 0;
- hp_sdc_enqueue_transaction(&priv->trans);
+ __hp_sdc_enqueue_transaction(&priv->trans);
busy:
- write_unlock_irqrestore(&mlc->lock, flags);
return 1;
done:
priv->trans.act.semaphore = &mlc->osem;
up(&mlc->csem);
- write_unlock_irqrestore(&mlc->lock, flags);
return 0;
}
static void hp_sdc_mlc_out(hil_mlc *mlc)
{
struct hp_sdc_mlc_priv_s *priv;
- unsigned long flags;
priv = mlc->priv;
- write_lock_irqsave(&mlc->lock, flags);
-
/* Try to down the semaphore -- it should be up. */
BUG_ON(down_trylock(&mlc->osem));
@@ -250,7 +237,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc)
do_data:
if (priv->emtestmode) {
up(&mlc->osem);
- goto done;
+ return;
}
/* Shouldn't be sending commands when loop may be busy */
BUG_ON(down_trylock(&mlc->csem));
@@ -313,8 +300,6 @@ static void hp_sdc_mlc_out(hil_mlc *mlc)
}
enqueue:
hp_sdc_enqueue_transaction(&priv->trans);
- done:
- write_unlock_irqrestore(&mlc->lock, flags);
}
static int __init hp_sdc_mlc_init(void)