]> Git Repo - linux.git/blobdiff - drivers/hwmon/it87.c
block: add a sanity check for non-write flush/fua bios
[linux.git] / drivers / hwmon / it87.c
index 7bd154ba351b90fad179c94cc5b17c58a9e0f052..9997f76b1f4aa345f3c46657960bb362f851cf0d 100644 (file)
@@ -69,6 +69,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
+static bool ignore_resource_conflict;
+module_param(ignore_resource_conflict, bool, 0);
+MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict");
+
 static struct platform_device *it87_pdev[2];
 
 #define        REG_2E  0x2e    /* The register to read/write */
@@ -563,6 +567,14 @@ struct it87_data {
        s8 auto_temp[NUM_AUTO_PWM][5];  /* [nr][0] is point1_temp_hyst */
 };
 
+/* Board specific settings from DMI matching */
+struct it87_dmi_data {
+       u8 skip_pwm;            /* pwm channels to skip for this board  */
+};
+
+/* Global for results from DMI matching, if needed */
+static struct it87_dmi_data *dmi_data;
+
 static int adc_lsb(const struct it87_data *data, int nr)
 {
        int lsb;
@@ -2389,7 +2401,6 @@ static int __init it87_find(int sioaddr, unsigned short *address,
 {
        int err;
        u16 chip_type;
-       const char *board_vendor, *board_name;
        const struct it87_devices *config;
 
        err = superio_enter(sioaddr);
@@ -2397,7 +2408,13 @@ static int __init it87_find(int sioaddr, unsigned short *address,
                return err;
 
        err = -ENODEV;
-       chip_type = force_id ? force_id : superio_inw(sioaddr, DEVID);
+       chip_type = superio_inw(sioaddr, DEVID);
+       /* check first for a valid chip before forcing chip id */
+       if (chip_type == 0xffff)
+               goto exit;
+
+       if (force_id)
+               chip_type = force_id;
 
        switch (chip_type) {
        case IT8705F_DEVID:
@@ -2802,24 +2819,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
        if (sio_data->beep_pin)
                pr_info("Beeping is supported\n");
 
-       /* Disable specific features based on DMI strings */
-       board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
-       board_name = dmi_get_system_info(DMI_BOARD_NAME);
-       if (board_vendor && board_name) {
-               if (strcmp(board_vendor, "nVIDIA") == 0 &&
-                   strcmp(board_name, "FN68PT") == 0) {
-                       /*
-                        * On the Shuttle SN68PT, FAN_CTL2 is apparently not
-                        * connected to a fan, but to something else. One user
-                        * has reported instant system power-off when changing
-                        * the PWM2 duty cycle, so we disable it.
-                        * I use the board name string as the trigger in case
-                        * the same board is ever used in other systems.
-                        */
-                       pr_info("Disabling pwm2 due to hardware constraints\n");
-                       sio_data->skip_pwm = BIT(1);
-               }
-       }
+       /* Set values based on DMI matches */
+       if (dmi_data)
+               sio_data->skip_pwm |= dmi_data->skip_pwm;
 
 exit:
        superio_exit(sioaddr);
@@ -3261,8 +3263,10 @@ static int __init it87_device_add(int index, unsigned short address,
        int err;
 
        err = acpi_check_resource_conflict(&res);
-       if (err)
-               return err;
+       if (err) {
+               if (!ignore_resource_conflict)
+                       return err;
+       }
 
        pdev = platform_device_alloc(DRVNAME, address);
        if (!pdev)
@@ -3295,6 +3299,46 @@ exit_device_put:
        return err;
 }
 
+/* callback function for DMI */
+static int it87_dmi_cb(const struct dmi_system_id *dmi_entry)
+{
+       dmi_data = dmi_entry->driver_data;
+
+       if (dmi_data && dmi_data->skip_pwm)
+               pr_info("Disabling pwm2 due to hardware constraints\n");
+
+       return 1;
+}
+
+/*
+ * On the Shuttle SN68PT, FAN_CTL2 is apparently not
+ * connected to a fan, but to something else. One user
+ * has reported instant system power-off when changing
+ * the PWM2 duty cycle, so we disable it.
+ * I use the board name string as the trigger in case
+ * the same board is ever used in other systems.
+ */
+static struct it87_dmi_data nvidia_fn68pt = {
+       .skip_pwm = BIT(1),
+};
+
+#define IT87_DMI_MATCH_VND(vendor, name, cb, data) \
+       { \
+               .callback = cb, \
+               .matches = { \
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, vendor), \
+                       DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \
+               }, \
+               .driver_data = data, \
+       }
+
+static const struct dmi_system_id it87_dmi_table[] __initconst = {
+       IT87_DMI_MATCH_VND("nVIDIA", "FN68PT", it87_dmi_cb, &nvidia_fn68pt),
+       { }
+
+};
+MODULE_DEVICE_TABLE(dmi, it87_dmi_table);
+
 static int __init sm_it87_init(void)
 {
        int sioaddr[2] = { REG_2E, REG_4E };
@@ -3307,6 +3351,8 @@ static int __init sm_it87_init(void)
        if (err)
                return err;
 
+       dmi_check_system(it87_dmi_table);
+
        for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
                memset(&sio_data, 0, sizeof(struct it87_sio_data));
                isa_address[i] = 0;
This page took 0.032221 seconds and 4 git commands to generate.