Re: [PATCH v2] mfd: Add support for RTS5250S power saving

2017-08-21 Thread Lee Jones
On Mon, 21 Aug 2017, rui_f...@realsil.com.cn wrote:

> From: rui_feng 

Please use the format "First Last" for you name.

> Signed-off-by: rui_feng 

Same.

You should also send patches using `git format patch` and `git send-email`.

> ---
>  drivers/mfd/rts5249.c| 183 ++
>  drivers/mfd/rtsx_pcr.c   | 206 
> +--
>  drivers/mfd/rtsx_pcr.h   |   2 +
>  include/linux/mfd/rtsx_pci.h |  47 ++
>  4 files changed, 433 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
> index 40f8bb1..a560b5a 100644
> --- a/drivers/mfd/rts5249.c
> +++ b/drivers/mfd/rts5249.c
> @@ -103,8 +103,70 @@ static void rtsx_base_force_power_down(struct rtsx_pcr 
> *pcr, u8 pm_state)
>   rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
>  }
>  
> +static int rts5249_init_from_cfg(struct rtsx_pcr *pcr)
> +{
> + struct cr_option *option = &(pcr->option);
> + u32 lval;
> +
> + if (CHK_PCI_PID(pcr, 0x524A))

No magic numbers please.

Almost all of the numbers below should be defined.

> + rtsx_pci_read_config_dword(pcr, 0x160, );
> + else
> + rtsx_pci_read_config_dword(pcr, 0x168, );
> +
> + if (lval & (1 << 3))

... including these.

> + set_dev_flag(pcr, ASPM_L1_1_EN);
> + else
> + clear_dev_flag(pcr, ASPM_L1_1_EN);
> + if (lval & (1 << 2))
> + set_dev_flag(pcr, ASPM_L1_2_EN);
> + else
> + clear_dev_flag(pcr, ASPM_L1_2_EN);
> +
> + if (lval & (1 << 1))
> + set_dev_flag(pcr, PM_L1_1_EN);
> + else
> + clear_dev_flag(pcr, PM_L1_1_EN);
> + if (lval & (1 << 0))
> + set_dev_flag(pcr, PM_L1_2_EN);
> + else
> + clear_dev_flag(pcr, PM_L1_2_EN);
> +
> + if (option->ltr_en) {
> + u16 val;
> +
> + pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
> + if (val & PCI_EXP_DEVCTL2_LTR_EN) {
> + option->ltr_enabled = 1;
> + option->ltr_active = 1;

These should be bool.  Then use 'true' instead of '1'.

Same for all the other 'yes/no' variables used here.

> + rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
> + } else {
> + option->ltr_enabled = 0;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
> +{
> + struct cr_option *option = &(pcr->option);
> +
> + if (check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
> + | PM_L1_1_EN | PM_L1_2_EN))
> + option->force_clkreq_0 = 0;
> + else
> + option->force_clkreq_0 = 1;
> +
> + return 0;
> +}
> +
>  static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
>  {
> + struct cr_option *option = &(pcr->option);
> +
> + rts5249_init_from_cfg(pcr);
> + rts5249_init_from_hw(pcr);
> +
>   rtsx_pci_init_cmd(pcr);
>  
>   /* Rest L1SUB Config */
> @@ -125,6 +187,14 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
>   else
>   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
>  
> + /* u_force_clkreq_0

The first line of a multi-line comment should be blank.

> +  * If 1, CLKREQ# PIN will be forced to drive 0 to request clock

"If 1"?  That's a very ambiguous comment.

Leave coding nuances out of comments.  Just use plain English.

> +  */
> + if (option->force_clkreq_0)
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x80);
> + else
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x00);

More magic numbers to define.

>   return rtsx_pci_send_cmd(pcr, 100);
>  }
>  
> @@ -353,6 +423,8 @@ static int rtsx_base_switch_output_voltage(struct 
> rtsx_pcr *pcr, u8 voltage)
>  
>  void rts5249_init_params(struct rtsx_pcr *pcr)
>  {
> + struct cr_option *option = &(pcr->option);
> +
>   pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
>   pcr->num_slots = 2;
>   pcr->ops = _pcr_ops;
> @@ -372,6 +444,19 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
>   pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
>  
>   pcr->reg_pm_ctrl3 = PM_CTRL3;
> +
> + option->dev_flags |= LTR_L1SS_PWR_GATE_CHECK_CARD_EN;
> + option->dev_flags |= LTR_L1SS_PWR_GATE_EN;

It's more common to do both of these using a single statement.

> + option->ltr_en = 1;

Bool.

> + /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
> + /* 60us:0x883C, 300us:0x892C, 3ms:0x9003 */

No need for this comment, just define them all.

> + option->ltr_active_latency = 0x883C;
> + option->ltr_idle_latency = 0x892C;
> + option->ltr_l1off_latency = 0x9003;
> + option->dev_aspm_mode = DEV_ASPM_DYNAMIC;
> + option->l1_snooze_delay = 1;
> 

Re: [PATCH v2] mfd: Add support for RTS5250S power saving

2017-08-21 Thread Lee Jones
On Mon, 21 Aug 2017, rui_f...@realsil.com.cn wrote:

> From: rui_feng 

Please use the format "First Last" for you name.

> Signed-off-by: rui_feng 

Same.

You should also send patches using `git format patch` and `git send-email`.

> ---
>  drivers/mfd/rts5249.c| 183 ++
>  drivers/mfd/rtsx_pcr.c   | 206 
> +--
>  drivers/mfd/rtsx_pcr.h   |   2 +
>  include/linux/mfd/rtsx_pci.h |  47 ++
>  4 files changed, 433 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
> index 40f8bb1..a560b5a 100644
> --- a/drivers/mfd/rts5249.c
> +++ b/drivers/mfd/rts5249.c
> @@ -103,8 +103,70 @@ static void rtsx_base_force_power_down(struct rtsx_pcr 
> *pcr, u8 pm_state)
>   rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
>  }
>  
> +static int rts5249_init_from_cfg(struct rtsx_pcr *pcr)
> +{
> + struct cr_option *option = &(pcr->option);
> + u32 lval;
> +
> + if (CHK_PCI_PID(pcr, 0x524A))

No magic numbers please.

Almost all of the numbers below should be defined.

> + rtsx_pci_read_config_dword(pcr, 0x160, );
> + else
> + rtsx_pci_read_config_dword(pcr, 0x168, );
> +
> + if (lval & (1 << 3))

... including these.

> + set_dev_flag(pcr, ASPM_L1_1_EN);
> + else
> + clear_dev_flag(pcr, ASPM_L1_1_EN);
> + if (lval & (1 << 2))
> + set_dev_flag(pcr, ASPM_L1_2_EN);
> + else
> + clear_dev_flag(pcr, ASPM_L1_2_EN);
> +
> + if (lval & (1 << 1))
> + set_dev_flag(pcr, PM_L1_1_EN);
> + else
> + clear_dev_flag(pcr, PM_L1_1_EN);
> + if (lval & (1 << 0))
> + set_dev_flag(pcr, PM_L1_2_EN);
> + else
> + clear_dev_flag(pcr, PM_L1_2_EN);
> +
> + if (option->ltr_en) {
> + u16 val;
> +
> + pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
> + if (val & PCI_EXP_DEVCTL2_LTR_EN) {
> + option->ltr_enabled = 1;
> + option->ltr_active = 1;

These should be bool.  Then use 'true' instead of '1'.

Same for all the other 'yes/no' variables used here.

> + rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
> + } else {
> + option->ltr_enabled = 0;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
> +{
> + struct cr_option *option = &(pcr->option);
> +
> + if (check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
> + | PM_L1_1_EN | PM_L1_2_EN))
> + option->force_clkreq_0 = 0;
> + else
> + option->force_clkreq_0 = 1;
> +
> + return 0;
> +}
> +
>  static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
>  {
> + struct cr_option *option = &(pcr->option);
> +
> + rts5249_init_from_cfg(pcr);
> + rts5249_init_from_hw(pcr);
> +
>   rtsx_pci_init_cmd(pcr);
>  
>   /* Rest L1SUB Config */
> @@ -125,6 +187,14 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
>   else
>   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
>  
> + /* u_force_clkreq_0

The first line of a multi-line comment should be blank.

> +  * If 1, CLKREQ# PIN will be forced to drive 0 to request clock

"If 1"?  That's a very ambiguous comment.

Leave coding nuances out of comments.  Just use plain English.

> +  */
> + if (option->force_clkreq_0)
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x80);
> + else
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x00);

More magic numbers to define.

>   return rtsx_pci_send_cmd(pcr, 100);
>  }
>  
> @@ -353,6 +423,8 @@ static int rtsx_base_switch_output_voltage(struct 
> rtsx_pcr *pcr, u8 voltage)
>  
>  void rts5249_init_params(struct rtsx_pcr *pcr)
>  {
> + struct cr_option *option = &(pcr->option);
> +
>   pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
>   pcr->num_slots = 2;
>   pcr->ops = _pcr_ops;
> @@ -372,6 +444,19 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
>   pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
>  
>   pcr->reg_pm_ctrl3 = PM_CTRL3;
> +
> + option->dev_flags |= LTR_L1SS_PWR_GATE_CHECK_CARD_EN;
> + option->dev_flags |= LTR_L1SS_PWR_GATE_EN;

It's more common to do both of these using a single statement.

> + option->ltr_en = 1;

Bool.

> + /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
> + /* 60us:0x883C, 300us:0x892C, 3ms:0x9003 */

No need for this comment, just define them all.

> + option->ltr_active_latency = 0x883C;
> + option->ltr_idle_latency = 0x892C;
> + option->ltr_l1off_latency = 0x9003;
> + option->dev_aspm_mode = DEV_ASPM_DYNAMIC;
> + option->l1_snooze_delay = 1;
> + option->ltr_l1off_sspwrgate = 0xAF;
> + 

[PATCH v2] mfd: Add support for RTS5250S power saving

2017-08-21 Thread rui_feng
From: rui_feng 

Signed-off-by: rui_feng 
---
 drivers/mfd/rts5249.c| 183 ++
 drivers/mfd/rtsx_pcr.c   | 206 +--
 drivers/mfd/rtsx_pcr.h   |   2 +
 include/linux/mfd/rtsx_pci.h |  47 ++
 4 files changed, 433 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 40f8bb1..a560b5a 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -103,8 +103,70 @@ static void rtsx_base_force_power_down(struct rtsx_pcr 
*pcr, u8 pm_state)
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
 
+static int rts5249_init_from_cfg(struct rtsx_pcr *pcr)
+{
+   struct cr_option *option = &(pcr->option);
+   u32 lval;
+
+   if (CHK_PCI_PID(pcr, 0x524A))
+   rtsx_pci_read_config_dword(pcr, 0x160, );
+   else
+   rtsx_pci_read_config_dword(pcr, 0x168, );
+
+   if (lval & (1 << 3))
+   set_dev_flag(pcr, ASPM_L1_1_EN);
+   else
+   clear_dev_flag(pcr, ASPM_L1_1_EN);
+   if (lval & (1 << 2))
+   set_dev_flag(pcr, ASPM_L1_2_EN);
+   else
+   clear_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (lval & (1 << 1))
+   set_dev_flag(pcr, PM_L1_1_EN);
+   else
+   clear_dev_flag(pcr, PM_L1_1_EN);
+   if (lval & (1 << 0))
+   set_dev_flag(pcr, PM_L1_2_EN);
+   else
+   clear_dev_flag(pcr, PM_L1_2_EN);
+
+   if (option->ltr_en) {
+   u16 val;
+
+   pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
+   if (val & PCI_EXP_DEVCTL2_LTR_EN) {
+   option->ltr_enabled = 1;
+   option->ltr_active = 1;
+   rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
+   } else {
+   option->ltr_enabled = 0;
+   }
+   }
+
+   return 0;
+}
+
+static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
+{
+   struct cr_option *option = &(pcr->option);
+
+   if (check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
+   | PM_L1_1_EN | PM_L1_2_EN))
+   option->force_clkreq_0 = 0;
+   else
+   option->force_clkreq_0 = 1;
+
+   return 0;
+}
+
 static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
+   struct cr_option *option = &(pcr->option);
+
+   rts5249_init_from_cfg(pcr);
+   rts5249_init_from_hw(pcr);
+
rtsx_pci_init_cmd(pcr);
 
/* Rest L1SUB Config */
@@ -125,6 +187,14 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
 
+   /* u_force_clkreq_0
+* If 1, CLKREQ# PIN will be forced to drive 0 to request clock
+*/
+   if (option->force_clkreq_0)
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x80);
+   else
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x00);
+
return rtsx_pci_send_cmd(pcr, 100);
 }
 
@@ -353,6 +423,8 @@ static int rtsx_base_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
 
 void rts5249_init_params(struct rtsx_pcr *pcr)
 {
+   struct cr_option *option = &(pcr->option);
+
pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
pcr->num_slots = 2;
pcr->ops = _pcr_ops;
@@ -372,6 +444,19 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
 
pcr->reg_pm_ctrl3 = PM_CTRL3;
+
+   option->dev_flags |= LTR_L1SS_PWR_GATE_CHECK_CARD_EN;
+   option->dev_flags |= LTR_L1SS_PWR_GATE_EN;
+   option->ltr_en = 1;
+   /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
+   /* 60us:0x883C, 300us:0x892C, 3ms:0x9003 */
+   option->ltr_active_latency = 0x883C;
+   option->ltr_idle_latency = 0x892C;
+   option->ltr_l1off_latency = 0x9003;
+   option->dev_aspm_mode = DEV_ASPM_DYNAMIC;
+   option->l1_snooze_delay = 1;
+   option->ltr_l1off_sspwrgate = 0xAF;
+   option->ltr_l1off_snooze_sspwrgate = 0xAC;
 }
 
 static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
@@ -459,6 +544,54 @@ static int rts524a_extra_init_hw(struct rtsx_pcr *pcr)
return 0;
 }
 
+static void rts5250_set_l1off_cfg_sub_D0(struct rtsx_pcr *pcr, int active)
+{
+   struct cr_option *option = &(pcr->option);
+
+   u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR);
+   int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST);
+   int aspm_L1_1, aspm_L1_2;
+
+   aspm_L1_1 = check_dev_flag(pcr, ASPM_L1_1_EN);
+   aspm_L1_2 = check_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (active) {
+   /* run, latency: 60us */
+   if (aspm_L1_1) {
+   u8 val = 

[PATCH v2] mfd: Add support for RTS5250S power saving

2017-08-21 Thread rui_feng
From: rui_feng 

Signed-off-by: rui_feng 
---
 drivers/mfd/rts5249.c| 183 ++
 drivers/mfd/rtsx_pcr.c   | 206 +--
 drivers/mfd/rtsx_pcr.h   |   2 +
 include/linux/mfd/rtsx_pci.h |  47 ++
 4 files changed, 433 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 40f8bb1..a560b5a 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -103,8 +103,70 @@ static void rtsx_base_force_power_down(struct rtsx_pcr 
*pcr, u8 pm_state)
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
 
+static int rts5249_init_from_cfg(struct rtsx_pcr *pcr)
+{
+   struct cr_option *option = &(pcr->option);
+   u32 lval;
+
+   if (CHK_PCI_PID(pcr, 0x524A))
+   rtsx_pci_read_config_dword(pcr, 0x160, );
+   else
+   rtsx_pci_read_config_dword(pcr, 0x168, );
+
+   if (lval & (1 << 3))
+   set_dev_flag(pcr, ASPM_L1_1_EN);
+   else
+   clear_dev_flag(pcr, ASPM_L1_1_EN);
+   if (lval & (1 << 2))
+   set_dev_flag(pcr, ASPM_L1_2_EN);
+   else
+   clear_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (lval & (1 << 1))
+   set_dev_flag(pcr, PM_L1_1_EN);
+   else
+   clear_dev_flag(pcr, PM_L1_1_EN);
+   if (lval & (1 << 0))
+   set_dev_flag(pcr, PM_L1_2_EN);
+   else
+   clear_dev_flag(pcr, PM_L1_2_EN);
+
+   if (option->ltr_en) {
+   u16 val;
+
+   pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
+   if (val & PCI_EXP_DEVCTL2_LTR_EN) {
+   option->ltr_enabled = 1;
+   option->ltr_active = 1;
+   rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
+   } else {
+   option->ltr_enabled = 0;
+   }
+   }
+
+   return 0;
+}
+
+static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
+{
+   struct cr_option *option = &(pcr->option);
+
+   if (check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
+   | PM_L1_1_EN | PM_L1_2_EN))
+   option->force_clkreq_0 = 0;
+   else
+   option->force_clkreq_0 = 1;
+
+   return 0;
+}
+
 static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
+   struct cr_option *option = &(pcr->option);
+
+   rts5249_init_from_cfg(pcr);
+   rts5249_init_from_hw(pcr);
+
rtsx_pci_init_cmd(pcr);
 
/* Rest L1SUB Config */
@@ -125,6 +187,14 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
 
+   /* u_force_clkreq_0
+* If 1, CLKREQ# PIN will be forced to drive 0 to request clock
+*/
+   if (option->force_clkreq_0)
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x80);
+   else
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x80, 0x00);
+
return rtsx_pci_send_cmd(pcr, 100);
 }
 
@@ -353,6 +423,8 @@ static int rtsx_base_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
 
 void rts5249_init_params(struct rtsx_pcr *pcr)
 {
+   struct cr_option *option = &(pcr->option);
+
pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
pcr->num_slots = 2;
pcr->ops = _pcr_ops;
@@ -372,6 +444,19 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
 
pcr->reg_pm_ctrl3 = PM_CTRL3;
+
+   option->dev_flags |= LTR_L1SS_PWR_GATE_CHECK_CARD_EN;
+   option->dev_flags |= LTR_L1SS_PWR_GATE_EN;
+   option->ltr_en = 1;
+   /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
+   /* 60us:0x883C, 300us:0x892C, 3ms:0x9003 */
+   option->ltr_active_latency = 0x883C;
+   option->ltr_idle_latency = 0x892C;
+   option->ltr_l1off_latency = 0x9003;
+   option->dev_aspm_mode = DEV_ASPM_DYNAMIC;
+   option->l1_snooze_delay = 1;
+   option->ltr_l1off_sspwrgate = 0xAF;
+   option->ltr_l1off_snooze_sspwrgate = 0xAC;
 }
 
 static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
@@ -459,6 +544,54 @@ static int rts524a_extra_init_hw(struct rtsx_pcr *pcr)
return 0;
 }
 
+static void rts5250_set_l1off_cfg_sub_D0(struct rtsx_pcr *pcr, int active)
+{
+   struct cr_option *option = &(pcr->option);
+
+   u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR);
+   int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST);
+   int aspm_L1_1, aspm_L1_2;
+
+   aspm_L1_1 = check_dev_flag(pcr, ASPM_L1_1_EN);
+   aspm_L1_2 = check_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (active) {
+   /* run, latency: 60us */
+   if (aspm_L1_1) {
+   u8 val = option->ltr_l1off_snooze_sspwrgate;
+
+   if