@@ -10130,6 +10130,7 @@ static struct ibm_struct proxsensor_driver_data = {
1013010130
1013110131#define DYTC_CMD_FUNC_CAP 3 /* To get DYTC capabilities */
1013210132#define DYTC_FC_MMC 27 /* MMC Mode supported */
10133+ #define DYTC_FC_PSC 29 /* PSC Mode supported */
1013310134
1013410135#define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */
1013510136#define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */
@@ -10140,12 +10141,17 @@ static struct ibm_struct proxsensor_driver_data = {
1014010141
1014110142#define DYTC_FUNCTION_STD 0 /* Function = 0, standard mode */
1014210143#define DYTC_FUNCTION_CQL 1 /* Function = 1, lap mode */
10143- #define DYTC_FUNCTION_MMC 11 /* Function = 11, desk mode */
10144+ #define DYTC_FUNCTION_MMC 11 /* Function = 11, MMC mode */
10145+ #define DYTC_FUNCTION_PSC 13 /* Function = 13, PSC mode */
1014410146
10145- #define DYTC_MODE_PERFORM 2 /* High power mode aka performance */
10146- #define DYTC_MODE_LOWPOWER 3 /* Low power mode */
10147- #define DYTC_MODE_BALANCE 0xF /* Default mode aka balanced */
10148- #define DYTC_MODE_MMC_BALANCE 0 /* Default mode from MMC_GET, aka balanced */
10147+ #define DYTC_MODE_MMC_PERFORM 2 /* High power mode aka performance */
10148+ #define DYTC_MODE_MMC_LOWPOWER 3 /* Low power mode */
10149+ #define DYTC_MODE_MMC_BALANCE 0xF /* Default mode aka balanced */
10150+ #define DYTC_MODE_MMC_DEFAULT 0 /* Default mode from MMC_GET, aka balanced */
10151+
10152+ #define DYTC_MODE_PSC_LOWPOWER 3 /* Low power mode */
10153+ #define DYTC_MODE_PSC_BALANCE 5 /* Default mode aka balanced */
10154+ #define DYTC_MODE_PSC_PERFORM 7 /* High power mode aka performance */
1014910155
1015010156#define DYTC_ERR_MASK 0xF /* Bits 0-3 in cmd result are the error result */
1015110157#define DYTC_ERR_SUCCESS 1 /* CMD completed successful */
@@ -10155,30 +10161,54 @@ static struct ibm_struct proxsensor_driver_data = {
1015510161 (mode) << DYTC_SET_MODE_BIT | \
1015610162 (on) << DYTC_SET_VALID_BIT)
1015710163
10158- #define DYTC_DISABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_BALANCE, 0)
10164+ #define DYTC_DISABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 0)
10165+ #define DYTC_ENABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 1)
1015910166
10160- #define DYTC_ENABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_BALANCE, 1)
10167+ enum dytc_profile_funcmode {
10168+ DYTC_FUNCMODE_NONE = 0 ,
10169+ DYTC_FUNCMODE_MMC ,
10170+ DYTC_FUNCMODE_PSC ,
10171+ };
1016110172
10173+ static enum dytc_profile_funcmode dytc_profile_available ;
1016210174static enum platform_profile_option dytc_current_profile ;
1016310175static atomic_t dytc_ignore_event = ATOMIC_INIT (0 );
1016410176static DEFINE_MUTEX (dytc_mutex );
1016510177static bool dytc_mmc_get_available ;
1016610178
1016710179static int convert_dytc_to_profile (int dytcmode , enum platform_profile_option * profile )
1016810180{
10169- switch (dytcmode ) {
10170- case DYTC_MODE_LOWPOWER :
10171- * profile = PLATFORM_PROFILE_LOW_POWER ;
10172- break ;
10173- case DYTC_MODE_BALANCE :
10174- case DYTC_MODE_MMC_BALANCE :
10175- * profile = PLATFORM_PROFILE_BALANCED ;
10176- break ;
10177- case DYTC_MODE_PERFORM :
10178- * profile = PLATFORM_PROFILE_PERFORMANCE ;
10179- break ;
10180- default : /* Unknown mode */
10181- return - EINVAL ;
10181+ if (dytc_profile_available == DYTC_FUNCMODE_MMC ) {
10182+ switch (dytcmode ) {
10183+ case DYTC_MODE_MMC_LOWPOWER :
10184+ * profile = PLATFORM_PROFILE_LOW_POWER ;
10185+ break ;
10186+ case DYTC_MODE_MMC_DEFAULT :
10187+ case DYTC_MODE_MMC_BALANCE :
10188+ * profile = PLATFORM_PROFILE_BALANCED ;
10189+ break ;
10190+ case DYTC_MODE_MMC_PERFORM :
10191+ * profile = PLATFORM_PROFILE_PERFORMANCE ;
10192+ break ;
10193+ default : /* Unknown mode */
10194+ return - EINVAL ;
10195+ }
10196+ return 0 ;
10197+ }
10198+ if (dytc_profile_available == DYTC_FUNCMODE_PSC ) {
10199+ switch (dytcmode ) {
10200+ case DYTC_MODE_PSC_LOWPOWER :
10201+ * profile = PLATFORM_PROFILE_LOW_POWER ;
10202+ break ;
10203+ case DYTC_MODE_PSC_BALANCE :
10204+ * profile = PLATFORM_PROFILE_BALANCED ;
10205+ break ;
10206+ case DYTC_MODE_PSC_PERFORM :
10207+ * profile = PLATFORM_PROFILE_PERFORMANCE ;
10208+ break ;
10209+ default : /* Unknown mode */
10210+ return - EINVAL ;
10211+ }
1018210212 }
1018310213 return 0 ;
1018410214}
@@ -10187,13 +10217,22 @@ static int convert_profile_to_dytc(enum platform_profile_option profile, int *pe
1018710217{
1018810218 switch (profile ) {
1018910219 case PLATFORM_PROFILE_LOW_POWER :
10190- * perfmode = DYTC_MODE_LOWPOWER ;
10220+ if (dytc_profile_available == DYTC_FUNCMODE_MMC )
10221+ * perfmode = DYTC_MODE_MMC_LOWPOWER ;
10222+ else if (dytc_profile_available == DYTC_FUNCMODE_PSC )
10223+ * perfmode = DYTC_MODE_PSC_LOWPOWER ;
1019110224 break ;
1019210225 case PLATFORM_PROFILE_BALANCED :
10193- * perfmode = DYTC_MODE_BALANCE ;
10226+ if (dytc_profile_available == DYTC_FUNCMODE_MMC )
10227+ * perfmode = DYTC_MODE_MMC_BALANCE ;
10228+ else if (dytc_profile_available == DYTC_FUNCMODE_PSC )
10229+ * perfmode = DYTC_MODE_PSC_BALANCE ;
1019410230 break ;
1019510231 case PLATFORM_PROFILE_PERFORMANCE :
10196- * perfmode = DYTC_MODE_PERFORM ;
10232+ if (dytc_profile_available == DYTC_FUNCMODE_MMC )
10233+ * perfmode = DYTC_MODE_MMC_PERFORM ;
10234+ else if (dytc_profile_available == DYTC_FUNCMODE_PSC )
10235+ * perfmode = DYTC_MODE_PSC_PERFORM ;
1019710236 break ;
1019810237 default : /* Unknown profile */
1019910238 return - EOPNOTSUPP ;
@@ -10266,25 +10305,39 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
1026610305 if (err )
1026710306 return err ;
1026810307
10269- if (profile == PLATFORM_PROFILE_BALANCED ) {
10270- /*
10271- * To get back to balanced mode we need to issue a reset command.
10272- * Note we still need to disable CQL mode before hand and re-enable
10273- * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays
10274- * stuck at 0 for aprox. 30 minutes.
10275- */
10276- err = dytc_cql_command (DYTC_CMD_RESET , & output );
10277- if (err )
10278- goto unlock ;
10279- } else {
10308+ if (dytc_profile_available == DYTC_FUNCMODE_MMC ) {
10309+ if (profile == PLATFORM_PROFILE_BALANCED ) {
10310+ /*
10311+ * To get back to balanced mode we need to issue a reset command.
10312+ * Note we still need to disable CQL mode before hand and re-enable
10313+ * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays
10314+ * stuck at 0 for aprox. 30 minutes.
10315+ */
10316+ err = dytc_cql_command (DYTC_CMD_RESET , & output );
10317+ if (err )
10318+ goto unlock ;
10319+ } else {
10320+ int perfmode ;
10321+
10322+ err = convert_profile_to_dytc (profile , & perfmode );
10323+ if (err )
10324+ goto unlock ;
10325+
10326+ /* Determine if we are in CQL mode. This alters the commands we do */
10327+ err = dytc_cql_command (DYTC_SET_COMMAND (DYTC_FUNCTION_MMC , perfmode , 1 ),
10328+ & output );
10329+ if (err )
10330+ goto unlock ;
10331+ }
10332+ }
10333+ if (dytc_profile_available == DYTC_FUNCMODE_PSC ) {
1028010334 int perfmode ;
1028110335
1028210336 err = convert_profile_to_dytc (profile , & perfmode );
1028310337 if (err )
1028410338 goto unlock ;
1028510339
10286- /* Determine if we are in CQL mode. This alters the commands we do */
10287- err = dytc_cql_command (DYTC_SET_COMMAND (DYTC_FUNCTION_MMC , perfmode , 1 ), & output );
10340+ err = dytc_command (DYTC_SET_COMMAND (DYTC_FUNCTION_PSC , perfmode , 1 ), & output );
1028810341 if (err )
1028910342 goto unlock ;
1029010343 }
@@ -10302,10 +10355,14 @@ static void dytc_profile_refresh(void)
1030210355 int perfmode ;
1030310356
1030410357 mutex_lock (& dytc_mutex );
10305- if (dytc_mmc_get_available )
10306- err = dytc_command (DYTC_CMD_MMC_GET , & output );
10307- else
10308- err = dytc_cql_command (DYTC_CMD_GET , & output );
10358+ if (dytc_profile_available == DYTC_FUNCMODE_MMC ) {
10359+ if (dytc_mmc_get_available )
10360+ err = dytc_command (DYTC_CMD_MMC_GET , & output );
10361+ else
10362+ err = dytc_cql_command (DYTC_CMD_GET , & output );
10363+ } else if (dytc_profile_available == DYTC_FUNCMODE_PSC )
10364+ err = dytc_command (DYTC_CMD_GET , & output );
10365+
1030910366 mutex_unlock (& dytc_mutex );
1031010367 if (err )
1031110368 return ;
@@ -10332,6 +10389,7 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
1033210389 set_bit (PLATFORM_PROFILE_BALANCED , dytc_profile .choices );
1033310390 set_bit (PLATFORM_PROFILE_PERFORMANCE , dytc_profile .choices );
1033410391
10392+ dytc_profile_available = DYTC_FUNCMODE_NONE ;
1033510393 err = dytc_command (DYTC_CMD_QUERY , & output );
1033610394 if (err )
1033710395 return err ;
@@ -10343,27 +10401,34 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
1034310401 if (dytc_version < 5 )
1034410402 return - ENODEV ;
1034510403
10346- /* Check what capabilities are supported. Currently MMC is needed */
10404+ /* Check what capabilities are supported */
1034710405 err = dytc_command (DYTC_CMD_FUNC_CAP , & output );
1034810406 if (err )
1034910407 return err ;
10350- if (!(output & BIT (DYTC_FC_MMC ))) {
10351- dbg_printk (TPACPI_DBG_INIT , " DYTC MMC mode not supported\n" );
10408+
10409+ if (test_bit (DYTC_FC_MMC , (void * )& output )) { /* MMC MODE */
10410+ dytc_profile_available = DYTC_FUNCMODE_MMC ;
10411+
10412+ /*
10413+ * Check if MMC_GET functionality available
10414+ * Version > 6 and return success from MMC_GET command
10415+ */
10416+ dytc_mmc_get_available = false;
10417+ if (dytc_version >= 6 ) {
10418+ err = dytc_command (DYTC_CMD_MMC_GET , & output );
10419+ if (!err && ((output & DYTC_ERR_MASK ) == DYTC_ERR_SUCCESS ))
10420+ dytc_mmc_get_available = true;
10421+ }
10422+ } else if (test_bit (DYTC_FC_PSC , (void * )& output )) { /*PSC MODE */
10423+ dytc_profile_available = DYTC_FUNCMODE_PSC ;
10424+ } else {
10425+ dbg_printk (TPACPI_DBG_INIT , "No DYTC support available\n" );
1035210426 return - ENODEV ;
1035310427 }
1035410428
1035510429 dbg_printk (TPACPI_DBG_INIT ,
1035610430 "DYTC version %d: thermal mode available\n" , dytc_version );
10357- /*
10358- * Check if MMC_GET functionality available
10359- * Version > 6 and return success from MMC_GET command
10360- */
10361- dytc_mmc_get_available = false;
10362- if (dytc_version >= 6 ) {
10363- err = dytc_command (DYTC_CMD_MMC_GET , & output );
10364- if (!err && ((output & DYTC_ERR_MASK ) == DYTC_ERR_SUCCESS ))
10365- dytc_mmc_get_available = true;
10366- }
10431+
1036710432 /* Create platform_profile structure and register */
1036810433 err = platform_profile_register (& dytc_profile );
1036910434 /*
@@ -10381,6 +10446,7 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
1038110446
1038210447static void dytc_profile_exit (void )
1038310448{
10449+ dytc_profile_available = DYTC_FUNCMODE_NONE ;
1038410450 platform_profile_remove ();
1038510451}
1038610452
0 commit comments