1919static rt_list_t dmac_nodes = RT_LIST_OBJECT_INIT (dmac_nodes );
2020static RT_DEFINE_SPINLOCK (dmac_nodes_lock );
2121
22+ static void dma_lock (struct rt_dma_controller * ctrl )
23+ {
24+ if (rt_thread_self ())
25+ {
26+ rt_mutex_take (& ctrl -> mutex , RT_WAITING_FOREVER );
27+ }
28+ }
29+
30+ static void dma_unlock (struct rt_dma_controller * ctrl )
31+ {
32+ if (rt_thread_self ())
33+ {
34+ rt_mutex_release (& ctrl -> mutex );
35+ }
36+ }
37+
2238rt_err_t rt_dma_controller_register (struct rt_dma_controller * ctrl )
2339{
2440 const char * dev_name ;
@@ -64,11 +80,11 @@ rt_err_t rt_dma_controller_unregister(struct rt_dma_controller *ctrl)
6480 return - RT_EINVAL ;
6581 }
6682
67- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
83+ dma_lock ( ctrl );
6884
6985 if (!rt_list_isempty (& ctrl -> channels_nodes ))
7086 {
71- rt_mutex_release ( & ctrl -> mutex );
87+ dma_unlock ( ctrl );
7288 return - RT_EBUSY ;
7389 }
7490
@@ -77,7 +93,7 @@ rt_err_t rt_dma_controller_unregister(struct rt_dma_controller *ctrl)
7793 rt_dm_dev_unbind_fwdata (ctrl -> dev , RT_NULL );
7894 }
7995
80- rt_mutex_release ( & ctrl -> mutex );
96+ dma_unlock ( ctrl );
8197 rt_mutex_detach (& ctrl -> mutex );
8298
8399 rt_spin_lock (& dmac_nodes_lock );
@@ -106,11 +122,45 @@ rt_err_t rt_dma_chan_start(struct rt_dma_chan *chan)
106122
107123 ctrl = chan -> ctrl ;
108124
109- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
125+ dma_lock ( ctrl );
110126
111127 err = ctrl -> ops -> start (chan );
112128
113- rt_mutex_release (& ctrl -> mutex );
129+ dma_unlock (ctrl );
130+
131+ return err ;
132+ }
133+
134+ rt_err_t rt_dma_chan_pause (struct rt_dma_chan * chan )
135+ {
136+ rt_err_t err ;
137+ struct rt_dma_controller * ctrl ;
138+
139+ if (!chan )
140+ {
141+ return - RT_EINVAL ;
142+ }
143+
144+ if (!chan -> ctrl -> ops -> pause )
145+ {
146+ LOG_D ("%s: No pause, try stop" , rt_dm_dev_get_name (chan -> ctrl -> dev ));
147+ return rt_dma_chan_stop (chan );
148+ }
149+
150+ if (chan -> prep_err )
151+ {
152+ LOG_D ("%s: Not config done" , rt_dm_dev_get_name (chan -> slave ));
153+
154+ return chan -> prep_err ;
155+ }
156+
157+ ctrl = chan -> ctrl ;
158+
159+ dma_lock (ctrl );
160+
161+ err = ctrl -> ops -> pause (chan );
162+
163+ dma_unlock (ctrl );
114164
115165 return err ;
116166}
@@ -134,11 +184,11 @@ rt_err_t rt_dma_chan_stop(struct rt_dma_chan *chan)
134184
135185 ctrl = chan -> ctrl ;
136186
137- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
187+ dma_lock ( ctrl );
138188
139189 err = ctrl -> ops -> stop (chan );
140190
141- rt_mutex_release ( & ctrl -> mutex );
191+ dma_unlock ( ctrl );
142192
143193 return err ;
144194}
@@ -188,11 +238,11 @@ rt_err_t rt_dma_chan_config(struct rt_dma_chan *chan,
188238 goto _end ;
189239 }
190240
191- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
241+ dma_lock ( ctrl );
192242
193243 err = ctrl -> ops -> config (chan , conf );
194244
195- rt_mutex_release ( & ctrl -> mutex );
245+ dma_unlock ( ctrl );
196246
197247 if (!err )
198248 {
@@ -233,6 +283,19 @@ static rt_bool_t range_is_illegal(const char *name, const char *desc,
233283 return illegal ;
234284}
235285
286+ static rt_bool_t addr_is_supported (const char * name , const char * desc ,
287+ rt_uint64_t mask , rt_ubase_t addr )
288+ {
289+ rt_bool_t illegal = !!(addr & ~mask );
290+
291+ if (illegal )
292+ {
293+ LOG_E ("%s: %s %p is out of mask %p" , name , desc , addr , mask );
294+ }
295+
296+ return illegal ;
297+ }
298+
236299rt_err_t rt_dma_prep_memcpy (struct rt_dma_chan * chan ,
237300 struct rt_dma_slave_transfer * transfer )
238301{
@@ -262,6 +325,18 @@ rt_err_t rt_dma_prep_memcpy(struct rt_dma_chan *chan,
262325 dma_addr_dst = transfer -> dst_addr ;
263326 len = transfer -> buffer_len ;
264327
328+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
329+ ctrl -> addr_mask , conf -> src_addr ))
330+ {
331+ return - RT_ENOSYS ;
332+ }
333+
334+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "dest" ,
335+ ctrl -> addr_mask , conf -> dst_addr ))
336+ {
337+ return - RT_ENOSYS ;
338+ }
339+
265340 if (range_is_illegal (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
266341 dma_addr_src , conf -> src_addr ))
267342 {
@@ -276,11 +351,11 @@ rt_err_t rt_dma_prep_memcpy(struct rt_dma_chan *chan,
276351
277352 if (ctrl -> ops -> prep_memcpy )
278353 {
279- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
354+ dma_lock ( ctrl );
280355
281356 err = ctrl -> ops -> prep_memcpy (chan , dma_addr_src , dma_addr_dst , len );
282357
283- rt_mutex_release ( & ctrl -> mutex );
358+ dma_unlock ( ctrl );
284359 }
285360 else
286361 {
@@ -327,6 +402,12 @@ rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan,
327402 {
328403 dma_buf_addr = transfer -> src_addr ;
329404
405+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
406+ ctrl -> addr_mask , conf -> src_addr ))
407+ {
408+ return - RT_ENOSYS ;
409+ }
410+
330411 if (range_is_illegal (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
331412 dma_buf_addr , conf -> src_addr ))
332413 {
@@ -337,6 +418,12 @@ rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan,
337418 {
338419 dma_buf_addr = transfer -> dst_addr ;
339420
421+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "dest" ,
422+ ctrl -> addr_mask , conf -> dst_addr ))
423+ {
424+ return - RT_ENOSYS ;
425+ }
426+
340427 if (range_is_illegal (rt_dm_dev_get_name (ctrl -> dev ), "dest" ,
341428 dma_buf_addr , conf -> dst_addr ))
342429 {
@@ -350,12 +437,12 @@ rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan,
350437
351438 if (ctrl -> ops -> prep_cyclic )
352439 {
353- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
440+ dma_lock ( ctrl );
354441
355442 err = ctrl -> ops -> prep_cyclic (chan , dma_buf_addr ,
356443 transfer -> buffer_len , transfer -> period_len , dir );
357444
358- rt_mutex_release ( & ctrl -> mutex );
445+ dma_unlock ( ctrl );
359446 }
360447 else
361448 {
@@ -402,6 +489,12 @@ rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan,
402489 {
403490 dma_buf_addr = transfer -> src_addr ;
404491
492+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
493+ ctrl -> addr_mask , conf -> src_addr ))
494+ {
495+ return - RT_ENOSYS ;
496+ }
497+
405498 if (range_is_illegal (rt_dm_dev_get_name (ctrl -> dev ), "source" ,
406499 dma_buf_addr , conf -> src_addr ))
407500 {
@@ -412,6 +505,12 @@ rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan,
412505 {
413506 dma_buf_addr = transfer -> dst_addr ;
414507
508+ if (addr_is_supported (rt_dm_dev_get_name (ctrl -> dev ), "dest" ,
509+ ctrl -> addr_mask , conf -> dst_addr ))
510+ {
511+ return - RT_ENOSYS ;
512+ }
513+
415514 if (range_is_illegal (rt_dm_dev_get_name (ctrl -> dev ), "dest" ,
416515 dma_buf_addr , conf -> dst_addr ))
417516 {
@@ -425,12 +524,12 @@ rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan,
425524
426525 if (ctrl -> ops -> prep_single )
427526 {
428- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
527+ dma_lock ( ctrl );
429528
430529 err = ctrl -> ops -> prep_single (chan , dma_buf_addr ,
431530 transfer -> buffer_len , dir );
432531
433- rt_mutex_release ( & ctrl -> mutex );
532+ dma_unlock ( ctrl );
434533 }
435534 else
436535 {
@@ -556,9 +655,9 @@ struct rt_dma_chan *rt_dma_chan_request(struct rt_device *dev, const char *name)
556655 chan -> conf_err = - RT_ERROR ;
557656 chan -> prep_err = - RT_ERROR ;
558657
559- rt_mutex_take ( & ctrl -> mutex , RT_WAITING_FOREVER );
658+ dma_lock ( ctrl );
560659 rt_list_insert_before (& ctrl -> channels_nodes , & chan -> list );
561- rt_mutex_release ( & ctrl -> mutex );
660+ dma_unlock ( ctrl );
562661
563662 return chan ;
564663}
0 commit comments