Skip to content

Commit 4c27ac4

Browse files
cyndisthierryreding
authored andcommitted
gpu: host1x: Request syncpoint IRQs only during probe
Syncpoint IRQs are currently requested in a code path that runs during resume. Due to this, we get multiple overlapping registered interrupt handlers as host1x is suspended and resumed. Rearrange interrupt code to only request IRQs during initialization. Signed-off-by: Mikko Perttunen <[email protected]> Signed-off-by: Thierry Reding <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent bad928d commit 4c27ac4

File tree

4 files changed

+30
-35
lines changed

4 files changed

+30
-35
lines changed

drivers/gpu/host1x/dev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/device.h>
1010
#include <linux/iommu.h>
1111
#include <linux/iova.h>
12+
#include <linux/irqreturn.h>
1213
#include <linux/platform_device.h>
1314
#include <linux/reset.h>
1415

@@ -81,6 +82,7 @@ struct host1x_intr_ops {
8182
void (*disable_syncpt_intr)(struct host1x *host, unsigned int id);
8283
void (*disable_all_syncpt_intrs)(struct host1x *host);
8384
int (*free_syncpt_irq)(struct host1x *host);
85+
irqreturn_t (*isr)(int irq, void *dev_id);
8486
};
8587

8688
struct host1x_sid_entry {

drivers/gpu/host1x/hw/intr_hw.c

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,11 @@
66
* Copyright (c) 2010-2013, NVIDIA Corporation.
77
*/
88

9-
#include <linux/interrupt.h>
10-
#include <linux/irq.h>
119
#include <linux/io.h>
1210

1311
#include "../intr.h"
1412
#include "../dev.h"
1513

16-
struct host1x_intr_irq_data {
17-
struct host1x *host;
18-
u32 offset;
19-
};
20-
2114
static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
2215
{
2316
struct host1x_intr_irq_data *irq_data = dev_id;
@@ -54,7 +47,8 @@ static void host1x_intr_disable_all_syncpt_intrs(struct host1x *host)
5447
}
5548
}
5649

57-
static void intr_hw_init(struct host1x *host, u32 cpm)
50+
static int
51+
host1x_intr_init_host_sync(struct host1x *host, u32 cpm)
5852
{
5953
#if HOST1X_HW < 6
6054
/* disable the ip_busy_timeout. this prevents write drops */
@@ -85,32 +79,6 @@ static void intr_hw_init(struct host1x *host, u32 cpm)
8579
host1x_sync_writel(host, irq_index, HOST1X_SYNC_SYNCPT_INTR_DEST(id));
8680
}
8781
#endif
88-
}
89-
90-
static int
91-
host1x_intr_init_host_sync(struct host1x *host, u32 cpm)
92-
{
93-
int err, i;
94-
struct host1x_intr_irq_data *irq_data;
95-
96-
irq_data = devm_kcalloc(host->dev, host->num_syncpt_irqs, sizeof(irq_data[0]), GFP_KERNEL);
97-
if (!irq_data)
98-
return -ENOMEM;
99-
100-
host1x_hw_intr_disable_all_syncpt_intrs(host);
101-
102-
for (i = 0; i < host->num_syncpt_irqs; i++) {
103-
irq_data[i].host = host;
104-
irq_data[i].offset = i;
105-
106-
err = devm_request_irq(host->dev, host->syncpt_irqs[i],
107-
syncpt_thresh_isr, IRQF_SHARED,
108-
"host1x_syncpt", &irq_data[i]);
109-
if (err < 0)
110-
return err;
111-
}
112-
113-
intr_hw_init(host, cpm);
11482

11583
return 0;
11684
}
@@ -144,4 +112,5 @@ static const struct host1x_intr_ops host1x_intr_ops = {
144112
.enable_syncpt_intr = host1x_intr_enable_syncpt_intr,
145113
.disable_syncpt_intr = host1x_intr_disable_syncpt_intr,
146114
.disable_all_syncpt_intrs = host1x_intr_disable_all_syncpt_intrs,
115+
.isr = syncpt_thresh_isr,
147116
};

drivers/gpu/host1x/intr.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
#include <linux/clk.h>
9-
9+
#include <linux/interrupt.h>
1010
#include "dev.h"
1111
#include "fence.h"
1212
#include "intr.h"
@@ -100,7 +100,9 @@ void host1x_intr_handle_interrupt(struct host1x *host, unsigned int id)
100100

101101
int host1x_intr_init(struct host1x *host)
102102
{
103+
struct host1x_intr_irq_data *irq_data;
103104
unsigned int id;
105+
int i, err;
104106

105107
mutex_init(&host->intr_mutex);
106108

@@ -111,6 +113,23 @@ int host1x_intr_init(struct host1x *host)
111113
INIT_LIST_HEAD(&syncpt->fences.list);
112114
}
113115

116+
irq_data = devm_kcalloc(host->dev, host->num_syncpt_irqs, sizeof(irq_data[0]), GFP_KERNEL);
117+
if (!irq_data)
118+
return -ENOMEM;
119+
120+
host1x_hw_intr_disable_all_syncpt_intrs(host);
121+
122+
for (i = 0; i < host->num_syncpt_irqs; i++) {
123+
irq_data[i].host = host;
124+
irq_data[i].offset = i;
125+
126+
err = devm_request_irq(host->dev, host->syncpt_irqs[i],
127+
host->intr_op->isr, IRQF_SHARED,
128+
"host1x_syncpt", &irq_data[i]);
129+
if (err < 0)
130+
return err;
131+
}
132+
114133
return 0;
115134
}
116135

drivers/gpu/host1x/intr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
struct host1x;
1212
struct host1x_syncpt_fence;
1313

14+
struct host1x_intr_irq_data {
15+
struct host1x *host;
16+
u32 offset;
17+
};
18+
1419
/* Initialize host1x sync point interrupt */
1520
int host1x_intr_init(struct host1x *host);
1621

0 commit comments

Comments
 (0)