Linux 硬體監控核心 API

Guenter Roeck

簡介

本文件介紹了希望使用硬體監控框架的硬體監控驅動程式可以使用的 API。

本文件不描述什麼是硬體監控 (hwmon) 驅動程式或裝置。它也不描述使用者空間可以用來與硬體監控裝置通訊的 API。如果您想了解這一點,請閱讀以下檔案:sysfs 檔案的命名和資料格式標準

有關如何編寫和改進 hwmon 驅動程式的更多指南,請閱讀如何使您的補丁被 Hwmon 子系統接受

API

每個硬體監控驅動程式必須 #include <linux/hwmon.h>,在某些情況下,還必須 #include <linux/hwmon-sysfs.h>。 linux/hwmon.h 聲明瞭以下注冊/登出函式

struct device *
hwmon_device_register_with_info(struct device *dev,
                                const char *name, void *drvdata,
                                const struct hwmon_chip_info *info,
                                const struct attribute_group **extra_groups);

struct device *
devm_hwmon_device_register_with_info(struct device *dev,
                                     const char *name,
                                     void *drvdata,
                                     const struct hwmon_chip_info *info,
                                     const struct attribute_group **extra_groups);

void hwmon_device_unregister(struct device *dev);

char *hwmon_sanitize_name(const char *name);

char *devm_hwmon_sanitize_name(struct device *dev, const char *name);

hwmon_device_register_with_info 註冊一個硬體監控裝置。它在硬體監控核心中建立標準的 sysfs 屬性,使驅動程式能夠專注於從晶片讀取和寫入,而不必為 sysfs 屬性而煩惱。父裝置引數以及晶片引數不得為 NULL。其引數在下面有更詳細的描述。

devm_hwmon_device_register_with_info 類似於 hwmon_device_register_with_info。但是,它是裝置管理的,這意味著 hwmon 裝置不必透過移除函式顯式移除。

所有其他硬體監控設備註冊功能都已棄用,不得在新驅動程式中使用。

hwmon_device_unregister 登出已註冊的硬體監控裝置。此函式的引數是指向已註冊的硬體監控裝置結構的指標。如果硬體監控裝置是透過 hwmon_device_register_with_info 註冊的,則必須從驅動程式移除函式中呼叫此函式。

所有受支援的 hwmon 設備註冊函式只接受有效的裝置名稱。包含無效字元(空格、“*”或“-”)的裝置名稱將被拒絕。如果將 NULL 作為 name 引數傳遞,硬體監控裝置名稱將從父裝置名稱派生。

如果驅動程式不使用靜態裝置名稱(例如,它使用 dev_name()),因此無法確保名稱僅包含有效字元,則可以使用 hwmon_sanitize_name。此便利函式將複製字串並將任何無效字元替換為下劃線。它將為新字串分配記憶體,呼叫者有責任在移除裝置時釋放記憶體。

devm_hwmon_sanitize_name 是 hwmon_sanitize_name 的資源管理版本;記憶體將在裝置移除時自動釋放。

使用 devm_hwmon_device_register_with_info()

hwmon_device_register_with_info() 註冊一個硬體監控裝置。此函式的引數是

struct device *dev

指向父裝置的指標

const char *name

裝置名稱

void *drvdata

驅動程式私有資料

const struct hwmon_chip_info *info

指向晶片描述的指標。

const struct attribute_group **extra_groups

附加的非標準 sysfs 屬性組的以 null 結尾的列表。

此函式成功時返回指向已建立的硬體監控裝置的指標,失敗時返回負錯誤程式碼。

hwmon_chip_info 結構如下所示

struct hwmon_chip_info {
        const struct hwmon_ops *ops;
        const struct hwmon_channel_info * const *info;
};

它包含以下欄位

  • ops

    指向裝置操作的指標。

  • info

    以 NULL 結尾的裝置通道描述符列表。

hwmon 操作列表定義為

struct hwmon_ops {
      umode_t (*is_visible)(const void *, enum hwmon_sensor_types type,
                            u32 attr, int);
      int (*read)(struct device *, enum hwmon_sensor_types type,
                  u32 attr, int, long *);
      int (*write)(struct device *, enum hwmon_sensor_types type,
                   u32 attr, int, long);
};

它定義了以下操作。

  • is_visible

    指向為每個受支援的屬性返回檔案模式的函式的指標。此函式是強制性的。

  • read

    指向從晶片讀取值的函式的指標。此函式是可選的,但如果存在任何可讀屬性,則必須提供。

  • write

    指向將值寫入晶片的函式的指標。此函式是可選的,但如果存在任何可寫屬性,則必須提供。

每個感測器通道都使用 struct hwmon_channel_info 描述,其定義如下

struct hwmon_channel_info {
        enum hwmon_sensor_types type;
        u32 *config;
};

它包含以下欄位

  • type

    硬體監控感測器型別。

    支援的感測器型別有

    hwmon_chip

    一種虛擬感測器型別,用於描述未繫結到特定輸入或輸出的屬性

    hwmon_temp

    溫度感測器

    hwmon_in

    電壓感測器

    hwmon_curr

    電流感測器

    hwmon_power

    功率感測器

    hwmon_energy

    能量感測器

    hwmon_humidity

    溼度感測器

    hwmon_fan

    風扇速度感測器

    hwmon_pwm

    PWM 控制

  • config

    指向給定型別的每個感測器的配置值的以 0 結尾的列表的指標。每個值都是描述單個感測器支援的屬性的位值的組合。

例如,這是 LM75 相容感測器晶片的完整描述檔案。該晶片只有一個溫度感測器。驅動程式希望在熱子系統 (HWMON_C_REGISTER_TZ) 中註冊,它支援 update_interval 屬性 (HWMON_C_UPDATE_INTERVAL)。該晶片支援讀取溫度 (HWMON_T_INPUT),它具有最高溫度暫存器 (HWMON_T_MAX) 以及最高溫度滯後暫存器 (HWMON_T_MAX_HYST)

static const u32 lm75_chip_config[] = {
        HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL,
        0
};

static const struct hwmon_channel_info lm75_chip = {
        .type = hwmon_chip,
        .config = lm75_chip_config,
};

static const u32 lm75_temp_config[] = {
        HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST,
        0
};

static const struct hwmon_channel_info lm75_temp = {
        .type = hwmon_temp,
        .config = lm75_temp_config,
};

static const struct hwmon_channel_info * const lm75_info[] = {
        &lm75_chip,
        &lm75_temp,
        NULL
};

The HWMON_CHANNEL_INFO() macro can and should be used when possible.
With this macro, the above example can be simplified to

static const struct hwmon_channel_info * const lm75_info[] = {
        HWMON_CHANNEL_INFO(chip,
                        HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
        HWMON_CHANNEL_INFO(temp,
                        HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
        NULL
};

The remaining declarations are as follows.

static const struct hwmon_ops lm75_hwmon_ops = {
        .is_visible = lm75_is_visible,
        .read = lm75_read,
        .write = lm75_write,
};

static const struct hwmon_chip_info lm75_chip_info = {
        .ops = &lm75_hwmon_ops,
        .info = lm75_info,
};

指示各個屬性支援的位值的完整列表在 include/linux/hwmon.h 中定義。定義字首如下。

HWMON_C_xxxx

晶片屬性,用於 hwmon_chip。

HWMON_T_xxxx

溫度屬性,用於 hwmon_temp。

HWMON_I_xxxx

電壓屬性,用於 hwmon_in。

HWMON_C_xxxx

電流屬性,用於 hwmon_curr。請注意與晶片屬性的字首重疊。

HWMON_P_xxxx

功率屬性,用於 hwmon_power。

HWMON_E_xxxx

能量屬性,用於 hwmon_energy。

HWMON_H_xxxx

溼度屬性,用於 hwmon_humidity。

HWMON_F_xxxx

風扇速度屬性,用於 hwmon_fan。

HWMON_PWM_xxxx

PWM 控制屬性,用於 hwmon_pwm。

驅動程式回撥函式

每個驅動程式都提供 is_visible、read 和 write 函式。這些函式的引數和返回值如下

umode_t is_visible_func(const void *data, enum hwmon_sensor_types type,
                        u32 attr, int channel)
引數
data

指向裝置私有資料結構的指標。

type

感測器型別。

attr

與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關位欄位到屬性值的完整對映,請參見 include/linux/hwmon.h。

channel

感測器通道號。

返回值

此屬性的檔案模式。通常,這將為 0(不會建立該屬性)、0444 或 0644。

int read_func(struct device *dev, enum hwmon_sensor_types type,
              u32 attr, int channel, long *val)
引數
dev

指向硬體監控裝置的指標。

type

感測器型別。

attr

與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關完整對映,請參見 include/linux/hwmon.h。

channel

感測器通道號。

val

指向屬性值的指標。

返回值

成功時為 0,否則為負錯誤號。

int write_func(struct device *dev, enum hwmon_sensor_types type,
               u32 attr, int channel, long val)
引數
dev

指向硬體監控裝置的指標。

type

感測器型別。

attr

與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關完整對映,請參見 include/linux/hwmon.h。

channel

感測器通道號。

val

要寫入晶片的值。

返回值

成功時為 0,否則為負錯誤號。

驅動程式提供的 sysfs 屬性

在大多數情況下,驅動程式無需提供 sysfs 屬性,因為硬體監控核心會在內部建立這些屬性。只需要提供額外的非標準 sysfs 屬性。

標頭檔案 linux/hwmon-sysfs.h 提供了許多有用的宏來宣告和使用硬體監控 sysfs 屬性。

在許多情況下,您可以使用現有的 define DEVICE_ATTR 或其變體 DEVICE_ATTR_{RW,RO,WO} 來宣告此類屬性。如果屬性沒有其他上下文,這是可行的。但是,在許多情況下,會有其他資訊,例如感測器索引,需要傳遞給 sysfs 屬性處理函式。

SENSOR_DEVICE_ATTR 和 SENSOR_DEVICE_ATTR_2 可用於定義需要此類額外上下文資訊的屬性。 SENSOR_DEVICE_ATTR 需要一個額外的引數,SENSOR_DEVICE_ATTR_2 需要兩個。

SENSOR_DEVICE_ATTR 的簡化變體和 SENSOR_DEVICE_ATTR_2 可用,如果標準屬性許可權和函式名稱可行,則應使用。標準許可權對於 SENSOR_DEVICE_ATTR[_2]_RW 為 0644,對於 SENSOR_DEVICE_ATTR[_2]_RO 為 0444,對於 SENSOR_DEVICE_ATTR[_2]_WO 為 0200。標準函式類似於 DEVICE_ATTR_{RW,RO,WO},在提供的函式名稱後附加 _show 和 _store。

SENSOR_DEVICE_ATTR 及其變體定義了一個 struct sensor_device_attribute 變數。此結構具有以下欄位

struct sensor_device_attribute {
        struct device_attribute dev_attr;
        int index;
};

您可以使用 to_sensor_dev_attr 從屬性讀取或寫入函式中獲取指向此結構的指標。它的引數是附加了屬性的裝置。

SENSOR_DEVICE_ATTR_2 及其變體定義了一個 struct sensor_device_attribute_2 變數,其定義如下

struct sensor_device_attribute_2 {
        struct device_attribute dev_attr;
        u8 index;
        u8 nr;
};

使用 to_sensor_dev_attr_2 獲取指向此結構的指標。它的引數是附加了屬性的裝置。