cregit-Linux how code gets into the kernel

Release 4.7 drivers/hwmon/hwmon.c

Directory: drivers/hwmon
/*
 * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring
 *
 * This file defines the sysfs class "hwmon", for use by sensors drivers.
 *
 * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
#include <linux/hwmon.h>
#include <linux/gfp.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/string.h>


#define HWMON_ID_PREFIX "hwmon"

#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"


struct hwmon_device {
	
const char *name;
	
struct device dev;
};

#define to_hwmon_device(d) container_of(d, struct hwmon_device, dev)


static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", to_hwmon_device(dev)->name); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck35100.00%1100.00%
Total35100.00%1100.00%

static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *hwmon_dev_attrs[] = { &dev_attr_name.attr, NULL };
static umode_t hwmon_dev_name_is_visible(struct kobject *kobj, struct attribute *attr, int n) { struct device *dev = container_of(kobj, struct device, kobj); if (to_hwmon_device(dev)->name == NULL) return 0; return attr->mode; }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck53100.00%1100.00%
Total53100.00%1100.00%

static struct attribute_group hwmon_dev_attr_group = { .attrs = hwmon_dev_attrs, .is_visible = hwmon_dev_name_is_visible, }; static const struct attribute_group *hwmon_dev_attr_groups[] = { &hwmon_dev_attr_group, NULL };
static void hwmon_dev_release(struct device *dev) { kfree(to_hwmon_device(dev)); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck19100.00%1100.00%
Total19100.00%1100.00%

static struct class hwmon_class = { .name = "hwmon", .owner = THIS_MODULE, .dev_groups = hwmon_dev_attr_groups, .dev_release = hwmon_dev_release, }; static DEFINE_IDA(hwmon_ida); /** * hwmon_device_register_with_groups - register w/ hwmon * @dev: the parent device * @name: hwmon name attribute * @drvdata: driver data to attach to created device * @groups: List of attribute groups to create * * hwmon_device_unregister() must be called when the device is no * longer needed. * * Returns the pointer to the new device. */
struct device * hwmon_device_register_with_groups(struct device *dev, const char *name, void *drvdata, const struct attribute_group **groups) { struct hwmon_device *hwdev; int err, id; /* Do not accept invalid characters in hwmon name attribute */ if (name && (!strlen(name) || strpbrk(name, "-* \t\n"))) return ERR_PTR(-EINVAL); id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); if (id < 0) return ERR_PTR(id); hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL); if (hwdev == NULL) { err = -ENOMEM; goto ida_remove; } hwdev->name = name; hwdev->dev.class = &hwmon_class; hwdev->dev.parent = dev; hwdev->dev.groups = groups; hwdev->dev.of_node = dev ? dev->of_node : NULL; dev_set_drvdata(&hwdev->dev, drvdata); dev_set_name(&hwdev->dev, HWMON_ID_FORMAT, id); err = device_register(&hwdev->dev); if (err) goto free; return &hwdev->dev; free: kfree(hwdev); ida_remove: ida_simple_remove(&hwmon_ida, id); return ERR_PTR(err); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck16269.53%228.57%
mark m. hoffmanmark m. hoffman5322.75%228.57%
jonathan cameronjonathan cameron125.15%114.29%
tony jonestony jones52.15%114.29%
greg kroah-hartmangreg kroah-hartman10.43%114.29%
Total233100.00%7100.00%

EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups); /** * hwmon_device_register - register w/ hwmon * @dev: the device to register * * hwmon_device_unregister() must be called when the device is no * longer needed. * * Returns the pointer to the new device. */
struct device *hwmon_device_register(struct device *dev) { return hwmon_device_register_with_groups(dev, NULL, NULL, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck2291.67%150.00%
mark m. hoffmanmark m. hoffman28.33%150.00%
Total24100.00%2100.00%

EXPORT_SYMBOL_GPL(hwmon_device_register); /** * hwmon_device_unregister - removes the previously registered class device * * @dev: the class device to destroy */
void hwmon_device_unregister(struct device *dev) { int id; if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { device_unregister(dev); ida_simple_remove(&hwmon_ida, id); } else dev_dbg(dev->parent, "hwmon_device_unregister() failed: bad class ID!\n"); }

Contributors

PersonTokensPropCommitsCommitProp
mark m. hoffmanmark m. hoffman4679.31%240.00%
tony jonestony jones712.07%120.00%
kay sieverskay sievers35.17%120.00%
jonathan cameronjonathan cameron23.45%120.00%
Total58100.00%5100.00%

EXPORT_SYMBOL_GPL(hwmon_device_unregister);
static void devm_hwmon_release(struct device *dev, void *res) { struct device *hwdev = *(struct device **)res; hwmon_device_unregister(hwdev); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck34100.00%1100.00%
Total34100.00%1100.00%

/** * devm_hwmon_device_register_with_groups - register w/ hwmon * @dev: the parent device * @name: hwmon name attribute * @drvdata: driver data to attach to created device * @groups: List of attribute groups to create * * Returns the pointer to the new device. The new device is automatically * unregistered with the parent device. */
struct device * devm_hwmon_device_register_with_groups(struct device *dev, const char *name, void *drvdata, const struct attribute_group **groups) { struct device **ptr, *hwdev; if (!dev) return ERR_PTR(-EINVAL); ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return ERR_PTR(-ENOMEM); hwdev = hwmon_device_register_with_groups(dev, name, drvdata, groups); if (IS_ERR(hwdev)) goto error; *ptr = hwdev; devres_add(dev, ptr); return hwdev; error: devres_free(ptr); return hwdev; }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck124100.00%1100.00%
Total124100.00%1100.00%

EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups);
static int devm_hwmon_match(struct device *dev, void *res, void *data) { struct device **hwdev = res; return *hwdev == data; }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck33100.00%1100.00%
Total33100.00%1100.00%

/** * devm_hwmon_device_unregister - removes a previously registered hwmon device * * @dev: the parent device of the device to unregister */
void devm_hwmon_device_unregister(struct device *dev) { WARN_ON(devres_release(dev, devm_hwmon_release, devm_hwmon_match, dev)); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck24100.00%1100.00%
Total24100.00%1100.00%

EXPORT_SYMBOL_GPL(devm_hwmon_device_unregister);
static void __init hwmon_pci_quirks(void) { #if defined CONFIG_X86 && defined CONFIG_PCI struct pci_dev *sb; u16 base; u8 enable; /* Open access to 0x295-0x296 on MSI MS-7031 */ sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL); if (sb) { if (sb->subsystem_vendor == 0x1462 && /* MSI */ sb->subsystem_device == 0x0031) { /* MS-7031 */ pci_read_config_byte(sb, 0x48, &enable); pci_read_config_word(sb, 0x64, &base); if (base == 0 && !(enable & BIT(2))) { dev_info(&sb->dev, "Opening wide generic port at 0x295\n"); pci_write_config_word(sb, 0x64, 0x295); pci_write_config_byte(sb, 0x48, enable | BIT(2)); } } pci_dev_put(sb); } #endif }

Contributors

PersonTokensPropCommitsCommitProp
jean delvarejean delvare141100.00%2100.00%
Total141100.00%2100.00%


static int __init hwmon_init(void) { int err; hwmon_pci_quirks(); err = class_register(&hwmon_class); if (err) { pr_err("couldn't register hwmon sysfs class\n"); return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mark m. hoffmanmark m. hoffman2665.00%125.00%
guenter roeckguenter roeck1025.00%125.00%
jean delvarejean delvare37.50%125.00%
joe perchesjoe perches12.50%125.00%
Total40100.00%4100.00%


static void __exit hwmon_exit(void) { class_unregister(&hwmon_class); }

Contributors

PersonTokensPropCommitsCommitProp
mark m. hoffmanmark m. hoffman1386.67%150.00%
guenter roeckguenter roeck213.33%150.00%
Total15100.00%2100.00%

subsys_initcall(hwmon_init); module_exit(hwmon_exit); MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); MODULE_DESCRIPTION("hardware monitoring sysfs/class support"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck64761.56%425.00%
mark m. hoffmanmark m. hoffman20219.22%212.50%
jean delvarejean delvare14713.99%212.50%
jonathan cameronjonathan cameron161.52%16.25%
tony jonestony jones131.24%16.25%
frans meulenbroeksfrans meulenbroeks100.95%16.25%
joe perchesjoe perches80.76%16.25%
kay sieverskay sievers30.29%16.25%
tim schmielautim schmielau30.29%16.25%
greg kroah-hartmangreg kroah-hartman10.10%16.25%
david brownelldavid brownell10.10%16.25%
Total1051100.00%16100.00%
Directory: drivers/hwmon
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}