11236441fSMark M. Hoffman /* 21236441fSMark M. Hoffman hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring 31236441fSMark M. Hoffman 41236441fSMark M. Hoffman This file defines the sysfs class "hwmon", for use by sensors drivers. 51236441fSMark M. Hoffman 61236441fSMark M. Hoffman Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> 71236441fSMark M. Hoffman 81236441fSMark M. Hoffman This program is free software; you can redistribute it and/or modify 91236441fSMark M. Hoffman it under the terms of the GNU General Public License as published by 101236441fSMark M. Hoffman the Free Software Foundation; version 2 of the License. 111236441fSMark M. Hoffman */ 121236441fSMark M. Hoffman 131236441fSMark M. Hoffman #include <linux/module.h> 141236441fSMark M. Hoffman #include <linux/device.h> 151236441fSMark M. Hoffman #include <linux/err.h> 161236441fSMark M. Hoffman #include <linux/kdev_t.h> 171236441fSMark M. Hoffman #include <linux/idr.h> 181236441fSMark M. Hoffman #include <linux/hwmon.h> 19*8c65b4a6STim Schmielau #include <linux/gfp.h> 201236441fSMark M. Hoffman 211236441fSMark M. Hoffman #define HWMON_ID_PREFIX "hwmon" 221236441fSMark M. Hoffman #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 231236441fSMark M. Hoffman 241236441fSMark M. Hoffman static struct class *hwmon_class; 251236441fSMark M. Hoffman 261236441fSMark M. Hoffman static DEFINE_IDR(hwmon_idr); 271236441fSMark M. Hoffman 281236441fSMark M. Hoffman /** 291236441fSMark M. Hoffman * hwmon_device_register - register w/ hwmon sysfs class 301236441fSMark M. Hoffman * @dev: the device to register 311236441fSMark M. Hoffman * 321236441fSMark M. Hoffman * hwmon_device_unregister() must be called when the class device is no 331236441fSMark M. Hoffman * longer needed. 341236441fSMark M. Hoffman * 351236441fSMark M. Hoffman * Returns the pointer to the new struct class device. 361236441fSMark M. Hoffman */ 371236441fSMark M. Hoffman struct class_device *hwmon_device_register(struct device *dev) 381236441fSMark M. Hoffman { 391236441fSMark M. Hoffman struct class_device *cdev; 401236441fSMark M. Hoffman int id; 411236441fSMark M. Hoffman 421236441fSMark M. Hoffman if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0) 431236441fSMark M. Hoffman return ERR_PTR(-ENOMEM); 441236441fSMark M. Hoffman 451236441fSMark M. Hoffman if (idr_get_new(&hwmon_idr, NULL, &id) < 0) 461236441fSMark M. Hoffman return ERR_PTR(-ENOMEM); 471236441fSMark M. Hoffman 481236441fSMark M. Hoffman id = id & MAX_ID_MASK; 4953f46542SGreg Kroah-Hartman cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, 501236441fSMark M. Hoffman HWMON_ID_FORMAT, id); 511236441fSMark M. Hoffman 521236441fSMark M. Hoffman if (IS_ERR(cdev)) 531236441fSMark M. Hoffman idr_remove(&hwmon_idr, id); 541236441fSMark M. Hoffman 551236441fSMark M. Hoffman return cdev; 561236441fSMark M. Hoffman } 571236441fSMark M. Hoffman 581236441fSMark M. Hoffman /** 591236441fSMark M. Hoffman * hwmon_device_unregister - removes the previously registered class device 601236441fSMark M. Hoffman * 611236441fSMark M. Hoffman * @cdev: the class device to destroy 621236441fSMark M. Hoffman */ 631236441fSMark M. Hoffman void hwmon_device_unregister(struct class_device *cdev) 641236441fSMark M. Hoffman { 651236441fSMark M. Hoffman int id; 661236441fSMark M. Hoffman 671236441fSMark M. Hoffman if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) { 681236441fSMark M. Hoffman class_device_unregister(cdev); 691236441fSMark M. Hoffman idr_remove(&hwmon_idr, id); 701236441fSMark M. Hoffman } else 711236441fSMark M. Hoffman dev_dbg(cdev->dev, 721236441fSMark M. Hoffman "hwmon_device_unregister() failed: bad class ID!\n"); 731236441fSMark M. Hoffman } 741236441fSMark M. Hoffman 751236441fSMark M. Hoffman static int __init hwmon_init(void) 761236441fSMark M. Hoffman { 771236441fSMark M. Hoffman hwmon_class = class_create(THIS_MODULE, "hwmon"); 781236441fSMark M. Hoffman if (IS_ERR(hwmon_class)) { 791236441fSMark M. Hoffman printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); 801236441fSMark M. Hoffman return PTR_ERR(hwmon_class); 811236441fSMark M. Hoffman } 821236441fSMark M. Hoffman return 0; 831236441fSMark M. Hoffman } 841236441fSMark M. Hoffman 851236441fSMark M. Hoffman static void __exit hwmon_exit(void) 861236441fSMark M. Hoffman { 871236441fSMark M. Hoffman class_destroy(hwmon_class); 881236441fSMark M. Hoffman } 891236441fSMark M. Hoffman 901236441fSMark M. Hoffman module_init(hwmon_init); 911236441fSMark M. Hoffman module_exit(hwmon_exit); 921236441fSMark M. Hoffman 931236441fSMark M. Hoffman EXPORT_SYMBOL_GPL(hwmon_device_register); 941236441fSMark M. Hoffman EXPORT_SYMBOL_GPL(hwmon_device_unregister); 951236441fSMark M. Hoffman 961236441fSMark M. Hoffman MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); 971236441fSMark M. Hoffman MODULE_DESCRIPTION("hardware monitoring sysfs/class support"); 981236441fSMark M. Hoffman MODULE_LICENSE("GPL"); 991236441fSMark M. Hoffman 100