]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
mfd: rtsx: Add shutdown callback in rtsx_pci_driver
authorWei WANG <wei_wang@realsil.com.cn>
Tue, 20 Aug 2013 06:18:52 +0000 (14:18 +0800)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 20 Aug 2013 08:22:00 +0000 (10:22 +0200)
Some actions to clear power state should be handled in .shutdown
callback in rtsx_pci_driver. This patch adopts the following measures to
catch this goal:
1. Add a function rtsx_pci_power_off to abstract the common ops in
.shutdown and .suspend
2. Add pcr->ops->force_power_down to fulfill the individual action for
each reader model

Signed-off-by: Wei WANG <wei_wang@realsil.com.cn>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/mfd/rtl8411.c
drivers/mfd/rts5209.c
drivers/mfd/rts5227.c
drivers/mfd/rts5229.c
drivers/mfd/rts5249.c
drivers/mfd/rtsx_pcr.c
include/linux/mfd/rtsx_pci.h

index 5a68c9bdeddf9d9d98ae948d76ecb6b0d39f9908..56cc248392b53e6d78de007a9dafccdf305f67a9 100644 (file)
@@ -86,6 +86,11 @@ static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
                map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
 }
 
+static void rtl8411_force_power_down(struct rtsx_pcr *pcr)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
+}
+
 static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
@@ -285,6 +290,7 @@ static const struct pcr_ops rtl8411_pcr_ops = {
        .switch_output_voltage = rtl8411_switch_output_voltage,
        .cd_deglitch = rtl8411_cd_deglitch,
        .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+       .force_power_down = rtl8411_force_power_down,
 };
 
 static const struct pcr_ops rtl8411b_pcr_ops = {
@@ -300,6 +306,7 @@ static const struct pcr_ops rtl8411b_pcr_ops = {
        .switch_output_voltage = rtl8411_switch_output_voltage,
        .cd_deglitch = rtl8411_cd_deglitch,
        .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+       .force_power_down = rtl8411_force_power_down,
 };
 
 /* SD Pull Control Enable:
index 2170449bd7e5a4facd93bc5a43a6ab86883ee9f5..c67935efd4f5b5de9219fd8964039cf1f2afbadb 100644 (file)
@@ -59,6 +59,11 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
        }
 }
 
+static void rts5209_force_power_down(struct rtsx_pcr *pcr)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
+}
+
 static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
@@ -197,6 +202,7 @@ static const struct pcr_ops rts5209_pcr_ops = {
        .switch_output_voltage = rts5209_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5209_force_power_down,
 };
 
 /* SD Pull Control Enable:
index c3181d71fedda75a99f74c1a95aa0182b45455c8..42ebf5c050c145e0d1ce70212c4360b9d4aa3e0c 100644 (file)
@@ -83,6 +83,16 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
                pcr->flags |= PCR_REVERSE_SOCKET;
 }
 
+static void rts5227_force_power_down(struct rtsx_pcr *pcr)
+{
+       /* Set relink_time to 0 */
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
 {
        u16 cap;
@@ -218,6 +228,7 @@ static const struct pcr_ops rts5227_pcr_ops = {
        .switch_output_voltage = rts5227_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5227_force_power_down,
 };
 
 /* SD Pull Control Enable:
index 7a1ad6dd29179ddb522b287b5a2165c6f8a39705..a0b695af85618bbcc6413f6de98d90958d3bc64d 100644 (file)
@@ -56,6 +56,11 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
                map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
 }
 
+static void rts5229_force_power_down(struct rtsx_pcr *pcr)
+{
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
@@ -179,6 +184,7 @@ static const struct pcr_ops rts5229_pcr_ops = {
        .switch_output_voltage = rts5229_switch_output_voltage,
        .cd_deglitch = NULL,
        .conv_clk_and_div_n = NULL,
+       .force_power_down = rts5229_force_power_down,
 };
 
 /* SD Pull Control Enable:
index d5db182f35dbade4722dc8234e1939c97308c390..79ff212c3e7bac433ce525d4bfca1cd97b1afa6d 100644 (file)
@@ -88,6 +88,16 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
                pcr->flags |= PCR_REVERSE_SOCKET;
 }
 
+static void rts5249_force_power_down(struct rtsx_pcr *pcr)
+{
+       /* Set relink_time to 0 */
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
+       rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
+
+       rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
+}
+
 static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
        rtsx_pci_init_cmd(pcr);
@@ -217,6 +227,7 @@ static const struct pcr_ops rts5249_pcr_ops = {
        .card_power_on = rts5249_card_power_on,
        .card_power_off = rts5249_card_power_off,
        .switch_output_voltage = rts5249_switch_output_voltage,
+       .force_power_down = rts5249_force_power_down,
 };
 
 /* SD Pull Control Enable:
index e06d6b0d55f64bb67476e87a524d5620a0018773..97526f1acf967623e69f99388b065070a38dd5e1 100644 (file)
@@ -927,6 +927,21 @@ static void rtsx_pci_idle_work(struct work_struct *work)
        mutex_unlock(&pcr->pcr_mutex);
 }
 
+static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
+{
+       if (pcr->ops->turn_off_led)
+               pcr->ops->turn_off_led(pcr);
+
+       rtsx_pci_writel(pcr, RTSX_BIER, 0);
+       pcr->bier = 0;
+
+       rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
+       rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, pm_state);
+
+       if (pcr->ops->force_power_down)
+               pcr->ops->force_power_down(pcr);
+}
+
 static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
 {
        int err;
@@ -1255,7 +1270,6 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
 {
        struct pcr_handle *handle;
        struct rtsx_pcr *pcr;
-       int ret = 0;
 
        dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
 
@@ -1267,14 +1281,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
 
        mutex_lock(&pcr->pcr_mutex);
 
-       if (pcr->ops->turn_off_led)
-               pcr->ops->turn_off_led(pcr);
-
-       rtsx_pci_writel(pcr, RTSX_BIER, 0);
-       pcr->bier = 0;
-
-       rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
-       rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
+       rtsx_pci_power_off(pcr, HOST_ENTER_S3);
 
        pci_save_state(pcidev);
        pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
@@ -1282,7 +1289,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
        pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
 
        mutex_unlock(&pcr->pcr_mutex);
-       return ret;
+       return 0;
 }
 
 static int rtsx_pci_resume(struct pci_dev *pcidev)
@@ -1320,10 +1327,25 @@ out:
        return ret;
 }
 
+static void rtsx_pci_shutdown(struct pci_dev *pcidev)
+{
+       struct pcr_handle *handle;
+       struct rtsx_pcr *pcr;
+
+       dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+       handle = pci_get_drvdata(pcidev);
+       pcr = handle->pcr;
+       rtsx_pci_power_off(pcr, HOST_ENTER_S1);
+
+       pci_disable_device(pcidev);
+}
+
 #else /* CONFIG_PM */
 
 #define rtsx_pci_suspend NULL
 #define rtsx_pci_resume NULL
+#define rtsx_pci_shutdown NULL
 
 #endif /* CONFIG_PM */
 
@@ -1334,6 +1356,7 @@ static struct pci_driver rtsx_pci_driver = {
        .remove = rtsx_pci_remove,
        .suspend = rtsx_pci_suspend,
        .resume = rtsx_pci_resume,
+       .shutdown = rtsx_pci_shutdown,
 };
 module_pci_driver(rtsx_pci_driver);
 
index 9cba73703704cb49c4d9a991a1414926087d41a7..11ab786fdc8383b402e3dfd7c3d04a20bb50c399 100644 (file)
@@ -25,8 +25,7 @@
 
 #include <linux/sched.h>
 #include <linux/pci.h>
-
-#include "rtsx_common.h"
+#include <linux/mfd/rtsx_common.h>
 
 #define MAX_RW_REG_CNT                 1024
 
 #define SAMPLE_VAR_CLK0                        (0x01 << 4)
 #define SAMPLE_VAR_CLK1                        (0x02 << 4)
 
+/* HOST_SLEEP_STATE */
+#define HOST_ENTER_S1                  1
+#define HOST_ENTER_S3                  2
+
 #define MS_CFG                         0xFD40
 #define MS_TPC                         0xFD41
 #define MS_TRANS_CFG                   0xFD42
 
 #define AUTOLOAD_CFG_BASE              0xFF00
 
+#define PM_CTRL1                       0xFF44
+#define PM_CTRL2                       0xFF45
+#define PM_CTRL3                       0xFF46
+#define PM_CTRL4                       0xFF47
+
 /* Memory mapping */
 #define SRAM_BASE                      0xE600
 #define RBUF_BASE                      0xF400
@@ -770,6 +778,7 @@ struct pcr_ops {
        unsigned int    (*cd_deglitch)(struct rtsx_pcr *pcr);
        int             (*conv_clk_and_div_n)(int clk, int dir);
        void            (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
+       void            (*force_power_down)(struct rtsx_pcr *pcr);
 };
 
 enum PDEV_STAT  {PDEV_STAT_IDLE, PDEV_STAT_RUN};