Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Signed-off-by: Matthias Hochsteger <matthias.hochsteger@tuwien.ac.at>
- diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
- index e305ab5..6de3a6a 100644
- --- a/drivers/platform/x86/thinkpad_acpi.c
- +++ b/drivers/platform/x86/thinkpad_acpi.c
- @@ -312,6 +312,7 @@ static struct {
- u32 uwb:1;
- u32 fan_ctrl_status_undef:1;
- u32 second_fan:1;
- + u32 second_fan_control:1;
- u32 beep_needs_two_args:1;
- u32 mixer_no_level_control:1;
- u32 input_device_registered:1;
- @@ -7821,6 +7822,8 @@ static u8 fan_control_desired_level;
- static u8 fan_control_resume_level;
- static int fan_watchdog_maxinterval;
- +static u8 fan_active_fan;
- +
- static struct mutex fan_mutex;
- static void fan_watchdog_fire(struct work_struct *ignored);
- @@ -7907,6 +7910,14 @@ static bool fan_select_fan2(void)
- return true;
- }
- +static void fan_select_fan(void)
- +{
- + if (fan_active_fan == 1)
- + fan_select_fan1();
- + else
- + fan_select_fan2();
- +}
- +
- /*
- * Call with fan_mutex held
- */
- @@ -7943,6 +7954,11 @@ static int fan_get_status(u8 *status)
- }
- case TPACPI_FAN_RD_TPEC:
- /* all except 570, 600e/x, 770e, 770x */
- +
- + /* BUG: regardless of selected fan,
- + * always status of fan1 is returned
- + */
- + fan_select_fan();
- if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
- return -EIO;
- @@ -8059,6 +8075,7 @@ static int fan_set_level(int level)
- else if (level & TP_EC_FAN_AUTO)
- level |= 4; /* safety min speed 4 */
- + fan_select_fan();
- if (!acpi_ec_write(fan_status_offset, level))
- return -EIO;
- else
- @@ -8403,6 +8420,58 @@ static ssize_t fan_pwm1_store(struct device *dev,
- static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store);
- +static ssize_t fan_pwm2_enable_show(struct device *dev,
- + struct device_attribute *attr,
- + char *buf)
- +{
- + ssize_t result;
- +
- + fan_active_fan = 2;
- + result = fan_pwm1_enable_show(dev, attr, buf);
- + fan_active_fan = 1;
- + return result;
- +}
- +
- +static ssize_t fan_pwm2_enable_store(struct device *dev,
- + struct device_attribute *attr,
- + const char *buf, size_t count)
- +{
- + ssize_t result;
- +
- + fan_active_fan = 2;
- + result = fan_pwm1_enable_store(dev, attr, buf, count);
- + fan_active_fan = 1;
- + return result;
- +}
- +
- +static ssize_t fan_pwm2_show(struct device *dev,
- + struct device_attribute *attr,
- + char *buf)
- +{
- + ssize_t result;
- +
- + fan_active_fan = 2;
- + result = fan_pwm1_show(dev, attr, buf);
- + fan_active_fan = 1;
- + return result;
- +}
- +
- +static ssize_t fan_pwm2_store(struct device *dev,
- + struct device_attribute *attr,
- + const char *buf, size_t count)
- +{
- + ssize_t result;
- +
- + fan_active_fan = 2;
- + result = fan_pwm1_store(dev, attr, buf, count);
- + fan_active_fan = 1;
- + return result;
- +}
- +
- +static DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
- + fan_pwm2_enable_show, fan_pwm2_enable_store);
- +static DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, fan_pwm2_show, fan_pwm2_store);
- +
- /* sysfs fan fan1_input ------------------------------------------------ */
- static ssize_t fan_fan1_input_show(struct device *dev,
- struct device_attribute *attr,
- @@ -8470,6 +8539,8 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
- static struct attribute *fan_attributes[] = {
- &dev_attr_pwm1_enable.attr, &dev_attr_pwm1.attr,
- &dev_attr_fan1_input.attr,
- + NULL, /* for pwm2_enable*/
- + NULL, /* for pwm2 */
- NULL, /* for fan2_input */
- NULL
- };
- @@ -8480,6 +8551,7 @@ static const struct attribute_group fan_attr_group = {
- #define TPACPI_FAN_Q1 0x0001 /* Unitialized HFSP */
- #define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */
- +#define TPACPI_FAN_2FAN_CONTROL 0x0004 /* support to control fan2 */
- #define TPACPI_FAN_QI(__id1, __id2, __quirks) \
- { .vendor = PCI_VENDOR_ID_IBM, \
- @@ -8499,6 +8571,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
- TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
- TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
- TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
- + TPACPI_Q_LNV('N', '1', TPACPI_FAN_2FAN_CONTROL), /* P50, P70 */
- };
- #undef TPACPI_FAN_QL
- @@ -8546,6 +8619,12 @@ static int __init fan_init(struct ibm_init_struct *iibm)
- dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
- "secondary fan support enabled\n");
- }
- + if (quirks & TPACPI_FAN_2FAN_CONTROL) {
- + tp_features.second_fan = 1;
- + tp_features.second_fan_control = 1;
- + dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
- + "secondary fan write support enabled\n");
- + }
- } else {
- pr_err("ThinkPad ACPI EC access misbehaving, "
- "fan status and control unavailable\n");
- @@ -8600,6 +8679,13 @@ static int __init fan_init(struct ibm_init_struct *iibm)
- if (fan_status_access_mode != TPACPI_FAN_NONE ||
- fan_control_access_mode != TPACPI_FAN_WR_NONE) {
- + if (tp_features.second_fan_control) {
- + /* attach second fan pwm attributes */
- + fan_attributes[ARRAY_SIZE(fan_attributes)-4] =
- + &dev_attr_pwm2_enable.attr;
- + fan_attributes[ARRAY_SIZE(fan_attributes)-3] =
- + &dev_attr_pwm2.attr;
- + }
- if (tp_features.second_fan) {
- /* attach second fan tachometer */
- fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement