Advertisement
Guest User

thinkpad_acpi patch for Lenovo P50/P70

a guest
Apr 10th, 2016
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 5.19 KB | None | 0 0
  1. Signed-off-by: Matthias Hochsteger <matthias.hochsteger@tuwien.ac.at>
  2. diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
  3. index e305ab5..6de3a6a 100644
  4. --- a/drivers/platform/x86/thinkpad_acpi.c
  5. +++ b/drivers/platform/x86/thinkpad_acpi.c
  6. @@ -312,6 +312,7 @@ static struct {
  7.     u32 uwb:1;
  8.     u32 fan_ctrl_status_undef:1;
  9.     u32 second_fan:1;
  10. +   u32 second_fan_control:1;
  11.     u32 beep_needs_two_args:1;
  12.     u32 mixer_no_level_control:1;
  13.     u32 input_device_registered:1;
  14. @@ -7821,6 +7822,8 @@ static u8 fan_control_desired_level;
  15.  static u8 fan_control_resume_level;
  16.  static int fan_watchdog_maxinterval;
  17.  
  18. +static u8 fan_active_fan;
  19. +
  20.  static struct mutex fan_mutex;
  21.  
  22.  static void fan_watchdog_fire(struct work_struct *ignored);
  23. @@ -7907,6 +7910,14 @@ static bool fan_select_fan2(void)
  24.     return true;
  25.  }
  26.  
  27. +static void fan_select_fan(void)
  28. +{
  29. +   if (fan_active_fan == 1)
  30. +       fan_select_fan1();
  31. +   else
  32. +       fan_select_fan2();
  33. +}
  34. +
  35.  /*
  36.   * Call with fan_mutex held
  37.   */
  38. @@ -7943,6 +7954,11 @@ static int fan_get_status(u8 *status)
  39.     }
  40.     case TPACPI_FAN_RD_TPEC:
  41.         /* all except 570, 600e/x, 770e, 770x */
  42. +
  43. +       /* BUG: regardless of selected fan,
  44. +        * always status of fan1 is returned
  45. +        */
  46. +       fan_select_fan();
  47.         if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
  48.             return -EIO;
  49.  
  50. @@ -8059,6 +8075,7 @@ static int fan_set_level(int level)
  51.         else if (level & TP_EC_FAN_AUTO)
  52.             level |= 4; /* safety min speed 4 */
  53.  
  54. +       fan_select_fan();
  55.         if (!acpi_ec_write(fan_status_offset, level))
  56.             return -EIO;
  57.         else
  58. @@ -8403,6 +8420,58 @@ static ssize_t fan_pwm1_store(struct device *dev,
  59.  
  60.  static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store);
  61.  
  62. +static ssize_t fan_pwm2_enable_show(struct device *dev,
  63. +                   struct device_attribute *attr,
  64. +                   char *buf)
  65. +{
  66. +   ssize_t result;
  67. +
  68. +   fan_active_fan = 2;
  69. +   result = fan_pwm1_enable_show(dev, attr, buf);
  70. +   fan_active_fan = 1;
  71. +   return result;
  72. +}
  73. +
  74. +static ssize_t fan_pwm2_enable_store(struct device *dev,
  75. +                    struct device_attribute *attr,
  76. +                    const char *buf, size_t count)
  77. +{
  78. +   ssize_t result;
  79. +
  80. +   fan_active_fan = 2;
  81. +   result = fan_pwm1_enable_store(dev, attr, buf, count);
  82. +   fan_active_fan = 1;
  83. +   return result;
  84. +}
  85. +
  86. +static ssize_t fan_pwm2_show(struct device *dev,
  87. +                struct device_attribute *attr,
  88. +                char *buf)
  89. +{
  90. +   ssize_t result;
  91. +
  92. +   fan_active_fan = 2;
  93. +   result = fan_pwm1_show(dev, attr, buf);
  94. +   fan_active_fan = 1;
  95. +   return result;
  96. +}
  97. +
  98. +static ssize_t fan_pwm2_store(struct device *dev,
  99. +                 struct device_attribute *attr,
  100. +                 const char *buf, size_t count)
  101. +{
  102. +   ssize_t result;
  103. +
  104. +   fan_active_fan = 2;
  105. +   result = fan_pwm1_store(dev, attr, buf, count);
  106. +   fan_active_fan = 1;
  107. +   return result;
  108. +}
  109. +
  110. +static DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
  111. +          fan_pwm2_enable_show, fan_pwm2_enable_store);
  112. +static DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, fan_pwm2_show, fan_pwm2_store);
  113. +
  114.  /* sysfs fan fan1_input ------------------------------------------------ */
  115.  static ssize_t fan_fan1_input_show(struct device *dev,
  116.                struct device_attribute *attr,
  117. @@ -8470,6 +8539,8 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
  118.  static struct attribute *fan_attributes[] = {
  119.     &dev_attr_pwm1_enable.attr, &dev_attr_pwm1.attr,
  120.     &dev_attr_fan1_input.attr,
  121. +   NULL, /* for pwm2_enable*/
  122. +   NULL, /* for pwm2 */
  123.     NULL, /* for fan2_input */
  124.     NULL
  125.  };
  126. @@ -8480,6 +8551,7 @@ static const struct attribute_group fan_attr_group = {
  127.  
  128.  #define    TPACPI_FAN_Q1   0x0001      /* Unitialized HFSP */
  129.  #define TPACPI_FAN_2FAN    0x0002      /* EC 0x31 bit 0 selects fan2 */
  130. +#define TPACPI_FAN_2FAN_CONTROL    0x0004  /* support to control fan2 */
  131.  
  132.  #define TPACPI_FAN_QI(__id1, __id2, __quirks)  \
  133.     { .vendor = PCI_VENDOR_ID_IBM,      \
  134. @@ -8499,6 +8571,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
  135.     TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
  136.     TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
  137.     TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
  138. +   TPACPI_Q_LNV('N', '1', TPACPI_FAN_2FAN_CONTROL), /* P50, P70 */
  139.  };
  140.  
  141.  #undef TPACPI_FAN_QL
  142. @@ -8546,6 +8619,12 @@ static int __init fan_init(struct ibm_init_struct *iibm)
  143.                 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
  144.                     "secondary fan support enabled\n");
  145.             }
  146. +           if (quirks & TPACPI_FAN_2FAN_CONTROL) {
  147. +               tp_features.second_fan = 1;
  148. +               tp_features.second_fan_control = 1;
  149. +               dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
  150. +                   "secondary fan write support enabled\n");
  151. +           }
  152.         } else {
  153.             pr_err("ThinkPad ACPI EC access misbehaving, "
  154.                    "fan status and control unavailable\n");
  155. @@ -8600,6 +8679,13 @@ static int __init fan_init(struct ibm_init_struct *iibm)
  156.  
  157.     if (fan_status_access_mode != TPACPI_FAN_NONE ||
  158.         fan_control_access_mode != TPACPI_FAN_WR_NONE) {
  159. +       if (tp_features.second_fan_control) {
  160. +           /* attach second fan pwm attributes */
  161. +           fan_attributes[ARRAY_SIZE(fan_attributes)-4] =
  162. +                   &dev_attr_pwm2_enable.attr;
  163. +           fan_attributes[ARRAY_SIZE(fan_attributes)-3] =
  164. +                   &dev_attr_pwm2.attr;
  165. +       }
  166.         if (tp_features.second_fan) {
  167.             /* attach second fan tachometer */
  168.             fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement