aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 26bf0552b3cb..9087c4cfb6ba 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/debugfs.h>
30#include "drmP.h" 31#include "drmP.h"
31#include "drm.h" 32#include "drm.h"
32#include "i915_drm.h" 33#include "i915_drm.h"
@@ -412,6 +413,109 @@ static int i915_registers_info(struct seq_file *m, void *data) {
412 return 0; 413 return 0;
413} 414}
414 415
416static int
417i915_wedged_open(struct inode *inode,
418 struct file *filp)
419{
420 filp->private_data = inode->i_private;
421 return 0;
422}
423
424static ssize_t
425i915_wedged_read(struct file *filp,
426 char __user *ubuf,
427 size_t max,
428 loff_t *ppos)
429{
430 struct drm_device *dev = filp->private_data;
431 drm_i915_private_t *dev_priv = dev->dev_private;
432 char buf[80];
433 int len;
434
435 len = snprintf(buf, sizeof (buf),
436 "wedged : %d\n",
437 atomic_read(&dev_priv->mm.wedged));
438
439 return simple_read_from_buffer(ubuf, max, ppos, buf, len);
440}
441
442static ssize_t
443i915_wedged_write(struct file *filp,
444 const char __user *ubuf,
445 size_t cnt,
446 loff_t *ppos)
447{
448 struct drm_device *dev = filp->private_data;
449 drm_i915_private_t *dev_priv = dev->dev_private;
450 char buf[20];
451 int val = 1;
452
453 if (cnt > 0) {
454 if (cnt > sizeof (buf) - 1)
455 return -EINVAL;
456
457 if (copy_from_user(buf, ubuf, cnt))
458 return -EFAULT;
459 buf[cnt] = 0;
460
461 val = simple_strtoul(buf, NULL, 0);
462 }
463
464 DRM_INFO("Manually setting wedged to %d\n", val);
465
466 atomic_set(&dev_priv->mm.wedged, val);
467 if (val) {
468 DRM_WAKEUP(&dev_priv->irq_queue);
469 queue_work(dev_priv->wq, &dev_priv->error_work);
470 }
471
472 return cnt;
473}
474
475static const struct file_operations i915_wedged_fops = {
476 .owner = THIS_MODULE,
477 .open = i915_wedged_open,
478 .read = i915_wedged_read,
479 .write = i915_wedged_write,
480};
481
482/* As the drm_debugfs_init() routines are called before dev->dev_private is
483 * allocated we need to hook into the minor for release. */
484static int
485drm_add_fake_info_node(struct drm_minor *minor,
486 struct dentry *ent,
487 const void *key)
488{
489 struct drm_info_node *node;
490
491 node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
492 if (node == NULL) {
493 debugfs_remove(ent);
494 return -ENOMEM;
495 }
496
497 node->minor = minor;
498 node->dent = ent;
499 node->info_ent = (void *) key;
500 list_add(&node->list, &minor->debugfs_nodes.list);
501
502 return 0;
503}
504
505static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
506{
507 struct drm_device *dev = minor->dev;
508 struct dentry *ent;
509
510 ent = debugfs_create_file("i915_wedged",
511 S_IRUGO | S_IWUSR,
512 root, dev,
513 &i915_wedged_fops);
514 if (IS_ERR(ent))
515 return PTR_ERR(ent);
516
517 return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
518}
415 519
416static struct drm_info_list i915_debugfs_list[] = { 520static struct drm_info_list i915_debugfs_list[] = {
417 {"i915_regs", i915_registers_info, 0}, 521 {"i915_regs", i915_registers_info, 0},
@@ -432,6 +536,12 @@ static struct drm_info_list i915_debugfs_list[] = {
432 536
433int i915_debugfs_init(struct drm_minor *minor) 537int i915_debugfs_init(struct drm_minor *minor)
434{ 538{
539 int ret;
540
541 ret = i915_wedged_create(minor->debugfs_root, minor);
542 if (ret)
543 return ret;
544
435 return drm_debugfs_create_files(i915_debugfs_list, 545 return drm_debugfs_create_files(i915_debugfs_list,
436 I915_DEBUGFS_ENTRIES, 546 I915_DEBUGFS_ENTRIES,
437 minor->debugfs_root, minor); 547 minor->debugfs_root, minor);
@@ -439,9 +549,13 @@ int i915_debugfs_init(struct drm_minor *minor)
439 549
440void i915_debugfs_cleanup(struct drm_minor *minor) 550void i915_debugfs_cleanup(struct drm_minor *minor)
441{ 551{
552 const void *key;
553
442 drm_debugfs_remove_files(i915_debugfs_list, 554 drm_debugfs_remove_files(i915_debugfs_list,
443 I915_DEBUGFS_ENTRIES, minor); 555 I915_DEBUGFS_ENTRIES, minor);
556
557 key = &i915_wedged_fops;
558 drm_debugfs_remove_files((struct drm_info_list *) &key, 1, minor);
444} 559}
445 560
446#endif /* CONFIG_DEBUG_FS */ 561#endif /* CONFIG_DEBUG_FS */
447