Re: [PATCH RESEND] rtsx_usb_ms: Use msleep_interruptible() in polling loop

2015-10-07 Thread Roger Tseng
On Mon, 2015-09-28 at 01:34 +0100, Ben Hutchings wrote:
> rtsx_usb_ms creates a task that mostly sleeps, but tasks in
> uninterruptible sleep still contribute to the load average (for
> bug-compatibility with Unix).  A load average of ~1 on a system that
> should be idle is somewhat alarming.
> 
> Change the sleep to be interruptible, but still ignore signals.
> 
> A better fix might be to replace this loop with a delayed work item.
The change should be OK providing it does the same delay. You can add my
ack.

> References: https://bugs.debian.org/765717
> Signed-off-by: Ben Hutchings 
> ---
> --- a/drivers/memstick/host/rtsx_usb_ms.c
> +++ b/drivers/memstick/host/rtsx_usb_ms.c
> @@ -706,7 +706,8 @@ poll_again:
>   if (host->eject)
>   break;
>  
> - msleep(1000);
> + if (msleep_interruptible(1000))
> + flush_signals(current);
>   }
>  
>   complete(>detect_ms_exit);

-- 
Best regards,
Roger Tseng


Re: [PATCH RESEND] rtsx_usb_ms: Use msleep_interruptible() in polling loop

2015-10-07 Thread Roger Tseng
On Mon, 2015-09-28 at 01:34 +0100, Ben Hutchings wrote:
> rtsx_usb_ms creates a task that mostly sleeps, but tasks in
> uninterruptible sleep still contribute to the load average (for
> bug-compatibility with Unix).  A load average of ~1 on a system that
> should be idle is somewhat alarming.
> 
> Change the sleep to be interruptible, but still ignore signals.
> 
> A better fix might be to replace this loop with a delayed work item.
The change should be OK providing it does the same delay. You can add my
ack.

> References: https://bugs.debian.org/765717
> Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
> ---
> --- a/drivers/memstick/host/rtsx_usb_ms.c
> +++ b/drivers/memstick/host/rtsx_usb_ms.c
> @@ -706,7 +706,8 @@ poll_again:
>   if (host->eject)
>   break;
>  
> - msleep(1000);
> + if (msleep_interruptible(1000))
> + flush_signals(current);
>   }
>  
>   complete(>detect_ms_exit);

-- 
Best regards,
Roger Tseng


[PATCH] mfd: rtsx_usb: prevent DMA from stack

2015-03-05 Thread Roger Tseng
Functions rtsx_usb_ep0_read_register() and rtsx_usb_get_card_status()
both use arbitrary buffer addresses from arguments directly for DMA and
the buffers could be located in stack. This was caught by DMA-API debug
check.

Fixes this by using double-buffers via kzalloc in both functions to
guarantee the validity of DMA buffer.

WARNING: CPU: 1 PID: 25 at lib/dma-debug.c:1166 check_for_stack+0x96/0xe0()
ehci-pci :00:1a.0: DMA-API: device driver maps memory from stack
[addr=8801199e3cef]
Modules linked in: rtsx_usb_ms arc4 memstick intel_rapl iosf_mbi
rtl8192ce snd_hda_codec_hdmi snd_hda_codec_realtek
snd_hda_codec_generic snd_hda_intel rtl_pci rtl8192c_common
snd_hda_controller x86_pkg_temp_thermal snd_hda_codec rtlwifi mac80211
coretemp kvm_intel kvm iTCO_wdt snd_hwdep snd_seq snd_seq_device
crct10dif_pclmul iTCO_vendor_support sparse_keymap cfg80211
crc32_pclmul snd_pcm crc32c_intel ghash_clmulni_intel rfkill i2c_i801
snd_timer shpchp snd serio_raw mei_me lpc_ich soundcore mei tpm_tis
tpm wmi nfsd auth_rpcgss nfs_acl lockd grace sunrpc i915
rtsx_usb_sdmmc mmc_core 8021q uas garp stp i2c_algo_bit llc mrp
drm_kms_helper usb_storage drm rtsx_usb mfd_core r8169 mii video
CPU: 1 PID: 25 Comm: kworker/1:2 Not tainted 3.20.0-0.rc0.git7.3.fc22.x86_64 #1
Hardware name: WB WB-B06211/WB-B0621, BIOS EB062IWB V1.0 12/12/2013
Workqueue: events rtsx_usb_ms_handle_req [rtsx_usb_ms]
  3d188e66 8801199e3808 8187642b
  8801199e3860 8801199e3848 810ab39a
 8801199e3864 8801199e3cef 880119b57098 880119b37320
Call Trace:
 [] dump_stack+0x4c/0x65
 [] warn_slowpath_common+0x8a/0xc0
 [] warn_slowpath_fmt+0x55/0x70
 [] ? _raw_spin_unlock_irqrestore+0x36/0x70
 [] check_for_stack+0x96/0xe0
 [] debug_dma_map_page+0x104/0x150
 [] usb_hcd_map_urb_for_dma+0x646/0x790
 [] usb_hcd_submit_urb+0x1d5/0xa90
 [] ? mark_held_locks+0x7f/0xc0
 [] ? mark_held_locks+0x7f/0xc0
 [] ? lockdep_init_map+0x65/0x5d0
 [] usb_submit_urb+0x42e/0x5f0
 [] usb_start_wait_urb+0x77/0x190
 [] ? __kmalloc+0x205/0x2d0
 [] usb_control_msg+0xdc/0x130
 [] rtsx_usb_ep0_read_register+0x59/0x70 [rtsx_usb]
 [] ? rtsx_usb_get_rsp+0x41/0x50 [rtsx_usb]
 [] rtsx_usb_ms_handle_req+0x7ce/0x9c5 [rtsx_usb_ms]

Reported-by: Josh Boyer 
Signed-off-by: Roger Tseng 
---
 drivers/mfd/rtsx_usb.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index ede50244f265..dbd907d7170e 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -196,18 +196,27 @@ EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register);
 int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
 {
u16 value;
+   u8 *buf;
+   int ret;
 
if (!data)
return -EINVAL;
-   *data = 0;
+
+   buf = kzalloc(sizeof(u8), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
 
addr |= EP0_READ_REG_CMD << EP0_OP_SHIFT;
value = swab16(addr);
 
-   return usb_control_msg(ucr->pusb_dev,
+   ret = usb_control_msg(ucr->pusb_dev,
usb_rcvctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-   value, 0, data, 1, 100);
+   value, 0, buf, 1, 100);
+   *data = *buf;
+
+   kfree(buf);
+   return ret;
 }
 EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register);
 
@@ -288,18 +297,27 @@ static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr 
*ucr, u16 *status)
 int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
 {
int ret;
+   u16 *buf;
 
if (!status)
return -EINVAL;
 
-   if (polling_pipe == 0)
+   if (polling_pipe == 0) {
+   buf = kzalloc(sizeof(u16), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
ret = usb_control_msg(ucr->pusb_dev,
usb_rcvctrlpipe(ucr->pusb_dev, 0),
RTSX_USB_REQ_POLL,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-   0, 0, status, 2, 100);
-   else
+   0, 0, buf, 2, 100);
+   *status = *buf;
+
+   kfree(buf);
+   } else {
ret = rtsx_usb_get_status_with_bulk(ucr, status);
+   }
 
/* usb_control_msg may return positive when success */
if (ret < 0)
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mfd: rtsx_usb: prevent DMA from stack

2015-03-05 Thread Roger Tseng
Functions rtsx_usb_ep0_read_register() and rtsx_usb_get_card_status()
both use arbitrary buffer addresses from arguments directly for DMA and
the buffers could be located in stack. This was caught by DMA-API debug
check.

Fixes this by using double-buffers via kzalloc in both functions to
guarantee the validity of DMA buffer.

WARNING: CPU: 1 PID: 25 at lib/dma-debug.c:1166 check_for_stack+0x96/0xe0()
ehci-pci :00:1a.0: DMA-API: device driver maps memory from stack
[addr=8801199e3cef]
Modules linked in: rtsx_usb_ms arc4 memstick intel_rapl iosf_mbi
rtl8192ce snd_hda_codec_hdmi snd_hda_codec_realtek
snd_hda_codec_generic snd_hda_intel rtl_pci rtl8192c_common
snd_hda_controller x86_pkg_temp_thermal snd_hda_codec rtlwifi mac80211
coretemp kvm_intel kvm iTCO_wdt snd_hwdep snd_seq snd_seq_device
crct10dif_pclmul iTCO_vendor_support sparse_keymap cfg80211
crc32_pclmul snd_pcm crc32c_intel ghash_clmulni_intel rfkill i2c_i801
snd_timer shpchp snd serio_raw mei_me lpc_ich soundcore mei tpm_tis
tpm wmi nfsd auth_rpcgss nfs_acl lockd grace sunrpc i915
rtsx_usb_sdmmc mmc_core 8021q uas garp stp i2c_algo_bit llc mrp
drm_kms_helper usb_storage drm rtsx_usb mfd_core r8169 mii video
CPU: 1 PID: 25 Comm: kworker/1:2 Not tainted 3.20.0-0.rc0.git7.3.fc22.x86_64 #1
Hardware name: WB WB-B06211/WB-B0621, BIOS EB062IWB V1.0 12/12/2013
Workqueue: events rtsx_usb_ms_handle_req [rtsx_usb_ms]
  3d188e66 8801199e3808 8187642b
  8801199e3860 8801199e3848 810ab39a
 8801199e3864 8801199e3cef 880119b57098 880119b37320
Call Trace:
 [8187642b] dump_stack+0x4c/0x65
 [810ab39a] warn_slowpath_common+0x8a/0xc0
 [810ab425] warn_slowpath_fmt+0x55/0x70
 [8187efe6] ? _raw_spin_unlock_irqrestore+0x36/0x70
 [81453156] check_for_stack+0x96/0xe0
 [81453934] debug_dma_map_page+0x104/0x150
 [81613b86] usb_hcd_map_urb_for_dma+0x646/0x790
 [81614165] usb_hcd_submit_urb+0x1d5/0xa90
 [81106f8f] ? mark_held_locks+0x7f/0xc0
 [81106f8f] ? mark_held_locks+0x7f/0xc0
 [81103a15] ? lockdep_init_map+0x65/0x5d0
 [81615d7e] usb_submit_urb+0x42e/0x5f0
 [81616787] usb_start_wait_urb+0x77/0x190
 [8124f035] ? __kmalloc+0x205/0x2d0
 [8161697c] usb_control_msg+0xdc/0x130
 [a0031669] rtsx_usb_ep0_read_register+0x59/0x70 [rtsx_usb]
 [a00310c1] ? rtsx_usb_get_rsp+0x41/0x50 [rtsx_usb]
 [a071da4e] rtsx_usb_ms_handle_req+0x7ce/0x9c5 [rtsx_usb_ms]

Reported-by: Josh Boyer jwbo...@fedoraproject.org
Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mfd/rtsx_usb.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index ede50244f265..dbd907d7170e 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -196,18 +196,27 @@ EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register);
 int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
 {
u16 value;
+   u8 *buf;
+   int ret;
 
if (!data)
return -EINVAL;
-   *data = 0;
+
+   buf = kzalloc(sizeof(u8), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
 
addr |= EP0_READ_REG_CMD  EP0_OP_SHIFT;
value = swab16(addr);
 
-   return usb_control_msg(ucr-pusb_dev,
+   ret = usb_control_msg(ucr-pusb_dev,
usb_rcvctrlpipe(ucr-pusb_dev, 0), RTSX_USB_REQ_REG_OP,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-   value, 0, data, 1, 100);
+   value, 0, buf, 1, 100);
+   *data = *buf;
+
+   kfree(buf);
+   return ret;
 }
 EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register);
 
@@ -288,18 +297,27 @@ static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr 
*ucr, u16 *status)
 int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
 {
int ret;
+   u16 *buf;
 
if (!status)
return -EINVAL;
 
-   if (polling_pipe == 0)
+   if (polling_pipe == 0) {
+   buf = kzalloc(sizeof(u16), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
ret = usb_control_msg(ucr-pusb_dev,
usb_rcvctrlpipe(ucr-pusb_dev, 0),
RTSX_USB_REQ_POLL,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-   0, 0, status, 2, 100);
-   else
+   0, 0, buf, 2, 100);
+   *status = *buf;
+
+   kfree(buf);
+   } else {
ret = rtsx_usb_get_status_with_bulk(ucr, status);
+   }
 
/* usb_control_msg may return positive when success */
if (ret  0)
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message

Re: DMA-API backtrace from rtsx_usb_ms driver

2015-02-25 Thread Roger Tseng
On Thu, 2015-02-19 at 11:58 -0500, Josh Boyer wrote:
> Hi All,
> 
> We've had a few bug reports with the stack trace below.  It looks like
> the ms_read_bytes and ms_write_bytes functions in
> drivers/memstick/host/rtsx_usb_mc.c are using a stack variable when
> calling rtsx_usb_ep0_read_register.  That eventually gets to the
> DMA-API debugging checks, which throws the warning backtrace.
> 
> A typical fix is to replace:
> 
> u8 val;
> 
> rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, );
> dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);
> 
> with something like:
> 
> u8 val = kzalloc(sizeof(u8), GFP_KERNEL);
> if (!val) return -ENOMEM;
> 
> rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, );
> dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);
> 
> <>
> kfree(val);
> 
> However, I'm not familiar enough with this driver to know if this
> function is called frequently in an IRQ handler, etc.  If the above
> pseudo code looks sufficient, I can come up with a patch.
> 
Thanks for reporting this.

rtsx_usb_ep0_read_register() is not called in any interrupt context. It 
is a high-priority(control pipe) but less used alternative to
communicate with device. It is primarily for error handling.

I'll fix it inside rtsx_usb_ep0_read_register() itself by a DMA'able
double buffer because it could be called somewhere else(e.g. mmc side).

> WARNING: CPU: 1 PID: 25 at lib/dma-debug.c:1166 check_for_stack+0x96/0xe0()
> ehci-pci :00:1a.0: DMA-API: device driver maps memory from stack
> [addr=8801199e3cef]
> Modules linked in: rtsx_usb_ms arc4 memstick intel_rapl iosf_mbi
> rtl8192ce snd_hda_codec_hdmi snd_hda_codec_realtek
> snd_hda_codec_generic snd_hda_intel rtl_pci rtl8192c_common
> snd_hda_controller x86_pkg_temp_thermal snd_hda_codec rtlwifi mac80211
> coretemp kvm_intel kvm iTCO_wdt snd_hwdep snd_seq snd_seq_device
> crct10dif_pclmul iTCO_vendor_support sparse_keymap cfg80211
> crc32_pclmul snd_pcm crc32c_intel ghash_clmulni_intel rfkill i2c_i801
> snd_timer shpchp snd serio_raw mei_me lpc_ich soundcore mei tpm_tis
> tpm wmi nfsd auth_rpcgss nfs_acl lockd grace sunrpc i915
> rtsx_usb_sdmmc mmc_core 8021q uas garp stp i2c_algo_bit llc mrp
> drm_kms_helper usb_storage drm rtsx_usb mfd_core r8169 mii video
> CPU: 1 PID: 25 Comm: kworker/1:2 Not tainted 3.20.0-0.rc0.git7.3.fc22.x86_64 
> #1
> Hardware name: WB WB-B06211/WB-B0621, BIOS EB062IWB V1.0 12/12/2013
> Workqueue: events rtsx_usb_ms_handle_req [rtsx_usb_ms]
>   3d188e66 8801199e3808 8187642b
>   8801199e3860 8801199e3848 810ab39a
>  8801199e3864 8801199e3cef 880119b57098 880119b37320
> Call Trace:
>  [] dump_stack+0x4c/0x65
>  [] warn_slowpath_common+0x8a/0xc0
>  [] warn_slowpath_fmt+0x55/0x70
>  [] ? _raw_spin_unlock_irqrestore+0x36/0x70
>  [] check_for_stack+0x96/0xe0
>  [] debug_dma_map_page+0x104/0x150
>  [] usb_hcd_map_urb_for_dma+0x646/0x790
>  [] usb_hcd_submit_urb+0x1d5/0xa90
>  [] ? mark_held_locks+0x7f/0xc0
>  [] ? mark_held_locks+0x7f/0xc0
>  [] ? lockdep_init_map+0x65/0x5d0
>  [] usb_submit_urb+0x42e/0x5f0
>  [] usb_start_wait_urb+0x77/0x190
>  [] ? __kmalloc+0x205/0x2d0
>  [] usb_control_msg+0xdc/0x130
>  [] rtsx_usb_ep0_read_register+0x59/0x70 [rtsx_usb]
>  [] ? rtsx_usb_get_rsp+0x41/0x50 [rtsx_usb]
>  [] rtsx_usb_ms_handle_req+0x7ce/0x9c5 [rtsx_usb_ms]
>  [] ? process_one_work+0x19b/0x860
>  [] process_one_work+0x232/0x860
>  [] ? process_one_work+0x19b/0x860
>  [] ? worker_thread+0xda/0x470
>  [] worker_thread+0x53/0x470
>  [] ? process_one_work+0x860/0x860
>  [] kthread+0x104/0x120
>  [] ? local_clock+0x25/0x30
>  [] ? kthread_create_on_node+0x250/0x250
>  [] ret_from_fork+0x7c/0xb0
>  [] ? kthread_create_on_node+0x250/0x250
> 
> josh
> 
> --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng




Re: DMA-API backtrace from rtsx_usb_ms driver

2015-02-25 Thread Roger Tseng
On Thu, 2015-02-19 at 11:58 -0500, Josh Boyer wrote:
 Hi All,
 
 We've had a few bug reports with the stack trace below.  It looks like
 the ms_read_bytes and ms_write_bytes functions in
 drivers/memstick/host/rtsx_usb_mc.c are using a stack variable when
 calling rtsx_usb_ep0_read_register.  That eventually gets to the
 DMA-API debugging checks, which throws the warning backtrace.
 
 A typical fix is to replace:
 
 u8 val;
 
 rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, val);
 dev_dbg(ms_dev(host), MS_TRANS_CFG: 0x%02x\n, val);
 
 with something like:
 
 u8 val = kzalloc(sizeof(u8), GFP_KERNEL);
 if (!val) return -ENOMEM;
 
 rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, val);
 dev_dbg(ms_dev(host), MS_TRANS_CFG: 0x%02x\n, val);
 
 
 kfree(val);
 
 However, I'm not familiar enough with this driver to know if this
 function is called frequently in an IRQ handler, etc.  If the above
 pseudo code looks sufficient, I can come up with a patch.
 
Thanks for reporting this.

rtsx_usb_ep0_read_register() is not called in any interrupt context. It 
is a high-priority(control pipe) but less used alternative to
communicate with device. It is primarily for error handling.

I'll fix it inside rtsx_usb_ep0_read_register() itself by a DMA'able
double buffer because it could be called somewhere else(e.g. mmc side).

 WARNING: CPU: 1 PID: 25 at lib/dma-debug.c:1166 check_for_stack+0x96/0xe0()
 ehci-pci :00:1a.0: DMA-API: device driver maps memory from stack
 [addr=8801199e3cef]
 Modules linked in: rtsx_usb_ms arc4 memstick intel_rapl iosf_mbi
 rtl8192ce snd_hda_codec_hdmi snd_hda_codec_realtek
 snd_hda_codec_generic snd_hda_intel rtl_pci rtl8192c_common
 snd_hda_controller x86_pkg_temp_thermal snd_hda_codec rtlwifi mac80211
 coretemp kvm_intel kvm iTCO_wdt snd_hwdep snd_seq snd_seq_device
 crct10dif_pclmul iTCO_vendor_support sparse_keymap cfg80211
 crc32_pclmul snd_pcm crc32c_intel ghash_clmulni_intel rfkill i2c_i801
 snd_timer shpchp snd serio_raw mei_me lpc_ich soundcore mei tpm_tis
 tpm wmi nfsd auth_rpcgss nfs_acl lockd grace sunrpc i915
 rtsx_usb_sdmmc mmc_core 8021q uas garp stp i2c_algo_bit llc mrp
 drm_kms_helper usb_storage drm rtsx_usb mfd_core r8169 mii video
 CPU: 1 PID: 25 Comm: kworker/1:2 Not tainted 3.20.0-0.rc0.git7.3.fc22.x86_64 
 #1
 Hardware name: WB WB-B06211/WB-B0621, BIOS EB062IWB V1.0 12/12/2013
 Workqueue: events rtsx_usb_ms_handle_req [rtsx_usb_ms]
   3d188e66 8801199e3808 8187642b
   8801199e3860 8801199e3848 810ab39a
  8801199e3864 8801199e3cef 880119b57098 880119b37320
 Call Trace:
  [8187642b] dump_stack+0x4c/0x65
  [810ab39a] warn_slowpath_common+0x8a/0xc0
  [810ab425] warn_slowpath_fmt+0x55/0x70
  [8187efe6] ? _raw_spin_unlock_irqrestore+0x36/0x70
  [81453156] check_for_stack+0x96/0xe0
  [81453934] debug_dma_map_page+0x104/0x150
  [81613b86] usb_hcd_map_urb_for_dma+0x646/0x790
  [81614165] usb_hcd_submit_urb+0x1d5/0xa90
  [81106f8f] ? mark_held_locks+0x7f/0xc0
  [81106f8f] ? mark_held_locks+0x7f/0xc0
  [81103a15] ? lockdep_init_map+0x65/0x5d0
  [81615d7e] usb_submit_urb+0x42e/0x5f0
  [81616787] usb_start_wait_urb+0x77/0x190
  [8124f035] ? __kmalloc+0x205/0x2d0
  [8161697c] usb_control_msg+0xdc/0x130
  [a0031669] rtsx_usb_ep0_read_register+0x59/0x70 [rtsx_usb]
  [a00310c1] ? rtsx_usb_get_rsp+0x41/0x50 [rtsx_usb]
  [a071da4e] rtsx_usb_ms_handle_req+0x7ce/0x9c5 [rtsx_usb_ms]
  [810cc60b] ? process_one_work+0x19b/0x860
  [810cc6a2] process_one_work+0x232/0x860
  [810cc60b] ? process_one_work+0x19b/0x860
  [810ccdaa] ? worker_thread+0xda/0x470
  [810ccd23] worker_thread+0x53/0x470
  [810cccd0] ? process_one_work+0x860/0x860
  [810d31b4] kthread+0x104/0x120
  [810e7fb5] ? local_clock+0x25/0x30
  [810d30b0] ? kthread_create_on_node+0x250/0x250
  [8187fb7c] ret_from_fork+0x7c/0xb0
  [810d30b0] ? kthread_create_on_node+0x250/0x250
 
 josh
 
 --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng




[OVERWRITE] mfd: rtsx_usb: Defer autosuspend while card exists

2015-01-21 Thread Roger Tseng
A card insertion happens after the lastest polling before reader is
suspended may never have a chance to be detected. Under current 1-HZ
polling interval setting in mmc_core, the worst case of such
undetectablility is about 1 second.

To further reduce the undetectability, detect card slot again in suspend
method and defer the autosuspend if the slot is loaded. The default 2
second autosuspend delay of USB subsystem should let the next polling
detects the card.

Signed-off-by: Roger Tseng 
---
 drivers/mfd/rtsx_usb.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 210d1f85679e..ede50244f265 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -681,9 +681,27 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
 #ifdef CONFIG_PM
 static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {
+   struct rtsx_ucr *ucr =
+   (struct rtsx_ucr *)usb_get_intfdata(intf);
+   u16 val = 0;
+
dev_dbg(>dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(>dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, );
+   mutex_unlock(>dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val & (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[OVERWRITE] mfd: rtsx_usb: Defer autosuspend while card exists

2015-01-21 Thread Roger Tseng
A card insertion happens after the lastest polling before reader is
suspended may never have a chance to be detected. Under current 1-HZ
polling interval setting in mmc_core, the worst case of such
undetectablility is about 1 second.

To further reduce the undetectability, detect card slot again in suspend
method and defer the autosuspend if the slot is loaded. The default 2
second autosuspend delay of USB subsystem should let the next polling
detects the card.

Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mfd/rtsx_usb.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 210d1f85679e..ede50244f265 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -681,9 +681,27 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
 #ifdef CONFIG_PM
 static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {
+   struct rtsx_ucr *ucr =
+   (struct rtsx_ucr *)usb_get_intfdata(intf);
+   u16 val = 0;
+
dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(ucr-dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, val);
+   mutex_unlock(ucr-dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val  (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-20 Thread Roger Tseng
On Tue, 2015-01-20 at 16:07 +, Lee Jones wrote:
> On Tue, 20 Jan 2015, Roger Tseng wrote:
> 
> > On Mon, 2015-01-19 at 09:45 +, Lee Jones wrote:
> > > On Thu, 15 Jan 2015, Roger Tseng wrote:
> > > 
> > > > sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
> > > > acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
> > > > device is awake while initializing a newly inserted card. Once it is
> > > > called during suspending state and explicitly before rtsx_usb_suspend()
> > > > acquires the same dev_mutex, both routine deadlock and further hang the
> > > > driver because pm_runtime_get_sync() waits the pending PM operations.
> > > > 
> > > > Fix this by using an empty suspend method. mmc_core always turns the
> > > > LED off after a request is done and thus it is ok to remove the only
> > > > rtsx_usb_turn_off_led() here.
> > > > 
> > > > Cc:  # v3.16+
> > > > Fixes: 730876be2566 ("mfd: Add realtek USB card reader driver")
> > > > Signed-off-by: Roger Tseng 
> > > > ---
> > > >  drivers/mfd/rtsx_usb.c | 9 -
> > > >  1 file changed, 9 deletions(-)
> > > 
> > > Applied, thanks.
> > > 
> > I'm sorry but build bot from Intel just reported me that I forgot to
> > delete an unused variable "ucr" between two commits. My bad.
> > 
> > Do I have a chance to send v2?
> 
> You're lucky I'm in a good mood. ;)
> 
> I fixed it already.
> 
That's great, thanks! And thus patch 2/2 also needs to be changed
accordingly.

By the way, the build bot reported again about an undefined variable
build error in 2/2(I'm sorry for this again). I put the overall updated
content of 2/2 here for you if you're going to fix it, or I can also
re-send it individually.

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 210d1f85679e..ede50244f265 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -681,9 +681,27 @@ static void rtsx_usb_disconnect(struct
usb_interface *intf)
 #ifdef CONFIG_PM
 static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t
message)
 {
+   struct rtsx_ucr *ucr =
+   (struct rtsx_ucr *)usb_get_intfdata(intf);
+   u16 val = 0;
+
dev_dbg(>dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(>dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, );
+   mutex_unlock(>dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val & (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }



> > > > diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
> > > > index dbdd0faeb6ce..076694126e5d 100644
> > > > --- a/drivers/mfd/rtsx_usb.c
> > > > +++ b/drivers/mfd/rtsx_usb.c
> > > > @@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface 
> > > > *intf, pm_message_t message)
> > > > dev_dbg(>dev, "%s called with pm message 0x%04x\n",
> > > > __func__, message.event);
> > > >  
> > > > -   /*
> > > > -    * Call to make sure LED is off during suspend to save more 
> > > > power.
> > > > -* It is NOT a permanent state and could be turned on anytime 
> > > > later.
> > > > -* Thus no need to call turn_on when resunming.
> > > > -*/
> > > > -   mutex_lock(>dev_mutex);
> > > > -   rtsx_usb_turn_off_led(ucr);
> > > > -   mutex_unlock(>dev_mutex);
> > > > -
> > > > return 0;
> > > >  }
> > > >  
> > > 
> > 
> 

-- 
Best regards,
Roger Tseng
N�r��yb�X��ǧv�^�)޺{.n�+{zX����ܨ}���Ơz�:+v���zZ+��+zf���h���~i���z��w���?�&�)ߢf��^jǫy�m��@A�a���
0��h���i

Re: [PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-20 Thread Roger Tseng
On Mon, 2015-01-19 at 09:45 +, Lee Jones wrote:
> On Thu, 15 Jan 2015, Roger Tseng wrote:
> 
> > sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
> > acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
> > device is awake while initializing a newly inserted card. Once it is
> > called during suspending state and explicitly before rtsx_usb_suspend()
> > acquires the same dev_mutex, both routine deadlock and further hang the
> > driver because pm_runtime_get_sync() waits the pending PM operations.
> > 
> > Fix this by using an empty suspend method. mmc_core always turns the
> > LED off after a request is done and thus it is ok to remove the only
> > rtsx_usb_turn_off_led() here.
> > 
> > Cc:  # v3.16+
> > Fixes: 730876be2566 ("mfd: Add realtek USB card reader driver")
> > Signed-off-by: Roger Tseng 
> > ---
> >  drivers/mfd/rtsx_usb.c | 9 -
> >  1 file changed, 9 deletions(-)
> 
> Applied, thanks.
> 
I'm sorry but build bot from Intel just reported me that I forgot to
delete an unused variable "ucr" between two commits. My bad.

Do I have a chance to send v2?

> > diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
> > index dbdd0faeb6ce..076694126e5d 100644
> > --- a/drivers/mfd/rtsx_usb.c
> > +++ b/drivers/mfd/rtsx_usb.c
> > @@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface 
> > *intf, pm_message_t message)
> > dev_dbg(>dev, "%s called with pm message 0x%04x\n",
> > __func__, message.event);
> >  
> > -   /*
> > -* Call to make sure LED is off during suspend to save more power.
> > -* It is NOT a permanent state and could be turned on anytime later.
> > -    * Thus no need to call turn_on when resunming.
> > -*/
> > -   mutex_lock(>dev_mutex);
> > -   rtsx_usb_turn_off_led(ucr);
> > -   mutex_unlock(>dev_mutex);
> > -
> > return 0;
> >  }
> >  
> 

-- 
Best regards,
Roger Tseng


Re: [PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-20 Thread Roger Tseng
On Mon, 2015-01-19 at 09:45 +, Lee Jones wrote:
 On Thu, 15 Jan 2015, Roger Tseng wrote:
 
  sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
  acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
  device is awake while initializing a newly inserted card. Once it is
  called during suspending state and explicitly before rtsx_usb_suspend()
  acquires the same dev_mutex, both routine deadlock and further hang the
  driver because pm_runtime_get_sync() waits the pending PM operations.
  
  Fix this by using an empty suspend method. mmc_core always turns the
  LED off after a request is done and thus it is ok to remove the only
  rtsx_usb_turn_off_led() here.
  
  Cc: sta...@vger.kernel.org # v3.16+
  Fixes: 730876be2566 (mfd: Add realtek USB card reader driver)
  Signed-off-by: Roger Tseng rogera...@realtek.com
  ---
   drivers/mfd/rtsx_usb.c | 9 -
   1 file changed, 9 deletions(-)
 
 Applied, thanks.
 
I'm sorry but build bot from Intel just reported me that I forgot to
delete an unused variable ucr between two commits. My bad.

Do I have a chance to send v2?

  diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
  index dbdd0faeb6ce..076694126e5d 100644
  --- a/drivers/mfd/rtsx_usb.c
  +++ b/drivers/mfd/rtsx_usb.c
  @@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface 
  *intf, pm_message_t message)
  dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
  __func__, message.event);
   
  -   /*
  -* Call to make sure LED is off during suspend to save more power.
  -* It is NOT a permanent state and could be turned on anytime later.
  -* Thus no need to call turn_on when resunming.
  -*/
  -   mutex_lock(ucr-dev_mutex);
  -   rtsx_usb_turn_off_led(ucr);
  -   mutex_unlock(ucr-dev_mutex);
  -
  return 0;
   }
   
 

-- 
Best regards,
Roger Tseng


Re: [PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-20 Thread Roger Tseng
On Tue, 2015-01-20 at 16:07 +, Lee Jones wrote:
 On Tue, 20 Jan 2015, Roger Tseng wrote:
 
  On Mon, 2015-01-19 at 09:45 +, Lee Jones wrote:
   On Thu, 15 Jan 2015, Roger Tseng wrote:
   
sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
device is awake while initializing a newly inserted card. Once it is
called during suspending state and explicitly before rtsx_usb_suspend()
acquires the same dev_mutex, both routine deadlock and further hang the
driver because pm_runtime_get_sync() waits the pending PM operations.

Fix this by using an empty suspend method. mmc_core always turns the
LED off after a request is done and thus it is ok to remove the only
rtsx_usb_turn_off_led() here.

Cc: sta...@vger.kernel.org # v3.16+
Fixes: 730876be2566 (mfd: Add realtek USB card reader driver)
Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mfd/rtsx_usb.c | 9 -
 1 file changed, 9 deletions(-)
   
   Applied, thanks.
   
  I'm sorry but build bot from Intel just reported me that I forgot to
  delete an unused variable ucr between two commits. My bad.
  
  Do I have a chance to send v2?
 
 You're lucky I'm in a good mood. ;)
 
 I fixed it already.
 
That's great, thanks! And thus patch 2/2 also needs to be changed
accordingly.

By the way, the build bot reported again about an undefined variable
build error in 2/2(I'm sorry for this again). I put the overall updated
content of 2/2 here for you if you're going to fix it, or I can also
re-send it individually.

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 210d1f85679e..ede50244f265 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -681,9 +681,27 @@ static void rtsx_usb_disconnect(struct
usb_interface *intf)
 #ifdef CONFIG_PM
 static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t
message)
 {
+   struct rtsx_ucr *ucr =
+   (struct rtsx_ucr *)usb_get_intfdata(intf);
+   u16 val = 0;
+
dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(ucr-dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, val);
+   mutex_unlock(ucr-dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val  (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }



diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index dbdd0faeb6ce..076694126e5d 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface 
*intf, pm_message_t message)
dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
__func__, message.event);
 
-   /*
-* Call to make sure LED is off during suspend to save more 
power.
-* It is NOT a permanent state and could be turned on anytime 
later.
-* Thus no need to call turn_on when resunming.
-*/
-   mutex_lock(ucr-dev_mutex);
-   rtsx_usb_turn_off_led(ucr);
-   mutex_unlock(ucr-dev_mutex);
-
return 0;
 }
 
   
  
 

-- 
Best regards,
Roger Tseng
N�r��yb�X��ǧv�^�)޺{.n�+{zX����ܨ}���Ơz�j:+v���zZ+��+zf���h���~i���z��w���?��)ߢf��^jǫy�m��@A�a���
0��h���i

[PATCH 2/2] mfd: rtsx_usb: Defer autosuspend while card exists

2015-01-14 Thread Roger Tseng
A card insertion happens after the lastest polling before reader is
suspended may never have a chance to be detected. Under current 1-HZ
polling interval setting in mmc_core, the worst case of such
undetectablility is about 1 second.

To further reduce the undetectability, detect card slot again in suspend
method and defer the autosuspend if the slot is loaded. The default 2
second autosuspend delay of USB subsystem should let the next polling
detects the card.

Signed-off-by: Roger Tseng 
---
 drivers/mfd/rtsx_usb.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 076694126e5d..63883fd025c0 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -687,6 +687,20 @@ static int rtsx_usb_suspend(struct usb_interface *intf, 
pm_message_t message)
dev_dbg(>dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(>dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, );
+   mutex_unlock(>dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val & (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] Fix PM deadlock and card detection problem

2015-01-14 Thread Roger Tseng
The patchset fixes a deadlock situation of runtime PM methods and minimize
card detection "deadtime" during runtime suspending.

Roger Tseng (2):
  mfd: rtsx_usb: Fix runtime PM deadlock
  mfd: rtsx_usb: Defer autosuspend while card exists

 drivers/mfd/rtsx_usb.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-14 Thread Roger Tseng
sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
device is awake while initializing a newly inserted card. Once it is
called during suspending state and explicitly before rtsx_usb_suspend()
acquires the same dev_mutex, both routine deadlock and further hang the
driver because pm_runtime_get_sync() waits the pending PM operations.

Fix this by using an empty suspend method. mmc_core always turns the
LED off after a request is done and thus it is ok to remove the only
rtsx_usb_turn_off_led() here.

Cc:  # v3.16+
Fixes: 730876be2566 ("mfd: Add realtek USB card reader driver")
Signed-off-by: Roger Tseng 
---
 drivers/mfd/rtsx_usb.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index dbdd0faeb6ce..076694126e5d 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface *intf, 
pm_message_t message)
dev_dbg(>dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
 
-   /*
-* Call to make sure LED is off during suspend to save more power.
-* It is NOT a permanent state and could be turned on anytime later.
-* Thus no need to call turn_on when resunming.
-*/
-   mutex_lock(>dev_mutex);
-   rtsx_usb_turn_off_led(ucr);
-   mutex_unlock(>dev_mutex);
-
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] mfd: rtsx_usb: Defer autosuspend while card exists

2015-01-14 Thread Roger Tseng
A card insertion happens after the lastest polling before reader is
suspended may never have a chance to be detected. Under current 1-HZ
polling interval setting in mmc_core, the worst case of such
undetectablility is about 1 second.

To further reduce the undetectability, detect card slot again in suspend
method and defer the autosuspend if the slot is loaded. The default 2
second autosuspend delay of USB subsystem should let the next polling
detects the card.

Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mfd/rtsx_usb.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 076694126e5d..63883fd025c0 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -687,6 +687,20 @@ static int rtsx_usb_suspend(struct usb_interface *intf, 
pm_message_t message)
dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
__func__, message.event);
 
+   if (PMSG_IS_AUTO(message)) {
+   if (mutex_trylock(ucr-dev_mutex)) {
+   rtsx_usb_get_card_status(ucr, val);
+   mutex_unlock(ucr-dev_mutex);
+
+   /* Defer the autosuspend if card exists */
+   if (val  (SD_CD | MS_CD))
+   return -EAGAIN;
+   } else {
+   /* There is an ongoing operation*/
+   return -EAGAIN;
+   }
+   }
+
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] Fix PM deadlock and card detection problem

2015-01-14 Thread Roger Tseng
The patchset fixes a deadlock situation of runtime PM methods and minimize
card detection deadtime during runtime suspending.

Roger Tseng (2):
  mfd: rtsx_usb: Fix runtime PM deadlock
  mfd: rtsx_usb: Defer autosuspend while card exists

 drivers/mfd/rtsx_usb.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] mfd: rtsx_usb: Fix runtime PM deadlock

2015-01-14 Thread Roger Tseng
sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c
acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the
device is awake while initializing a newly inserted card. Once it is
called during suspending state and explicitly before rtsx_usb_suspend()
acquires the same dev_mutex, both routine deadlock and further hang the
driver because pm_runtime_get_sync() waits the pending PM operations.

Fix this by using an empty suspend method. mmc_core always turns the
LED off after a request is done and thus it is ok to remove the only
rtsx_usb_turn_off_led() here.

Cc: sta...@vger.kernel.org # v3.16+
Fixes: 730876be2566 (mfd: Add realtek USB card reader driver)
Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mfd/rtsx_usb.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index dbdd0faeb6ce..076694126e5d 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -687,15 +687,6 @@ static int rtsx_usb_suspend(struct usb_interface *intf, 
pm_message_t message)
dev_dbg(intf-dev, %s called with pm message 0x%04x\n,
__func__, message.event);
 
-   /*
-* Call to make sure LED is off during suspend to save more power.
-* It is NOT a permanent state and could be turned on anytime later.
-* Thus no need to call turn_on when resunming.
-*/
-   mutex_lock(ucr-dev_mutex);
-   rtsx_usb_turn_off_led(ucr);
-   mutex_unlock(ucr-dev_mutex);
-
return 0;
 }
 
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] mmc: core: Add new power_mode MMC_POWER_UNDEFINED

2014-09-24 Thread Roger Tseng
Define new macro MMC_POWER_UNDEFINED for power_mode in struct mmc_ios.
It will also be set as the initial value of host->ios.power_mode in
mmc_start_host().

For hosts with MMC_CAP2_NO_PRESCAN_POWERUP, this makes the later
mmc_power_off() do real power-off things instead of NOP, and further
prevents state messed up in cards that was already initialized(eg. by
BIOS of UEFI driver).

Signed-off-by: Roger Tseng 
---
 drivers/mmc/core/core.c  |1 +
 include/linux/mmc/host.h |1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d03a080fb9cd..7dad1a1adf18 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2489,6 +2489,7 @@ void mmc_start_host(struct mmc_host *host)
 {
host->f_init = max(freqs[0], host->f_min);
host->rescan_disable = 0;
+   host->ios.power_mode = MMC_POWER_UNDEFINED;
if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
mmc_power_off(host);
else
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7960424d0bc0..b3bfa609816a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -42,6 +42,7 @@ struct mmc_ios {
 #define MMC_POWER_OFF  0
 #define MMC_POWER_UP   1
 #define MMC_POWER_ON   2
+#define MMC_POWER_UNDEFINED3
 
unsigned char   bus_width;  /* data bus width */
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] mmc: Add power_mode MMC_POWER_UNDEFINED

2014-09-24 Thread Roger Tseng
Invent MMC_POWER_UNDEFINED to describe the initial host power_mode which
might be either off or turned on by an early driver such as BIOS or UEFI driver.
This lets the later mmc_power_off() do actual power-off things and power_mode
will be in a known state eventually.

Roger Tseng (2):
  mmc: core: Add new power_mode MMC_POWER_UNDEFINED
  mmc: rtsx_pci: Set power related cap2 macros

 drivers/mmc/core/core.c   |1 +
 drivers/mmc/host/rtsx_pci_sdmmc.c |1 +
 drivers/mmc/host/rtsx_usb_sdmmc.c |1 +
 include/linux/mmc/host.h  |1 +
 4 files changed, 4 insertions(+)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] mmc: rtsx_pci: Set power related cap2 macros

2014-09-24 Thread Roger Tseng
Set MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE for
rtsx_pci_sdmmc and rtsx_usb_sdmmc to reflect properties of Realtek
card reader hosts.

Signed-off-by: Roger Tseng 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |1 +
 drivers/mmc/host/rtsx_usb_sdmmc.c |1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index dfde4a210238..d49460b5ff07 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1292,6 +1292,7 @@ static void realtek_init_host(struct realtek_pci_sdmmc 
*host)
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+   mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE;
mmc->max_current_330 = 400;
mmc->max_current_180 = 800;
mmc->ops = _pci_sdmmc_ops;
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c 
b/drivers/mmc/host/rtsx_usb_sdmmc.c
index 5d3766e792f0..a884631d7eea 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1329,6 +1329,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc 
*host)
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
MMC_CAP_NEEDS_POLL;
+   mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE;
 
mmc->max_current_330 = 400;
mmc->max_current_180 = 800;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] mmc: rtsx_pci: Set power related cap2 macros

2014-09-24 Thread Roger Tseng
Set MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE for
rtsx_pci_sdmmc and rtsx_usb_sdmmc to reflect properties of Realtek
card reader hosts.

Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |1 +
 drivers/mmc/host/rtsx_usb_sdmmc.c |1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index dfde4a210238..d49460b5ff07 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1292,6 +1292,7 @@ static void realtek_init_host(struct realtek_pci_sdmmc 
*host)
mmc-caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+   mmc-caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE;
mmc-max_current_330 = 400;
mmc-max_current_180 = 800;
mmc-ops = realtek_pci_sdmmc_ops;
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c 
b/drivers/mmc/host/rtsx_usb_sdmmc.c
index 5d3766e792f0..a884631d7eea 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1329,6 +1329,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc 
*host)
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
MMC_CAP_NEEDS_POLL;
+   mmc-caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE;
 
mmc-max_current_330 = 400;
mmc-max_current_180 = 800;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] mmc: Add power_mode MMC_POWER_UNDEFINED

2014-09-24 Thread Roger Tseng
Invent MMC_POWER_UNDEFINED to describe the initial host power_mode which
might be either off or turned on by an early driver such as BIOS or UEFI driver.
This lets the later mmc_power_off() do actual power-off things and power_mode
will be in a known state eventually.

Roger Tseng (2):
  mmc: core: Add new power_mode MMC_POWER_UNDEFINED
  mmc: rtsx_pci: Set power related cap2 macros

 drivers/mmc/core/core.c   |1 +
 drivers/mmc/host/rtsx_pci_sdmmc.c |1 +
 drivers/mmc/host/rtsx_usb_sdmmc.c |1 +
 include/linux/mmc/host.h  |1 +
 4 files changed, 4 insertions(+)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] mmc: core: Add new power_mode MMC_POWER_UNDEFINED

2014-09-24 Thread Roger Tseng
Define new macro MMC_POWER_UNDEFINED for power_mode in struct mmc_ios.
It will also be set as the initial value of host-ios.power_mode in
mmc_start_host().

For hosts with MMC_CAP2_NO_PRESCAN_POWERUP, this makes the later
mmc_power_off() do real power-off things instead of NOP, and further
prevents state messed up in cards that was already initialized(eg. by
BIOS of UEFI driver).

Signed-off-by: Roger Tseng rogera...@realtek.com
---
 drivers/mmc/core/core.c  |1 +
 include/linux/mmc/host.h |1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d03a080fb9cd..7dad1a1adf18 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2489,6 +2489,7 @@ void mmc_start_host(struct mmc_host *host)
 {
host-f_init = max(freqs[0], host-f_min);
host-rescan_disable = 0;
+   host-ios.power_mode = MMC_POWER_UNDEFINED;
if (host-caps2  MMC_CAP2_NO_PRESCAN_POWERUP)
mmc_power_off(host);
else
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7960424d0bc0..b3bfa609816a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -42,6 +42,7 @@ struct mmc_ios {
 #define MMC_POWER_OFF  0
 #define MMC_POWER_UP   1
 #define MMC_POWER_ON   2
+#define MMC_POWER_UNDEFINED3
 
unsigned char   bus_width;  /* data bus width */
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mmc: rtsx: add card power off during probe

2014-09-22 Thread Roger Tseng
On Thu, 2014-09-18 at 23:14 +0200, Ulf Hansson wrote:
> [...]
> 
> >>
> >> In that case, don't forget to enable MMC_CAP2_FULL_PWR_CYCLE.
> >>
> >> >
> >> > if MMC_CAP2_NO_PRESCAN_POWERUP enable, will call mmc_power_off() at 
> >> > start,
> >> > then it will check ios.power_mode, but the state is MMC_POWER_OFF and 
> >> > just
> >> > return.
> >>
> >> Uhh, that's right! So, I wonder why we invokes mmc_power_off() from
> >> that path at all.
> >>
> >> Hmm, I think we should change the behavior in mmc_start_host(), like below:
> >> 1) Add a "MMC_POWER_UNDEFINED" state which is what the power state
> >> should be assigned to at allocation.
> >> 2 ) From mmc_start_host(), invoke mmc_power_off() when
> >> MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE is set.
> >>
> >> Would that work?
> > Yes. I have confirmed this by following changes. The MMC_POWER_UNDEFINED
> > designation in mmc_start_host() will eventually cause a power-off
> > operation.
> >
> > But I wonder if we need to additionally check MMC_CAP2_FULL_PWR_CYCLE
> > before calling mmc_power_off()?
> 
> The intent from my side was to keep the current behaviour for those
> that already used MMC_CAP2_NO_PRESCAN_POWERUP, but it's s not a big
> deal.
> 

I checked the log and found the commit that invokes mmc_power_off():
a08b17be8b984a7c51cd5a480cd977363df353f9
0d3e3350d5871c53464be4c92d57198744247005
(https://www.mail-archive.com/linux-mmc@vger.kernel.org/msg19638.html )

The proposed change might bring back some delay since invoking
mmc_power_off() in mmc_start_host() is more than NOP now and triggers
real power-off and re-init in sdhci.

Will this be OK?

> So, let's try your proposal, thus don't check MMC_CAP2_FULL_PWR_CYCLE.
> 
> Can you repost new version of your patches and please split them up on
> core and host separately.
> 
> Kind regards
> Uffe
> 
> --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng


Re: [PATCH] mmc: rtsx: add card power off during probe

2014-09-22 Thread Roger Tseng
On Thu, 2014-09-18 at 23:14 +0200, Ulf Hansson wrote:
 [...]
 
 
  In that case, don't forget to enable MMC_CAP2_FULL_PWR_CYCLE.
 
  
   if MMC_CAP2_NO_PRESCAN_POWERUP enable, will call mmc_power_off() at 
   start,
   then it will check ios.power_mode, but the state is MMC_POWER_OFF and 
   just
   return.
 
  Uhh, that's right! So, I wonder why we invokes mmc_power_off() from
  that path at all.
 
  Hmm, I think we should change the behavior in mmc_start_host(), like below:
  1) Add a MMC_POWER_UNDEFINED state which is what the power state
  should be assigned to at allocation.
  2 ) From mmc_start_host(), invoke mmc_power_off() when
  MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE is set.
 
  Would that work?
  Yes. I have confirmed this by following changes. The MMC_POWER_UNDEFINED
  designation in mmc_start_host() will eventually cause a power-off
  operation.
 
  But I wonder if we need to additionally check MMC_CAP2_FULL_PWR_CYCLE
  before calling mmc_power_off()?
 
 The intent from my side was to keep the current behaviour for those
 that already used MMC_CAP2_NO_PRESCAN_POWERUP, but it's s not a big
 deal.
 

I checked the log and found the commit that invokes mmc_power_off():
a08b17be8b984a7c51cd5a480cd977363df353f9
0d3e3350d5871c53464be4c92d57198744247005
(https://www.mail-archive.com/linux-mmc@vger.kernel.org/msg19638.html )

The proposed change might bring back some delay since invoking
mmc_power_off() in mmc_start_host() is more than NOP now and triggers
real power-off and re-init in sdhci.

Will this be OK?

 So, let's try your proposal, thus don't check MMC_CAP2_FULL_PWR_CYCLE.
 
 Can you repost new version of your patches and please split them up on
 core and host separately.
 
 Kind regards
 Uffe
 
 --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng


Re: [PATCH] mmc: rtsx: add card power off during probe

2014-09-18 Thread Roger Tseng
On Wed, 2014-09-17 at 21:29 +0200, Ulf Hansson wrote:
> On 17 September 2014 11:11, micky  wrote:
> > On 09/17/2014 02:01 AM, Ulf Hansson wrote:
> >>
> >> On 12 September 2014 03:39,   wrote:
> >>>
> >>> From: Roger Tseng 
> >>>
> >>> Some platform have both UEFI driver and MFD/mmc driver, if entering
> >>> linux while card in the slot, the card power is already on, and rtsx-mmc
> >>> driver have no chance to make card power off. This will lead UHSI card
> >>> failed to enter UHSI mode.
> >>>
> >>> It is hard to control the UEFI driver leaving state, so we power off the
> >>> card power during probe.
> >>>
> >>> Signed-off-by: Roger Tseng 
> >>> Signed-off-by: Micky Ching 
> >>> ---
> >>>   drivers/mmc/host/rtsx_pci_sdmmc.c |7 ++-
> >>>   1 file changed, 6 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
> >>> b/drivers/mmc/host/rtsx_pci_sdmmc.c
> >>> index dfde4a2..57b0796 100644
> >>> --- a/drivers/mmc/host/rtsx_pci_sdmmc.c
> >>> +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
> >>> @@ -1341,8 +1341,13 @@ static int rtsx_pci_sdmmc_drv_probe(struct
> >>> platform_device *pdev)
> >>>  host->pcr = pcr;
> >>>  host->mmc = mmc;
> >>>  host->pdev = pdev;
> >>> -   host->power_state = SDMMC_POWER_OFF;
> >>>  INIT_WORK(>work, sd_request);
> >>> +   sd_power_off(host);
> >>> +   /*
> >>> +* ref: SD spec 3.01: 6.4.1.2 Power On or Power Cycle
> >>> +*/
> >>> +   usleep_range(1000, 2000);
> >>> +
> >>
> >> This won't work in cases were you power off eMMC cards, unless you can
> >> do a full power cycle - cut both VCC and VCCQ. Can you?
> >
> > Hi Uffe,
> >
> > VCCQ will poweroff at the same time.
> 
> In that case, don't forget to enable MMC_CAP2_FULL_PWR_CYCLE.
> 
> >
> > if MMC_CAP2_NO_PRESCAN_POWERUP enable, will call mmc_power_off() at start,
> > then it will check ios.power_mode, but the state is MMC_POWER_OFF and just
> > return.
> 
> Uhh, that's right! So, I wonder why we invokes mmc_power_off() from
> that path at all.
> 
> Hmm, I think we should change the behavior in mmc_start_host(), like below:
> 1) Add a "MMC_POWER_UNDEFINED" state which is what the power state
> should be assigned to at allocation.
> 2 ) From mmc_start_host(), invoke mmc_power_off() when
> MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE is set.
> 
> Would that work?
Yes. I have confirmed this by following changes. The MMC_POWER_UNDEFINED
designation in mmc_start_host() will eventually cause a power-off
operation.

But I wonder if we need to additionally check MMC_CAP2_FULL_PWR_CYCLE
before calling mmc_power_off()?

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d03a080fb9cd..3457b0f74b71 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2489,7 +2489,9 @@ void mmc_start_host(struct mmc_host *host)
 {
host->f_init = max(freqs[0], host->f_min);
host->rescan_disable = 0;
-   if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
+   host->ios.power_mode = MMC_POWER_UNDEFINED;
+   if (host->caps2 & (MMC_CAP2_NO_PRESCAN_POWERUP |
+   MMC_CAP2_FULL_PWR_CYCLE))
mmc_power_off(host);
else
mmc_power_up(host, host->ocr_avail);
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index dfde4a210238..d49460b5ff07 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1292,6 +1292,7 @@ static void realtek_init_host(struct
realtek_pci_sdmmc *host)
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+   mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP |
MMC_CAP2_FULL_PWR_CYCLE;
mmc->max_current_330 = 400;
mmc->max_current_180 = 800;
mmc->ops = _pci_sdmmc_ops;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7960424d0bc0..b3bfa609816a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -42,6 +42,7 @@ struct mmc_ios {
 #define MMC_POWER_OFF  0
 #define MMC_POWER_UP   1
 #define MMC_POWER_ON   2
+#define MMC_POWER_UNDEFINED3
 
unsigned char   bus_width;      /* data bus width */

> Kind regards
> Uffe
> 
> > Best Regards.
> > micky.
> >
> >> There are also another option you might want to use,
> >> MMC_CAP2_NO_PRESCAN_POWERUP. But again, it must only be used for those
> >> hosts that you are able to do a full power cycle for.
> >>
> >> Kind regards
> >> Uffe
> >>
> >>>  platform_set_drvdata(pdev, host);
> >>>  pcr->slots[RTSX_SD_CARD].p_dev = pdev;
> >>>  pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
> >>> --
> >>> 1.7.9.5
> >>>
> >> .
> >>
> >
> 
> --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng


Re: [PATCH] mmc: rtsx: add card power off during probe

2014-09-18 Thread Roger Tseng
On Wed, 2014-09-17 at 21:29 +0200, Ulf Hansson wrote:
 On 17 September 2014 11:11, micky micky_ch...@realsil.com.cn wrote:
  On 09/17/2014 02:01 AM, Ulf Hansson wrote:
 
  On 12 September 2014 03:39,  micky_ch...@realsil.com.cn wrote:
 
  From: Roger Tseng rogera...@realtek.com
 
  Some platform have both UEFI driver and MFD/mmc driver, if entering
  linux while card in the slot, the card power is already on, and rtsx-mmc
  driver have no chance to make card power off. This will lead UHSI card
  failed to enter UHSI mode.
 
  It is hard to control the UEFI driver leaving state, so we power off the
  card power during probe.
 
  Signed-off-by: Roger Tseng rogera...@realtek.com
  Signed-off-by: Micky Ching micky_ch...@realsil.com.cn
  ---
drivers/mmc/host/rtsx_pci_sdmmc.c |7 ++-
1 file changed, 6 insertions(+), 1 deletion(-)
 
  diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
  b/drivers/mmc/host/rtsx_pci_sdmmc.c
  index dfde4a2..57b0796 100644
  --- a/drivers/mmc/host/rtsx_pci_sdmmc.c
  +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
  @@ -1341,8 +1341,13 @@ static int rtsx_pci_sdmmc_drv_probe(struct
  platform_device *pdev)
   host-pcr = pcr;
   host-mmc = mmc;
   host-pdev = pdev;
  -   host-power_state = SDMMC_POWER_OFF;
   INIT_WORK(host-work, sd_request);
  +   sd_power_off(host);
  +   /*
  +* ref: SD spec 3.01: 6.4.1.2 Power On or Power Cycle
  +*/
  +   usleep_range(1000, 2000);
  +
 
  This won't work in cases were you power off eMMC cards, unless you can
  do a full power cycle - cut both VCC and VCCQ. Can you?
 
  Hi Uffe,
 
  VCCQ will poweroff at the same time.
 
 In that case, don't forget to enable MMC_CAP2_FULL_PWR_CYCLE.
 
 
  if MMC_CAP2_NO_PRESCAN_POWERUP enable, will call mmc_power_off() at start,
  then it will check ios.power_mode, but the state is MMC_POWER_OFF and just
  return.
 
 Uhh, that's right! So, I wonder why we invokes mmc_power_off() from
 that path at all.
 
 Hmm, I think we should change the behavior in mmc_start_host(), like below:
 1) Add a MMC_POWER_UNDEFINED state which is what the power state
 should be assigned to at allocation.
 2 ) From mmc_start_host(), invoke mmc_power_off() when
 MMC_CAP2_NO_PRESCAN_POWERUP and MMC_CAP2_FULL_PWR_CYCLE is set.
 
 Would that work?
Yes. I have confirmed this by following changes. The MMC_POWER_UNDEFINED
designation in mmc_start_host() will eventually cause a power-off
operation.

But I wonder if we need to additionally check MMC_CAP2_FULL_PWR_CYCLE
before calling mmc_power_off()?

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d03a080fb9cd..3457b0f74b71 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2489,7 +2489,9 @@ void mmc_start_host(struct mmc_host *host)
 {
host-f_init = max(freqs[0], host-f_min);
host-rescan_disable = 0;
-   if (host-caps2  MMC_CAP2_NO_PRESCAN_POWERUP)
+   host-ios.power_mode = MMC_POWER_UNDEFINED;
+   if (host-caps2  (MMC_CAP2_NO_PRESCAN_POWERUP |
+   MMC_CAP2_FULL_PWR_CYCLE))
mmc_power_off(host);
else
mmc_power_up(host, host-ocr_avail);
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index dfde4a210238..d49460b5ff07 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1292,6 +1292,7 @@ static void realtek_init_host(struct
realtek_pci_sdmmc *host)
mmc-caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+   mmc-caps2 = MMC_CAP2_NO_PRESCAN_POWERUP |
MMC_CAP2_FULL_PWR_CYCLE;
mmc-max_current_330 = 400;
mmc-max_current_180 = 800;
mmc-ops = realtek_pci_sdmmc_ops;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7960424d0bc0..b3bfa609816a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -42,6 +42,7 @@ struct mmc_ios {
 #define MMC_POWER_OFF  0
 #define MMC_POWER_UP   1
 #define MMC_POWER_ON   2
+#define MMC_POWER_UNDEFINED3
 
unsigned char   bus_width;  /* data bus width */

 Kind regards
 Uffe
 
  Best Regards.
  micky.
 
  There are also another option you might want to use,
  MMC_CAP2_NO_PRESCAN_POWERUP. But again, it must only be used for those
  hosts that you are able to do a full power cycle for.
 
  Kind regards
  Uffe
 
   platform_set_drvdata(pdev, host);
   pcr-slots[RTSX_SD_CARD].p_dev = pdev;
   pcr-slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
  --
  1.7.9.5
 
  .
 
 
 
 --Please consider the environment before printing this e-mail.

-- 
Best regards,
Roger Tseng


Re: [PATCH] mmc: rtsx: fix incorrect last byte in R2 response

2014-08-14 Thread Roger Tseng
On Wed, 2014-08-13 at 17:09 +0200, Ulf Hansson wrote:
> On 11 August 2014 10:32,   wrote:
> > From: Roger Tseng 
> >
> > Current code erroneously fill the last byte of R2 response with an undefined
> > value. In addition, it is impossible to obtain the real values since the
> > controller actually 'offloads' the last byte(CRC7, end bit) while receiving 
> > R2
> > response. This could cause mmc stack to obtain inconsistent CID from the 
> > same
> > card after resume and misidentify it as a different card.
> >
> > Fix by assigning a dummy value 0x01 to the last byte of R2 response.
> >
> > Signed-off-by: Roger Tseng 
> 
> Thanks! Queued for 3.18.
> 
> I guess this should go for stable as well?
Yes. However, since rtsx_usb* is present in 3.16 and later, this patch
will not apply on 3.15.y or older. Should I separately send an adapted
version to stable?

By the way, according to Dan's comment I would like to add a few word
to explain the code. Would you help fix it up by following diff?

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 54849d8..ca31279 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -412,7 +412,13 @@ static void sd_send_cmd_get_rsp(struct
realtek_pci_sdmmc *host,
}
 
if (rsp_type == SD_RSP_TYPE_R2) {
+   /*
+* The controller offloads the last byte {CRC-7, stop bit 1'b1}
+* of response type R2. Assign a dummy CRC, 0, and stop bit to
+* the byte(ptr[16], goes into the LSB of resp[3] later).
+*/
ptr[16] = 1;
+
for (i = 0; i < 4; i++) {
cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n",
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c
b/drivers/mmc/host/rtsx_usb_sdmmc.c
index ca08df1..727a88d 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -435,7 +435,13 @@ static void sd_send_cmd_get_rsp(struct
rtsx_usb_sdmmc *host,
}
 
if (rsp_type == SD_RSP_TYPE_R2) {
+   /*
+* The controller offloads the last byte {CRC-7, stop bit 1'b1}
+* of response type R2. Assign a dummy CRC, 0, and stop bit to
+* the byte(ptr[16], goes into the LSB of resp[3] later).
+*/
ptr[16] = 1;
+
for (i = 0; i < 4; i++) {
cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n",

-- 
Best regards,
Roger Tseng


Re: [PATCH] mmc: rtsx: fix incorrect last byte in R2 response

2014-08-14 Thread Roger Tseng
On Wed, 2014-08-13 at 17:09 +0200, Ulf Hansson wrote:
 On 11 August 2014 10:32,  rogera...@realtek.com wrote:
  From: Roger Tseng rogera...@realtek.com
 
  Current code erroneously fill the last byte of R2 response with an undefined
  value. In addition, it is impossible to obtain the real values since the
  controller actually 'offloads' the last byte(CRC7, end bit) while receiving 
  R2
  response. This could cause mmc stack to obtain inconsistent CID from the 
  same
  card after resume and misidentify it as a different card.
 
  Fix by assigning a dummy value 0x01 to the last byte of R2 response.
 
  Signed-off-by: Roger Tseng rogera...@realtek.com
 
 Thanks! Queued for 3.18.
 
 I guess this should go for stable as well?
Yes. However, since rtsx_usb* is present in 3.16 and later, this patch
will not apply on 3.15.y or older. Should I separately send an adapted
version to stable?

By the way, according to Dan's comment I would like to add a few word
to explain the code. Would you help fix it up by following diff?

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 54849d8..ca31279 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -412,7 +412,13 @@ static void sd_send_cmd_get_rsp(struct
realtek_pci_sdmmc *host,
}
 
if (rsp_type == SD_RSP_TYPE_R2) {
+   /*
+* The controller offloads the last byte {CRC-7, stop bit 1'b1}
+* of response type R2. Assign a dummy CRC, 0, and stop bit to
+* the byte(ptr[16], goes into the LSB of resp[3] later).
+*/
ptr[16] = 1;
+
for (i = 0; i  4; i++) {
cmd-resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
dev_dbg(sdmmc_dev(host), cmd-resp[%d] = 0x%08x\n,
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c
b/drivers/mmc/host/rtsx_usb_sdmmc.c
index ca08df1..727a88d 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -435,7 +435,13 @@ static void sd_send_cmd_get_rsp(struct
rtsx_usb_sdmmc *host,
}
 
if (rsp_type == SD_RSP_TYPE_R2) {
+   /*
+* The controller offloads the last byte {CRC-7, stop bit 1'b1}
+* of response type R2. Assign a dummy CRC, 0, and stop bit to
+* the byte(ptr[16], goes into the LSB of resp[3] later).
+*/
ptr[16] = 1;
+
for (i = 0; i  4; i++) {
cmd-resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
dev_dbg(sdmmc_dev(host), cmd-resp[%d] = 0x%08x\n,

-- 
Best regards,
Roger Tseng


RE: [PATCH 1/3] mfd: Add realtek USB card reader driver

2014-01-07 Thread Roger Tseng
Hi Dan,

>> +int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr,
>> + u8 mask, u8 data)
>> +{
>> + u16 value = 0, index = 0;
>> +
>> + value |= (u16)(3 & 0x03) << 14;
>> + value |= (u16)(addr & 0x3FFF);
>
>Don't do pointless things:
>
>value |= 0x03 << 14;
>value |= addr & 0x3FFF;
>
>> + value = ((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF);
>
>This is an endian conversion?  It is buggy.  Use the kernel endian
>conversion functions cpu_to_le16().

This is not a conversion for endianess with respect to CPU but for command 
format  of the device. It should always be performed regardless of platform.

In other words, it could be equivalent to:
value |= 0x03 << 6; // lower byte
value |= (addr & 0x3F00) >> 8; // lower byte
value |= (addr & 0xFF) << 8; //higher byte

We think the previous form is easier to read. Should we keep it or change to 
the later one?--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 1/3] mfd: Add realtek USB card reader driver

2014-01-07 Thread Roger Tseng
Hi Dan,

 +int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr,
 + u8 mask, u8 data)
 +{
 + u16 value = 0, index = 0;
 +
 + value |= (u16)(3  0x03)  14;
 + value |= (u16)(addr  0x3FFF);

Don't do pointless things:

value |= 0x03  14;
value |= addr  0x3FFF;

 + value = ((value  8)  0xFF00) | ((value  8)  0x00FF);

This is an endian conversion?  It is buggy.  Use the kernel endian
conversion functions cpu_to_le16().

This is not a conversion for endianess with respect to CPU but for command 
format  of the device. It should always be performed regardless of platform.

In other words, it could be equivalent to:
value |= 0x03  6; // lower byte
value |= (addr  0x3F00)  8; // lower byte
value |= (addr  0xFF)  8; //higher byte

We think the previous form is easier to read. Should we keep it or change to 
the later one?--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH] mfd:rtsx: Support RTL8411B

2013-04-19 Thread Roger Tseng
>On Fri, Apr 19, 2013 at 09:52:42PM +0800, rogera...@realtek.com wrote:
>> From: Roger Tseng 
>>
>> Adding support of model RTL8411B. Since the model is similar to RTL8411,
>> differences are implemented in rtl8411.c.
>>
>
>What tree is this against?
>
>regards,
>dan carpenter

It should be the mfd-next tree.

Best regards,
Roger Tseng--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH] mfd:rtsx: Support RTL8411B

2013-04-19 Thread Roger Tseng
On Fri, Apr 19, 2013 at 09:52:42PM +0800, rogera...@realtek.com wrote:
 From: Roger Tseng rogera...@realtek.com

 Adding support of model RTL8411B. Since the model is similar to RTL8411,
 differences are implemented in rtl8411.c.


What tree is this against?

regards,
dan carpenter

It should be the mfd-next tree.

Best regards,
Roger Tseng--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] MMC: rtsx: remove driving adjustment

2013-02-04 Thread Roger Tseng

Hi Dan,

Correct. I will prevent this kind of breaking in the future.

However, after our analysis the breaking of patch 1/3 and 2/3 should not 
fail old devices. And since Samuel has applied 2/3 and 3/3, it might be 
better for Chris to apply patch 1/3 and let all this things appear in 
kernel v3.9.


Hi Chris,

Would you please apply patch 1/3 for kernel v3.9. Thanks.

Best regards,
Roger Tseng

On 02/04/2013 04:47 PM, Dan Carpenter wrote:

On Mon, Feb 04, 2013 at 03:45:57PM +0800, Roger Tseng wrote:

Several new models of readers use different way to select driving
capability(a necessary adjustment along with voltage change). Removing this
from device-independent rtsx_pci_sdmmc module. It will be implemented in
device-depend calls encapsulated by rtsx_pci_switch_output_voltage().



I'm not sure I understand.

Does this patch break things and then "[PATCH 2/3] mfd: rtsx:
implement driving adjustment to device-dependent callbacks" fixes
things again?  In other words, will all the old devices run if we
only apply patch 1/3 and not 2/3?

That's not the right idea.  Just merge the two patches into one
patch.

regards,
dan carpenter


--Please consider the environment before printing this e-mail.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] MMC: rtsx: remove driving adjustment

2013-02-04 Thread Roger Tseng

Hi Dan,

Correct. I will prevent this kind of breaking in the future.

However, after our analysis the breaking of patch 1/3 and 2/3 should not 
fail old devices. And since Samuel has applied 2/3 and 3/3, it might be 
better for Chris to apply patch 1/3 and let all this things appear in 
kernel v3.9.


Hi Chris,

Would you please apply patch 1/3 for kernel v3.9. Thanks.

Best regards,
Roger Tseng

On 02/04/2013 04:47 PM, Dan Carpenter wrote:

On Mon, Feb 04, 2013 at 03:45:57PM +0800, Roger Tseng wrote:

Several new models of readers use different way to select driving
capability(a necessary adjustment along with voltage change). Removing this
from device-independent rtsx_pci_sdmmc module. It will be implemented in
device-depend calls encapsulated by rtsx_pci_switch_output_voltage().



I'm not sure I understand.

Does this patch break things and then [PATCH 2/3] mfd: rtsx:
implement driving adjustment to device-dependent callbacks fixes
things again?  In other words, will all the old devices run if we
only apply patch 1/3 and not 2/3?

That's not the right idea.  Just merge the two patches into one
patch.

regards,
dan carpenter


--Please consider the environment before printing this e-mail.



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] mfd: rtsx: support RTS5227

2013-02-03 Thread Roger Tseng
Support new model RTS5227.

Signed-off-by: Roger Tseng 
Reviewed-by: Wei WANG 
---
 drivers/mfd/Makefile |   2 +-
 drivers/mfd/rts5227.c| 234 +++
 drivers/mfd/rtsx_pcr.c   |   5 +
 drivers/mfd/rtsx_pcr.h   |   1 +
 include/linux/mfd/rtsx_pci.h |   5 +
 5 files changed, 246 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/rts5227.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8b977f8..b90409c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805)   += 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)+= asic3.o tmio_core.o
 
-rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 
 obj-$(CONFIG_HTC_EGPIO)+= htc-egpio.o
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
new file mode 100644
index 000..fc831dc
--- /dev/null
+++ b/drivers/mfd/rts5227.c
@@ -0,0 +1,234 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG 
+ *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ *
+ *   Roger Tseng 
+ *   No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
+ */
+
+#include 
+#include 
+#include 
+
+#include "rtsx_pcr.h"
+
+static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   u16 cap;
+
+   rtsx_pci_init_cmd(pcr);
+
+   /* Configure GPIO as output */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+   /* Switch LDO3318 source from DV33 to card_3v3 */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+   /* LED shine disabled, set initial shine cycle period */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+   /* Configure LTR */
+   pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
+   if (cap & PCI_EXP_LTR_EN)
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
+   /* Configure OBFF */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
+   /* Configure force_clock_req
+* Maybe We should define 0xFF03 as some name
+*/
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
+   /* Correct driving */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CLK_DRIVE_SEL, 0xFF, 0x96);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CMD_DRIVE_SEL, 0xFF, 0x96);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_DAT_DRIVE_SEL, 0xFF, 0x96);
+
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
+{
+   /* Optimize RX sensitivity */
+   return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
+}
+
+static int rts5227_turn_on_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5227_turn_off_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5227_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5227_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   int err;
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_PARTIAL_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+   LDO3318_PWR_MASK, 0x02);
+   err = rtsx_pci_send_cmd(pcr, 100);
+   if (err < 0)
+   return err;
+
+   /* To avoid too large in-rush current */
+   udelay(150);
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_POWER_ON);
+ 

[PATCH 2/3] mfd: rtsx: implement driving adjustment to device-dependent callbacks

2013-02-03 Thread Roger Tseng
Implement different ways of selecting driving capability(a necessary adjustment
along with voltage change). It was origionally in device-independent
mmc/host/rtsx_pci_sdmmc.c. Moving it here to support devices which may have a
different way of adjustment.

Signed-off-by: Roger Tseng 
Reviewed-by: Wei WANG 
---
 drivers/mfd/rtl8411.c | 16 +---
 drivers/mfd/rts5209.c |  8 
 drivers/mfd/rts5229.c |  8 
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index 3d3b4ad..2a2d316 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -115,14 +115,24 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, 
int card)
 static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 mask, val;
+   int err;
 
mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
-   if (voltage == OUTPUT_3V3)
+   if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err < 0)
+   return err;
val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
-   else if (voltage == OUTPUT_1V8)
+   } else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err < 0)
+   return err;
val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
-   else
+   } else {
return -EINVAL;
+   }
 
return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
 }
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index 98fe0f3..ec78d9f 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -149,10 +149,18 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
int err;
 
if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err < 0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err < 0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err < 0)
return err;
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
index 29d889c..58af4db 100644
--- a/drivers/mfd/rts5229.c
+++ b/drivers/mfd/rts5229.c
@@ -119,10 +119,18 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
int err;
 
if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err < 0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err < 0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err < 0)
return err;
-- 
1.7.12.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/3] rtsx: patchset for supporting new model RTS5227

2013-02-03 Thread Roger Tseng
The patchset makes necessary changes in mfd and mmc tree for supporting RTS5227
card reader.

Roger Tseng (3):
  MMC: rtsx: remove driving adjustment
  mfd: rtsx: implement driving adjustment to device-dependent callbacks
  mfd: rtsx: support RTS5227

 drivers/mfd/Makefile  |   2 +-
 drivers/mfd/rtl8411.c |  16 ++-
 drivers/mfd/rts5209.c |   8 ++
 drivers/mfd/rts5227.c | 234 ++
 drivers/mfd/rts5229.c |   8 ++
 drivers/mfd/rtsx_pcr.c|   5 +
 drivers/mfd/rtsx_pcr.h|   1 +
 drivers/mmc/host/rtsx_pci_sdmmc.c |   5 -
 include/linux/mfd/rtsx_pci.h  |   5 +
 9 files changed, 275 insertions(+), 9 deletions(-)
 create mode 100644 drivers/mfd/rts5227.c

-- 
1.7.12.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] MMC: rtsx: remove driving adjustment

2013-02-03 Thread Roger Tseng
Several new models of readers use different way to select driving
capability(a necessary adjustment along with voltage change). Removing this
from device-independent rtsx_pci_sdmmc module. It will be implemented in
device-depend calls encapsulated by rtsx_pci_switch_output_voltage().

Signed-off-by: Roger Tseng 
Reviewed-by: Wei WANG 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index f74b5ad..f93f100 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1083,11 +1083,6 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, 
struct mmc_ios *ios)
voltage = OUTPUT_1V8;
 
if (voltage == OUTPUT_1V8) {
-   err = rtsx_pci_write_register(pcr,
-   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
-   if (err < 0)
-   goto out;
-
err = sd_wait_voltage_stable_1(host);
if (err < 0)
goto out;
-- 
1.7.12.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] MMC: rtsx: remove driving adjustment

2013-02-03 Thread Roger Tseng
Several new models of readers use different way to select driving
capability(a necessary adjustment along with voltage change). Removing this
from device-independent rtsx_pci_sdmmc module. It will be implemented in
device-depend calls encapsulated by rtsx_pci_switch_output_voltage().

Signed-off-by: Roger Tseng rogera...@realtek.com
Reviewed-by: Wei WANG wei_w...@realsil.com.cn
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index f74b5ad..f93f100 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1083,11 +1083,6 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, 
struct mmc_ios *ios)
voltage = OUTPUT_1V8;
 
if (voltage == OUTPUT_1V8) {
-   err = rtsx_pci_write_register(pcr,
-   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
-   if (err  0)
-   goto out;
-
err = sd_wait_voltage_stable_1(host);
if (err  0)
goto out;
-- 
1.7.12.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/3] rtsx: patchset for supporting new model RTS5227

2013-02-03 Thread Roger Tseng
The patchset makes necessary changes in mfd and mmc tree for supporting RTS5227
card reader.

Roger Tseng (3):
  MMC: rtsx: remove driving adjustment
  mfd: rtsx: implement driving adjustment to device-dependent callbacks
  mfd: rtsx: support RTS5227

 drivers/mfd/Makefile  |   2 +-
 drivers/mfd/rtl8411.c |  16 ++-
 drivers/mfd/rts5209.c |   8 ++
 drivers/mfd/rts5227.c | 234 ++
 drivers/mfd/rts5229.c |   8 ++
 drivers/mfd/rtsx_pcr.c|   5 +
 drivers/mfd/rtsx_pcr.h|   1 +
 drivers/mmc/host/rtsx_pci_sdmmc.c |   5 -
 include/linux/mfd/rtsx_pci.h  |   5 +
 9 files changed, 275 insertions(+), 9 deletions(-)
 create mode 100644 drivers/mfd/rts5227.c

-- 
1.7.12.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] mfd: rtsx: implement driving adjustment to device-dependent callbacks

2013-02-03 Thread Roger Tseng
Implement different ways of selecting driving capability(a necessary adjustment
along with voltage change). It was origionally in device-independent
mmc/host/rtsx_pci_sdmmc.c. Moving it here to support devices which may have a
different way of adjustment.

Signed-off-by: Roger Tseng rogera...@realtek.com
Reviewed-by: Wei WANG wei_w...@realsil.com.cn
---
 drivers/mfd/rtl8411.c | 16 +---
 drivers/mfd/rts5209.c |  8 
 drivers/mfd/rts5229.c |  8 
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index 3d3b4ad..2a2d316 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -115,14 +115,24 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, 
int card)
 static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 mask, val;
+   int err;
 
mask = (BPP_REG_TUNED18  BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
-   if (voltage == OUTPUT_3V3)
+   if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err  0)
+   return err;
val = (BPP_ASIC_3V3  BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
-   else if (voltage == OUTPUT_1V8)
+   } else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err  0)
+   return err;
val = (BPP_ASIC_1V8  BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
-   else
+   } else {
return -EINVAL;
+   }
 
return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
 }
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index 98fe0f3..ec78d9f 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -149,10 +149,18 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
int err;
 
if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err  0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err  0)
return err;
} else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err  0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err  0)
return err;
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
index 29d889c..58af4db 100644
--- a/drivers/mfd/rts5229.c
+++ b/drivers/mfd/rts5229.c
@@ -119,10 +119,18 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
int err;
 
if (voltage == OUTPUT_3V3) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D);
+   if (err  0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err  0)
return err;
} else if (voltage == OUTPUT_1V8) {
+   err = rtsx_pci_write_register(pcr,
+   SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
+   if (err  0)
+   return err;
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err  0)
return err;
-- 
1.7.12.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] mfd: rtsx: support RTS5227

2013-02-03 Thread Roger Tseng
Support new model RTS5227.

Signed-off-by: Roger Tseng rogera...@realtek.com
Reviewed-by: Wei WANG wei_w...@realsil.com.cn
---
 drivers/mfd/Makefile |   2 +-
 drivers/mfd/rts5227.c| 234 +++
 drivers/mfd/rtsx_pcr.c   |   5 +
 drivers/mfd/rtsx_pcr.h   |   1 +
 include/linux/mfd/rtsx_pci.h |   5 +
 5 files changed, 246 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/rts5227.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8b977f8..b90409c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805)   += 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)+= asic3.o tmio_core.o
 
-rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 
 obj-$(CONFIG_HTC_EGPIO)+= htc-egpio.o
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
new file mode 100644
index 000..fc831dc
--- /dev/null
+++ b/drivers/mfd/rts5227.c
@@ -0,0 +1,234 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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, 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, see http://www.gnu.org/licenses/.
+ *
+ * Author:
+ *   Wei WANG wei_w...@realsil.com.cn
+ *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ *
+ *   Roger Tseng rogera...@realtek.com
+ *   No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
+ */
+
+#include linux/module.h
+#include linux/delay.h
+#include linux/mfd/rtsx_pci.h
+
+#include rtsx_pcr.h
+
+static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   u16 cap;
+
+   rtsx_pci_init_cmd(pcr);
+
+   /* Configure GPIO as output */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+   /* Switch LDO3318 source from DV33 to card_3v3 */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+   /* LED shine disabled, set initial shine cycle period */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+   /* Configure LTR */
+   pcie_capability_read_word(pcr-pci, PCI_EXP_DEVCTL2, cap);
+   if (cap  PCI_EXP_LTR_EN)
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
+   /* Configure OBFF */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
+   /* Configure force_clock_req
+* Maybe We should define 0xFF03 as some name
+*/
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08);
+   /* Correct driving */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CLK_DRIVE_SEL, 0xFF, 0x96);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_CMD_DRIVE_SEL, 0xFF, 0x96);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+   SD30_DAT_DRIVE_SEL, 0xFF, 0x96);
+
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
+{
+   /* Optimize RX sensitivity */
+   return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
+}
+
+static int rts5227_turn_on_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5227_turn_off_led(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5227_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5227_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+   return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   int err;
+
+   rtsx_pci_init_cmd(pcr);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+   SD_POWER_MASK, SD_PARTIAL_POWER_ON);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+   LDO3318_PWR_MASK, 0x02);
+   err = rtsx_pci_send_cmd(pcr, 100);
+   if (err  0)
+   return err;
+
+   /* To avoid too large in-rush current */
+   udelay(150);
+
+   rtsx_pci_init_cmd(pcr