* [PATCH v2 1/6] mmc: sdhci: clear auto cmd setting bits for no data cmds
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-11-19 11:52 ` Fabio Estevam
2013-10-30 14:09 ` [PATCH v2 2/6] mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read function Dong Aisheng
` (6 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
The auto cmd settings bits should be cleared before sending new commands
or we may receive command timeout error for normal commands due to wrongly
pre-sent auto cmd.
e.g. we receive CMD13 timeout error due to ACMD23 is wrongly enabled
by former data commands.
mmc2: new high speed DDR MMC card at address 0001
mmcblk1: mmc2:0001 SEM08G 7.39 GiB
mmcblk1boot0: mmc2:0001 SEM08G partition 1 2.00 MiB
mmcblk1boot1: mmc2:0001 SEM08G partition 2 2.00 MiB
mmcblk1rpmb: mmc2:0001 SEM08G partition 3 128 KiB
mmcblk1: p1 p2 p3 p4 < p5 p6 p7 >
mmc2: Timeout waiting for hardware interrupt.
mmcblk1boot1: unknown partition table
mmc2: Timeout waiting for hardware interrupt.
mmcblk1boot0: unknown partition table
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
drivers/mmc/host/sdhci.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 68b3cac..22eab3a 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -903,8 +903,13 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
u16 mode;
struct mmc_data *data = cmd->data;
- if (data == NULL)
+ if (data == NULL) {
+ /* clear Auto CMD settings for no data CMDs */
+ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
+ sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 |
+ SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE);
return;
+ }
WARN_ON(!host->data);
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/6] mmc: sdhci: clear auto cmd setting bits for no data cmds
2013-10-30 14:09 ` [PATCH v2 1/6] mmc: sdhci: clear auto cmd setting bits for no data cmds Dong Aisheng
@ 2013-11-19 11:52 ` Fabio Estevam
0 siblings, 0 replies; 12+ messages in thread
From: Fabio Estevam @ 2013-11-19 11:52 UTC (permalink / raw)
To: Dong Aisheng
Cc: linux-mmc, Shawn Guo, Wolfram Sang, Sascha Hauer, Chris Ball,
linux-arm-kernel@lists.infradead.org
On Wed, Oct 30, 2013 at 12:09 PM, Dong Aisheng <b29396@freescale.com> wrote:
> The auto cmd settings bits should be cleared before sending new commands
> or we may receive command timeout error for normal commands due to wrongly
> pre-sent auto cmd.
>
> e.g. we receive CMD13 timeout error due to ACMD23 is wrongly enabled
> by former data commands.
>
> mmc2: new high speed DDR MMC card at address 0001
> mmcblk1: mmc2:0001 SEM08G 7.39 GiB
> mmcblk1boot0: mmc2:0001 SEM08G partition 1 2.00 MiB
> mmcblk1boot1: mmc2:0001 SEM08G partition 2 2.00 MiB
> mmcblk1rpmb: mmc2:0001 SEM08G partition 3 128 KiB
> mmcblk1: p1 p2 p3 p4 < p5 p6 p7 >
> mmc2: Timeout waiting for hardware interrupt.
> mmcblk1boot1: unknown partition table
> mmc2: Timeout waiting for hardware interrupt.
> mmcblk1boot0: unknown partition table
>
> Signed-off-by: Dong Aisheng <b29396@freescale.com>
Thanks for the patch, Dong.
This fixes the eMMC interrupt timeout issue on mx6qsabresd.
I think we should mark it for stable. At least 3.11 and 3.12 have this
issue and your patch fixes it.
Regards,
Fabio Estevam
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/6] mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read function
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 1/6] mmc: sdhci: clear auto cmd setting bits for no data cmds Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 3/6] ARM: dts: sabresd: add usdhc4 support Dong Aisheng
` (5 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
Used to read out the correct value of SDHCI_TRANSFER_MODE register
for upper layer.
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1ce3511..92d5782 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -385,6 +385,22 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
return ret;
}
+ if (unlikely(reg == SDHCI_TRANSFER_MODE)) {
+ if (esdhc_is_usdhc(imx_data)) {
+ u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+ ret = m & ESDHC_MIX_CTRL_SDHCI_MASK;
+ /* Swap AC23 bit */
+ if (m & ESDHC_MIX_CTRL_AC23EN) {
+ ret &= ~ESDHC_MIX_CTRL_AC23EN;
+ ret |= SDHCI_TRNS_AUTO_CMD23;
+ }
+ } else {
+ ret = readw(host->ioaddr + SDHCI_TRANSFER_MODE);
+ }
+
+ return ret;
+ }
+
return readw(host->ioaddr + reg);
}
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/6] ARM: dts: sabresd: add usdhc4 support
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 1/6] mmc: sdhci: clear auto cmd setting bits for no data cmds Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 2/6] mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read function Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 4/6] mmc: sdhci-esdhc-imx: fix cpas over write issue Dong Aisheng
` (4 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
Add usdhc4 support which has an eMMC card mounted on board.
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 39eafc2..76762a3 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -241,3 +241,12 @@
wp-gpios = <&gpio2 1 0>;
status = "okay";
};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4_1>;
+ bus-width = <8>;
+ non-removable;
+ no-1-8-v;
+ status = "okay";
+};
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/6] mmc: sdhci-esdhc-imx: fix cpas over write issue
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
` (2 preceding siblings ...)
2013-10-30 14:09 ` [PATCH v2 3/6] ARM: dts: sabresd: add usdhc4 support Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 5/6] mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6 Dong Aisheng
` (3 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
We should use '|=' instead '=', or it may over write
the original caps assigned before this line.
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 92d5782..b2acb75 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1069,7 +1069,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
break;
case ESDHC_CD_PERMANENT:
- host->mmc->caps = MMC_CAP_NONREMOVABLE;
+ host->mmc->caps |= MMC_CAP_NONREMOVABLE;
break;
case ESDHC_CD_NONE:
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 5/6] mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
` (3 preceding siblings ...)
2013-10-30 14:09 ` [PATCH v2 4/6] mmc: sdhci-esdhc-imx: fix cpas over write issue Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-10-30 14:09 ` [PATCH v2 6/6] mmc: core: mmc DDR mode should not depend on UHS_DDR50 Dong Aisheng
` (2 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
The i.MX6 supports 1.8v/3.3v eMMC DDR mode, so add this flag.
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b2acb75..ec25421 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1025,6 +1025,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
if (esdhc_is_usdhc(imx_data)) {
writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
+ host->mmc->caps |= MMC_CAP_1_8V_DDR;
}
if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 6/6] mmc: core: mmc DDR mode should not depend on UHS_DDR50
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
` (4 preceding siblings ...)
2013-10-30 14:09 ` [PATCH v2 5/6] mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6 Dong Aisheng
@ 2013-10-30 14:09 ` Dong Aisheng
2013-10-30 22:36 ` Ulf Hansson
2013-10-31 7:04 ` [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Shawn Guo
2013-11-26 21:37 ` Chris Ball
7 siblings, 1 reply; 12+ messages in thread
From: Dong Aisheng @ 2013-10-30 14:09 UTC (permalink / raw)
To: linux-mmc; +Cc: linux-arm-kernel, cjb, shawn.guo, s.hauer, b29396, wsa
The MMC_CAP_UHS_DDR50 must work on 1.8v.
However, the eMMC DDR mode can work on either 1.8v or 3.3v and
should not depend on UHS_DDR50.
So get rid of this limitation to let controller without 1.8v
signal voltage support can also work for eMMC DDR mode if it claims.
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
drivers/mmc/core/mmc.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f631f5a..98e9eb0 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1119,14 +1119,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
if (mmc_card_highspeed(card)) {
if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
- && ((host->caps & (MMC_CAP_1_8V_DDR |
- MMC_CAP_UHS_DDR50))
- == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
+ && (host->caps & MMC_CAP_1_8V_DDR))
ddr = MMC_1_8V_DDR_MODE;
else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
- && ((host->caps & (MMC_CAP_1_2V_DDR |
- MMC_CAP_UHS_DDR50))
- == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
+ && (host->caps & MMC_CAP_1_2V_DDR))
ddr = MMC_1_2V_DDR_MODE;
}
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 6/6] mmc: core: mmc DDR mode should not depend on UHS_DDR50
2013-10-30 14:09 ` [PATCH v2 6/6] mmc: core: mmc DDR mode should not depend on UHS_DDR50 Dong Aisheng
@ 2013-10-30 22:36 ` Ulf Hansson
0 siblings, 0 replies; 12+ messages in thread
From: Ulf Hansson @ 2013-10-30 22:36 UTC (permalink / raw)
To: Dong Aisheng
Cc: linux-mmc, linux-arm-kernel@lists.infradead.org, Chris Ball,
Shawn Guo, Sascha Hauer, wsa
On 30 October 2013 15:09, Dong Aisheng <b29396@freescale.com> wrote:
> The MMC_CAP_UHS_DDR50 must work on 1.8v.
> However, the eMMC DDR mode can work on either 1.8v or 3.3v and
> should not depend on UHS_DDR50.
> So get rid of this limitation to let controller without 1.8v
> signal voltage support can also work for eMMC DDR mode if it claims.
>
> Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
> drivers/mmc/core/mmc.c | 8 ++------
> 1 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index f631f5a..98e9eb0 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1119,14 +1119,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> */
> if (mmc_card_highspeed(card)) {
> if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
> - && ((host->caps & (MMC_CAP_1_8V_DDR |
> - MMC_CAP_UHS_DDR50))
> - == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
> + && (host->caps & MMC_CAP_1_8V_DDR))
> ddr = MMC_1_8V_DDR_MODE;
> else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
> - && ((host->caps & (MMC_CAP_1_2V_DDR |
> - MMC_CAP_UHS_DDR50))
> - == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
> + && (host->caps & MMC_CAP_1_2V_DDR))
> ddr = MMC_1_2V_DDR_MODE;
> }
>
> --
> 1.7.2.rc3
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
` (5 preceding siblings ...)
2013-10-30 14:09 ` [PATCH v2 6/6] mmc: core: mmc DDR mode should not depend on UHS_DDR50 Dong Aisheng
@ 2013-10-31 7:04 ` Shawn Guo
2013-11-13 11:16 ` Dong Aisheng
2013-11-26 21:37 ` Chris Ball
7 siblings, 1 reply; 12+ messages in thread
From: Shawn Guo @ 2013-10-31 7:04 UTC (permalink / raw)
To: Dong Aisheng; +Cc: s.hauer, cjb, linux-mmc, linux-arm-kernel, wsa
On Wed, Oct 30, 2013 at 10:09:47PM +0800, Dong Aisheng wrote:
> Dong Aisheng (6):
> mmc: sdhci: clear auto cmd setting bits for no data cmds
> mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read function
> ARM: dts: sabresd: add usdhc4 support
> mmc: sdhci-esdhc-imx: fix cpas over write issue
> mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6
> mmc: core: mmc DDR mode should not depend on UHS_DDR50
For the series:
Acked-by: Shawn Guo <shawn.guo@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues
2013-10-31 7:04 ` [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Shawn Guo
@ 2013-11-13 11:16 ` Dong Aisheng
0 siblings, 0 replies; 12+ messages in thread
From: Dong Aisheng @ 2013-11-13 11:16 UTC (permalink / raw)
To: Chris Ball
Cc: Dong Aisheng, Sascha Hauer, linux-mmc@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, wsa, Shawn Guo
Hi Chris,
On Thu, Oct 31, 2013 at 3:04 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Wed, Oct 30, 2013 at 10:09:47PM +0800, Dong Aisheng wrote:
>> Dong Aisheng (6):
>> mmc: sdhci: clear auto cmd setting bits for no data cmds
>> mmc: sdhci-esdhc-imx: add SDHCI_TRANSFER_MODE read function
>> ARM: dts: sabresd: add usdhc4 support
>> mmc: sdhci-esdhc-imx: fix cpas over write issue
>> mmc: sdhci-esdhc-imx: add MMC_CAP_1_8V_DDR for mx6
>> mmc: core: mmc DDR mode should not depend on UHS_DDR50
>
> For the series:
>
> Acked-by: Shawn Guo <shawn.guo@linaro.org>
>
Would you help pick up this series?
Regards
Dong Aisheng
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues
2013-10-30 14:09 [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Dong Aisheng
` (6 preceding siblings ...)
2013-10-31 7:04 ` [PATCH v2 0/6] mmc: sdhci-esdhc-imx: fix acmd23 unwork and ddr not supported on sabresd issues Shawn Guo
@ 2013-11-26 21:37 ` Chris Ball
7 siblings, 0 replies; 12+ messages in thread
From: Chris Ball @ 2013-11-26 21:37 UTC (permalink / raw)
To: Dong Aisheng; +Cc: linux-mmc, linux-arm-kernel, shawn.guo, s.hauer, wsa
Hi Dong,
On Wed, Oct 30 2013, Dong Aisheng wrote:
> Patch 1~3 fix acmd23 unwork issue.
> Currently the eMMC chip integrated on i.MX6Q SabreSD boards does not work.
> (It's easily reproduced once you enable usdhc4 on sabresd, see patch 3)
> It's caused by acmd setting bits are never cleared once it's been set
> which cause the next normal commands to work abnormally.
>
> Patch 4~6 fix DDR not supported on SabreSD board.
> The SabreSD board does not have 1.8v signal voltage switch support for uSDHC,
> thus it can not support UHS_DDR50 mode which can only run at 1.8v signal voltage.
Thanks, pushed patches 1-6 to mmc-next for 3.14.
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
^ permalink raw reply [flat|nested] 12+ messages in thread