xref: /openbmc/linux/drivers/hwmon/hwmon.c (revision 8c65b4a60450590e79a28e9717ceffa9e4debb3f)
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