• Serge Semin's avatar
    ata: libahci_platform: Introduce reset assertion/deassertion methods · f67f12ff
    Serge Semin authored
    Currently the ACHI-platform library supports only the assert and deassert
    reset signals and ignores the platforms with self-deasserting reset lines.
    That prone to having the platforms with self-deasserting reset method
    misbehaviour when it comes to resuming from sleep state after the clocks
    have been fully disabled. For such cases the controller needs to be fully
    reset all over after the reference clocks are enabled and stable,
    otherwise the controller state machine might be in an undetermined state.
    
    The best solution would be to auto-detect which reset method is supported
    by the particular platform and use it implicitly in the framework of the
    ahci_platform_enable_resources()/ahci_platform_disable_resources()
    methods. Alas it can't be implemented due to the AHCI-platform library
    already supporting the shared reset control lines. As [1] says in such
    case we have to use only one of the next methods:
    + reset_control_assert()/reset_control_deassert();
    + reset_control_reset()/reset_control_rearm().
    If the driver had an exclusive control over the reset lines we could have
    been able to manipulate the lines with no much limitation and just used
    the combination of the methods above to cover all the possible
    reset-control cases. Since the shared reset control has already been
    advertised and couldn't be changed with no risk to breaking the platforms
    relying on it, we have no choice but to make the platform drivers to
    determine which reset methods the platform reset system supports.
    
    In order to implement both types of reset control support we suggest to
    introduce the new AHCI-platform flag: AHCI_PLATFORM_RST_TRIGGER, which
    when passed to the ahci_platform_get_resources() method together with the
    AHCI_PLATFORM_GET_RESETS flag will indicate that the reset lines are
    self-deasserting thus the reset_control_reset()/reset_control_rearm() will
    be used to control the reset state. Otherwise the
    reset_control_deassert()/reset_control_assert() methods will be utilized.
    
    [1] Documentation/driver-api/reset.rst
    Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
    Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
    Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
    f67f12ff
libahci_platform.c 21.8 KB