Convert all boards to use the servod 'power_state' control.

All boards now provide the standard board-independent interface for
power off, power on, recovery mode, and cold reset operations.

BUG=chromium:342875,chromium:326738
TEST=Pending

Change-Id: Ic68017a598df3745347ceff90cc8d8faf8e344fe
Reviewed-on: https://chromium-review.googlesource.com/202720
Tested-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Kris Rambish <krisr@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
Commit-Queue: Richard Barnette <jrbarnette@chromium.org>
diff --git a/server/cros/faft/faft_classes.py b/server/cros/faft/faft_classes.py
index cd6c20f..b91ea65 100644
--- a/server/cros/faft/faft_classes.py
+++ b/server/cros/faft/faft_classes.py
@@ -1351,14 +1351,7 @@
 
         A wrapper for underlying servo cold reset.
         """
-        if self.faft_config.broken_warm_reset:
-            self.servo.set('pwr_button', 'press')
-            self.servo.set('cold_reset', 'on')
-            self.servo.set('cold_reset', 'off')
-            time.sleep(self.faft_config.ec_boot_to_pwr_button)
-            self.servo.set('pwr_button', 'release')
-        else:
-            self.servo.get_power_state_controller().cold_reset()
+        self.servo.get_power_state_controller().reset()
 
     def sync_and_warm_reboot(self):
         """Request the client sync and do a warm reboot.
diff --git a/server/cros/faft/firmware_test.py b/server/cros/faft/firmware_test.py
index cfaa9dd..23de9a2 100644
--- a/server/cros/faft/firmware_test.py
+++ b/server/cros/faft/firmware_test.py
@@ -1191,14 +1191,7 @@
 
         A wrapper for underlying servo cold reset.
         """
-        if self.faft_config.broken_warm_reset:
-            self.servo.set('pwr_button', 'press')
-            self.servo.set('cold_reset', 'on')
-            self.servo.set('cold_reset', 'off')
-            time.sleep(self.faft_config.ec_boot_to_pwr_button)
-            self.servo.set('pwr_button', 'release')
-        else:
-            self.servo.get_power_state_controller().cold_reset()
+        self.servo.get_power_state_controller().reset()
 
     def sync_and_warm_reboot(self):
         """Request the client sync and do a warm reboot.
diff --git a/server/cros/servo/power_state_controller.py b/server/cros/servo/power_state_controller.py
index 1e7c835..a8601bf 100644
--- a/server/cros/servo/power_state_controller.py
+++ b/server/cros/servo/power_state_controller.py
@@ -2,39 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import time
-
-
-def _inherit_docstring(cls):
-    """Decorator to propagate a docstring to a subclass's method.
-
-    @param cls Class with the method whose docstring is to be
-               inherited.  The class must contain a method with
-               the same name as the name of the function to be
-               decorated.
-
-    """
-    def _copy_docstring(methfunc):
-        """Actually copy the parent docstring to the child.
-
-        @param methfunc Function that will inherit the docstring.
-
-        """
-        methfunc.__doc__ = getattr(cls, methfunc.__name__).__doc__
-        return methfunc
-    return _copy_docstring
-
-
-# Constants acceptable to be passed for the `rec_mode` parameter
-# to power_on().
-#
-# REC_ON:  Boot the DUT in recovery mode, i.e. boot from USB or
-#   SD card.
-# REC_OFF:  Boot in normal mode, i.e. boot from internal storage.
-
-REC_ON = 'on'
-REC_OFF = 'off'
-
 
 class _PowerStateController(object):
 
@@ -48,16 +15,19 @@
 
     """
 
-    # Delay in seconds needed between asserting and de-asserting cold
-    # or warm reset.  Subclasses will normally override this constant
-    # with a board-specific value.
-    _RESET_HOLD_TIME = 0.5
+    # Constants acceptable to be passed for the `rec_mode` parameter
+    # to power_on().
+    #
+    # REC_ON:  Boot the DUT in recovery mode, i.e. boot from USB or
+    #   SD card.
+    # REC_OFF:  Boot in normal mode, i.e. boot from internal storage.
 
-    # _EC_RESET_DELAY:  Time required before the EC will be working
-    #   after cold reset.  Five seconds is at least twice as long as
-    #   necessary for Alex, and is presumably good enough for all other
-    #   systems.
-    _EC_RESET_DELAY = 5.0
+    REC_ON = 'rec'
+    REC_OFF = 'on'
+
+    # Delay in seconds needed between asserting and de-asserting
+    # warm reset.
+    _RESET_HOLD_TIME = 0.5
 
     def __init__(self, servo):
         """Initialize the power state control.
@@ -68,20 +38,16 @@
         """
         self._servo = servo
 
-    def cold_reset(self):
-        """Apply cold reset to the DUT.
+    def reset(self):
+        """Force the DUT to reset.
 
-        This asserts, then de-asserts the 'cold_reset' signal.
-        The exact affect on the hardware varies depending on
-        the board type.
+        The DUT is guaranteed to be on at the end of this call,
+        regardless of its previous state, provided that there is
+        working OS software. This also guarantees that the EC has
+        been restarted.
 
         """
-        self._servo.set_get_all(['cold_reset:on',
-                                 'sleep:%.4f' % self._RESET_HOLD_TIME,
-                                 'cold_reset:off'])
-        # After the reset, give the EC the time it needs to
-        # re-initialize.
-        time.sleep(self._EC_RESET_DELAY)
+        self._servo.set_nocheck('power_state', 'reset')
 
     def warm_reset(self):
         """Apply warm reset to the DUT.
@@ -101,7 +67,7 @@
                 not raise a NotImplementedError.  False means they will.
 
         """
-        return False
+        return True
 
     def power_off(self):
         """Force the DUT to power off.
@@ -112,7 +78,7 @@
         working OS software.
 
         """
-        raise NotImplementedError()
+        self._servo.set_nocheck('power_state', 'off')
 
     def power_on(self, rec_mode=REC_OFF):
         """Force the DUT to power on.
@@ -134,107 +100,17 @@
                         power on. default: REC_OFF aka 'off'
 
         """
-        raise NotImplementedError()
+        self._servo.set_nocheck('power_state', rec_mode)
 
 
-    def reset(self):
-        """Force the DUT to reset.
-
-        The DUT is guaranteed to be on at the end of this call,
-        regardless of its previous state, provided that there is
-        working OS software. This also guarantees that the EC has
-        been restarted.
-
-        """
-        raise NotImplementedError()
-
-
-class _ServodController(_PowerStateController):
-
-    """Controller based on the servod `power_state` control.
-
-    TODO(jrbarnette):  This is a transitional class.  Servod is
-    adding support for operations like `set('power_state', 'off')`,
-    which will supersede `_PowerStateController`.  However, not all
-    boards are both implemented and tested in servod.  To manage
-    the transition, boards that support the new feature are mapped
-    to this class.
-
-    Once support in hdctools is complete for all boards, this class
-    should be removed, and the functionality should be refactored to
-    be board-independent.
-
-    """
-
-    @_inherit_docstring(_PowerStateController)
-    def recovery_supported(self):
-        return True
-
-    @_inherit_docstring(_PowerStateController)
-    def power_off(self):
-        self._servo.set_nocheck('power_state', 'off')
-
-    @_inherit_docstring(_PowerStateController)
-    def power_on(self, rec_mode=REC_OFF):
-        if rec_mode == REC_OFF:
-            state = 'on'
-        else:
-            state = 'rec'
-        self._servo.set_nocheck('power_state', state)
-
-    @_inherit_docstring(_PowerStateController)
-    def reset(self):
-        self._servo.set_nocheck('power_state', 'reset')
-
-
-class _PantherController(_PowerStateController):
-
-    """Power-state controller for Panther and compatible boards.
-
-    For Panther, the 'cold_reset' signal is now connected (from DVT)
-    However releasing the 'cold_reset' line does not power on the
-    device. Hence the need to press the power button.
-    """
-
-    _RESET_HOLD_TIME = 0.5
-    _RESET_DELAY = 5.0
-    _TIME_TO_HOLD_POWER_BUTTON = 1.2
-
-    @_inherit_docstring(_PowerStateController)
-    def cold_reset(self):
-        self._servo.set_get_all(['cold_reset:on',
-                                 'sleep:%.4f' % self._RESET_HOLD_TIME,
-                                 'cold_reset:off'])
-        time.sleep(self._RESET_DELAY)
-
-        self._servo.set('pwr_button', 'press')
-        time.sleep(self._TIME_TO_HOLD_POWER_BUTTON)
-        self._servo.set('pwr_button', 'release')
-
-
-_CONTROLLER_BOARD_MAP = {
-    'panther': _PantherController,
-    'mccloud': _PantherController,
-    'monroe': _PantherController,
-    'zako': _PantherController,
-    'tricky': _PantherController,
-}
-
-
-def create_controller(servo, board):
+def create_controller(servo):
     """Create a power state controller instance.
 
-    The controller class will be selected based on the provided board type, and
-    instantiated with the provided servo instance. Default controller is
-    _ServodController.
-
     @param servo Servo object that will be used to manipulate DUT
                  power states.
-    @param board Board name of the DUT to be controlled.
 
-    @returns An instance of a power state controller appropriate to
-             the given board type, default controller is _ServodController if no
-             controller is specified for the board.
+    @returns An instance of _PowerStateController for the servo
+             object.
 
     """
-    return _CONTROLLER_BOARD_MAP.get(board, _ServodController)(servo)
+    return _PowerStateController(servo)
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index 09c2c5d..454606a 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -10,7 +10,6 @@
 import logging, re, time, xmlrpclib
 
 from autotest_lib.client.common_lib import error
-from autotest_lib.server import utils
 from autotest_lib.server.cros.servo import power_state_controller
 from autotest_lib.server.cros.servo import firmware_programmer
 
@@ -75,9 +74,8 @@
         self._servo_host = servo_host
         self._servo_serial = servo_serial
         self._server = servo_host.get_servod_server_proxy()
-        board = self._server.get_board()
         self._power_state = (
-            power_state_controller.create_controller(self, board))
+            power_state_controller.create_controller(self))
 
         # a string, showing what interface (host or dut) the USB device is
         # connected to.
@@ -124,16 +122,15 @@
         that's off, depending on the board type and previous state
         of the device.
 
-        If `cold_reset` is a true value, cold reset will be applied
-        to the DUT.  Cold reset will force the DUT to power off;
-        however, the final state of the DUT depends on the board type.
+        If `cold_reset` is a true value, the DUT and its EC will be
+        reset, and the DUT rebooted in normal mode.
 
         @param cold_reset If True, cold reset the device after
                           initialization.
         """
         self._server.hwinit()
         if cold_reset:
-            self._power_state.cold_reset()
+            self._power_state.reset()
 
 
     def is_localhost(self):
@@ -513,7 +510,7 @@
                                        automatically after installation.
         """
         self.image_to_servo_usb(image_path, make_image_noninteractive)
-        self._power_state.power_on(rec_mode=power_state_controller.REC_ON)
+        self._power_state.power_on(rec_mode=self._power_state.REC_ON)
         self.switch_usbkey('dut')
 
 
diff --git a/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py b/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
index 5c270a0..f02f3d8 100644
--- a/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
+++ b/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
@@ -2,9 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import json, logging, re, time
+import logging, re, time
 
-from autotest_lib.server import autotest, test
+from autotest_lib.server import test
 from autotest_lib.server.cros import stress
 from autotest_lib.server.cros.servo import servo
 from autotest_lib.client.common_lib import error
@@ -96,7 +96,7 @@
             if skip_gbb:
                 # For devices that do not support gbb we have servo
                 # accelerate booting through dev mode.
-                host.servo.get_power_state_controller().cold_reset()
+                host.servo.get_power_state_controller().reset()
                 host.servo.power_short_press()
                 time.sleep(servo.Servo.BOOT_DELAY)
                 host.servo.ctrl_d()
diff --git a/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py b/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
index 9dbbf7c..4d8760b 100644
--- a/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
+++ b/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
@@ -6,7 +6,6 @@
 
 from autotest_lib.client.common_lib import error
 from autotest_lib.server import test
-from autotest_lib.server.cros.servo import power_state_controller
 
 
 class platform_ServoPowerStateController(test.test):
@@ -25,7 +24,7 @@
             # Power off, then power on DUT from internal storage.
             self.controller.power_off()
             self.host.servo.switch_usbkey('off')
-            self.controller.power_on(power_state_controller.REC_OFF)
+            self.controller.power_on(self.controller.REC_OFF)
 
 
     def confirm_dut_on(self, rec_on=False):
@@ -73,7 +72,7 @@
         # Power DUT on in non-recovery mode with USB stick plugged in.
         # DUT shall boot from internal storage.
         logging.info('Power on DUT in non-recovery mode.')
-        self.controller.power_on(power_state_controller.REC_OFF)
+        self.controller.power_on(self.controller.REC_OFF)
         self.confirm_dut_on()
 
         logging.info('Power off DUT which is up in non-recovery mode.')
@@ -83,7 +82,7 @@
 
         logging.info('Power DUT on in recovery mode, DUT shall boot from USB.')
         self.host.servo.switch_usbkey('off')
-        self.controller.power_on(power_state_controller.REC_ON)
+        self.controller.power_on(self.controller.REC_ON)
         self.host.servo.switch_usbkey('dut')
         time.sleep(30)
         self.confirm_dut_on(rec_on=True)
@@ -94,7 +93,7 @@
                              'USB stick.')
 
         logging.info('Power on in non-recovery mode.')
-        self.controller.power_on(power_state_controller.REC_OFF)
+        self.controller.power_on(self.controller.REC_OFF)
         self.confirm_dut_on(rec_on=False)
 
 
@@ -116,7 +115,7 @@
 
         # DUT should be off before calling power_on(REC_ON)
         logging.info('Power on DUT in recovery mode with USB unplugged.')
-        self.controller.power_on(power_state_controller.REC_ON)
+        self.controller.power_on(self.controller.REC_ON)
         self.confirm_dut_off("power_state:rec didn't stay at recovery screen.")
 
         logging.info('Power off DUT in recovery mode with USB unplugged.')
@@ -124,13 +123,13 @@
         self.confirm_dut_off('power_state:off failed at recovery screen.')
 
         logging.info('Power on in non-recovery mode.')
-        self.controller.power_on(power_state_controller.REC_OFF)
+        self.controller.power_on(self.controller.REC_OFF)
         self.confirm_dut_on(rec_on=False)
 
         logging.info('Power DUT off and on without delay. DUT should be on '
                      'after power_on is completed.')
         self.controller.power_off()
-        self.controller.power_on(power_state_controller.REC_OFF)
+        self.controller.power_on(self.controller.REC_OFF)
         self.confirm_dut_on(rec_on=False)
 
         logging.info('Power DUT off and reset. DUT should be on after reset '
diff --git a/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py b/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
index 166ee78..065a59b 100644
--- a/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
+++ b/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
@@ -108,6 +108,6 @@
         self._servo.program_ec(os.path.join(self.tmpd.name, self._ec_image))
         logging.info('Will re-program BIOS now')
         self._servo.program_bios(os.path.join(self.tmpd.name, self._ap_image))
-        self._servo.get_power_state_controller().cold_reset()
+        self._servo.get_power_state_controller().reset()
         time.sleep(self._servo.BOOT_DELAY)
         self._add_version_label()