Skip to content

Commit 6c54a0a

Browse files
eliasbakkenRobertCNelson
authored andcommitted
Making the uio pruss driver work
1 parent 338fbb3 commit 6c54a0a

File tree

4 files changed

+128
-8
lines changed

4 files changed

+128
-8
lines changed

Documentation/devicetree/bindings/arm/omap/omap.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Optional properties:
2424
- ti,no-reset-on-init: When present, the module should not be reset at init
2525
- ti,no-idle-on-init: When present, the module should not be idled at init
2626
- ti,no-idle: When present, the module is never allowed to idle.
27+
- ti,deassert-hard-reset: list of hwmod and hardware reset line name pairs
28+
(ascii strings) to be deasserted upon device instantiation.
2729

2830
Example:
2931

arch/arm/mach-omap2/omap_device.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
138138
struct omap_device *od;
139139
struct omap_hwmod *oh;
140140
struct device_node *node = pdev->dev.of_node;
141-
const char *oh_name;
142-
int oh_cnt, i, ret = 0;
141+
const char *oh_name, *rst_name;
142+
int oh_cnt, dstr_cnt, i, ret = 0;
143143
bool device_active = false;
144144

145145
oh_cnt = of_property_count_strings(node, "ti,hwmods");
@@ -190,6 +190,26 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
190190
omap_device_enable(pdev);
191191
pm_runtime_set_active(&pdev->dev);
192192
}
193+
dstr_cnt =
194+
of_property_count_strings(node, "ti,deassert-hard-reset");
195+
if (dstr_cnt > 0) {
196+
for (i = 0; i < dstr_cnt; i += 2) {
197+
of_property_read_string_index(
198+
node, "ti,deassert-hard-reset", i,
199+
&oh_name);
200+
of_property_read_string_index(
201+
node, "ti,deassert-hard-reset", i+1,
202+
&rst_name);
203+
oh = omap_hwmod_lookup(oh_name);
204+
if (!oh) {
205+
dev_warn(&pdev->dev,
206+
"Cannot parse deassert property for '%s'\n",
207+
oh_name);
208+
break;
209+
}
210+
omap_hwmod_deassert_hardreset(oh, rst_name);
211+
}
212+
}
193213

194214
odbfd_exit1:
195215
kfree(hwmods);

drivers/uio/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ config UIO_PRUSS
129129
select GENERIC_ALLOCATOR
130130
depends on HAS_IOMEM && HAS_DMA
131131
help
132-
PRUSS driver for OMAPL138/DA850/AM18XX devices
132+
PRUSS driver for OMAPL138/DA850/AM18XX and AM33XX devices
133133
PRUSS driver requires user space components, examples and user space
134134
driver is available from below SVN repo - you may use anonymous login
135135

drivers/uio/uio_pruss.c

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/module.h>
2020
#include <linux/moduleparam.h>
2121
#include <linux/platform_device.h>
22+
#include <linux/of_gpio.h>
2223
#include <linux/uio_driver.h>
2324
#include <linux/platform_data/uio_pruss.h>
2425
#include <linux/io.h>
@@ -27,6 +28,11 @@
2728
#include <linux/sizes.h>
2829
#include <linux/slab.h>
2930
#include <linux/genalloc.h>
31+
#include <linux/of_address.h>
32+
#include <linux/of_device.h>
33+
#include <linux/pinctrl/consumer.h>
34+
#include <linux/err.h>
35+
#include <linux/pm_runtime.h>
3036

3137
#define DRV_NAME "pruss_uio"
3238
#define DRV_VERSION "1.0"
@@ -106,10 +112,12 @@ static void pruss_cleanup(struct device *dev, struct uio_pruss_dev *gdev)
106112
dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr,
107113
gdev->ddr_paddr);
108114
}
115+
#ifdef CONFIG_ARCH_DAVINCI_DA850
109116
if (gdev->sram_vaddr)
110117
gen_pool_free(gdev->sram_pool,
111118
gdev->sram_vaddr,
112119
sram_pool_sz);
120+
#endif
113121
kfree(gdev->info);
114122
clk_disable(gdev->pruss_clk);
115123
clk_put(gdev->pruss_clk);
@@ -121,9 +129,15 @@ static int pruss_probe(struct platform_device *pdev)
121129
struct uio_info *p;
122130
struct uio_pruss_dev *gdev;
123131
struct resource *regs_prussio;
132+
struct resource res;
124133
struct device *dev = &pdev->dev;
125134
int ret = -ENODEV, cnt = 0, len;
126135
struct uio_pruss_pdata *pdata = dev_get_platdata(dev);
136+
struct pinctrl *pinctrl;
137+
138+
int count;
139+
struct device_node *child;
140+
const char *pin_name;
127141

128142
gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
129143
if (!gdev)
@@ -134,7 +148,7 @@ static int pruss_probe(struct platform_device *pdev)
134148
kfree(gdev);
135149
return -ENOMEM;
136150
}
137-
151+
#ifdef CONFIG_ARCH_DAVINCI_DA850
138152
/* Power on PRU in case its not done as part of boot-loader */
139153
gdev->pruss_clk = clk_get(dev, "pruss");
140154
if (IS_ERR(gdev->pruss_clk)) {
@@ -153,8 +167,25 @@ static int pruss_probe(struct platform_device *pdev)
153167
return ret;
154168
}
155169
}
170+
#endif
171+
172+
if (pdev->dev.of_node) {
173+
pm_runtime_enable(&pdev->dev);
174+
ret = pm_runtime_get_sync(&pdev->dev);
175+
if (IS_ERR_VALUE(ret)) {
176+
dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
177+
return ret;
178+
}
156179

157-
regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
180+
ret = of_address_to_resource(pdev->dev.of_node, 0, &res);
181+
if (IS_ERR_VALUE(ret)) {
182+
dev_err(&pdev->dev, "failed to parse DT reg\n");
183+
return ret;
184+
}
185+
regs_prussio = &res;
186+
}
187+
else
188+
regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
158189
if (!regs_prussio) {
159190
dev_err(dev, "No PRUSS I/O resource specified\n");
160191
goto out_free;
@@ -165,7 +196,50 @@ static int pruss_probe(struct platform_device *pdev)
165196
goto out_free;
166197
}
167198

168-
if (pdata->sram_pool) {
199+
200+
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
201+
if (IS_ERR(pinctrl))
202+
dev_warn(&pdev->dev,
203+
"pins are not configured from the driver\n");
204+
else{
205+
count = of_get_child_count(pdev->dev.of_node);
206+
if (!count){
207+
dev_info(&pdev->dev, "No children\n");
208+
return -ENODEV;
209+
}
210+
// Run through all children. They have lables for easy reference.
211+
for_each_child_of_node(pdev->dev.of_node, child){
212+
enum of_gpio_flags flags;
213+
unsigned gpio;
214+
215+
count = of_gpio_count(child);
216+
217+
ret = of_property_count_strings(child, "pin-names");
218+
if (ret < 0) {
219+
dev_err(&pdev->dev, "Failed to get pin-names\n");
220+
continue;
221+
}
222+
if(count != ret){
223+
dev_err(&pdev->dev, "The number of gpios (%d) does not match"\
224+
" the number of pin names (%d)\n", count, ret);
225+
continue;
226+
}
227+
228+
for(cnt=0; cnt<count; cnt++){
229+
ret = of_property_read_string_index(child,
230+
"pin-names", cnt, &pin_name);
231+
if (ret != 0)
232+
dev_err(&pdev->dev, "Error on pin-name #%d\n", cnt);
233+
gpio = of_get_gpio_flags(child, cnt, &flags);
234+
ret = devm_gpio_request_one(&pdev->dev, gpio, flags, pin_name);
235+
if (ret < 0) {
236+
dev_err(dev, "Failed to request GPIO %d (%s) flags: '%d', error %d\n",
237+
gpio, pin_name, flags, ret);
238+
}
239+
}
240+
}
241+
}
242+
if (pdata && pdata->sram_pool) {
169243
gdev->sram_pool = pdata->sram_pool;
170244
gdev->sram_vaddr =
171245
(unsigned long)gen_pool_dma_alloc(gdev->sram_pool,
@@ -190,22 +264,37 @@ static int pruss_probe(struct platform_device *pdev)
190264
goto out_free;
191265
}
192266

193-
gdev->pintc_base = pdata->pintc_base;
267+
if (pdev->dev.of_node) {
268+
ret = of_property_read_u32(pdev->dev.of_node,
269+
"ti,pintc-offset",
270+
&gdev->pintc_base);
271+
if (ret < 0) {
272+
dev_err(&pdev->dev,
273+
"Can't parse ti,pintc-offset property\n");
274+
goto out_free;
275+
}
276+
} else
277+
gdev->pintc_base = pdata->pintc_base;
194278
gdev->hostirq_start = platform_get_irq(pdev, 0);
195279

196280
for (cnt = 0, p = gdev->info; cnt < MAX_PRUSS_EVT; cnt++, p++) {
197281
p->mem[0].addr = regs_prussio->start;
198282
p->mem[0].size = resource_size(regs_prussio);
199283
p->mem[0].memtype = UIO_MEM_PHYS;
200284

285+
#ifdef CONFIG_ARCH_DAVINCI_DA850
201286
p->mem[1].addr = gdev->sram_paddr;
202287
p->mem[1].size = sram_pool_sz;
203288
p->mem[1].memtype = UIO_MEM_PHYS;
204289

205290
p->mem[2].addr = gdev->ddr_paddr;
206291
p->mem[2].size = extram_pool_sz;
207292
p->mem[2].memtype = UIO_MEM_PHYS;
208-
293+
#else
294+
p->mem[1].addr = gdev->ddr_paddr;
295+
p->mem[1].size = extram_pool_sz;
296+
p->mem[1].memtype = UIO_MEM_PHYS;
297+
#endif
209298
p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt);
210299
p->version = DRV_VERSION;
211300

@@ -235,11 +324,20 @@ static int pruss_remove(struct platform_device *dev)
235324
return 0;
236325
}
237326

327+
static const struct of_device_id pruss_dt_ids[] = {
328+
{ .compatible = "ti,pruss-v1", .data = NULL, },
329+
{ .compatible = "ti,pruss-v2", .data = NULL, },
330+
{},
331+
};
332+
MODULE_DEVICE_TABLE(of, pruss_dt_ids);
333+
334+
238335
static struct platform_driver pruss_driver = {
239336
.probe = pruss_probe,
240337
.remove = pruss_remove,
241338
.driver = {
242339
.name = DRV_NAME,
340+
.of_match_table = pruss_dt_ids,
243341
},
244342
};
245343

0 commit comments

Comments
 (0)