diff mbox

[1/7] Make the --pm-method argument part of fwts_framework

Message ID 1406888440-5692-2-git-send-email-alberto.milone@canonical.com
State Accepted
Headers show

Commit Message

Alberto Milone Aug. 1, 2014, 10:20 a.m. UTC
This will allow us to share it with different handlers (e.g. s3 and s4)

Signed-off-by: Alberto Milone <alberto.milone@canonical.com>
---
 src/acpi/s3/s3.c                 | 36 ++++++++----------------------------
 src/lib/include/fwts_framework.h |  2 ++
 src/lib/include/fwts_pm_method.h | 30 ++++++++++++++++++++++++++++++
 src/lib/src/fwts_framework.c     | 28 ++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 28 deletions(-)
 create mode 100644 src/lib/include/fwts_pm_method.h

Comments

Alex Hung Aug. 4, 2014, 10:01 a.m. UTC | #1
On 08/01/2014 06:20 PM, Alberto Milone wrote:
> This will allow us to share it with different handlers (e.g. s3 and s4)
>
> Signed-off-by: Alberto Milone <alberto.milone@canonical.com>
> ---
>   src/acpi/s3/s3.c                 | 36 ++++++++----------------------------
>   src/lib/include/fwts_framework.h |  2 ++
>   src/lib/include/fwts_pm_method.h | 30 ++++++++++++++++++++++++++++++
>   src/lib/src/fwts_framework.c     | 28 ++++++++++++++++++++++++++++
>   4 files changed, 68 insertions(+), 28 deletions(-)
>   create mode 100644 src/lib/include/fwts_pm_method.h
>
> diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c
> index adcd188..3759de6 100644
> --- a/src/acpi/s3/s3.c
> +++ b/src/acpi/s3/s3.c
> @@ -46,14 +46,6 @@ static inline void freep(void *);
>   #define FWTS_SUSPEND		"FWTS_SUSPEND"
>   #define FWTS_RESUME		"FWTS_RESUME"
>
> -enum pm_methods
> -{
> -	logind,
> -	pm_utils,
> -	sysfs,
> -	undefined
> -};
> -
>   typedef struct
>   {
>   	fwts_framework *fw;
> @@ -76,7 +68,6 @@ static bool s3_min_max_delay = false;
>   static float s3_suspend_time = 15.0;	/* Maximum allowed suspend time */
>   static float s3_resume_time = 15.0;	/* Maximum allowed resume time */
>   static bool s3_hybrid = false;
> -static enum pm_methods pm_method = undefined; /* Default pm-method to use to suspend */
>
>   static inline void free_fwts_vars(void *vars)
>   {
> @@ -309,18 +300,18 @@ static bool sysfs_can_hybrid_suspend(const fwts_vars *fwts_settings)
>   }
>
>   /* Detect the best available power method */
> -static enum pm_methods detect_pm_method(fwts_vars *fwts_settings)
> +static void detect_pm_method(fwts_vars *fwts_settings)
>   {
>   	if (s3_hybrid ?
>   		logind_can_hybrid_suspend(fwts_settings) :
>   		logind_can_suspend(fwts_settings))
> -		return logind;
> +		fwts_settings->fw->pm_method = logind;
>   	else if (s3_hybrid ?
>   		sysfs_can_hybrid_suspend(fwts_settings) :
>   		sysfs_can_suspend(fwts_settings))
> -		return sysfs;
> +		fwts_settings->fw->pm_method = sysfs;
>   	else
> -		return pm_utils;
> +		fwts_settings->fw->pm_method = pm_utils;
>   }
>
>   /* Call Logind to suspend.
> @@ -517,13 +508,13 @@ static int s3_do_suspend_resume(fwts_framework *fw,
>   		return FWTS_OUT_OF_MEMORY;
>   	fwts_settings->fw = fw;
>
> -	if (pm_method == undefined) {
> +	if (fw->pm_method == undefined) {
>   		/* Autodetection */
>   		fwts_log_info(fw, "Detecting the power method.");
> -		pm_method = detect_pm_method(fwts_settings);
> +		detect_pm_method(fwts_settings);
>   	}
>
> -	switch (pm_method) {
> +	switch (fw->pm_method) {
>   		case logind:
>   			fwts_log_info(fw, "Using logind as the default power method.");
>   			if (logind_init_proxy(fwts_settings) != 0) {
> @@ -551,7 +542,7 @@ static int s3_do_suspend_resume(fwts_framework *fw,
>   		fwts_hwinfo_get(fw, &hwinfo1);
>
>   	/* Format up pm-suspend command with optional quirking arguments */
> -	if (pm_method == pm_utils) {
> +	if (fw->pm_method == pm_utils) {
>   		if (s3_hybrid) {
>   			if ((command = fwts_realloc_strcat(NULL, PM_SUSPEND_HYBRID_PMUTILS)) == NULL)
>   				return FWTS_OUT_OF_MEMORY;
> @@ -966,16 +957,6 @@ static int s3_options_handler(fwts_framework *fw, int argc, char * const argv[],
>   		case 10:
>   			s3_hybrid = true;
>   			break;
> -		case 11:
> -			if (strcmp(optarg, "logind") == 0)
> -				pm_method = logind;
> -			else if (strcmp(optarg, "pm-utils") == 0)
> -				pm_method = pm_utils;
> -			else if (strcmp(optarg, "sysfs") == 0)
> -				pm_method = sysfs;
> -			else
> -				return FWTS_ERROR;
> -			break;
>   		}
>   	}
>   	return FWTS_OK;
> @@ -993,7 +974,6 @@ static fwts_option s3_options[] = {
>   	{ "s3-suspend-time",	"", 1, "Maximum expected suspend time in seconds, e.g. --s3-suspend-time=3.5" },
>   	{ "s3-resume-time", 	"", 1, "Maximum expected resume time in seconds, e.g. --s3-resume-time=5.1" },
>   	{ "s3-hybrid",		"", 0, "Run S3 with hybrid sleep, i.e. saving system states as S4 does." },
> -	{ "pm-method",      "", 1, "Select the power method to use. Accepted values are \"logind\", \"pm-utils\", \"sysfs\""},
>   	{ NULL, NULL, 0, NULL }
>   };
>
> diff --git a/src/lib/include/fwts_framework.h b/src/lib/include/fwts_framework.h
> index 8af8bbe..ca6d41e 100644
> --- a/src/lib/include/fwts_framework.h
> +++ b/src/lib/include/fwts_framework.h
> @@ -27,6 +27,7 @@
>   #include "fwts_log.h"
>   #include "fwts_list.h"
>   #include "fwts_acpica_mode.h"
> +#include "fwts_pm_method.h"
>
>   #define FWTS_FRAMEWORK_MAGIC	0x2af61aec
>
> @@ -140,6 +141,7 @@ typedef struct {
>   	bool error_filtered_out;		/* True if a klog message has been filtered out */
>   	fwts_acpica_mode acpica_mode;		/* ACPICA mode flags */
>   	void *rsdp;				/* ACPI RSDP address */
> +	fwts_pm_method pm_method;
>   } fwts_framework;
>
>   typedef struct {
> diff --git a/src/lib/include/fwts_pm_method.h b/src/lib/include/fwts_pm_method.h
> new file mode 100644
> index 0000000..8a69719
> --- /dev/null
> +++ b/src/lib/include/fwts_pm_method.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright (C) 2014 Canonical
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + */
> +
> +#ifndef __FWTS_PM_METHOD_MODE_H__
> +#define __FWTS_PM_METHOD_MODE_H__
> +
> +typedef enum {
> +	logind,
> +	pm_utils,
> +	sysfs,
> +	undefined
> +} fwts_pm_method;
> +
> +#endif
> diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
> index 3609301..475e9a4 100644
> --- a/src/lib/src/fwts_framework.c
> +++ b/src/lib/src/fwts_framework.c
> @@ -83,6 +83,7 @@ static fwts_option fwts_framework_options[] = {
>   	{ "acpica",		"",   1, "Enable ACPICA run time options." },
>   	{ "uefi",		"",   0, "Run UEFI tests." },
>   	{ "rsdp",		"R:", 1, "Specify the physical address of the ACPI RSDP." },
> +	{ "pm-method",  "",   1, "Select the power method to use. Accepted values are \"logind\", \"pm-utils\", \"sysfs\""},
>   	{ NULL, NULL, 0, NULL }
>   };
>
> @@ -998,6 +999,26 @@ static int fwts_framework_acpica_parse(fwts_framework *fw, const char *arg)
>   	return FWTS_OK;
>   }
>
> +/*
> + *  fwts_framework_pm_method_parse()
> + *	parse optarg of pm-method mode flag
> + */
> +static int fwts_framework_pm_method_parse(fwts_framework *fw, const char *arg)
> +{
> +	if (strcmp(arg, "logind") == 0)
> +		fw->pm_method = logind;
> +	else if (strcmp(arg, "pm-utils") == 0)
> +		fw->pm_method = pm_utils;
> +	else if (strcmp(arg, "sysfs") == 0)
> +		fw->pm_method = sysfs;
> +	else {
> +		fprintf(stderr, "--pm-method only supports logind, pm-utils, and sysfs methods\n");
> +		return FWTS_ERROR;
> +	}
> +
> +	return FWTS_OK;
> +}
> +
>   int fwts_framework_options_handler(fwts_framework *fw, int argc, char * const argv[], int option_char, int long_index)
>   {
>   	FWTS_UNUSED(argc);
> @@ -1134,6 +1155,10 @@ int fwts_framework_options_handler(fwts_framework *fw, int argc, char * const ar
>   		case 37: /* --rsdp */
>   			fw->rsdp = (void *)strtoul(optarg, NULL, 0);
>   			break;
> +		case 38: /* --pm-method */
> +			if (fwts_framework_pm_method_parse(fw, optarg) != FWTS_OK)
> +				return FWTS_ERROR;
> +			break;
>   		}
>   		break;
>   	case 'a': /* --all */
> @@ -1231,6 +1256,9 @@ int fwts_framework_args(const int argc, char **argv)
>   	if ((fw = (fwts_framework *)calloc(1, sizeof(fwts_framework))) == NULL)
>   		return FWTS_ERROR;
>
> +	/* Set the power method to undefined before we parse arguments */
> +	fw->pm_method = undefined;
> +
>   	ret = fwts_args_add_options(fwts_framework_options,
>   		fwts_framework_options_handler, NULL);
>   	if (ret == FWTS_ERROR)
>

Acked-by: Alex Hung <alex.hung@canonical.com>
Keng-Yu Lin Aug. 4, 2014, 2:14 p.m. UTC | #2
On Mon, Aug 4, 2014 at 6:01 PM, Alex Hung <alex.hung@canonical.com> wrote:
> On 08/01/2014 06:20 PM, Alberto Milone wrote:
>>
>> This will allow us to share it with different handlers (e.g. s3 and s4)
>>
>> Signed-off-by: Alberto Milone <alberto.milone@canonical.com>
>> ---
>>   src/acpi/s3/s3.c                 | 36
>> ++++++++----------------------------
>>   src/lib/include/fwts_framework.h |  2 ++
>>   src/lib/include/fwts_pm_method.h | 30 ++++++++++++++++++++++++++++++
>>   src/lib/src/fwts_framework.c     | 28 ++++++++++++++++++++++++++++
>>   4 files changed, 68 insertions(+), 28 deletions(-)
>>   create mode 100644 src/lib/include/fwts_pm_method.h
>>
>> diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c
>> index adcd188..3759de6 100644
>> --- a/src/acpi/s3/s3.c
>> +++ b/src/acpi/s3/s3.c
>> @@ -46,14 +46,6 @@ static inline void freep(void *);
>>   #define FWTS_SUSPEND          "FWTS_SUSPEND"
>>   #define FWTS_RESUME           "FWTS_RESUME"
>>
>> -enum pm_methods
>> -{
>> -       logind,
>> -       pm_utils,
>> -       sysfs,
>> -       undefined
>> -};
>> -
>>   typedef struct
>>   {
>>         fwts_framework *fw;
>> @@ -76,7 +68,6 @@ static bool s3_min_max_delay = false;
>>   static float s3_suspend_time = 15.0;  /* Maximum allowed suspend time */
>>   static float s3_resume_time = 15.0;   /* Maximum allowed resume time */
>>   static bool s3_hybrid = false;
>> -static enum pm_methods pm_method = undefined; /* Default pm-method to use
>> to suspend */
>>
>>   static inline void free_fwts_vars(void *vars)
>>   {
>> @@ -309,18 +300,18 @@ static bool sysfs_can_hybrid_suspend(const fwts_vars
>> *fwts_settings)
>>   }
>>
>>   /* Detect the best available power method */
>> -static enum pm_methods detect_pm_method(fwts_vars *fwts_settings)
>> +static void detect_pm_method(fwts_vars *fwts_settings)
>>   {
>>         if (s3_hybrid ?
>>                 logind_can_hybrid_suspend(fwts_settings) :
>>                 logind_can_suspend(fwts_settings))
>> -               return logind;
>> +               fwts_settings->fw->pm_method = logind;
>>         else if (s3_hybrid ?
>>                 sysfs_can_hybrid_suspend(fwts_settings) :
>>                 sysfs_can_suspend(fwts_settings))
>> -               return sysfs;
>> +               fwts_settings->fw->pm_method = sysfs;
>>         else
>> -               return pm_utils;
>> +               fwts_settings->fw->pm_method = pm_utils;
>>   }
>>
>>   /* Call Logind to suspend.
>> @@ -517,13 +508,13 @@ static int s3_do_suspend_resume(fwts_framework *fw,
>>                 return FWTS_OUT_OF_MEMORY;
>>         fwts_settings->fw = fw;
>>
>> -       if (pm_method == undefined) {
>> +       if (fw->pm_method == undefined) {
>>                 /* Autodetection */
>>                 fwts_log_info(fw, "Detecting the power method.");
>> -               pm_method = detect_pm_method(fwts_settings);
>> +               detect_pm_method(fwts_settings);
>>         }
>>
>> -       switch (pm_method) {
>> +       switch (fw->pm_method) {
>>                 case logind:
>>                         fwts_log_info(fw, "Using logind as the default
>> power method.");
>>                         if (logind_init_proxy(fwts_settings) != 0) {
>> @@ -551,7 +542,7 @@ static int s3_do_suspend_resume(fwts_framework *fw,
>>                 fwts_hwinfo_get(fw, &hwinfo1);
>>
>>         /* Format up pm-suspend command with optional quirking arguments
>> */
>> -       if (pm_method == pm_utils) {
>> +       if (fw->pm_method == pm_utils) {
>>                 if (s3_hybrid) {
>>                         if ((command = fwts_realloc_strcat(NULL,
>> PM_SUSPEND_HYBRID_PMUTILS)) == NULL)
>>                                 return FWTS_OUT_OF_MEMORY;
>> @@ -966,16 +957,6 @@ static int s3_options_handler(fwts_framework *fw, int
>> argc, char * const argv[],
>>                 case 10:
>>                         s3_hybrid = true;
>>                         break;
>> -               case 11:
>> -                       if (strcmp(optarg, "logind") == 0)
>> -                               pm_method = logind;
>> -                       else if (strcmp(optarg, "pm-utils") == 0)
>> -                               pm_method = pm_utils;
>> -                       else if (strcmp(optarg, "sysfs") == 0)
>> -                               pm_method = sysfs;
>> -                       else
>> -                               return FWTS_ERROR;
>> -                       break;
>>                 }
>>         }
>>         return FWTS_OK;
>> @@ -993,7 +974,6 @@ static fwts_option s3_options[] = {
>>         { "s3-suspend-time",    "", 1, "Maximum expected suspend time in
>> seconds, e.g. --s3-suspend-time=3.5" },
>>         { "s3-resume-time",     "", 1, "Maximum expected resume time in
>> seconds, e.g. --s3-resume-time=5.1" },
>>         { "s3-hybrid",          "", 0, "Run S3 with hybrid sleep, i.e.
>> saving system states as S4 does." },
>> -       { "pm-method",      "", 1, "Select the power method to use.
>> Accepted values are \"logind\", \"pm-utils\", \"sysfs\""},
>>         { NULL, NULL, 0, NULL }
>>   };
>>
>> diff --git a/src/lib/include/fwts_framework.h
>> b/src/lib/include/fwts_framework.h
>> index 8af8bbe..ca6d41e 100644
>> --- a/src/lib/include/fwts_framework.h
>> +++ b/src/lib/include/fwts_framework.h
>> @@ -27,6 +27,7 @@
>>   #include "fwts_log.h"
>>   #include "fwts_list.h"
>>   #include "fwts_acpica_mode.h"
>> +#include "fwts_pm_method.h"
>>
>>   #define FWTS_FRAMEWORK_MAGIC  0x2af61aec
>>
>> @@ -140,6 +141,7 @@ typedef struct {
>>         bool error_filtered_out;                /* True if a klog message
>> has been filtered out */
>>         fwts_acpica_mode acpica_mode;           /* ACPICA mode flags */
>>         void *rsdp;                             /* ACPI RSDP address */
>> +       fwts_pm_method pm_method;
>>   } fwts_framework;
>>
>>   typedef struct {
>> diff --git a/src/lib/include/fwts_pm_method.h
>> b/src/lib/include/fwts_pm_method.h
>> new file mode 100644
>> index 0000000..8a69719
>> --- /dev/null
>> +++ b/src/lib/include/fwts_pm_method.h
>> @@ -0,0 +1,30 @@
>> +/*
>> + * Copyright (C) 2014 Canonical
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301, USA.
>> + *
>> + */
>> +
>> +#ifndef __FWTS_PM_METHOD_MODE_H__
>> +#define __FWTS_PM_METHOD_MODE_H__
>> +
>> +typedef enum {
>> +       logind,
>> +       pm_utils,
>> +       sysfs,
>> +       undefined
>> +} fwts_pm_method;
>> +
>> +#endif
>> diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
>> index 3609301..475e9a4 100644
>> --- a/src/lib/src/fwts_framework.c
>> +++ b/src/lib/src/fwts_framework.c
>> @@ -83,6 +83,7 @@ static fwts_option fwts_framework_options[] = {
>>         { "acpica",             "",   1, "Enable ACPICA run time options."
>> },
>>         { "uefi",               "",   0, "Run UEFI tests." },
>>         { "rsdp",               "R:", 1, "Specify the physical address of
>> the ACPI RSDP." },
>> +       { "pm-method",  "",   1, "Select the power method to use. Accepted
>> values are \"logind\", \"pm-utils\", \"sysfs\""},
>>         { NULL, NULL, 0, NULL }
>>   };
>>
>> @@ -998,6 +999,26 @@ static int fwts_framework_acpica_parse(fwts_framework
>> *fw, const char *arg)
>>         return FWTS_OK;
>>   }
>>
>> +/*
>> + *  fwts_framework_pm_method_parse()
>> + *     parse optarg of pm-method mode flag
>> + */
>> +static int fwts_framework_pm_method_parse(fwts_framework *fw, const char
>> *arg)
>> +{
>> +       if (strcmp(arg, "logind") == 0)
>> +               fw->pm_method = logind;
>> +       else if (strcmp(arg, "pm-utils") == 0)
>> +               fw->pm_method = pm_utils;
>> +       else if (strcmp(arg, "sysfs") == 0)
>> +               fw->pm_method = sysfs;
>> +       else {
>> +               fprintf(stderr, "--pm-method only supports logind,
>> pm-utils, and sysfs methods\n");
>> +               return FWTS_ERROR;
>> +       }
>> +
>> +       return FWTS_OK;
>> +}
>> +
>>   int fwts_framework_options_handler(fwts_framework *fw, int argc, char *
>> const argv[], int option_char, int long_index)
>>   {
>>         FWTS_UNUSED(argc);
>> @@ -1134,6 +1155,10 @@ int fwts_framework_options_handler(fwts_framework
>> *fw, int argc, char * const ar
>>                 case 37: /* --rsdp */
>>                         fw->rsdp = (void *)strtoul(optarg, NULL, 0);
>>                         break;
>> +               case 38: /* --pm-method */
>> +                       if (fwts_framework_pm_method_parse(fw, optarg) !=
>> FWTS_OK)
>> +                               return FWTS_ERROR;
>> +                       break;
>>                 }
>>                 break;
>>         case 'a': /* --all */
>> @@ -1231,6 +1256,9 @@ int fwts_framework_args(const int argc, char **argv)
>>         if ((fw = (fwts_framework *)calloc(1, sizeof(fwts_framework))) ==
>> NULL)
>>                 return FWTS_ERROR;
>>
>> +       /* Set the power method to undefined before we parse arguments */
>> +       fw->pm_method = undefined;
>> +
>>         ret = fwts_args_add_options(fwts_framework_options,
>>                 fwts_framework_options_handler, NULL);
>>         if (ret == FWTS_ERROR)
>>
>
> Acked-by: Alex Hung <alex.hung@canonical.com>
>

Acked-by: Keng-Yu Lin <kengyu@canonical.com>
diff mbox

Patch

diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c
index adcd188..3759de6 100644
--- a/src/acpi/s3/s3.c
+++ b/src/acpi/s3/s3.c
@@ -46,14 +46,6 @@  static inline void freep(void *);
 #define FWTS_SUSPEND		"FWTS_SUSPEND"
 #define FWTS_RESUME		"FWTS_RESUME"
 
-enum pm_methods
-{
-	logind,
-	pm_utils,
-	sysfs,
-	undefined
-};
-
 typedef struct
 {
 	fwts_framework *fw;
@@ -76,7 +68,6 @@  static bool s3_min_max_delay = false;
 static float s3_suspend_time = 15.0;	/* Maximum allowed suspend time */
 static float s3_resume_time = 15.0;	/* Maximum allowed resume time */
 static bool s3_hybrid = false;
-static enum pm_methods pm_method = undefined; /* Default pm-method to use to suspend */
 
 static inline void free_fwts_vars(void *vars)
 {
@@ -309,18 +300,18 @@  static bool sysfs_can_hybrid_suspend(const fwts_vars *fwts_settings)
 }
 
 /* Detect the best available power method */
-static enum pm_methods detect_pm_method(fwts_vars *fwts_settings)
+static void detect_pm_method(fwts_vars *fwts_settings)
 {
 	if (s3_hybrid ?
 		logind_can_hybrid_suspend(fwts_settings) :
 		logind_can_suspend(fwts_settings))
-		return logind;
+		fwts_settings->fw->pm_method = logind;
 	else if (s3_hybrid ?
 		sysfs_can_hybrid_suspend(fwts_settings) :
 		sysfs_can_suspend(fwts_settings))
-		return sysfs;
+		fwts_settings->fw->pm_method = sysfs;
 	else
-		return pm_utils;
+		fwts_settings->fw->pm_method = pm_utils;
 }
 
 /* Call Logind to suspend.
@@ -517,13 +508,13 @@  static int s3_do_suspend_resume(fwts_framework *fw,
 		return FWTS_OUT_OF_MEMORY;
 	fwts_settings->fw = fw;
 
-	if (pm_method == undefined) {
+	if (fw->pm_method == undefined) {
 		/* Autodetection */
 		fwts_log_info(fw, "Detecting the power method.");
-		pm_method = detect_pm_method(fwts_settings);
+		detect_pm_method(fwts_settings);
 	}
 
-	switch (pm_method) {
+	switch (fw->pm_method) {
 		case logind:
 			fwts_log_info(fw, "Using logind as the default power method.");
 			if (logind_init_proxy(fwts_settings) != 0) {
@@ -551,7 +542,7 @@  static int s3_do_suspend_resume(fwts_framework *fw,
 		fwts_hwinfo_get(fw, &hwinfo1);
 
 	/* Format up pm-suspend command with optional quirking arguments */
-	if (pm_method == pm_utils) {
+	if (fw->pm_method == pm_utils) {
 		if (s3_hybrid) {
 			if ((command = fwts_realloc_strcat(NULL, PM_SUSPEND_HYBRID_PMUTILS)) == NULL)
 				return FWTS_OUT_OF_MEMORY;
@@ -966,16 +957,6 @@  static int s3_options_handler(fwts_framework *fw, int argc, char * const argv[],
 		case 10:
 			s3_hybrid = true;
 			break;
-		case 11:
-			if (strcmp(optarg, "logind") == 0)
-				pm_method = logind;
-			else if (strcmp(optarg, "pm-utils") == 0)
-				pm_method = pm_utils;
-			else if (strcmp(optarg, "sysfs") == 0)
-				pm_method = sysfs;
-			else
-				return FWTS_ERROR;
-			break;
 		}
 	}
 	return FWTS_OK;
@@ -993,7 +974,6 @@  static fwts_option s3_options[] = {
 	{ "s3-suspend-time",	"", 1, "Maximum expected suspend time in seconds, e.g. --s3-suspend-time=3.5" },
 	{ "s3-resume-time", 	"", 1, "Maximum expected resume time in seconds, e.g. --s3-resume-time=5.1" },
 	{ "s3-hybrid",		"", 0, "Run S3 with hybrid sleep, i.e. saving system states as S4 does." },
-	{ "pm-method",      "", 1, "Select the power method to use. Accepted values are \"logind\", \"pm-utils\", \"sysfs\""},
 	{ NULL, NULL, 0, NULL }
 };
 
diff --git a/src/lib/include/fwts_framework.h b/src/lib/include/fwts_framework.h
index 8af8bbe..ca6d41e 100644
--- a/src/lib/include/fwts_framework.h
+++ b/src/lib/include/fwts_framework.h
@@ -27,6 +27,7 @@ 
 #include "fwts_log.h"
 #include "fwts_list.h"
 #include "fwts_acpica_mode.h"
+#include "fwts_pm_method.h"
 
 #define FWTS_FRAMEWORK_MAGIC	0x2af61aec
 
@@ -140,6 +141,7 @@  typedef struct {
 	bool error_filtered_out;		/* True if a klog message has been filtered out */
 	fwts_acpica_mode acpica_mode;		/* ACPICA mode flags */
 	void *rsdp;				/* ACPI RSDP address */
+	fwts_pm_method pm_method;
 } fwts_framework;
 
 typedef struct {
diff --git a/src/lib/include/fwts_pm_method.h b/src/lib/include/fwts_pm_method.h
new file mode 100644
index 0000000..8a69719
--- /dev/null
+++ b/src/lib/include/fwts_pm_method.h
@@ -0,0 +1,30 @@ 
+/*
+ * Copyright (C) 2014 Canonical
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __FWTS_PM_METHOD_MODE_H__
+#define __FWTS_PM_METHOD_MODE_H__
+
+typedef enum {
+	logind,
+	pm_utils,
+	sysfs,
+	undefined
+} fwts_pm_method;
+
+#endif
diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
index 3609301..475e9a4 100644
--- a/src/lib/src/fwts_framework.c
+++ b/src/lib/src/fwts_framework.c
@@ -83,6 +83,7 @@  static fwts_option fwts_framework_options[] = {
 	{ "acpica",		"",   1, "Enable ACPICA run time options." },
 	{ "uefi",		"",   0, "Run UEFI tests." },
 	{ "rsdp",		"R:", 1, "Specify the physical address of the ACPI RSDP." },
+	{ "pm-method",  "",   1, "Select the power method to use. Accepted values are \"logind\", \"pm-utils\", \"sysfs\""},
 	{ NULL, NULL, 0, NULL }
 };
 
@@ -998,6 +999,26 @@  static int fwts_framework_acpica_parse(fwts_framework *fw, const char *arg)
 	return FWTS_OK;
 }
 
+/*
+ *  fwts_framework_pm_method_parse()
+ *	parse optarg of pm-method mode flag
+ */
+static int fwts_framework_pm_method_parse(fwts_framework *fw, const char *arg)
+{
+	if (strcmp(arg, "logind") == 0)
+		fw->pm_method = logind;
+	else if (strcmp(arg, "pm-utils") == 0)
+		fw->pm_method = pm_utils;
+	else if (strcmp(arg, "sysfs") == 0)
+		fw->pm_method = sysfs;
+	else {
+		fprintf(stderr, "--pm-method only supports logind, pm-utils, and sysfs methods\n");
+		return FWTS_ERROR;
+	}
+
+	return FWTS_OK;
+}
+
 int fwts_framework_options_handler(fwts_framework *fw, int argc, char * const argv[], int option_char, int long_index)
 {
 	FWTS_UNUSED(argc);
@@ -1134,6 +1155,10 @@  int fwts_framework_options_handler(fwts_framework *fw, int argc, char * const ar
 		case 37: /* --rsdp */
 			fw->rsdp = (void *)strtoul(optarg, NULL, 0);
 			break;
+		case 38: /* --pm-method */
+			if (fwts_framework_pm_method_parse(fw, optarg) != FWTS_OK)
+				return FWTS_ERROR;
+			break;
 		}
 		break;
 	case 'a': /* --all */
@@ -1231,6 +1256,9 @@  int fwts_framework_args(const int argc, char **argv)
 	if ((fw = (fwts_framework *)calloc(1, sizeof(fwts_framework))) == NULL)
 		return FWTS_ERROR;
 
+	/* Set the power method to undefined before we parse arguments */
+	fw->pm_method = undefined;
+
 	ret = fwts_args_add_options(fwts_framework_options,
 		fwts_framework_options_handler, NULL);
 	if (ret == FWTS_ERROR)