diff options
-rw-r--r-- | drivers/hwmon/it87.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 818f123ac475..f8499cb95fec 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -497,12 +497,14 @@ static const struct it87_devices it87_devices[] = { | |||
497 | #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) | 497 | #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) |
498 | 498 | ||
499 | struct it87_sio_data { | 499 | struct it87_sio_data { |
500 | int sioaddr; | ||
500 | enum chips type; | 501 | enum chips type; |
501 | /* Values read from Super-I/O config space */ | 502 | /* Values read from Super-I/O config space */ |
502 | u8 revision; | 503 | u8 revision; |
503 | u8 vid_value; | 504 | u8 vid_value; |
504 | u8 beep_pin; | 505 | u8 beep_pin; |
505 | u8 internal; /* Internal sensors can be labeled */ | 506 | u8 internal; /* Internal sensors can be labeled */ |
507 | bool need_in7_reroute; | ||
506 | /* Features skipped based on config or DMI */ | 508 | /* Features skipped based on config or DMI */ |
507 | u16 skip_in; | 509 | u16 skip_in; |
508 | u8 skip_vid; | 510 | u8 skip_vid; |
@@ -517,6 +519,7 @@ struct it87_sio_data { | |||
517 | */ | 519 | */ |
518 | struct it87_data { | 520 | struct it87_data { |
519 | const struct attribute_group *groups[7]; | 521 | const struct attribute_group *groups[7]; |
522 | int sioaddr; | ||
520 | enum chips type; | 523 | enum chips type; |
521 | u32 features; | 524 | u32 features; |
522 | u8 peci_mask; | 525 | u8 peci_mask; |
@@ -532,6 +535,7 @@ struct it87_data { | |||
532 | u16 in_internal; /* Bitfield, internal sensors (for labels) */ | 535 | u16 in_internal; /* Bitfield, internal sensors (for labels) */ |
533 | u16 has_in; /* Bitfield, voltage sensors enabled */ | 536 | u16 has_in; /* Bitfield, voltage sensors enabled */ |
534 | u8 in[NUM_VIN][3]; /* [nr][0]=in, [1]=min, [2]=max */ | 537 | u8 in[NUM_VIN][3]; /* [nr][0]=in, [1]=min, [2]=max */ |
538 | bool need_in7_reroute; | ||
535 | u8 has_fan; /* Bitfield, fans enabled */ | 539 | u8 has_fan; /* Bitfield, fans enabled */ |
536 | u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */ | 540 | u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */ |
537 | u8 has_temp; /* Bitfield, temp sensors enabled */ | 541 | u8 has_temp; /* Bitfield, temp sensors enabled */ |
@@ -2487,6 +2491,7 @@ static int __init it87_find(int sioaddr, unsigned short *address, | |||
2487 | } | 2491 | } |
2488 | 2492 | ||
2489 | err = 0; | 2493 | err = 0; |
2494 | sio_data->sioaddr = sioaddr; | ||
2490 | sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f; | 2495 | sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f; |
2491 | pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, | 2496 | pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, |
2492 | it87_devices[sio_data->type].suffix, | 2497 | it87_devices[sio_data->type].suffix, |
@@ -2575,6 +2580,7 @@ static int __init it87_find(int sioaddr, unsigned short *address, | |||
2575 | reg2c |= BIT(1); | 2580 | reg2c |= BIT(1); |
2576 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, | 2581 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, |
2577 | reg2c); | 2582 | reg2c); |
2583 | sio_data->need_in7_reroute = true; | ||
2578 | pr_notice("Routing internal VCCH5V to in7.\n"); | 2584 | pr_notice("Routing internal VCCH5V to in7.\n"); |
2579 | } | 2585 | } |
2580 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); | 2586 | pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); |
@@ -2777,6 +2783,7 @@ static int __init it87_find(int sioaddr, unsigned short *address, | |||
2777 | if ((sio_data->type == it8720 || uart6) && !(reg & BIT(1))) { | 2783 | if ((sio_data->type == it8720 || uart6) && !(reg & BIT(1))) { |
2778 | reg |= BIT(1); | 2784 | reg |= BIT(1); |
2779 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg); | 2785 | superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg); |
2786 | sio_data->need_in7_reroute = true; | ||
2780 | pr_notice("Routing internal VCCH5V to in7\n"); | 2787 | pr_notice("Routing internal VCCH5V to in7\n"); |
2781 | } | 2788 | } |
2782 | if (reg & BIT(0)) | 2789 | if (reg & BIT(0)) |
@@ -3024,8 +3031,6 @@ static int it87_check_pwm(struct device *dev) | |||
3024 | "PWM configuration is too broken to be fixed\n"); | 3031 | "PWM configuration is too broken to be fixed\n"); |
3025 | } | 3032 | } |
3026 | 3033 | ||
3027 | dev_info(dev, | ||
3028 | "Detected broken BIOS defaults, disabling PWM interface\n"); | ||
3029 | return 0; | 3034 | return 0; |
3030 | } else if (fix_pwm_polarity) { | 3035 | } else if (fix_pwm_polarity) { |
3031 | dev_info(dev, | 3036 | dev_info(dev, |
@@ -3058,6 +3063,7 @@ static int it87_probe(struct platform_device *pdev) | |||
3058 | return -ENOMEM; | 3063 | return -ENOMEM; |
3059 | 3064 | ||
3060 | data->addr = res->start; | 3065 | data->addr = res->start; |
3066 | data->sioaddr = sio_data->sioaddr; | ||
3061 | data->type = sio_data->type; | 3067 | data->type = sio_data->type; |
3062 | data->features = it87_devices[sio_data->type].features; | 3068 | data->features = it87_devices[sio_data->type].features; |
3063 | data->peci_mask = it87_devices[sio_data->type].peci_mask; | 3069 | data->peci_mask = it87_devices[sio_data->type].peci_mask; |
@@ -3096,6 +3102,9 @@ static int it87_probe(struct platform_device *pdev) | |||
3096 | 3102 | ||
3097 | /* Check PWM configuration */ | 3103 | /* Check PWM configuration */ |
3098 | enable_pwm_interface = it87_check_pwm(dev); | 3104 | enable_pwm_interface = it87_check_pwm(dev); |
3105 | if (!enable_pwm_interface) | ||
3106 | dev_info(dev, | ||
3107 | "Detected broken BIOS defaults, disabling PWM interface\n"); | ||
3099 | 3108 | ||
3100 | /* Starting with IT8721F, we handle scaling of internal voltages */ | 3109 | /* Starting with IT8721F, we handle scaling of internal voltages */ |
3101 | if (has_12mv_adc(data)) { | 3110 | if (has_12mv_adc(data)) { |
@@ -3123,6 +3132,7 @@ static int it87_probe(struct platform_device *pdev) | |||
3123 | } | 3132 | } |
3124 | 3133 | ||
3125 | data->in_internal = sio_data->internal; | 3134 | data->in_internal = sio_data->internal; |
3135 | data->need_in7_reroute = sio_data->need_in7_reroute; | ||
3126 | data->has_in = 0x3ff & ~sio_data->skip_in; | 3136 | data->has_in = 0x3ff & ~sio_data->skip_in; |
3127 | 3137 | ||
3128 | if (has_six_temp(data)) { | 3138 | if (has_six_temp(data)) { |
@@ -3178,9 +3188,71 @@ static int it87_probe(struct platform_device *pdev) | |||
3178 | return PTR_ERR_OR_ZERO(hwmon_dev); | 3188 | return PTR_ERR_OR_ZERO(hwmon_dev); |
3179 | } | 3189 | } |
3180 | 3190 | ||
3191 | static void __maybe_unused it87_resume_sio(struct platform_device *pdev) | ||
3192 | { | ||
3193 | struct it87_data *data = dev_get_drvdata(&pdev->dev); | ||
3194 | int err; | ||
3195 | int reg2c; | ||
3196 | |||
3197 | if (!data->need_in7_reroute) | ||
3198 | return; | ||
3199 | |||
3200 | err = superio_enter(data->sioaddr); | ||
3201 | if (err) { | ||
3202 | dev_warn(&pdev->dev, | ||
3203 | "Unable to enter Super I/O to reroute in7 (%d)", | ||
3204 | err); | ||
3205 | return; | ||
3206 | } | ||
3207 | |||
3208 | superio_select(data->sioaddr, GPIO); | ||
3209 | |||
3210 | reg2c = superio_inb(data->sioaddr, IT87_SIO_PINX2_REG); | ||
3211 | if (!(reg2c & BIT(1))) { | ||
3212 | dev_dbg(&pdev->dev, | ||
3213 | "Routing internal VCCH5V to in7 again"); | ||
3214 | |||
3215 | reg2c |= BIT(1); | ||
3216 | superio_outb(data->sioaddr, IT87_SIO_PINX2_REG, | ||
3217 | reg2c); | ||
3218 | } | ||
3219 | |||
3220 | superio_exit(data->sioaddr); | ||
3221 | } | ||
3222 | |||
3223 | static int __maybe_unused it87_resume(struct device *dev) | ||
3224 | { | ||
3225 | struct platform_device *pdev = to_platform_device(dev); | ||
3226 | struct it87_data *data = dev_get_drvdata(dev); | ||
3227 | |||
3228 | it87_resume_sio(pdev); | ||
3229 | |||
3230 | mutex_lock(&data->update_lock); | ||
3231 | |||
3232 | it87_check_pwm(dev); | ||
3233 | it87_check_limit_regs(data); | ||
3234 | it87_check_voltage_monitors_reset(data); | ||
3235 | it87_check_tachometers_reset(pdev); | ||
3236 | it87_check_tachometers_16bit_mode(pdev); | ||
3237 | |||
3238 | it87_start_monitoring(data); | ||
3239 | |||
3240 | /* force update */ | ||
3241 | data->valid = 0; | ||
3242 | |||
3243 | mutex_unlock(&data->update_lock); | ||
3244 | |||
3245 | it87_update_device(dev); | ||
3246 | |||
3247 | return 0; | ||
3248 | } | ||
3249 | |||
3250 | static SIMPLE_DEV_PM_OPS(it87_dev_pm_ops, NULL, it87_resume); | ||
3251 | |||
3181 | static struct platform_driver it87_driver = { | 3252 | static struct platform_driver it87_driver = { |
3182 | .driver = { | 3253 | .driver = { |
3183 | .name = DRVNAME, | 3254 | .name = DRVNAME, |
3255 | .pm = &it87_dev_pm_ops, | ||
3184 | }, | 3256 | }, |
3185 | .probe = it87_probe, | 3257 | .probe = it87_probe, |
3186 | }; | 3258 | }; |