Skip to content

Commit b176f95

Browse files
Alex Elderdavem330
authored andcommitted
net: ipa: move gsi_irq_init() code into setup
The GSI IRQ handler could be triggered as soon as it is registered with request_irq(). The handler function, gsi_isr(), touches hardware, meaning the IPA clock must be operational. The IPA clock is not operating when the handler is registered (in gsi_irq_init()), so this is a problem. Move the call to request_irq() for the GSI interrupt handler into gsi_irq_setup(), which is called when the IPA clock is known to be operational (and furthermore, the GSI firmware will have been loaded). Request the IRQ at the end of that function, after all interrupt types have been disabled and masked. Move the matching free_irq() call into gsi_irq_teardown(), and get rid of the now empty gsi_irq_exit(), Signed-off-by: Alex Elder <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1657d8a commit b176f95

File tree

1 file changed

+12
-21
lines changed

1 file changed

+12
-21
lines changed

drivers/net/ipa/gsi.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,33 +1303,20 @@ static irqreturn_t gsi_isr(int irq, void *dev_id)
13031303
return IRQ_HANDLED;
13041304
}
13051305

1306+
/* Init function for GSI IRQ lookup; there is no gsi_irq_exit() */
13061307
static int gsi_irq_init(struct gsi *gsi, struct platform_device *pdev)
13071308
{
1308-
struct device *dev = &pdev->dev;
1309-
unsigned int irq;
13101309
int ret;
13111310

13121311
ret = platform_get_irq_byname(pdev, "gsi");
13131312
if (ret <= 0)
13141313
return ret ? : -EINVAL;
13151314

1316-
irq = ret;
1317-
1318-
ret = request_irq(irq, gsi_isr, 0, "gsi", gsi);
1319-
if (ret) {
1320-
dev_err(dev, "error %d requesting \"gsi\" IRQ\n", ret);
1321-
return ret;
1322-
}
1323-
gsi->irq = irq;
1315+
gsi->irq = ret;
13241316

13251317
return 0;
13261318
}
13271319

1328-
static void gsi_irq_exit(struct gsi *gsi)
1329-
{
1330-
free_irq(gsi->irq, gsi);
1331-
}
1332-
13331320
/* Return the transaction associated with a transfer completion event */
13341321
static struct gsi_trans *gsi_event_trans(struct gsi_channel *channel,
13351322
struct gsi_event *event)
@@ -1810,6 +1797,8 @@ static void gsi_channel_teardown(struct gsi *gsi)
18101797
/* Turn off all GSI interrupts initially */
18111798
static int gsi_irq_setup(struct gsi *gsi)
18121799
{
1800+
int ret;
1801+
18131802
/* Writing 1 indicates IRQ interrupts; 0 would be MSI */
18141803
iowrite32(1, gsi->virt + GSI_CNTXT_INTSET_OFFSET);
18151804

@@ -1835,11 +1824,16 @@ static int gsi_irq_setup(struct gsi *gsi)
18351824

18361825
iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET);
18371826

1838-
return 0;
1827+
ret = request_irq(gsi->irq, gsi_isr, 0, "gsi", gsi);
1828+
if (ret)
1829+
dev_err(gsi->dev, "error %d requesting \"gsi\" IRQ\n", ret);
1830+
1831+
return ret;
18391832
}
18401833

18411834
static void gsi_irq_teardown(struct gsi *gsi)
18421835
{
1836+
free_irq(gsi->irq, gsi);
18431837
}
18441838

18451839
/* Get # supported channel and event rings; there is no gsi_ring_teardown() */
@@ -2224,20 +2218,18 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
22242218

22252219
init_completion(&gsi->completion);
22262220

2227-
ret = gsi_irq_init(gsi, pdev);
2221+
ret = gsi_irq_init(gsi, pdev); /* No matching exit required */
22282222
if (ret)
22292223
goto err_iounmap;
22302224

22312225
ret = gsi_channel_init(gsi, count, data);
22322226
if (ret)
2233-
goto err_irq_exit;
2227+
goto err_iounmap;
22342228

22352229
mutex_init(&gsi->mutex);
22362230

22372231
return 0;
22382232

2239-
err_irq_exit:
2240-
gsi_irq_exit(gsi);
22412233
err_iounmap:
22422234
iounmap(gsi->virt_raw);
22432235

@@ -2249,7 +2241,6 @@ void gsi_exit(struct gsi *gsi)
22492241
{
22502242
mutex_destroy(&gsi->mutex);
22512243
gsi_channel_exit(gsi);
2252-
gsi_irq_exit(gsi);
22532244
iounmap(gsi->virt_raw);
22542245
}
22552246

0 commit comments

Comments
 (0)