| .. | .. |
|---|
| 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 | |
|---|