Skip to content

Commit 06cf6d1

Browse files
mvduinRobertCNelson
authored andcommitted
uio-pruss: cleanups and pruss v2 (pru-icss) support
1 parent 5fd21a2 commit 06cf6d1

File tree

1 file changed

+90
-34
lines changed

1 file changed

+90
-34
lines changed

drivers/uio/uio_pruss.c

Lines changed: 90 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,22 @@
2626
#include <linux/dma-mapping.h>
2727
#include <linux/sizes.h>
2828
#include <linux/slab.h>
29+
#include <linux/of.h>
30+
#ifdef CONFIG_ARCH_DAVINCI_DA850
2931
#include <linux/genalloc.h>
32+
#else
33+
#include <linux/pm_runtime.h>
34+
#endif
3035

3136
#define DRV_NAME "pruss_uio"
3237
#define DRV_VERSION "1.0"
3338

39+
#ifdef CONFIG_ARCH_DAVINCI_DA850
3440
static int sram_pool_sz = SZ_16K;
3541
module_param(sram_pool_sz, int, 0);
36-
MODULE_PARM_DESC(sram_pool_sz, "sram pool size to allocate ");
42+
MODULE_PARM_DESC(sram_pool_sz, "sram pool size to allocate");
43+
#endif
44+
3745

3846
static int extram_pool_sz = SZ_256K;
3947
module_param(extram_pool_sz, int, 0);
@@ -61,22 +69,23 @@ MODULE_PARM_DESC(extram_pool_sz, "external ram pool size to allocate");
6169
#define PINTC_HIER 0x1500
6270

6371
struct uio_pruss_dev {
64-
struct uio_info *info;
65-
struct clk *pruss_clk;
66-
dma_addr_t sram_paddr;
72+
struct uio_info info[MAX_PRUSS_EVT];
6773
dma_addr_t ddr_paddr;
6874
void __iomem *prussio_vaddr;
69-
unsigned long sram_vaddr;
7075
void *ddr_vaddr;
71-
unsigned int hostirq_start;
7276
unsigned int pintc_base;
77+
#ifdef CONFIG_ARCH_DAVINCI_DA850
78+
struct clk *pruss_clk;
7379
struct gen_pool *sram_pool;
80+
dma_addr_t sram_paddr;
81+
unsigned long sram_vaddr;
82+
#endif
7483
};
7584

7685
static irqreturn_t pruss_handler(int irq, struct uio_info *info)
7786
{
7887
struct uio_pruss_dev *gdev = info->priv;
79-
int intr_bit = (irq - gdev->hostirq_start + 2);
88+
int intr_bit = 2 + (info - gdev->info);
8089
int val, intr_mask = (1 << intr_bit);
8190
void __iomem *base = gdev->prussio_vaddr + gdev->pintc_base;
8291
void __iomem *intren_reg = base + PINTC_HIER;
@@ -94,60 +103,66 @@ static irqreturn_t pruss_handler(int irq, struct uio_info *info)
94103

95104
static void pruss_cleanup(struct device *dev, struct uio_pruss_dev *gdev)
96105
{
97-
int cnt;
98-
struct uio_info *p = gdev->info;
106+
int i;
99107

100-
for (cnt = 0; cnt < MAX_PRUSS_EVT; cnt++, p++) {
101-
uio_unregister_device(p);
102-
kfree(p->name);
108+
for (i = 0; i < MAX_PRUSS_EVT; i++) {
109+
uio_unregister_device(&gdev->info[i]);
110+
kfree(gdev->info[i].name);
103111
}
104112
iounmap(gdev->prussio_vaddr);
105113
if (gdev->ddr_vaddr) {
106114
dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr,
107115
gdev->ddr_paddr);
108116
}
117+
#ifdef CONFIG_ARCH_DAVINCI_DA850
109118
if (gdev->sram_vaddr)
110119
gen_pool_free(gdev->sram_pool,
111120
gdev->sram_vaddr,
112121
sram_pool_sz);
113-
kfree(gdev->info);
114122
clk_disable(gdev->pruss_clk);
115123
clk_put(gdev->pruss_clk);
124+
#else
125+
pm_runtime_put(dev);
126+
pm_runtime_disable(dev);
127+
#endif
116128
kfree(gdev);
117129
}
118130

119131
static int pruss_probe(struct platform_device *pdev)
120132
{
121-
struct uio_info *p;
122133
struct uio_pruss_dev *gdev;
123134
struct resource *regs_prussio;
124135
struct device *dev = &pdev->dev;
125-
int ret, cnt, i, len;
136+
int ret, i, len;
126137
struct uio_pruss_pdata *pdata = dev_get_platdata(dev);
127138

128139
gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
129140
if (!gdev)
130141
return -ENOMEM;
131142

132-
gdev->info = kcalloc(MAX_PRUSS_EVT, sizeof(*p), GFP_KERNEL);
133-
if (!gdev->info) {
134-
ret = -ENOMEM;
135-
goto err_free_gdev;
136-
}
137-
143+
#ifdef CONFIG_ARCH_DAVINCI_DA850
138144
/* Power on PRU in case its not done as part of boot-loader */
139145
gdev->pruss_clk = clk_get(dev, "pruss");
140146
if (IS_ERR(gdev->pruss_clk)) {
141147
dev_err(dev, "Failed to get clock\n");
142148
ret = PTR_ERR(gdev->pruss_clk);
143-
goto err_free_info;
149+
goto err_free_gdev;
144150
}
145151

146152
ret = clk_enable(gdev->pruss_clk);
147153
if (ret) {
148154
dev_err(dev, "Failed to enable clock\n");
149155
goto err_clk_put;
150156
}
157+
#else
158+
pm_runtime_enable(dev);
159+
ret = pm_runtime_get_sync(dev);
160+
if (ret < 0) {
161+
dev_err(dev, "pm_runtime_get_sync() failed\n");
162+
pm_runtime_disable(dev);
163+
goto err_free_gdev;
164+
}
165+
#endif
151166

152167
regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
153168
if (!regs_prussio) {
@@ -162,6 +177,18 @@ static int pruss_probe(struct platform_device *pdev)
162177
goto err_clk_disable;
163178
}
164179

180+
if (dev->of_node) {
181+
ret = of_property_read_u32(dev->of_node,
182+
"ti,pintc-offset",
183+
&gdev->pintc_base);
184+
if (ret < 0) {
185+
dev_err(dev, "Can't parse ti,pintc-offset property\n");
186+
goto err_clk_disable;
187+
}
188+
} else
189+
gdev->pintc_base = pdata->pintc_base;
190+
191+
#ifdef CONFIG_ARCH_DAVINCI_DA850
165192
if (pdata->sram_pool) {
166193
gdev->sram_pool = pdata->sram_pool;
167194
gdev->sram_vaddr =
@@ -173,9 +200,10 @@ static int pruss_probe(struct platform_device *pdev)
173200
goto err_clk_disable;
174201
}
175202
}
203+
#endif
176204

177205
gdev->ddr_vaddr = dma_alloc_coherent(dev, extram_pool_sz,
178-
&(gdev->ddr_paddr), GFP_KERNEL | GFP_DMA);
206+
&gdev->ddr_paddr, GFP_KERNEL | GFP_DMA);
179207
if (!gdev->ddr_vaddr) {
180208
dev_err(dev, "Could not allocate external memory\n");
181209
ret = -ENOMEM;
@@ -185,32 +213,48 @@ static int pruss_probe(struct platform_device *pdev)
185213
len = resource_size(regs_prussio);
186214
gdev->prussio_vaddr = ioremap(regs_prussio->start, len);
187215
if (!gdev->prussio_vaddr) {
188-
dev_err(dev, "Can't remap PRUSS I/O address range\n");
216+
dev_err(dev, "Can't remap PRUSS I/O address range\n");
189217
ret = -ENOMEM;
190218
goto err_free_ddr_vaddr;
191219
}
192220

193-
gdev->pintc_base = pdata->pintc_base;
194-
gdev->hostirq_start = platform_get_irq(pdev, 0);
221+
for (i = 0; i < MAX_PRUSS_EVT; i++) {
222+
struct uio_info *p = &gdev->info[i];
195223

196-
for (cnt = 0, p = gdev->info; cnt < MAX_PRUSS_EVT; cnt++, p++) {
224+
p->mem[0].name = "pruss";
197225
p->mem[0].addr = regs_prussio->start;
198226
p->mem[0].size = resource_size(regs_prussio);
199227
p->mem[0].memtype = UIO_MEM_PHYS;
200228

229+
/* note: some userspace code uses hardcoded mem indices... */
230+
#ifdef CONFIG_ARCH_DAVINCI_DA850
231+
p->mem[1].name = "sram";
201232
p->mem[1].addr = gdev->sram_paddr;
202233
p->mem[1].size = sram_pool_sz;
203234
p->mem[1].memtype = UIO_MEM_PHYS;
204235

236+
p->mem[2].name = "ddr";
205237
p->mem[2].addr = gdev->ddr_paddr;
206238
p->mem[2].size = extram_pool_sz;
207239
p->mem[2].memtype = UIO_MEM_PHYS;
240+
#else
241+
p->mem[1].name = "ddr";
242+
p->mem[1].addr = gdev->ddr_paddr;
243+
p->mem[1].size = extram_pool_sz;
244+
p->mem[1].memtype = UIO_MEM_PHYS;
245+
#endif
208246

209-
p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt);
247+
ret = platform_get_irq(pdev, i);
248+
if (ret < 0) {
249+
dev_err(dev, "Failed to obtain irq %d (%d)\n", i, ret);
250+
goto err_unloop;
251+
}
252+
253+
p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", i);
210254
p->version = DRV_VERSION;
211255

212256
/* Register PRUSS IRQ lines */
213-
p->irq = gdev->hostirq_start + cnt;
257+
p->irq = ret;
214258
p->handler = pruss_handler;
215259
p->priv = gdev;
216260

@@ -225,23 +269,27 @@ static int pruss_probe(struct platform_device *pdev)
225269
return 0;
226270

227271
err_unloop:
228-
for (i = 0, p = gdev->info; i < cnt; i++, p++) {
229-
uio_unregister_device(p);
230-
kfree(p->name);
272+
while( --i >= 0 ) {
273+
uio_unregister_device(&gdev->info[i]);
274+
kfree(gdev->info[i].name);
231275
}
232276
iounmap(gdev->prussio_vaddr);
233277
err_free_ddr_vaddr:
234278
dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr,
235279
gdev->ddr_paddr);
236280
err_free_sram:
281+
#ifdef CONFIG_ARCH_DAVINCI_DA850
237282
if (pdata->sram_pool)
238283
gen_pool_free(gdev->sram_pool, gdev->sram_vaddr, sram_pool_sz);
239284
err_clk_disable:
240285
clk_disable(gdev->pruss_clk);
241286
err_clk_put:
242287
clk_put(gdev->pruss_clk);
243-
err_free_info:
244-
kfree(gdev->info);
288+
#else
289+
err_clk_disable:
290+
pm_runtime_put(dev);
291+
pm_runtime_disable(dev);
292+
#endif
245293
err_free_gdev:
246294
kfree(gdev);
247295

@@ -256,11 +304,19 @@ static int pruss_remove(struct platform_device *dev)
256304
return 0;
257305
}
258306

307+
static const struct of_device_id pruss_dt_ids[] = {
308+
{ .compatible = "ti,pruss-v1" },
309+
{ .compatible = "ti,pruss-v2" },
310+
{},
311+
};
312+
MODULE_DEVICE_TABLE(of, pruss_dt_ids);
313+
259314
static struct platform_driver pruss_driver = {
260315
.probe = pruss_probe,
261316
.remove = pruss_remove,
262317
.driver = {
263318
.name = DRV_NAME,
319+
.of_match_table = pruss_dt_ids,
264320
},
265321
};
266322

0 commit comments

Comments
 (0)