@@ -7885,6 +7885,7 @@ static struct ibm_struct volume_driver_data = {
7885
7885
7886
7886
#define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */
7887
7887
#define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */
7888
+ #define FAN_CLOCK_TPM (22500*60) /* Ticks per minute for a 22.5 kHz clock */
7888
7889
7889
7890
enum { /* Fan control constants */
7890
7891
fan_status_offset = 0x2f , /* EC register 0x2f */
@@ -7940,6 +7941,7 @@ static int fan_watchdog_maxinterval;
7940
7941
7941
7942
static bool fan_with_ns_addr ;
7942
7943
static bool ecfw_with_fan_dec_rpm ;
7944
+ static bool fan_speed_in_tpr ;
7943
7945
7944
7946
static struct mutex fan_mutex ;
7945
7947
@@ -8142,8 +8144,11 @@ static int fan_get_speed(unsigned int *speed)
8142
8144
!acpi_ec_read (fan_rpm_offset + 1 , & hi )))
8143
8145
return - EIO ;
8144
8146
8145
- if (likely (speed ))
8147
+ if (likely (speed )) {
8146
8148
* speed = (hi << 8 ) | lo ;
8149
+ if (fan_speed_in_tpr && * speed != 0 )
8150
+ * speed = FAN_CLOCK_TPM / * speed ;
8151
+ }
8147
8152
break ;
8148
8153
case TPACPI_FAN_RD_TPEC_NS :
8149
8154
if (!acpi_ec_read (fan_rpm_status_ns , & lo ))
@@ -8176,8 +8181,11 @@ static int fan2_get_speed(unsigned int *speed)
8176
8181
if (rc )
8177
8182
return - EIO ;
8178
8183
8179
- if (likely (speed ))
8184
+ if (likely (speed )) {
8180
8185
* speed = (hi << 8 ) | lo ;
8186
+ if (fan_speed_in_tpr && * speed != 0 )
8187
+ * speed = FAN_CLOCK_TPM / * speed ;
8188
+ }
8181
8189
break ;
8182
8190
8183
8191
case TPACPI_FAN_RD_TPEC_NS :
@@ -8788,6 +8796,7 @@ static const struct attribute_group fan_driver_attr_group = {
8788
8796
#define TPACPI_FAN_NOFAN 0x0008 /* no fan available */
8789
8797
#define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */
8790
8798
#define TPACPI_FAN_DECRPM 0x0020 /* For ECFW's with RPM in register as decimal */
8799
+ #define TPACPI_FAN_TPR 0x0040 /* Fan speed is in Ticks Per Revolution */
8791
8800
8792
8801
static const struct tpacpi_quirk fan_quirk_table [] __initconst = {
8793
8802
TPACPI_QEC_IBM ('1' , 'Y' , TPACPI_FAN_Q1 ),
@@ -8817,6 +8826,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
8817
8826
TPACPI_Q_LNV3 ('R' , '0' , 'V' , TPACPI_FAN_NS ), /* 11e Gen5 KL-Y */
8818
8827
TPACPI_Q_LNV3 ('N' , '1' , 'O' , TPACPI_FAN_NOFAN ), /* X1 Tablet (2nd gen) */
8819
8828
TPACPI_Q_LNV3 ('R' , '0' , 'Q' , TPACPI_FAN_DECRPM ),/* L480 */
8829
+ TPACPI_Q_LNV ('8' , 'F' , TPACPI_FAN_TPR ), /* ThinkPad x120e */
8820
8830
};
8821
8831
8822
8832
static int __init fan_init (struct ibm_init_struct * iibm )
@@ -8887,6 +8897,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
8887
8897
8888
8898
if (quirks & TPACPI_FAN_Q1 )
8889
8899
fan_quirk1_setup ();
8900
+ if (quirks & TPACPI_FAN_TPR )
8901
+ fan_speed_in_tpr = true;
8890
8902
/* Try and probe the 2nd fan */
8891
8903
tp_features .second_fan = 1 ; /* needed for get_speed to work */
8892
8904
res = fan2_get_speed (& speed );
@@ -10319,6 +10331,10 @@ static struct ibm_struct proxsensor_driver_data = {
10319
10331
#define DYTC_MODE_PSC_BALANCE 5 /* Default mode aka balanced */
10320
10332
#define DYTC_MODE_PSC_PERFORM 7 /* High power mode aka performance */
10321
10333
10334
+ #define DYTC_MODE_PSCV9_LOWPOWER 1 /* Low power mode */
10335
+ #define DYTC_MODE_PSCV9_BALANCE 3 /* Default mode aka balanced */
10336
+ #define DYTC_MODE_PSCV9_PERFORM 4 /* High power mode aka performance */
10337
+
10322
10338
#define DYTC_ERR_MASK 0xF /* Bits 0-3 in cmd result are the error result */
10323
10339
#define DYTC_ERR_SUCCESS 1 /* CMD completed successful */
10324
10340
@@ -10339,6 +10355,10 @@ static int dytc_capabilities;
10339
10355
static bool dytc_mmc_get_available ;
10340
10356
static int profile_force ;
10341
10357
10358
+ static int platform_psc_profile_lowpower = DYTC_MODE_PSC_LOWPOWER ;
10359
+ static int platform_psc_profile_balanced = DYTC_MODE_PSC_BALANCE ;
10360
+ static int platform_psc_profile_performance = DYTC_MODE_PSC_PERFORM ;
10361
+
10342
10362
static int convert_dytc_to_profile (int funcmode , int dytcmode ,
10343
10363
enum platform_profile_option * profile )
10344
10364
{
@@ -10360,19 +10380,15 @@ static int convert_dytc_to_profile(int funcmode, int dytcmode,
10360
10380
}
10361
10381
return 0 ;
10362
10382
case DYTC_FUNCTION_PSC :
10363
- switch (dytcmode ) {
10364
- case DYTC_MODE_PSC_LOWPOWER :
10383
+ if (dytcmode == platform_psc_profile_lowpower )
10365
10384
* profile = PLATFORM_PROFILE_LOW_POWER ;
10366
- break ;
10367
- case DYTC_MODE_PSC_BALANCE :
10385
+ else if (dytcmode == platform_psc_profile_balanced )
10368
10386
* profile = PLATFORM_PROFILE_BALANCED ;
10369
- break ;
10370
- case DYTC_MODE_PSC_PERFORM :
10387
+ else if (dytcmode == platform_psc_profile_performance )
10371
10388
* profile = PLATFORM_PROFILE_PERFORMANCE ;
10372
- break ;
10373
- default : /* Unknown mode */
10389
+ else
10374
10390
return - EINVAL ;
10375
- }
10391
+
10376
10392
return 0 ;
10377
10393
case DYTC_FUNCTION_AMT :
10378
10394
/* For now return balanced. It's the closest we have to 'auto' */
@@ -10393,19 +10409,19 @@ static int convert_profile_to_dytc(enum platform_profile_option profile, int *pe
10393
10409
if (dytc_capabilities & BIT (DYTC_FC_MMC ))
10394
10410
* perfmode = DYTC_MODE_MMC_LOWPOWER ;
10395
10411
else if (dytc_capabilities & BIT (DYTC_FC_PSC ))
10396
- * perfmode = DYTC_MODE_PSC_LOWPOWER ;
10412
+ * perfmode = platform_psc_profile_lowpower ;
10397
10413
break ;
10398
10414
case PLATFORM_PROFILE_BALANCED :
10399
10415
if (dytc_capabilities & BIT (DYTC_FC_MMC ))
10400
10416
* perfmode = DYTC_MODE_MMC_BALANCE ;
10401
10417
else if (dytc_capabilities & BIT (DYTC_FC_PSC ))
10402
- * perfmode = DYTC_MODE_PSC_BALANCE ;
10418
+ * perfmode = platform_psc_profile_balanced ;
10403
10419
break ;
10404
10420
case PLATFORM_PROFILE_PERFORMANCE :
10405
10421
if (dytc_capabilities & BIT (DYTC_FC_MMC ))
10406
10422
* perfmode = DYTC_MODE_MMC_PERFORM ;
10407
10423
else if (dytc_capabilities & BIT (DYTC_FC_PSC ))
10408
- * perfmode = DYTC_MODE_PSC_PERFORM ;
10424
+ * perfmode = platform_psc_profile_performance ;
10409
10425
break ;
10410
10426
default : /* Unknown profile */
10411
10427
return - EOPNOTSUPP ;
@@ -10599,6 +10615,7 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
10599
10615
if (output & BIT (DYTC_QUERY_ENABLE_BIT ))
10600
10616
dytc_version = (output >> DYTC_QUERY_REV_BIT ) & 0xF ;
10601
10617
10618
+ dbg_printk (TPACPI_DBG_INIT , "DYTC version %d\n" , dytc_version );
10602
10619
/* Check DYTC is enabled and supports mode setting */
10603
10620
if (dytc_version < 5 )
10604
10621
return - ENODEV ;
@@ -10637,6 +10654,11 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
10637
10654
}
10638
10655
} else if (dytc_capabilities & BIT (DYTC_FC_PSC )) { /* PSC MODE */
10639
10656
pr_debug ("PSC is supported\n" );
10657
+ if (dytc_version >= 9 ) { /* update profiles for DYTC 9 and up */
10658
+ platform_psc_profile_lowpower = DYTC_MODE_PSCV9_LOWPOWER ;
10659
+ platform_psc_profile_balanced = DYTC_MODE_PSCV9_BALANCE ;
10660
+ platform_psc_profile_performance = DYTC_MODE_PSCV9_PERFORM ;
10661
+ }
10640
10662
} else {
10641
10663
dbg_printk (TPACPI_DBG_INIT , "No DYTC support available\n" );
10642
10664
return - ENODEV ;
@@ -10646,8 +10668,8 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
10646
10668
"DYTC version %d: thermal mode available\n" , dytc_version );
10647
10669
10648
10670
/* Create platform_profile structure and register */
10649
- tpacpi_pprof = devm_platform_profile_register (& tpacpi_pdev -> dev , "thinkpad-acpi" ,
10650
- NULL , & dytc_profile_ops );
10671
+ tpacpi_pprof = platform_profile_register (& tpacpi_pdev -> dev , "thinkpad-acpi-profile " ,
10672
+ NULL , & dytc_profile_ops );
10651
10673
/*
10652
10674
* If for some reason platform_profiles aren't enabled
10653
10675
* don't quit terminally.
@@ -10665,8 +10687,15 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
10665
10687
return 0 ;
10666
10688
}
10667
10689
10690
+ static void dytc_profile_exit (void )
10691
+ {
10692
+ if (!IS_ERR_OR_NULL (tpacpi_pprof ))
10693
+ platform_profile_remove (tpacpi_pprof );
10694
+ }
10695
+
10668
10696
static struct ibm_struct dytc_profile_driver_data = {
10669
10697
.name = "dytc-profile" ,
10698
+ .exit = dytc_profile_exit ,
10670
10699
};
10671
10700
10672
10701
/*************************************************************************
0 commit comments