diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 120 |
1 files changed, 116 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 26bf0552b3cb..18476bf0b580 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" |
@@ -96,13 +97,14 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
96 | { | 97 | { |
97 | struct drm_gem_object *obj = obj_priv->obj; | 98 | struct drm_gem_object *obj = obj_priv->obj; |
98 | 99 | ||
99 | seq_printf(m, " %p: %s %8zd %08x %08x %d %s", | 100 | seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", |
100 | obj, | 101 | obj, |
101 | get_pin_flag(obj_priv), | 102 | get_pin_flag(obj_priv), |
102 | obj->size, | 103 | obj->size, |
103 | obj->read_domains, obj->write_domain, | 104 | obj->read_domains, obj->write_domain, |
104 | obj_priv->last_rendering_seqno, | 105 | obj_priv->last_rendering_seqno, |
105 | obj_priv->dirty ? "dirty" : ""); | 106 | obj_priv->dirty ? " dirty" : "", |
107 | obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | ||
106 | 108 | ||
107 | if (obj->name) | 109 | if (obj->name) |
108 | seq_printf(m, " (name: %d)", obj->name); | 110 | seq_printf(m, " (name: %d)", obj->name); |
@@ -160,7 +162,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
160 | struct drm_device *dev = node->minor->dev; | 162 | struct drm_device *dev = node->minor->dev; |
161 | drm_i915_private_t *dev_priv = dev->dev_private; | 163 | drm_i915_private_t *dev_priv = dev->dev_private; |
162 | 164 | ||
163 | if (!IS_IGDNG(dev)) { | 165 | if (!IS_IRONLAKE(dev)) { |
164 | seq_printf(m, "Interrupt enable: %08x\n", | 166 | seq_printf(m, "Interrupt enable: %08x\n", |
165 | I915_READ(IER)); | 167 | I915_READ(IER)); |
166 | seq_printf(m, "Interrupt identity: %08x\n", | 168 | seq_printf(m, "Interrupt identity: %08x\n", |
@@ -412,6 +414,109 @@ static int i915_registers_info(struct seq_file *m, void *data) { | |||
412 | return 0; | 414 | return 0; |
413 | } | 415 | } |
414 | 416 | ||
417 | static int | ||
418 | i915_wedged_open(struct inode *inode, | ||
419 | struct file *filp) | ||
420 | { | ||
421 | filp->private_data = inode->i_private; | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static ssize_t | ||
426 | i915_wedged_read(struct file *filp, | ||
427 | char __user *ubuf, | ||
428 | size_t max, | ||
429 | loff_t *ppos) | ||
430 | { | ||
431 | struct drm_device *dev = filp->private_data; | ||
432 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
433 | char buf[80]; | ||
434 | int len; | ||
435 | |||
436 | len = snprintf(buf, sizeof (buf), | ||
437 | "wedged : %d\n", | ||
438 | atomic_read(&dev_priv->mm.wedged)); | ||
439 | |||
440 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); | ||
441 | } | ||
442 | |||
443 | static ssize_t | ||
444 | i915_wedged_write(struct file *filp, | ||
445 | const char __user *ubuf, | ||
446 | size_t cnt, | ||
447 | loff_t *ppos) | ||
448 | { | ||
449 | struct drm_device *dev = filp->private_data; | ||
450 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
451 | char buf[20]; | ||
452 | int val = 1; | ||
453 | |||
454 | if (cnt > 0) { | ||
455 | if (cnt > sizeof (buf) - 1) | ||
456 | return -EINVAL; | ||
457 | |||
458 | if (copy_from_user(buf, ubuf, cnt)) | ||
459 | return -EFAULT; | ||
460 | buf[cnt] = 0; | ||
461 | |||
462 | val = simple_strtoul(buf, NULL, 0); | ||
463 | } | ||
464 | |||
465 | DRM_INFO("Manually setting wedged to %d\n", val); | ||
466 | |||
467 | atomic_set(&dev_priv->mm.wedged, val); | ||
468 | if (val) { | ||
469 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
470 | queue_work(dev_priv->wq, &dev_priv->error_work); | ||
471 | } | ||
472 | |||
473 | return cnt; | ||
474 | } | ||
475 | |||
476 | static const struct file_operations i915_wedged_fops = { | ||
477 | .owner = THIS_MODULE, | ||
478 | .open = i915_wedged_open, | ||
479 | .read = i915_wedged_read, | ||
480 | .write = i915_wedged_write, | ||
481 | }; | ||
482 | |||
483 | /* As the drm_debugfs_init() routines are called before dev->dev_private is | ||
484 | * allocated we need to hook into the minor for release. */ | ||
485 | static int | ||
486 | drm_add_fake_info_node(struct drm_minor *minor, | ||
487 | struct dentry *ent, | ||
488 | const void *key) | ||
489 | { | ||
490 | struct drm_info_node *node; | ||
491 | |||
492 | node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); | ||
493 | if (node == NULL) { | ||
494 | debugfs_remove(ent); | ||
495 | return -ENOMEM; | ||
496 | } | ||
497 | |||
498 | node->minor = minor; | ||
499 | node->dent = ent; | ||
500 | node->info_ent = (void *) key; | ||
501 | list_add(&node->list, &minor->debugfs_nodes.list); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | ||
507 | { | ||
508 | struct drm_device *dev = minor->dev; | ||
509 | struct dentry *ent; | ||
510 | |||
511 | ent = debugfs_create_file("i915_wedged", | ||
512 | S_IRUGO | S_IWUSR, | ||
513 | root, dev, | ||
514 | &i915_wedged_fops); | ||
515 | if (IS_ERR(ent)) | ||
516 | return PTR_ERR(ent); | ||
517 | |||
518 | return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); | ||
519 | } | ||
415 | 520 | ||
416 | static struct drm_info_list i915_debugfs_list[] = { | 521 | static struct drm_info_list i915_debugfs_list[] = { |
417 | {"i915_regs", i915_registers_info, 0}, | 522 | {"i915_regs", i915_registers_info, 0}, |
@@ -432,6 +537,12 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
432 | 537 | ||
433 | int i915_debugfs_init(struct drm_minor *minor) | 538 | int i915_debugfs_init(struct drm_minor *minor) |
434 | { | 539 | { |
540 | int ret; | ||
541 | |||
542 | ret = i915_wedged_create(minor->debugfs_root, minor); | ||
543 | if (ret) | ||
544 | return ret; | ||
545 | |||
435 | return drm_debugfs_create_files(i915_debugfs_list, | 546 | return drm_debugfs_create_files(i915_debugfs_list, |
436 | I915_DEBUGFS_ENTRIES, | 547 | I915_DEBUGFS_ENTRIES, |
437 | minor->debugfs_root, minor); | 548 | minor->debugfs_root, minor); |
@@ -441,7 +552,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) | |||
441 | { | 552 | { |
442 | drm_debugfs_remove_files(i915_debugfs_list, | 553 | drm_debugfs_remove_files(i915_debugfs_list, |
443 | I915_DEBUGFS_ENTRIES, minor); | 554 | I915_DEBUGFS_ENTRIES, minor); |
555 | drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, | ||
556 | 1, minor); | ||
444 | } | 557 | } |
445 | 558 | ||
446 | #endif /* CONFIG_DEBUG_FS */ | 559 | #endif /* CONFIG_DEBUG_FS */ |
447 | |||