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
3440static int sram_pool_sz = SZ_16K ;
3541module_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
3846static int extram_pool_sz = SZ_256K ;
3947module_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
6371struct 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
7685static 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
95104static 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
119131static 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
227271err_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 );
233277err_free_ddr_vaddr :
234278 dma_free_coherent (dev , extram_pool_sz , gdev -> ddr_vaddr ,
235279 gdev -> ddr_paddr );
236280err_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 );
239284err_clk_disable :
240285 clk_disable (gdev -> pruss_clk );
241286err_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
245293err_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+
259314static 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