1
From: Sujith Thomas <sujith.thomas@intel.com>
3
Generic fan & memory controller sysfs class driver.
4
Fan: Expose state & max_state to /sys/class/fan/<FAN0>
5
ACPI fan driver will register to this class driver.
6
memory_controller : Expose state & max_state to
7
/sys/class/memory_controller/<MEM0>
9
Signed-off-by: Sujith Thomas <sujith.thomas@intel.com>
14
drivers/sysfsclass/Kconfig | 30 +++++
15
drivers/sysfsclass/Makefile | 7 +
16
drivers/sysfsclass/fan_sysfs.c | 200 ++++++++++++++++++++++++++++++++++++++
17
drivers/sysfsclass/memory_sysfs.c | 199 +++++++++++++++++++++++++++++++++++++
18
include/linux/fan.h | 66 ++++++++++++
19
include/linux/memory_controller.h | 75 ++++++++++++++
20
8 files changed, 580 insertions(+)
22
Index: linux-2.6.22/drivers/Kconfig
23
===================================================================
24
--- linux-2.6.22.orig/drivers/Kconfig
25
+++ linux-2.6.22/drivers/Kconfig
26
@@ -12,6 +12,8 @@ source "drivers/parport/Kconfig"
28
source "drivers/pnp/Kconfig"
30
+source "drivers/sysfsclass/Kconfig"
32
source "drivers/block/Kconfig"
34
# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
35
Index: linux-2.6.22/drivers/Makefile
36
===================================================================
37
--- linux-2.6.22.orig/drivers/Makefile
38
+++ linux-2.6.22/drivers/Makefile
39
@@ -9,6 +9,7 @@ obj-$(CONFIG_PCI) += pci/
40
obj-$(CONFIG_PARISC) += parisc/
41
obj-$(CONFIG_RAPIDIO) += rapidio/
43
+obj-$(CONFIG_SYSFS_DEV_CLASS) += sysfsclass/
44
obj-$(CONFIG_ACPI) += acpi/
45
# PnP must come after ACPI since it will eventually need to check if acpi
46
# was used and do nothing if so
47
Index: linux-2.6.22/drivers/sysfsclass/Kconfig
48
===================================================================
50
+++ linux-2.6.22/drivers/sysfsclass/Kconfig
53
+menu "Sysfs device class support"
55
+config SYSFS_DEV_CLASS
56
+ bool "Sysfs device class support"
59
+ Say Y to enable sysfs class driver support for the below devices.
62
+ tristate "Fan class in sysfs"
64
+ depends on SYSFS_DEV_CLASS
66
+ This option enables the support for controlling a generic fan
67
+ from sysfs. Sysfs will have attributes to switch the
68
+ fan speed into different supported states.
71
+ tristate "Memory class in sysfs"
73
+ depends on SYSFS_DEV_CLASS
75
+ This option enables the support for controlling a generic
76
+ memory controller from sysfs. Sysfs will have attributes
77
+ to control the bandwidth of memory controller.
82
Index: linux-2.6.22/drivers/sysfsclass/Makefile
83
===================================================================
85
+++ linux-2.6.22/drivers/sysfsclass/Makefile
88
+# Makefile for the sysfs class device driver support
92
+obj-$(CONFIG_FAN_SYSFS) += fan_sysfs.o
93
+obj-$(CONFIG_MEMORY_SYSFS) += memory_sysfs.o
94
Index: linux-2.6.22/drivers/sysfsclass/fan_sysfs.c
95
===================================================================
97
+++ linux-2.6.22/drivers/sysfsclass/fan_sysfs.c
100
+* fan.c - Fan sysfs driver ($Revision: 1 $)
102
+* Copyright (C) 2006, 2007 Sujith Thomas <sujith.thomas@intel.com>
103
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105
+* This program is free software; you can redistribute it and/or modify
106
+* it under the terms of the GNU General Public License as published by
107
+* the Free Software Foundation; version 2 of the License.
109
+* This program is distributed in the hope that it will be useful, but
110
+* WITHOUT ANY WARRANTY; without even the implied warranty of
111
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
112
+* General Public License for more details.
114
+* You should have received a copy of the GNU General Public License along
115
+* with this program; if not, write to the Free Software Foundation, Inc.,
116
+* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
118
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119
+* Sysfs class driver for fan devices. Exposes attributes for get/set
125
+#include <linux/kernel.h>
126
+#include <linux/module.h>
127
+#include <linux/init.h>
128
+#include <linux/types.h>
129
+#include <linux/pci.h>
130
+#include <linux/fan.h>
132
+MODULE_AUTHOR("Sujith Thomas");
133
+MODULE_DESCRIPTION("Fan sysfs Driver");
134
+MODULE_LICENSE("GPL");
136
+static ssize_t state_show(struct class_device *cdev, char *buf)
138
+ struct fan_device *fd;
142
+ fd = to_fan_device(cdev);
143
+ if (fd->ops && fd->ops->get_cur_state)
144
+ if (fd->ops->get_cur_state(fd, buf))
147
+ return strlen(buf);
150
+static ssize_t state_store(struct class_device *cdev, const char *buf,
153
+ struct fan_device *fd;
158
+ fd = to_fan_device(cdev);
159
+ if (fd->ops && fd->ops->set_cur_state)
160
+ if (fd->ops->set_cur_state(fd, buf))
166
+static ssize_t max_state_show(struct class_device *cdev, char *buf)
168
+ struct fan_device *fd;
172
+ fd = to_fan_device(cdev);
173
+ if (fd->ops && fd->ops->get_max_state)
174
+ if (fd->ops->get_max_state(fd, buf))
177
+ return strlen(buf);
180
+static void fan_class_release(struct class_device *dev)
182
+ struct fan_device *device = to_fan_device(dev);
186
+static struct class fan_class = {
188
+ .release = fan_class_release,
191
+static CLASS_DEVICE_ATTR(state, 0644, state_show, state_store);
192
+static CLASS_DEVICE_ATTR(max_state, 0444, max_state_show, NULL);
194
+static const struct class_device_attribute *fd_class_dev_attribs[] = {
195
+ &class_device_attr_state,
196
+ &class_device_attr_max_state,
200
+ * fan_device_register
201
+ * --------------------------------
202
+ * Method for registering fan class of devices with sysfs
203
+ * name: The name that should appear in sysfs
204
+ * dev : device* on which sysfs folder should appear
205
+ * devdata : Device private context
206
+ * ops : List of call back functions for various attributes
207
+ * Returns either an
208
+ * ERR_PTR() or a pointer to the newly allocated device.
210
+struct fan_device *fan_device_register(const char *name,
211
+ struct device *dev,
212
+ void *devdata, struct fan_ops *ops)
215
+ struct fan_device *new_fd;
218
+ return ERR_PTR(-EINVAL);
220
+ pr_debug("fan_device_alloc: name=%s\n", name);
222
+ new_fd = kzalloc(sizeof(struct fan_device), GFP_KERNEL);
224
+ return ERR_PTR(-ENOMEM);
227
+ new_fd->class_dev.class = &fan_class;
228
+ new_fd->class_dev.dev = dev;
229
+ strlcpy(new_fd->class_dev.class_id, name, KOBJ_NAME_LEN);
230
+ class_set_devdata(&new_fd->class_dev, devdata);
232
+ rc = class_device_register(&new_fd->class_dev);
235
+ return ERR_PTR(rc);
238
+ for (i = 0; i < ARRAY_SIZE(fd_class_dev_attribs); i++) {
239
+ rc = class_device_create_file(&new_fd->class_dev,
240
+ fd_class_dev_attribs[i]);
243
+ class_device_remove_file(&new_fd->class_dev,
244
+ fd_class_dev_attribs
246
+ class_device_unregister(&new_fd->class_dev);
247
+ /* No need to kfree(new_bd) since release()
248
+ method was called */
249
+ return ERR_PTR(rc);
255
+EXPORT_SYMBOL(fan_device_register);
258
+ * fan_device_unregister
259
+ * ----------------------------------
260
+ * Method for unregistering fan devices with sysfs
261
+ * fd: Pointer to fan device
263
+void fan_device_unregister(struct fan_device *fd)
270
+ pr_debug("fan_device_unregister: name=%s\n", fd->class_dev.class_id);
272
+ for (i = 0; i < ARRAY_SIZE(fd_class_dev_attribs); i++)
273
+ class_device_remove_file(&fd->class_dev,
274
+ fd_class_dev_attribs[i]);
278
+ class_device_unregister(&fd->class_dev);
280
+EXPORT_SYMBOL(fan_device_unregister);
282
+static int __init fan_device_init(void)
284
+ return class_register(&fan_class);
287
+static void __exit fan_device_exit(void)
289
+ class_unregister(&fan_class);
293
+ * if this is compiled into the kernel, we need to ensure that the
294
+ * class is registered before users of the class try to register lcd's
297
+postcore_initcall(fan_device_init);
298
+module_exit(fan_device_exit);
299
Index: linux-2.6.22/drivers/sysfsclass/memory_sysfs.c
300
===================================================================
302
+++ linux-2.6.22/drivers/sysfsclass/memory_sysfs.c
305
+* memory_controller.c - Memory controller sysfs driver ($Revision: 1 $)
307
+* Copyright (C) 2006, 2007 Sujith Thomas <sujith.thomas@intel.com>
308
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310
+* This program is free software; you can redistribute it and/or modify
311
+* it under the terms of the GNU General Public License as published by
312
+* the Free Software Foundation; version 2 of the License.
314
+* This program is distributed in the hope that it will be useful, but
315
+* WITHOUT ANY WARRANTY; without even the implied warranty of
316
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
317
+* General Public License for more details.
319
+* You should have received a copy of the GNU General Public License along
320
+* with this program; if not, write to the Free Software Foundation, Inc.,
321
+* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
323
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324
+* Sysfs class driver for memory_controller. Exposes attributes for get/set
330
+#include <linux/kernel.h>
331
+#include <linux/module.h>
332
+#include <linux/init.h>
333
+#include <linux/types.h>
334
+#include <linux/pci.h>
335
+#include <linux/memory_controller.h>
337
+MODULE_AUTHOR("Sujith Thomas");
338
+MODULE_DESCRIPTION("Memory controller sysfs Driver");
339
+MODULE_LICENSE("GPL");
341
+static ssize_t bandwidth_show(struct class_device *cdev, char *buf)
343
+ struct memory_controller_device *mc;
348
+ mc = to_memory_controller_device(cdev);
349
+ if (mc->ops && mc->ops->get_cur_bandwidth)
350
+ if (mc->ops->get_cur_bandwidth(mc, buf))
353
+ return strlen(buf);
356
+static ssize_t bandwidth_store(struct class_device *cdev, const char *buf,
359
+ struct memory_controller_device *mc;
363
+ mc = to_memory_controller_device(cdev);
364
+ if (mc->ops && mc->ops->set_cur_bandwidth)
365
+ if (mc->ops->set_cur_bandwidth(mc, buf))
371
+static ssize_t max_bandwidth_show(struct class_device *cdev, char *buf)
373
+ struct memory_controller_device *mc;
377
+ mc = to_memory_controller_device(cdev);
378
+ if (mc->ops && mc->ops->get_max_bandwidth)
379
+ if (mc->ops->get_max_bandwidth(mc, buf))
382
+ return strlen(buf);
385
+static void memory_controller_class_release(struct class_device *dev)
387
+ struct memory_controller_device *device =
388
+ to_memory_controller_device(dev);
392
+static struct class memory_controller_class = {
393
+ .name = "memory_controller",
394
+ .release = memory_controller_class_release,
397
+static CLASS_DEVICE_ATTR(state, 0644, bandwidth_show, bandwidth_store);
398
+static CLASS_DEVICE_ATTR(max_state, 0444, max_bandwidth_show, NULL);
400
+static const struct class_device_attribute *mc_class_dev_attribs[] = {
401
+ &class_device_attr_state,
402
+ &class_device_attr_max_state,
406
+ * memory_controller_device_register
407
+ * --------------------------------
408
+ * Method for registering memory_controller class of devices with sysfs
409
+ * name: The name that should appear in sysfs
410
+ * dev : device* on which sysfs folder should appear
411
+ * devdata : Device private context
412
+ * ops : List of call back functions for various attributes
413
+ * Returns either an
414
+ * ERR_PTR() or a pointer to the newly allocated device.
416
+struct memory_controller_device *
417
+memory_controller_device_register(const char *name
418
+ , struct device *dev
420
+ , struct memory_controller_ops *ops)
423
+ struct memory_controller_device *new_mc;
426
+ return ERR_PTR(-EINVAL);
428
+ pr_debug("memory_controller_device_alloc: name=%s\n", name);
430
+ new_mc = kzalloc(sizeof(struct memory_controller_device), GFP_KERNEL);
432
+ return ERR_PTR(-ENOMEM);
435
+ new_mc->class_dev.class = &memory_controller_class;
436
+ new_mc->class_dev.dev = dev;
437
+ strlcpy(new_mc->class_dev.class_id, name, KOBJ_NAME_LEN);
438
+ class_set_devdata(&new_mc->class_dev, devdata);
440
+ rc = class_device_register(&new_mc->class_dev);
443
+ return ERR_PTR(rc);
446
+ for (i = 0; i < ARRAY_SIZE(mc_class_dev_attribs); i++) {
447
+ rc = class_device_create_file(&new_mc->class_dev,
448
+ mc_class_dev_attribs[i]);
451
+ class_device_remove_file(&new_mc->class_dev,
452
+ mc_class_dev_attribs
454
+ class_device_unregister(&new_mc->class_dev);
455
+ /* No need to kfree(new_bd) since release()
456
+ method was called */
457
+ return ERR_PTR(rc);
463
+EXPORT_SYMBOL(memory_controller_device_register);
466
+ * memory_controller_device_unregister
467
+ * ----------------------------------
468
+ * Method for unregistering memory_controller devices with sysfs
469
+ * mc: Pointer to memory_controller device
471
+void memory_controller_device_unregister(struct memory_controller_device *mc)
478
+ pr_debug("memory_controller_device_unregister: name=%s\n",
479
+ mc->class_dev.class_id);
481
+ for (i = 0; i < ARRAY_SIZE(mc_class_dev_attribs); i++)
482
+ class_device_remove_file(&mc->class_dev,
483
+ mc_class_dev_attribs[i]);
487
+ class_device_unregister(&mc->class_dev);
489
+EXPORT_SYMBOL(memory_controller_device_unregister);
491
+static int __init memory_controller_device_init(void)
493
+ return class_register(&memory_controller_class);
496
+static void __exit memory_controller_device_exit(void)
498
+ class_unregister(&memory_controller_class);
501
+module_init(memory_controller_device_init);
502
+module_exit(memory_controller_device_exit);
503
Index: linux-2.6.22/include/linux/fan.h
504
===================================================================
506
+++ linux-2.6.22/include/linux/fan.h
509
+* fan.h - Generic fan driver for sysfs ($Revision: 1 $)
511
+* Copyright (C) 2006, 2007 Sujith Thomas <sujith.thomas@intel.com>
512
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
514
+* This program is free software; you can redistribute it and/or modify
515
+* it under the terms of the GNU General Public License as published by
516
+* the Free Software Foundation; version 2 of the License.
518
+* This program is distributed in the hope that it will be useful, but
519
+* WITHOUT ANY WARRANTY; without even the implied warranty of
520
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
521
+* General Public License for more details.
523
+* You should have received a copy of the GNU General Public License along
524
+* with this program; if not, write to the Free Software Foundation, Inc.,
525
+* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
527
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
528
+* Sysfs class driver for fan devices. Exposes attributes for get/set
534
+#include <linux/device.h>
539
+ int (*get_max_state) (struct fan_device *device, char *buf);
540
+ int (*get_cur_state) (struct fan_device *device, char *buf);
541
+ int (*set_cur_state) (struct fan_device *device, const char *buf);
545
+ struct fan_ops *ops;
546
+ struct class sysfs_class; /* '/sys/class' entry */
547
+ struct class_device class_dev; /*class device entry in sys/class*/
551
+ * fan_device_register
552
+ * --------------------------------
553
+ * Method for registering fan class of devices with sysfs
554
+ * name: The name that should appear in sysfs
555
+ * dev : device* on which sysfs folder should appear
556
+ * devdata : Device private context
557
+ * ops : List of call back functions for various attributes
558
+ * Returns either an
559
+ * ERR_PTR() or a pointer to the newly allocated device.
561
+struct fan_device *fan_device_register(const char *name,
562
+ struct device *dev, void *devdata,
563
+ struct fan_ops *ops);
566
+ * fan_device_unregister
567
+ * ----------------------------------
568
+ * Method for unregistering fan devices with sysfs
569
+ * fd: Pointer to fan device
571
+void fan_device_unregister(struct fan_device *device);
573
+#define to_fan_device(obj) container_of(obj, struct fan_device, class_dev)
574
Index: linux-2.6.22/include/linux/memory_controller.h
575
===================================================================
577
+++ linux-2.6.22/include/linux/memory_controller.h
580
+* memory_controller.h - Generic memory controller driver for sysfs
583
+* Copyright (C) 2006, 2007 Sujith Thomas <sujith.thomas@intel.com>
584
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
586
+* This program is free software; you can redistribute it and/or modify
587
+* it under the terms of the GNU General Public License as published by
588
+* the Free Software Foundation; version 2 of the License.
590
+* This program is distributed in the hope that it will be useful, but
591
+* WITHOUT ANY WARRANTY; without even the implied warranty of
592
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
593
+* General Public License for more details.
595
+* You should have received a copy of the GNU General Public License along
596
+* with this program; if not, write to the Free Software Foundation, Inc.,
597
+* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
599
+* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
600
+* Sysfs class driver for memory_controller. Exposes attributes for get/set
606
+#include <linux/device.h>
608
+struct memory_controller_device;
610
+/* Callback functions to the actual memory device driver */
611
+struct memory_controller_ops {
612
+ int (*get_max_bandwidth) (struct memory_controller_device *device,
614
+ int (*get_cur_bandwidth) (struct memory_controller_device *device,
616
+ int (*set_cur_bandwidth) (struct memory_controller_device *device,
620
+struct memory_controller_device {
621
+ struct memory_controller_ops *ops; /* Callback routines */
622
+ struct class sysfs_class; /* '/sys/class' entry*/
623
+ struct class_device class_dev; /*class device entry in sys/class*/
627
+ * memory_controller_device_register
628
+ * --------------------------------
629
+ * Method for registering memory_controller class of devices with sysfs
630
+ * name: The name that should appear in sysfs
631
+ * dev : device* on which sysfs folder should appear
632
+ * devdata : Device private context
633
+ * ops : List of call back functions for various attributes
634
+ * Returns either an
635
+ * ERR_PTR() or a pointer to the newly allocated device.
637
+struct memory_controller_device *
638
+memory_controller_device_register(const char *name
639
+ , struct device *dev
641
+ , struct memory_controller_ops *ops);
644
+ * memory_controller_device_unregister
645
+ * ----------------------------------
646
+ * Method for unregistering memory_controller devices with sysfs
647
+ * mc: Pointer to memory_controller device
649
+void memory_controller_device_unregister(struct memory_controller_device
652
+#define to_memory_controller_device(obj) \
653
+container_of(obj, struct memory_controller_device, class_dev)