Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 989a7241df87526bfef0396567e71ebe53a84ae4 204 lines 5.2 kB view raw
1 2/* 3 * drm_sysfs.c - Modifications to drm_sysfs_class.c to support 4 * extra sysfs attribute from DRM. Normal drm_sysfs_class 5 * does not allow adding attributes. 6 * 7 * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com> 8 * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com> 9 * Copyright (c) 2003-2004 IBM Corp. 10 * 11 * This file is released under the GPLv2 12 * 13 */ 14 15#include <linux/device.h> 16#include <linux/kdev_t.h> 17#include <linux/err.h> 18 19#include "drm_core.h" 20#include "drmP.h" 21 22#define to_drm_device(d) container_of(d, struct drm_device, dev) 23 24/** 25 * drm_sysfs_suspend - DRM class suspend hook 26 * @dev: Linux device to suspend 27 * @state: power state to enter 28 * 29 * Just figures out what the actual struct drm_device associated with 30 * @dev is and calls its suspend hook, if present. 31 */ 32static int drm_sysfs_suspend(struct device *dev, pm_message_t state) 33{ 34 struct drm_device *drm_dev = to_drm_device(dev); 35 36 printk(KERN_ERR "%s\n", __FUNCTION__); 37 38 if (drm_dev->driver->suspend) 39 return drm_dev->driver->suspend(drm_dev, state); 40 41 return 0; 42} 43 44/** 45 * drm_sysfs_resume - DRM class resume hook 46 * @dev: Linux device to resume 47 * 48 * Just figures out what the actual struct drm_device associated with 49 * @dev is and calls its resume hook, if present. 50 */ 51static int drm_sysfs_resume(struct device *dev) 52{ 53 struct drm_device *drm_dev = to_drm_device(dev); 54 55 if (drm_dev->driver->resume) 56 return drm_dev->driver->resume(drm_dev); 57 58 return 0; 59} 60 61/* Display the version of drm_core. This doesn't work right in current design */ 62static ssize_t version_show(struct class *dev, char *buf) 63{ 64 return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR, 65 CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); 66} 67 68static CLASS_ATTR(version, S_IRUGO, version_show, NULL); 69 70/** 71 * drm_sysfs_create - create a struct drm_sysfs_class structure 72 * @owner: pointer to the module that is to "own" this struct drm_sysfs_class 73 * @name: pointer to a string for the name of this class. 74 * 75 * This is used to create DRM class pointer that can then be used 76 * in calls to drm_sysfs_device_add(). 77 * 78 * Note, the pointer created here is to be destroyed when finished by making a 79 * call to drm_sysfs_destroy(). 80 */ 81struct class *drm_sysfs_create(struct module *owner, char *name) 82{ 83 struct class *class; 84 int err; 85 86 class = class_create(owner, name); 87 if (IS_ERR(class)) { 88 err = PTR_ERR(class); 89 goto err_out; 90 } 91 92 class->suspend = drm_sysfs_suspend; 93 class->resume = drm_sysfs_resume; 94 95 err = class_create_file(class, &class_attr_version); 96 if (err) 97 goto err_out_class; 98 99 return class; 100 101err_out_class: 102 class_destroy(class); 103err_out: 104 return ERR_PTR(err); 105} 106 107/** 108 * drm_sysfs_destroy - destroys DRM class 109 * 110 * Destroy the DRM device class. 111 */ 112void drm_sysfs_destroy(void) 113{ 114 if ((drm_class == NULL) || (IS_ERR(drm_class))) 115 return; 116 class_remove_file(drm_class, &class_attr_version); 117 class_destroy(drm_class); 118} 119 120static ssize_t show_dri(struct device *device, struct device_attribute *attr, 121 char *buf) 122{ 123 struct drm_device *dev = to_drm_device(device); 124 if (dev->driver->dri_library_name) 125 return dev->driver->dri_library_name(dev, buf); 126 return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); 127} 128 129static struct device_attribute device_attrs[] = { 130 __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), 131}; 132 133/** 134 * drm_sysfs_device_release - do nothing 135 * @dev: Linux device 136 * 137 * Normally, this would free the DRM device associated with @dev, along 138 * with cleaning up any other stuff. But we do that in the DRM core, so 139 * this function can just return and hope that the core does its job. 140 */ 141static void drm_sysfs_device_release(struct device *dev) 142{ 143 return; 144} 145 146/** 147 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 148 * @dev: DRM device to be added 149 * @head: DRM head in question 150 * 151 * Add a DRM device to the DRM's device model class. We use @dev's PCI device 152 * as the parent for the Linux device, and make sure it has a file containing 153 * the driver we're using (for userspace compatibility). 154 */ 155int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) 156{ 157 int err; 158 int i, j; 159 160 dev->dev.parent = &dev->pdev->dev; 161 dev->dev.class = drm_class; 162 dev->dev.release = drm_sysfs_device_release; 163 dev->dev.devt = head->device; 164 snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); 165 166 err = device_register(&dev->dev); 167 if (err) { 168 DRM_ERROR("device add failed: %d\n", err); 169 goto err_out; 170 } 171 172 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { 173 err = device_create_file(&dev->dev, &device_attrs[i]); 174 if (err) 175 goto err_out_files; 176 } 177 178 return 0; 179 180err_out_files: 181 if (i > 0) 182 for (j = 0; j < i; j++) 183 device_remove_file(&dev->dev, &device_attrs[i]); 184 device_unregister(&dev->dev); 185err_out: 186 187 return err; 188} 189 190/** 191 * drm_sysfs_device_remove - remove DRM device 192 * @dev: DRM device to remove 193 * 194 * This call unregisters and cleans up a class device that was created with a 195 * call to drm_sysfs_device_add() 196 */ 197void drm_sysfs_device_remove(struct drm_device *dev) 198{ 199 int i; 200 201 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) 202 device_remove_file(&dev->dev, &device_attrs[i]); 203 device_unregister(&dev->dev); 204}