Skip to content

Commit d50170a

Browse files
oleremgregkh
authored andcommitted
net: dsa: qca: ar9331: fix sleeping function called from invalid context bug
[ Upstream commit 3e47495 ] With lockdep enabled, we will get following warning: ar9331_switch ethernet.1:10 lan0 (uninitialized): PHY [!ahb!ethernet@1a000000!mdio!switch@10:00] driver [Qualcomm Atheros AR9331 built-in PHY] (irq=13) BUG: sleeping function called from invalid context at kernel/locking/mutex.c:935 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 18, name: kworker/0:1 INFO: lockdep is turned off. irq event stamp: 602 hardirqs last enabled at (601): [<8073fde0>] _raw_spin_unlock_irq+0x3c/0x80 hardirqs last disabled at (602): [<8073a4f4>] __schedule+0x184/0x800 softirqs last enabled at (0): [<80080f60>] copy_process+0x578/0x14c8 softirqs last disabled at (0): [<00000000>] 0x0 CPU: 0 PID: 18 Comm: kworker/0:1 Not tainted 5.10.0-rc3-ar9331-00734-g7d644991df0c Freescale#31 Workqueue: events deferred_probe_work_func Stack : 80980000 80980000 8089ef70 80890000 804b5414 80980000 00000002 80b53728 00000000 800d1268 804b5414 ffffffde 00000017 800afe08 81943860 0f5bfc32 00000000 00000000 8089ef70 819436c0 ffffffea 00000000 00000000 00000000 8194390c 808e353c 0000000f 66657272 80980000 00000000 00000000 80890000 804b5414 80980000 00000002 80b53728 00000000 00000000 00000000 80d40000 ... Call Trace: [<80069ce0>] show_stack+0x9c/0x140 [<800afe08>] ___might_sleep+0x220/0x244 [<8073bfb0>] __mutex_lock+0x70/0x374 [<8073c2e0>] mutex_lock_nested+0x2c/0x38 [<804b5414>] regmap_update_bits_base+0x38/0x8c [<804ee584>] regmap_update_bits+0x1c/0x28 [<804ee714>] ar9331_sw_unmask_irq+0x34/0x60 [<800d91f0>] unmask_irq+0x48/0x70 [<800d93d4>] irq_startup+0x114/0x11c [<800d65b4>] __setup_irq+0x4f4/0x6d0 [<800d68a0>] request_threaded_irq+0x110/0x190 [<804e3ef0>] phy_request_interrupt+0x4c/0xe4 [<804df508>] phylink_bringup_phy+0x2c0/0x37c [<804df7bc>] phylink_of_phy_connect+0x118/0x130 [<806c1a64>] dsa_slave_create+0x3d0/0x578 [<806bc4ec>] dsa_register_switch+0x934/0xa20 [<804eef98>] ar9331_sw_probe+0x34c/0x364 [<804eb48c>] mdio_probe+0x44/0x70 [<8049e3b4>] really_probe+0x30c/0x4f4 [<8049ea10>] driver_probe_device+0x264/0x26c [<8049bc10>] bus_for_each_drv+0xb4/0xd8 [<8049e684>] __device_attach+0xe8/0x18c [<8049ce58>] bus_probe_device+0x48/0xc4 [<8049db70>] deferred_probe_work_func+0xdc/0xf8 [<8009ff64>] process_one_work+0x2e4/0x4a0 [<800a0770>] worker_thread+0x2a8/0x354 [<800a774c>] kthread+0x16c/0x174 [<8006306c>] ret_from_kernel_thread+0x14/0x1c ar9331_switch ethernet.1:10 lan1 (uninitialized): PHY [!ahb!ethernet@1a000000!mdio!switch@10:02] driver [Qualcomm Atheros AR9331 built-in PHY] (irq=13) DSA: tree 0 setup To fix it, it is better to move access to MDIO register to the .irq_bus_sync_unlock call back. Fixes: ec6698c ("net: dsa: add support for Atheros AR9331 built-in switch") Signed-off-by: Oleksij Rempel <[email protected]> Reviewed-by: Vladimir Oltean <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent bc79bf6 commit d50170a

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

drivers/net/dsa/qca/ar9331.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ struct ar9331_sw_priv {
159159
struct dsa_switch ds;
160160
struct dsa_switch_ops ops;
161161
struct irq_domain *irqdomain;
162+
u32 irq_mask;
163+
struct mutex lock_irq;
162164
struct mii_bus *mbus; /* mdio master */
163165
struct mii_bus *sbus; /* mdio slave */
164166
struct regmap *regmap;
@@ -520,32 +522,44 @@ static irqreturn_t ar9331_sw_irq(int irq, void *data)
520522
static void ar9331_sw_mask_irq(struct irq_data *d)
521523
{
522524
struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
523-
struct regmap *regmap = priv->regmap;
524-
int ret;
525525

526-
ret = regmap_update_bits(regmap, AR9331_SW_REG_GINT_MASK,
527-
AR9331_SW_GINT_PHY_INT, 0);
528-
if (ret)
529-
dev_err(priv->dev, "could not mask IRQ\n");
526+
priv->irq_mask = 0;
530527
}
531528

532529
static void ar9331_sw_unmask_irq(struct irq_data *d)
530+
{
531+
struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
532+
533+
priv->irq_mask = AR9331_SW_GINT_PHY_INT;
534+
}
535+
536+
static void ar9331_sw_irq_bus_lock(struct irq_data *d)
537+
{
538+
struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
539+
540+
mutex_lock(&priv->lock_irq);
541+
}
542+
543+
static void ar9331_sw_irq_bus_sync_unlock(struct irq_data *d)
533544
{
534545
struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
535546
struct regmap *regmap = priv->regmap;
536547
int ret;
537548

538549
ret = regmap_update_bits(regmap, AR9331_SW_REG_GINT_MASK,
539-
AR9331_SW_GINT_PHY_INT,
540-
AR9331_SW_GINT_PHY_INT);
550+
AR9331_SW_GINT_PHY_INT, priv->irq_mask);
541551
if (ret)
542-
dev_err(priv->dev, "could not unmask IRQ\n");
552+
dev_err(priv->dev, "failed to change IRQ mask\n");
553+
554+
mutex_unlock(&priv->lock_irq);
543555
}
544556

545557
static struct irq_chip ar9331_sw_irq_chip = {
546558
.name = AR9331_SW_NAME,
547559
.irq_mask = ar9331_sw_mask_irq,
548560
.irq_unmask = ar9331_sw_unmask_irq,
561+
.irq_bus_lock = ar9331_sw_irq_bus_lock,
562+
.irq_bus_sync_unlock = ar9331_sw_irq_bus_sync_unlock,
549563
};
550564

551565
static int ar9331_sw_irq_map(struct irq_domain *domain, unsigned int irq,
@@ -584,6 +598,7 @@ static int ar9331_sw_irq_init(struct ar9331_sw_priv *priv)
584598
return irq ? irq : -EINVAL;
585599
}
586600

601+
mutex_init(&priv->lock_irq);
587602
ret = devm_request_threaded_irq(dev, irq, NULL, ar9331_sw_irq,
588603
IRQF_ONESHOT, AR9331_SW_NAME, priv);
589604
if (ret) {

0 commit comments

Comments
 (0)