hwmon: (dell-smm) Move whitelist handling to module init
authorArmin Wolf <W_Armin@gmx.de>
Thu, 23 Nov 2023 00:48:14 +0000 (01:48 +0100)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 11 Dec 2023 14:21:01 +0000 (06:21 -0800)
Future SMM calling backends will not be able to probe during
module init, meaning the DMI tables used for whitelisting
features would have to drop their __initconst attribute.
Prevent this by moving the whitelist handling to module init.

Tested-by: <serverror@serverror.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20231123004820.50635-4-W_Armin@gmx.de
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/dell-smm-hwmon.c

index 87d668799c9f5b0a3937d015d0f4244e36b28f3b..1cbdfd77773ebfbc4ec463bac6d122de88b04b1c 100644 (file)
@@ -90,8 +90,6 @@ struct dell_smm_data {
        uint i8k_fan_mult;
        uint i8k_pwm_mult;
        uint i8k_fan_max;
-       unsigned int manual_fan;
-       unsigned int auto_fan;
        int temp_type[DELL_SMM_NO_TEMP];
        bool fan[DELL_SMM_NO_FANS];
        int fan_type[DELL_SMM_NO_FANS];
@@ -138,6 +136,8 @@ MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)"
 
 static bool disallow_fan_type_call, disallow_fan_support;
 
+static unsigned int manual_fan, auto_fan;
+
 static const char * const temp_labels[] = {
        "CPU",
        "GPU",
@@ -329,7 +329,7 @@ static int i8k_enable_fan_auto_mode(const struct dell_smm_data *data, bool enabl
        if (disallow_fan_support)
                return -EINVAL;
 
-       regs.eax = enable ? data->auto_fan : data->manual_fan;
+       regs.eax = enable ? auto_fan : manual_fan;
        return dell_smm_call(data->ops, &regs);
 }
 
@@ -741,7 +741,7 @@ static umode_t dell_smm_is_visible(const void *drvdata, enum hwmon_sensor_types
 
                        break;
                case hwmon_pwm_enable:
-                       if (data->auto_fan)
+                       if (auto_fan)
                                /*
                                 * There is no command for retrieve the current status
                                 * from BIOS, and userspace/firmware itself can change
@@ -1370,7 +1370,7 @@ static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {
 static int __init dell_smm_probe(struct platform_device *pdev)
 {
        struct dell_smm_data *data;
-       const struct dmi_system_id *id, *fan_control;
+       const struct dmi_system_id *id;
        int ret;
 
        data = devm_kzalloc(&pdev->dev, sizeof(struct dell_smm_data), GFP_KERNEL);
@@ -1406,15 +1406,6 @@ static int __init dell_smm_probe(struct platform_device *pdev)
        data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH;
        data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max);
 
-       fan_control = dmi_first_match(i8k_whitelist_fan_control);
-       if (fan_control && fan_control->driver_data) {
-               const struct i8k_fan_control_data *control = fan_control->driver_data;
-
-               data->manual_fan = control->manual_fan;
-               data->auto_fan = control->auto_fan;
-               dev_info(&pdev->dev, "enabling support for setting automatic/manual fan control\n");
-       }
-
        ret = dell_smm_init_hwmon(&pdev->dev);
        if (ret)
                return ret;
@@ -1437,6 +1428,9 @@ static struct platform_device *dell_smm_device;
  */
 static void __init dell_smm_init_dmi(void)
 {
+       struct i8k_fan_control_data *control;
+       const struct dmi_system_id *id;
+
        if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) {
                if (!force) {
                        pr_notice("Disabling fan support due to BIOS bugs\n");
@@ -1454,6 +1448,15 @@ static void __init dell_smm_init_dmi(void)
                        pr_warn("Enabling fan type call despite BIOS bugs\n");
                }
        }
+
+       id = dmi_first_match(i8k_whitelist_fan_control);
+       if (id && id->driver_data) {
+               control = id->driver_data;
+               manual_fan = control->manual_fan;
+               auto_fan = control->auto_fan;
+
+               pr_info("Enabling support for setting automatic/manual fan control\n");
+       }
 }
 
 static int __init i8k_init(void)