1*1236441fSMark M. Hoffman /* 2*1236441fSMark M. Hoffman hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring 3*1236441fSMark M. Hoffman 4*1236441fSMark M. Hoffman This file defines the sysfs class "hwmon", for use by sensors drivers. 5*1236441fSMark M. Hoffman 6*1236441fSMark M. Hoffman Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> 7*1236441fSMark M. Hoffman 8*1236441fSMark M. Hoffman This program is free software; you can redistribute it and/or modify 9*1236441fSMark M. Hoffman it under the terms of the GNU General Public License as published by 10*1236441fSMark M. Hoffman the Free Software Foundation; version 2 of the License. 11*1236441fSMark M. Hoffman */ 12*1236441fSMark M. Hoffman 13*1236441fSMark M. Hoffman #include <linux/module.h> 14*1236441fSMark M. Hoffman #include <linux/device.h> 15*1236441fSMark M. Hoffman #include <linux/err.h> 16*1236441fSMark M. Hoffman #include <linux/kdev_t.h> 17*1236441fSMark M. Hoffman #include <linux/idr.h> 18*1236441fSMark M. Hoffman #include <linux/hwmon.h> 19*1236441fSMark M. Hoffman 20*1236441fSMark M. Hoffman #define HWMON_ID_PREFIX "hwmon" 21*1236441fSMark M. Hoffman #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 22*1236441fSMark M. Hoffman 23*1236441fSMark M. Hoffman static struct class *hwmon_class; 24*1236441fSMark M. Hoffman 25*1236441fSMark M. Hoffman static DEFINE_IDR(hwmon_idr); 26*1236441fSMark M. Hoffman 27*1236441fSMark M. Hoffman /** 28*1236441fSMark M. Hoffman * hwmon_device_register - register w/ hwmon sysfs class 29*1236441fSMark M. Hoffman * @dev: the device to register 30*1236441fSMark M. Hoffman * 31*1236441fSMark M. Hoffman * hwmon_device_unregister() must be called when the class device is no 32*1236441fSMark M. Hoffman * longer needed. 33*1236441fSMark M. Hoffman * 34*1236441fSMark M. Hoffman * Returns the pointer to the new struct class device. 35*1236441fSMark M. Hoffman */ 36*1236441fSMark M. Hoffman struct class_device *hwmon_device_register(struct device *dev) 37*1236441fSMark M. Hoffman { 38*1236441fSMark M. Hoffman struct class_device *cdev; 39*1236441fSMark M. Hoffman int id; 40*1236441fSMark M. Hoffman 41*1236441fSMark M. Hoffman if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0) 42*1236441fSMark M. Hoffman return ERR_PTR(-ENOMEM); 43*1236441fSMark M. Hoffman 44*1236441fSMark M. Hoffman if (idr_get_new(&hwmon_idr, NULL, &id) < 0) 45*1236441fSMark M. Hoffman return ERR_PTR(-ENOMEM); 46*1236441fSMark M. Hoffman 47*1236441fSMark M. Hoffman id = id & MAX_ID_MASK; 48*1236441fSMark M. Hoffman cdev = class_device_create(hwmon_class, MKDEV(0,0), dev, 49*1236441fSMark M. Hoffman HWMON_ID_FORMAT, id); 50*1236441fSMark M. Hoffman 51*1236441fSMark M. Hoffman if (IS_ERR(cdev)) 52*1236441fSMark M. Hoffman idr_remove(&hwmon_idr, id); 53*1236441fSMark M. Hoffman 54*1236441fSMark M. Hoffman return cdev; 55*1236441fSMark M. Hoffman } 56*1236441fSMark M. Hoffman 57*1236441fSMark M. Hoffman /** 58*1236441fSMark M. Hoffman * hwmon_device_unregister - removes the previously registered class device 59*1236441fSMark M. Hoffman * 60*1236441fSMark M. Hoffman * @cdev: the class device to destroy 61*1236441fSMark M. Hoffman */ 62*1236441fSMark M. Hoffman void hwmon_device_unregister(struct class_device *cdev) 63*1236441fSMark M. Hoffman { 64*1236441fSMark M. Hoffman int id; 65*1236441fSMark M. Hoffman 66*1236441fSMark M. Hoffman if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) { 67*1236441fSMark M. Hoffman class_device_unregister(cdev); 68*1236441fSMark M. Hoffman idr_remove(&hwmon_idr, id); 69*1236441fSMark M. Hoffman } else 70*1236441fSMark M. Hoffman dev_dbg(cdev->dev, 71*1236441fSMark M. Hoffman "hwmon_device_unregister() failed: bad class ID!\n"); 72*1236441fSMark M. Hoffman } 73*1236441fSMark M. Hoffman 74*1236441fSMark M. Hoffman static int __init hwmon_init(void) 75*1236441fSMark M. Hoffman { 76*1236441fSMark M. Hoffman hwmon_class = class_create(THIS_MODULE, "hwmon"); 77*1236441fSMark M. Hoffman if (IS_ERR(hwmon_class)) { 78*1236441fSMark M. Hoffman printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); 79*1236441fSMark M. Hoffman return PTR_ERR(hwmon_class); 80*1236441fSMark M. Hoffman } 81*1236441fSMark M. Hoffman return 0; 82*1236441fSMark M. Hoffman } 83*1236441fSMark M. Hoffman 84*1236441fSMark M. Hoffman static void __exit hwmon_exit(void) 85*1236441fSMark M. Hoffman { 86*1236441fSMark M. Hoffman class_destroy(hwmon_class); 87*1236441fSMark M. Hoffman } 88*1236441fSMark M. Hoffman 89*1236441fSMark M. Hoffman module_init(hwmon_init); 90*1236441fSMark M. Hoffman module_exit(hwmon_exit); 91*1236441fSMark M. Hoffman 92*1236441fSMark M. Hoffman EXPORT_SYMBOL_GPL(hwmon_device_register); 93*1236441fSMark M. Hoffman EXPORT_SYMBOL_GPL(hwmon_device_unregister); 94*1236441fSMark M. Hoffman 95*1236441fSMark M. Hoffman MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); 96*1236441fSMark M. Hoffman MODULE_DESCRIPTION("hardware monitoring sysfs/class support"); 97*1236441fSMark M. Hoffman MODULE_LICENSE("GPL"); 98*1236441fSMark M. Hoffman 99