.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2015 Robert Jarzmik <robert.jarzmik@free.fr> |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | */ |
---|
8 | 5 | |
---|
9 | 6 | #include <linux/err.h> |
---|
.. | .. |
---|
132 | 129 | spinlock_t phy_lock; /* Phy association */ |
---|
133 | 130 | #ifdef CONFIG_DEBUG_FS |
---|
134 | 131 | struct dentry *dbgfs_root; |
---|
135 | | - struct dentry *dbgfs_state; |
---|
136 | 132 | struct dentry **dbgfs_chan; |
---|
137 | 133 | #endif |
---|
138 | 134 | }; |
---|
.. | .. |
---|
179 | 175 | return 0x1000 + line * 4; |
---|
180 | 176 | } |
---|
181 | 177 | |
---|
182 | | -bool pxad_filter_fn(struct dma_chan *chan, void *param); |
---|
| 178 | +static bool pxad_filter_fn(struct dma_chan *chan, void *param); |
---|
183 | 179 | |
---|
184 | 180 | /* |
---|
185 | 181 | * Debug fs |
---|
.. | .. |
---|
189 | 185 | #include <linux/uaccess.h> |
---|
190 | 186 | #include <linux/seq_file.h> |
---|
191 | 187 | |
---|
192 | | -static int dbg_show_requester_chan(struct seq_file *s, void *p) |
---|
| 188 | +static int requester_chan_show(struct seq_file *s, void *p) |
---|
193 | 189 | { |
---|
194 | 190 | struct pxad_phy *phy = s->private; |
---|
195 | 191 | int i; |
---|
.. | .. |
---|
220 | 216 | #define PXA_DCSR_STR(flag) (dcsr & PXA_DCSR_##flag ? #flag" " : "") |
---|
221 | 217 | #define PXA_DCMD_STR(flag) (dcmd & PXA_DCMD_##flag ? #flag" " : "") |
---|
222 | 218 | |
---|
223 | | -static int dbg_show_descriptors(struct seq_file *s, void *p) |
---|
| 219 | +static int descriptors_show(struct seq_file *s, void *p) |
---|
224 | 220 | { |
---|
225 | 221 | struct pxad_phy *phy = s->private; |
---|
226 | 222 | int i, max_show = 20, burst, width; |
---|
.. | .. |
---|
263 | 259 | return 0; |
---|
264 | 260 | } |
---|
265 | 261 | |
---|
266 | | -static int dbg_show_chan_state(struct seq_file *s, void *p) |
---|
| 262 | +static int chan_state_show(struct seq_file *s, void *p) |
---|
267 | 263 | { |
---|
268 | 264 | struct pxad_phy *phy = s->private; |
---|
269 | 265 | u32 dcsr, dcmd; |
---|
.. | .. |
---|
306 | 302 | return 0; |
---|
307 | 303 | } |
---|
308 | 304 | |
---|
309 | | -static int dbg_show_state(struct seq_file *s, void *p) |
---|
| 305 | +static int state_show(struct seq_file *s, void *p) |
---|
310 | 306 | { |
---|
311 | 307 | struct pxad_device *pdev = s->private; |
---|
312 | 308 | |
---|
.. | .. |
---|
317 | 313 | return 0; |
---|
318 | 314 | } |
---|
319 | 315 | |
---|
320 | | -#define DBGFS_FUNC_DECL(name) \ |
---|
321 | | -static int dbg_open_##name(struct inode *inode, struct file *file) \ |
---|
322 | | -{ \ |
---|
323 | | - return single_open(file, dbg_show_##name, inode->i_private); \ |
---|
324 | | -} \ |
---|
325 | | -static const struct file_operations dbg_fops_##name = { \ |
---|
326 | | - .open = dbg_open_##name, \ |
---|
327 | | - .llseek = seq_lseek, \ |
---|
328 | | - .read = seq_read, \ |
---|
329 | | - .release = single_release, \ |
---|
330 | | -} |
---|
331 | | - |
---|
332 | | -DBGFS_FUNC_DECL(state); |
---|
333 | | -DBGFS_FUNC_DECL(chan_state); |
---|
334 | | -DBGFS_FUNC_DECL(descriptors); |
---|
335 | | -DBGFS_FUNC_DECL(requester_chan); |
---|
| 316 | +DEFINE_SHOW_ATTRIBUTE(state); |
---|
| 317 | +DEFINE_SHOW_ATTRIBUTE(chan_state); |
---|
| 318 | +DEFINE_SHOW_ATTRIBUTE(descriptors); |
---|
| 319 | +DEFINE_SHOW_ATTRIBUTE(requester_chan); |
---|
336 | 320 | |
---|
337 | 321 | static struct dentry *pxad_dbg_alloc_chan(struct pxad_device *pdev, |
---|
338 | 322 | int ch, struct dentry *chandir) |
---|
339 | 323 | { |
---|
340 | 324 | char chan_name[11]; |
---|
341 | | - struct dentry *chan, *chan_state = NULL, *chan_descr = NULL; |
---|
342 | | - struct dentry *chan_reqs = NULL; |
---|
| 325 | + struct dentry *chan; |
---|
343 | 326 | void *dt; |
---|
344 | 327 | |
---|
345 | 328 | scnprintf(chan_name, sizeof(chan_name), "%d", ch); |
---|
346 | 329 | chan = debugfs_create_dir(chan_name, chandir); |
---|
347 | 330 | dt = (void *)&pdev->phys[ch]; |
---|
348 | 331 | |
---|
349 | | - if (chan) |
---|
350 | | - chan_state = debugfs_create_file("state", 0400, chan, dt, |
---|
351 | | - &dbg_fops_chan_state); |
---|
352 | | - if (chan_state) |
---|
353 | | - chan_descr = debugfs_create_file("descriptors", 0400, chan, dt, |
---|
354 | | - &dbg_fops_descriptors); |
---|
355 | | - if (chan_descr) |
---|
356 | | - chan_reqs = debugfs_create_file("requesters", 0400, chan, dt, |
---|
357 | | - &dbg_fops_requester_chan); |
---|
358 | | - if (!chan_reqs) |
---|
359 | | - goto err_state; |
---|
| 332 | + debugfs_create_file("state", 0400, chan, dt, &chan_state_fops); |
---|
| 333 | + debugfs_create_file("descriptors", 0400, chan, dt, &descriptors_fops); |
---|
| 334 | + debugfs_create_file("requesters", 0400, chan, dt, &requester_chan_fops); |
---|
360 | 335 | |
---|
361 | 336 | return chan; |
---|
362 | | - |
---|
363 | | -err_state: |
---|
364 | | - debugfs_remove_recursive(chan); |
---|
365 | | - return NULL; |
---|
366 | 337 | } |
---|
367 | 338 | |
---|
368 | 339 | static void pxad_init_debugfs(struct pxad_device *pdev) |
---|
.. | .. |
---|
370 | 341 | int i; |
---|
371 | 342 | struct dentry *chandir; |
---|
372 | 343 | |
---|
373 | | - pdev->dbgfs_root = debugfs_create_dir(dev_name(pdev->slave.dev), NULL); |
---|
374 | | - if (IS_ERR(pdev->dbgfs_root) || !pdev->dbgfs_root) |
---|
375 | | - goto err_root; |
---|
376 | | - |
---|
377 | | - pdev->dbgfs_state = debugfs_create_file("state", 0400, pdev->dbgfs_root, |
---|
378 | | - pdev, &dbg_fops_state); |
---|
379 | | - if (!pdev->dbgfs_state) |
---|
380 | | - goto err_state; |
---|
381 | | - |
---|
382 | 344 | pdev->dbgfs_chan = |
---|
383 | | - kmalloc_array(pdev->nr_chans, sizeof(*pdev->dbgfs_state), |
---|
| 345 | + kmalloc_array(pdev->nr_chans, sizeof(struct dentry *), |
---|
384 | 346 | GFP_KERNEL); |
---|
385 | 347 | if (!pdev->dbgfs_chan) |
---|
386 | | - goto err_alloc; |
---|
| 348 | + return; |
---|
| 349 | + |
---|
| 350 | + pdev->dbgfs_root = debugfs_create_dir(dev_name(pdev->slave.dev), NULL); |
---|
| 351 | + |
---|
| 352 | + debugfs_create_file("state", 0400, pdev->dbgfs_root, pdev, &state_fops); |
---|
387 | 353 | |
---|
388 | 354 | chandir = debugfs_create_dir("channels", pdev->dbgfs_root); |
---|
389 | | - if (!chandir) |
---|
390 | | - goto err_chandir; |
---|
391 | 355 | |
---|
392 | | - for (i = 0; i < pdev->nr_chans; i++) { |
---|
| 356 | + for (i = 0; i < pdev->nr_chans; i++) |
---|
393 | 357 | pdev->dbgfs_chan[i] = pxad_dbg_alloc_chan(pdev, i, chandir); |
---|
394 | | - if (!pdev->dbgfs_chan[i]) |
---|
395 | | - goto err_chans; |
---|
396 | | - } |
---|
397 | | - |
---|
398 | | - return; |
---|
399 | | -err_chans: |
---|
400 | | -err_chandir: |
---|
401 | | - kfree(pdev->dbgfs_chan); |
---|
402 | | -err_alloc: |
---|
403 | | -err_state: |
---|
404 | | - debugfs_remove_recursive(pdev->dbgfs_root); |
---|
405 | | -err_root: |
---|
406 | | - pr_err("pxad: debugfs is not available\n"); |
---|
407 | 358 | } |
---|
408 | 359 | |
---|
409 | 360 | static void pxad_cleanup_debugfs(struct pxad_device *pdev) |
---|
.. | .. |
---|
1278 | 1229 | |
---|
1279 | 1230 | pxad_cleanup_debugfs(pdev); |
---|
1280 | 1231 | pxad_free_channels(&pdev->slave); |
---|
1281 | | - dma_async_device_unregister(&pdev->slave); |
---|
1282 | 1232 | return 0; |
---|
1283 | 1233 | } |
---|
1284 | 1234 | |
---|
.. | .. |
---|
1299 | 1249 | return -ENOMEM; |
---|
1300 | 1250 | |
---|
1301 | 1251 | for (i = 0; i < nb_phy_chans; i++) |
---|
1302 | | - if (platform_get_irq(op, i) > 0) |
---|
| 1252 | + if (platform_get_irq_optional(op, i) > 0) |
---|
1303 | 1253 | nr_irq++; |
---|
1304 | 1254 | |
---|
1305 | 1255 | for (i = 0; i < nb_phy_chans; i++) { |
---|
1306 | 1256 | phy = &pdev->phys[i]; |
---|
1307 | 1257 | phy->base = pdev->base; |
---|
1308 | 1258 | phy->idx = i; |
---|
1309 | | - irq = platform_get_irq(op, i); |
---|
| 1259 | + irq = platform_get_irq_optional(op, i); |
---|
1310 | 1260 | if ((nr_irq > 1) && (irq > 0)) |
---|
1311 | 1261 | ret = devm_request_irq(&op->dev, irq, |
---|
1312 | 1262 | pxad_chan_handler, |
---|
.. | .. |
---|
1389 | 1339 | init_waitqueue_head(&c->wq_state); |
---|
1390 | 1340 | } |
---|
1391 | 1341 | |
---|
1392 | | - return dma_async_device_register(&pdev->slave); |
---|
| 1342 | + return dmaenginem_async_device_register(&pdev->slave); |
---|
1393 | 1343 | } |
---|
1394 | 1344 | |
---|
1395 | 1345 | static int pxad_probe(struct platform_device *op) |
---|
.. | .. |
---|
1426 | 1376 | "#dma-requests set to default 32 as missing in OF: %d", |
---|
1427 | 1377 | ret); |
---|
1428 | 1378 | nb_requestors = 32; |
---|
1429 | | - }; |
---|
| 1379 | + } |
---|
1430 | 1380 | } else if (pdata && pdata->dma_channels) { |
---|
1431 | 1381 | dma_channels = pdata->dma_channels; |
---|
1432 | 1382 | nb_requestors = pdata->nb_requestors; |
---|
.. | .. |
---|
1494 | 1444 | .remove = pxad_remove, |
---|
1495 | 1445 | }; |
---|
1496 | 1446 | |
---|
1497 | | -bool pxad_filter_fn(struct dma_chan *chan, void *param) |
---|
| 1447 | +static bool pxad_filter_fn(struct dma_chan *chan, void *param) |
---|
1498 | 1448 | { |
---|
1499 | 1449 | struct pxad_chan *c = to_pxad_chan(chan); |
---|
1500 | 1450 | struct pxad_param *p = param; |
---|
.. | .. |
---|
1507 | 1457 | |
---|
1508 | 1458 | return true; |
---|
1509 | 1459 | } |
---|
1510 | | -EXPORT_SYMBOL_GPL(pxad_filter_fn); |
---|
1511 | 1460 | |
---|
1512 | 1461 | module_platform_driver(pxad_driver); |
---|
1513 | 1462 | |
---|