diff mbox series

[v2,1/4] hwmon: (asus-ec-sensors) introduce ec_board_info struct for board data

Message ID 20220426092340.495704-2-eugene.shalygin@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series asus-ec-sensors: add support for board families | expand

Commit Message

Eugene Shalygin April 26, 2022, 9:23 a.m. UTC
We need to keep some more information about the current board than just
the sensors set, and with more boards to add the dmi id array grows
quickly. Our probe code is always the same so let's switch to a custom
test code and a custom board info array. That allows us to omit board
vendor string (ASUS uses two strings that differ in case) in the board
info and use case-insensitive comparison, and also do not duplicate
sensor definitions for such board variants as " (WI-FI)" when sensors
are identical to the base variant.

Also saves a quarter of the module size by replacing big dmi_system_id
structs with smaller ones.

Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
---
 drivers/hwmon/asus-ec-sensors.c | 205 ++++++++++++++++++--------------
 1 file changed, 116 insertions(+), 89 deletions(-)

Comments

Guenter Roeck April 26, 2022, 3:16 p.m. UTC | #1
On Tue, Apr 26, 2022 at 11:23:37AM +0200, Eugene Shalygin wrote:
> We need to keep some more information about the current board than just
> the sensors set, and with more boards to add the dmi id array grows
> quickly. Our probe code is always the same so let's switch to a custom
> test code and a custom board info array. That allows us to omit board
> vendor string (ASUS uses two strings that differ in case) in the board
> info and use case-insensitive comparison, and also do not duplicate
> sensor definitions for such board variants as " (WI-FI)" when sensors
> are identical to the base variant.
> 
> Also saves a quarter of the module size by replacing big dmi_system_id
> structs with smaller ones.
> 
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> ---
...
>  
> -MODULE_DEVICE_TABLE(dmi, asus_ec_dmi_table);
> +MODULE_DEVICE_TABLE(acpi, acpi_ec_ids);
>  module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe);

Since this is now tied to MODULE_DEVICE_TABLE(acpi, ...), I think the
probe function should be referenced in asus_ec_sensors_platform_driver,
and it should be module_platform_driver() instead of
module_platform_driver_probe().

Guenter
Eugene Shalygin April 27, 2022, 9:32 a.m. UTC | #2
> Since this is now tied to MODULE_DEVICE_TABLE(acpi, ...), I think the
> probe function should be referenced in asus_ec_sensors_platform_driver,
> and it should be module_platform_driver() instead of
> module_platform_driver_probe().

As follows?

static struct platform_driver asus_ec_sensors_platform_driver_probe = {
    .probe = asus_ec_probe,
        .driver = {
        .name = "asus-ec-sensors",
    .acpi_match_table = acpi_ec_ids,
    },
};

MODULE_DEVICE_TABLE(acpi, acpi_ec_ids);
module_platform_driver(asus_ec_sensors_platform_driver_probe);

The "_probe" suffix added to keep the asus_ec_probe() code and its
deps as __init.

Eugene
Guenter Roeck April 27, 2022, 12:04 p.m. UTC | #3
On 4/27/22 02:32, Eugene Shalygin wrote:
>> Since this is now tied to MODULE_DEVICE_TABLE(acpi, ...), I think the
>> probe function should be referenced in asus_ec_sensors_platform_driver,
>> and it should be module_platform_driver() instead of
>> module_platform_driver_probe().
> 
> As follows?
> 
> static struct platform_driver asus_ec_sensors_platform_driver_probe = {
>      .probe = asus_ec_probe,
>          .driver = {
>          .name = "asus-ec-sensors",
>      .acpi_match_table = acpi_ec_ids,
>      },
> };
> 
> MODULE_DEVICE_TABLE(acpi, acpi_ec_ids);
> module_platform_driver(asus_ec_sensors_platform_driver_probe);
> 
> The "_probe" suffix added to keep the asus_ec_probe() code and its
> deps as __init.
> 

Sorry, I don't follow that part. One can add "__init" or "__initdata",
as in

static struct platform_driver asus_ec_sensors_platform_driver __initdata = {

to mark a function or data structure as __init. I don't think adding
"_probe" to the struct platform_driver variable name does that.

Guenter
Eugene Shalygin April 27, 2022, 12:16 p.m. UTC | #4
> Sorry, I don't follow that part. One can add "__init" or "__initdata",
> as in
>
> static struct platform_driver asus_ec_sensors_platform_driver __initdata = {
>
> to mark a function or data structure as __init. I don't think adding
> "_probe" to the struct platform_driver variable name does that.
>

__initdata leads to modpost warning:
WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.exit.text+0x3):
Section mismatch in reference from the function cleanup_module() to
the variable .init.data:asus_ec_sensors_platform_driver
The function __exit cleanup_module() references
a variable __initdata asus_ec_sensors_platform_driver.
This is often seen when error handling in the exit function
uses functionality in the init path.
The fix is often to remove the __initdata annotation of
asus_ec_sensors_platform_driver so it may be used outside an init section.

Compiling without attributes resulted in another message:
WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.data+0x0): Section
mismatch in reference from the variable
asus_ec_sensors_platform_driver to the function
.init.text:asus_ec_probe()
The variable asus_ec_sensors_platform_driver references
the function __init asus_ec_probe()
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console

Here is why I added the "_probe" suffix.

Eugene
Guenter Roeck April 27, 2022, 1:20 p.m. UTC | #5
On 4/27/22 05:16, Eugene Shalygin wrote:
>> Sorry, I don't follow that part. One can add "__init" or "__initdata",
>> as in
>>
>> static struct platform_driver asus_ec_sensors_platform_driver __initdata = {
>>
>> to mark a function or data structure as __init. I don't think adding
>> "_probe" to the struct platform_driver variable name does that.
>>
> 
> __initdata leads to modpost warning:
> WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.exit.text+0x3):
> Section mismatch in reference from the function cleanup_module() to
> the variable .init.data:asus_ec_sensors_platform_driver
> The function __exit cleanup_module() references
> a variable __initdata asus_ec_sensors_platform_driver.
> This is often seen when error handling in the exit function
> uses functionality in the init path.
> The fix is often to remove the __initdata annotation of
> asus_ec_sensors_platform_driver so it may be used outside an init section.
> 
> Compiling without attributes resulted in another message:
> WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.data+0x0): Section
> mismatch in reference from the variable
> asus_ec_sensors_platform_driver to the function
> .init.text:asus_ec_probe()
> The variable asus_ec_sensors_platform_driver references
> the function __init asus_ec_probe()
> If the reference is valid then annotate the
> variable with __init* or __refdata (see linux/init.h) or name the variable:
> *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
> 
> Here is why I added the "_probe" suffix.
> 
> Eugene

Ah yes, I forgot about the exit function. It needs a pointer to
the structure, which would be gone if marked __initdata.
Please add a comment to the structure name explaining why
it is named _probe.

Thanks,
Guenter
Eugene Shalygin April 27, 2022, 1:34 p.m. UTC | #6
Maybe I'd better leave a comment why module_platform_driver_probe() is
used as opposed to module_platform_driver()? I think that one would be
more straightforward...

Regards,
Eugene

On Wed, 27 Apr 2022 at 15:20, Guenter Roeck <linux@roeck-us.net> wrote:
>
> On 4/27/22 05:16, Eugene Shalygin wrote:
> >> Sorry, I don't follow that part. One can add "__init" or "__initdata",
> >> as in
> >>
> >> static struct platform_driver asus_ec_sensors_platform_driver __initdata = {
> >>
> >> to mark a function or data structure as __init. I don't think adding
> >> "_probe" to the struct platform_driver variable name does that.
> >>
> >
> > __initdata leads to modpost warning:
> > WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.exit.text+0x3):
> > Section mismatch in reference from the function cleanup_module() to
> > the variable .init.data:asus_ec_sensors_platform_driver
> > The function __exit cleanup_module() references
> > a variable __initdata asus_ec_sensors_platform_driver.
> > This is often seen when error handling in the exit function
> > uses functionality in the init path.
> > The fix is often to remove the __initdata annotation of
> > asus_ec_sensors_platform_driver so it may be used outside an init section.
> >
> > Compiling without attributes resulted in another message:
> > WARNING: modpost: drivers/hwmon/asus-ec-sensors.o(.data+0x0): Section
> > mismatch in reference from the variable
> > asus_ec_sensors_platform_driver to the function
> > .init.text:asus_ec_probe()
> > The variable asus_ec_sensors_platform_driver references
> > the function __init asus_ec_probe()
> > If the reference is valid then annotate the
> > variable with __init* or __refdata (see linux/init.h) or name the variable:
> > *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
> >
> > Here is why I added the "_probe" suffix.
> >
> > Eugene
>
> Ah yes, I forgot about the exit function. It needs a pointer to
> the structure, which would be gone if marked __initdata.
> Please add a comment to the structure name explaining why
> it is named _probe.
>
> Thanks,
> Guenter
Guenter Roeck April 27, 2022, 1:41 p.m. UTC | #7
On 4/27/22 06:34, Eugene Shalygin wrote:
> Maybe I'd better leave a comment why module_platform_driver_probe() is
> used as opposed to module_platform_driver()? I think that one would be
> more straightforward...
> 

You are correct, that is easier. I thought that it calls the probe
function directly and bypasses the normal probe handling, but that
is not the case. Sorry for the noise.

Guenter
Eugene Shalygin April 27, 2022, 1:46 p.m. UTC | #8
OK, thanks!

Eugene

> You are correct, that is easier. I thought that it calls the probe
> function directly and bypasses the normal probe handling, but that
> is not the case. Sorry for the noise.
>
> Guenter
diff mbox series

Patch

diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
index e3d794fb0534..de24dc3d1390 100644
--- a/drivers/hwmon/asus-ec-sensors.c
+++ b/drivers/hwmon/asus-ec-sensors.c
@@ -54,8 +54,7 @@  static char *mutex_path_override;
 /* ACPI mutex for locking access to the EC for the firmware */
 #define ASUS_HW_ACCESS_MUTEX_ASMX	"\\AMW0.ASMX"
 
-/* There are two variants of the vendor spelling */
-#define VENDOR_ASUS_UPPER_CASE	"ASUSTeK COMPUTER INC."
+#define MAX_IDENTICAL_BOARD_VARIATIONS	2
 
 typedef union {
 	u32 value;
@@ -164,74 +163,94 @@  static const struct ec_sensor_info known_ec_sensors[] = {
 	(SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB)
 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT)
 
-#define DMI_EXACT_MATCH_BOARD(vendor, name, sensors) {                         \
-	.matches = {                                                           \
-		DMI_EXACT_MATCH(DMI_BOARD_VENDOR, vendor),                     \
-		DMI_EXACT_MATCH(DMI_BOARD_NAME, name),                         \
-	},                                                                     \
-	.driver_data = (void *)(sensors), \
-}
+struct ec_board_info {
+	const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS];
+	unsigned long sensors;
+};
 
-static const struct dmi_system_id asus_ec_dmi_table[] __initconst = {
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "PRIME X570-PRO",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
-		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE,
-			      "ProArt X570-CREATOR WIFI",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
-		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "Pro WS X570-ACE",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
-		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE,
-			      "ROG CROSSHAIR VIII DARK HERO",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
-		SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE,
-			      "ROG CROSSHAIR VIII FORMULA",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG CROSSHAIR VIII HERO",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
-		SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
-		SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE,
-			      "ROG CROSSHAIR VIII HERO (WI-FI)",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
-		SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
-		SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE,
-			      "ROG CROSSHAIR VIII IMPACT",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX B550-E GAMING",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB |
-		SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX B550-I GAMING",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB |
-		SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_FAN_VRM_HS |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-E GAMING",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB |
-		SENSOR_TEMP_T_SENSOR |
-		SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET |
-		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-F GAMING",
-		SENSOR_SET_TEMP_CHIPSET_CPU_MB |
-		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET),
-	DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-I GAMING",
-		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS |
-		SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE),
+static const struct ec_board_info board_info[] = {
+	{
+		.board_names = {"PRIME X570-PRO"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
+			SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
+	},
+	{
+		.board_names = {"ProArt X570-CREATOR WIFI"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
+			SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT |
+			SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"Pro WS X570-ACE"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
+			SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET |
+			SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG CROSSHAIR VIII DARK HERO"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR |
+			SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
+			SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW |
+			SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG CROSSHAIR VIII FORMULA"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+			SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
+			SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {
+			"ROG CROSSHAIR VIII HERO",
+			"ROG CROSSHAIR VIII HERO (WI-FI)",
+		},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR |
+			SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
+			SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
+			SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU |
+			SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG CROSSHAIR VIII IMPACT"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+			SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
+			SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG STRIX B550-E GAMING"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+			SENSOR_FAN_CPU_OPT,
+	},
+	{
+		.board_names = {"ROG STRIX B550-I GAMING"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+			SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU |
+			SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG STRIX X570-E GAMING"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+			SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
+			SENSOR_IN_CPU_CORE,
+	},
+	{
+		.board_names = {"ROG STRIX X570-F GAMING"},
+		.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
+			SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
+	},
+	{
+		.board_names = {"ROG STRIX X570-I GAMING"},
+		.sensors = SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS |
+			SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
+			SENSOR_IN_CPU_CORE,
+	},
 	{}
 };
 
@@ -241,7 +260,7 @@  struct ec_sensor {
 };
 
 struct ec_sensors_data {
-	unsigned long board_sensors;
+	const struct ec_board_info *board_info;
 	struct ec_sensor *sensors;
 	/* EC registers to read from */
 	u16 *registers;
@@ -307,11 +326,6 @@  static int __init bank_compare(const void *a, const void *b)
 	return *((const s8 *)a) - *((const s8 *)b);
 }
 
-static int __init board_sensors_count(unsigned long sensors)
-{
-	return hweight_long(sensors);
-}
-
 static void __init setup_sensor_data(struct ec_sensors_data *ec)
 {
 	struct ec_sensor *s = ec->sensors;
@@ -322,8 +336,8 @@  static void __init setup_sensor_data(struct ec_sensors_data *ec)
 	ec->nr_banks = 0;
 	ec->nr_registers = 0;
 
-	for_each_set_bit(i, &ec->board_sensors,
-			  BITS_PER_TYPE(ec->board_sensors)) {
+	for_each_set_bit(i, &ec->board_info->sensors,
+			 BITS_PER_TYPE(ec->board_info->sensors)) {
 		s->info_index = i;
 		s->cached_value = 0;
 		ec->nr_registers +=
@@ -463,9 +477,10 @@  static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data)
 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data)
 {
 	const struct ec_sensor_info *si;
-	struct ec_sensor *s;
+	struct ec_sensor *s, *sensor_end;
 
-	for (s = ec->sensors; s != ec->sensors + ec->nr_sensors; s++) {
+	sensor_end = ec->sensors + ec->nr_sensors;
+	for (s = ec->sensors; s != sensor_end; s++) {
 		si = &known_ec_sensors[s->info_index];
 		s->cached_value = get_sensor_value(si, data);
 		data += si->addr.components.size;
@@ -603,12 +618,24 @@  static struct hwmon_chip_info asus_ec_chip_info = {
 	.ops = &asus_ec_hwmon_ops,
 };
 
-static unsigned long __init get_board_sensors(void)
+static const struct ec_board_info * __init get_board_info(void)
 {
-	const struct dmi_system_id *dmi_entry =
-		dmi_first_match(asus_ec_dmi_table);
+	const char *dmi_board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+	const char *dmi_board_name = dmi_get_system_info(DMI_BOARD_NAME);
+	const struct ec_board_info *board;
+
+	if (!dmi_board_vendor || !dmi_board_name ||
+	    strcasecmp(dmi_board_vendor, "ASUSTeK COMPUTER INC."))
+		return NULL;
+
+	for (board = board_info; board->sensors; board++) {
+		if (match_string(board->board_names,
+				 MAX_IDENTICAL_BOARD_VARIATIONS,
+				 dmi_board_name) >= 0)
+			return board;
+	}
 
-	return dmi_entry ? (unsigned long)dmi_entry->driver_data : 0;
+	return NULL;
 }
 
 static int __init asus_ec_probe(struct platform_device *pdev)
@@ -616,17 +643,17 @@  static int __init asus_ec_probe(struct platform_device *pdev)
 	const struct hwmon_channel_info **ptr_asus_ec_ci;
 	int nr_count[hwmon_max] = { 0 }, nr_types = 0;
 	struct hwmon_channel_info *asus_ec_hwmon_chan;
+	const struct ec_board_info *pboard_info;
 	const struct hwmon_chip_info *chip_info;
 	struct device *dev = &pdev->dev;
 	struct ec_sensors_data *ec_data;
 	const struct ec_sensor_info *si;
 	enum hwmon_sensor_types type;
-	unsigned long board_sensors;
 	struct device *hwdev;
 	unsigned int i;
 
-	board_sensors = get_board_sensors();
-	if (!board_sensors)
+	pboard_info = get_board_info();
+	if (!pboard_info)
 		return -ENODEV;
 
 	ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data),
@@ -635,8 +662,8 @@  static int __init asus_ec_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	dev_set_drvdata(dev, ec_data);
-	ec_data->board_sensors = board_sensors;
-	ec_data->nr_sensors = board_sensors_count(ec_data->board_sensors);
+	ec_data->board_info = pboard_info;
+	ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors);
 	ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors,
 					sizeof(struct ec_sensor), GFP_KERNEL);
 
@@ -709,7 +736,7 @@  static struct platform_driver asus_ec_sensors_platform_driver = {
 	},
 };
 
-MODULE_DEVICE_TABLE(dmi, asus_ec_dmi_table);
+MODULE_DEVICE_TABLE(acpi, acpi_ec_ids);
 module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe);
 
 module_param_named(mutex_path, mutex_path_override, charp, 0);