linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support
@ 2018-11-22  8:03 Jjian Zhou
  2018-11-26 11:47 ` Nicolas Boichat
  0 siblings, 1 reply; 4+ messages in thread
From: Jjian Zhou @ 2018-11-22  8:03 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Matthias Brugger, Chaotian Jing, Ryder Lee, jjian zhou,
	Sean Wang, linux-mmc, linux-arm-kernel, linux-mediatek,
	srv_heupstream, linux-kernel, Yong Mao

MT8183 need SDIO driver. So it need add new code
to support it.

Signed-off-by: Jjian Zhou <jjian.zhou@mediatek.com>
Signed-off-by: Yong mao <yong.mao@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 6334cc7..da2a047 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1114,6 +1114,7 @@ static void msdc_start_command(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd)
 {
 	u32 rawcmd;
+	unsigned long flags;

 	WARN_ON(host->cmd);
 	host->cmd = cmd;
@@ -1131,7 +1132,12 @@ static void msdc_start_command(struct msdc_host *host,
 	cmd->error = 0;
 	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);

+	if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+		spin_lock_irqsave(&host->lock, flags);
 	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
+	if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+		spin_unlock_irqrestore(&host->lock, flags);
+
 	writel(cmd->arg, host->base + SDC_ARG);
 	writel(rawcmd, host->base + SDC_CMD);
 }
@@ -1351,6 +1357,27 @@ static void msdc_request_timeout(struct work_struct *work)
 	}
 }

+static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
+{
+	unsigned long flags;
+	struct msdc_host *host = mmc_priv(mmc);
+
+	if (enb)
+		pm_runtime_get_sync(host->dev);
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (enb)
+		sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+	else
+		sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (!enb) {
+		pm_runtime_mark_last_busy(host->dev);
+		pm_runtime_put_autosuspend(host->dev);
+	}
+}
+
 static irqreturn_t msdc_irq(int irq, void *dev_id)
 {
 	struct msdc_host *host = (struct msdc_host *) dev_id;
@@ -1373,7 +1400,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
 		data = host->data;
 		spin_unlock_irqrestore(&host->lock, flags);

-		if (!(events & event_mask))
+		if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
+			msdc_enable_sdio_irq(host->mmc, 0);
+			sdio_signal_irq(host->mmc);
+		}
+
+		if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
 			break;

 		if (!mrq) {
@@ -1493,8 +1525,11 @@ static void msdc_init_hw(struct msdc_host *host)
 	 */
 	sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);

-	/* disable detect SDIO device interrupt function */
-	sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+	/* Config SDIO device detect interrupt function */
+	if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+		sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+	else
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);

 	/* Configure to default data timeout */
 	sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
@@ -2013,6 +2048,11 @@ static void msdc_hw_reset(struct mmc_host *mmc)
 	sdr_clr_bits(host->base + EMMC_IOCON, 1);
 }

+static void msdc_ack_sdio_irq(struct mmc_host *mmc)
+{
+	msdc_enable_sdio_irq(mmc, 1);
+}
+
 static const struct mmc_host_ops mt_msdc_ops = {
 	.post_req = msdc_post_req,
 	.pre_req = msdc_pre_req,
@@ -2020,6 +2060,8 @@ static void msdc_hw_reset(struct mmc_host *mmc)
 	.set_ios = msdc_ops_set_ios,
 	.get_ro = mmc_gpio_get_ro,
 	.get_cd = mmc_gpio_get_cd,
+	.enable_sdio_irq = msdc_enable_sdio_irq,
+	.ack_sdio_irq = msdc_ack_sdio_irq,
 	.start_signal_voltage_switch = msdc_ops_switch_volt,
 	.card_busy = msdc_card_busy,
 	.execute_tuning = msdc_execute_tuning,
@@ -2147,6 +2189,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	else
 		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);

+	if (mmc->caps & MMC_CAP_SDIO_IRQ)
+		mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+
 	mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
 	/* MMC core transfer sizes tunable parameters */
 	mmc->max_segs = MAX_BD_NUM;
--
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support
  2018-11-22  8:03 [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support Jjian Zhou
@ 2018-11-26 11:47 ` Nicolas Boichat
  2018-11-27  9:27   ` Jjian Zhou
  0 siblings, 1 reply; 4+ messages in thread
From: Nicolas Boichat @ 2018-11-26 11:47 UTC (permalink / raw)
  To: jjian.zhou
  Cc: Ulf Hansson, Matthias Brugger, Chaotian Jing, ryder.lee,
	sean.wang, linux-mmc, linux-arm Mailing List, linux-mediatek,
	srv_heupstream, lkml, yong.mao, Hsin-Yi Wang

On Thu, Nov 22, 2018 at 4:03 PM Jjian Zhou <jjian.zhou@mediatek.com> wrote:
>
> MT8183 need SDIO driver. So it need add new code
> to support it.

The description does not seem to match what is going on below: I don't
see anything that is obviously MT8183-specific. At first glance, this
seems like a patch that makes it possible to enable MMC_CAP_SDIO_IRQ
("cap-sdio-irq" dt property).

Can you describe in more detail what is going on here?

> Signed-off-by: Jjian Zhou <jjian.zhou@mediatek.com>
> Signed-off-by: Yong mao <yong.mao@mediatek.com>
> Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 6334cc7..da2a047 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -1114,6 +1114,7 @@ static void msdc_start_command(struct msdc_host *host,
>                 struct mmc_request *mrq, struct mmc_command *cmd)
>  {
>         u32 rawcmd;
> +       unsigned long flags;
>
>         WARN_ON(host->cmd);
>         host->cmd = cmd;
> @@ -1131,7 +1132,12 @@ static void msdc_start_command(struct msdc_host *host,
>         cmd->error = 0;
>         rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
>
> +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> +               spin_lock_irqsave(&host->lock, flags);
>         sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> +               spin_unlock_irqrestore(&host->lock, flags);
> +
>         writel(cmd->arg, host->base + SDC_ARG);
>         writel(rawcmd, host->base + SDC_CMD);
>  }
> @@ -1351,6 +1357,27 @@ static void msdc_request_timeout(struct work_struct *work)
>         }
>  }
>
> +static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
> +{
> +       unsigned long flags;
> +       struct msdc_host *host = mmc_priv(mmc);
> +
> +       if (enb)
> +               pm_runtime_get_sync(host->dev);
> +
> +       spin_lock_irqsave(&host->lock, flags);
> +       if (enb)
> +               sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> +       else
> +               sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> +       spin_unlock_irqrestore(&host->lock, flags);
> +
> +       if (!enb) {
> +               pm_runtime_mark_last_busy(host->dev);
> +               pm_runtime_put_autosuspend(host->dev);
> +       }
> +}
> +
>  static irqreturn_t msdc_irq(int irq, void *dev_id)
>  {
>         struct msdc_host *host = (struct msdc_host *) dev_id;
> @@ -1373,7 +1400,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
>                 data = host->data;
>                 spin_unlock_irqrestore(&host->lock, flags);
>
> -               if (!(events & event_mask))
> +               if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
> +                       msdc_enable_sdio_irq(host->mmc, 0);
> +                       sdio_signal_irq(host->mmc);
> +               }
> +
> +               if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
>                         break;
>
>                 if (!mrq) {
> @@ -1493,8 +1525,11 @@ static void msdc_init_hw(struct msdc_host *host)
>          */
>         sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
>
> -       /* disable detect SDIO device interrupt function */
> -       sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +       /* Config SDIO device detect interrupt function */
> +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> +               sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +       else
> +               sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
>
>         /* Configure to default data timeout */
>         sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
> @@ -2013,6 +2048,11 @@ static void msdc_hw_reset(struct mmc_host *mmc)
>         sdr_clr_bits(host->base + EMMC_IOCON, 1);
>  }
>
> +static void msdc_ack_sdio_irq(struct mmc_host *mmc)
> +{
> +       msdc_enable_sdio_irq(mmc, 1);
> +}
> +
>  static const struct mmc_host_ops mt_msdc_ops = {
>         .post_req = msdc_post_req,
>         .pre_req = msdc_pre_req,
> @@ -2020,6 +2060,8 @@ static void msdc_hw_reset(struct mmc_host *mmc)
>         .set_ios = msdc_ops_set_ios,
>         .get_ro = mmc_gpio_get_ro,
>         .get_cd = mmc_gpio_get_cd,
> +       .enable_sdio_irq = msdc_enable_sdio_irq,
> +       .ack_sdio_irq = msdc_ack_sdio_irq,
>         .start_signal_voltage_switch = msdc_ops_switch_volt,
>         .card_busy = msdc_card_busy,
>         .execute_tuning = msdc_execute_tuning,
> @@ -2147,6 +2189,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
>         else
>                 mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
>
> +       if (mmc->caps & MMC_CAP_SDIO_IRQ)
> +               mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
> +
>         mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
>         /* MMC core transfer sizes tunable parameters */
>         mmc->max_segs = MAX_BD_NUM;
> --
> 1.9.1
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support
  2018-11-26 11:47 ` Nicolas Boichat
@ 2018-11-27  9:27   ` Jjian Zhou
  2018-12-09  6:00     ` Nicolas Boichat
  0 siblings, 1 reply; 4+ messages in thread
From: Jjian Zhou @ 2018-11-27  9:27 UTC (permalink / raw)
  To: Nicolas Boichat
  Cc: Ulf Hansson, Matthias Brugger,
	Chaotian Jing (井朝天),
	Ryder Lee (李庚諺),
	sean.wang, linux-mmc, linux-arm Mailing List, linux-mediatek,
	srv_heupstream, lkml, Yong Mao (毛勇),
	Hsin-Yi Wang

On Mon, 2018-11-26 at 19:47 +0800, Nicolas Boichat wrote:
> On Thu, Nov 22, 2018 at 4:03 PM Jjian Zhou <jjian.zhou@mediatek.com> wrote:
> >
> > MT8183 need SDIO driver. So it need add new code
> > to support it.
> 
> The description does not seem to match what is going on below: I don't
> see anything that is obviously MT8183-specific. At first glance, this
> seems like a patch that makes it possible to enable MMC_CAP_SDIO_IRQ
> ("cap-sdio-irq" dt property).
> 
> Can you describe in more detail what is going on here?

Hi Nicolas,
   Thank you for your comments.

Host wants to use the new method to signal/process SDIO IRQs, must
enable MMC_CAPS_SDIO_IRQ_NOTHREAD and implement the ->ack_sdio_irq()
callback. The current driver doesn't support it. This code makes it
possible to enable SDIO IRQs by using the new method. It is described as
"MT8183 need SDIO driver". Because it is tested based on MT8183. 
How about the below commit message:

This code wants to support SDIO IRQs. It enables MMC_CAP_SDIO_IRQ &
MMC_CAP2_SDIO_IRQ_NOTHREAD and implement the ->ack_sdio_irq() callback.

   Thanks a lot.

> 
> > Signed-off-by: Jjian Zhou <jjian.zhou@mediatek.com>
> > Signed-off-by: Yong mao <yong.mao@mediatek.com>
> > Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
> > ---
> >  drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 48 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 6334cc7..da2a047 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -1114,6 +1114,7 @@ static void msdc_start_command(struct msdc_host *host,
> >                 struct mmc_request *mrq, struct mmc_command *cmd)
> >  {
> >         u32 rawcmd;
> > +       unsigned long flags;
> >
> >         WARN_ON(host->cmd);
> >         host->cmd = cmd;
> > @@ -1131,7 +1132,12 @@ static void msdc_start_command(struct msdc_host *host,
> >         cmd->error = 0;
> >         rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
> >
> > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > +               spin_lock_irqsave(&host->lock, flags);
> >         sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > +               spin_unlock_irqrestore(&host->lock, flags);
> > +
> >         writel(cmd->arg, host->base + SDC_ARG);
> >         writel(rawcmd, host->base + SDC_CMD);
> >  }
> > @@ -1351,6 +1357,27 @@ static void msdc_request_timeout(struct work_struct *work)
> >         }
> >  }
> >
> > +static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
> > +{
> > +       unsigned long flags;
> > +       struct msdc_host *host = mmc_priv(mmc);
> > +
> > +       if (enb)
> > +               pm_runtime_get_sync(host->dev);
> > +
> > +       spin_lock_irqsave(&host->lock, flags);
> > +       if (enb)
> > +               sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> > +       else
> > +               sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> > +       spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +       if (!enb) {
> > +               pm_runtime_mark_last_busy(host->dev);
> > +               pm_runtime_put_autosuspend(host->dev);
> > +       }
> > +}
> > +
> >  static irqreturn_t msdc_irq(int irq, void *dev_id)
> >  {
> >         struct msdc_host *host = (struct msdc_host *) dev_id;
> > @@ -1373,7 +1400,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
> >                 data = host->data;
> >                 spin_unlock_irqrestore(&host->lock, flags);
> >
> > -               if (!(events & event_mask))
> > +               if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
> > +                       msdc_enable_sdio_irq(host->mmc, 0);
> > +                       sdio_signal_irq(host->mmc);
> > +               }
> > +
> > +               if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
> >                         break;
> >
> >                 if (!mrq) {
> > @@ -1493,8 +1525,11 @@ static void msdc_init_hw(struct msdc_host *host)
> >          */
> >         sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
> >
> > -       /* disable detect SDIO device interrupt function */
> > -       sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > +       /* Config SDIO device detect interrupt function */
> > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > +               sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > +       else
> > +               sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> >
> >         /* Configure to default data timeout */
> >         sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
> > @@ -2013,6 +2048,11 @@ static void msdc_hw_reset(struct mmc_host *mmc)
> >         sdr_clr_bits(host->base + EMMC_IOCON, 1);
> >  }
> >
> > +static void msdc_ack_sdio_irq(struct mmc_host *mmc)
> > +{
> > +       msdc_enable_sdio_irq(mmc, 1);
> > +}
> > +
> >  static const struct mmc_host_ops mt_msdc_ops = {
> >         .post_req = msdc_post_req,
> >         .pre_req = msdc_pre_req,
> > @@ -2020,6 +2060,8 @@ static void msdc_hw_reset(struct mmc_host *mmc)
> >         .set_ios = msdc_ops_set_ios,
> >         .get_ro = mmc_gpio_get_ro,
> >         .get_cd = mmc_gpio_get_cd,
> > +       .enable_sdio_irq = msdc_enable_sdio_irq,
> > +       .ack_sdio_irq = msdc_ack_sdio_irq,
> >         .start_signal_voltage_switch = msdc_ops_switch_volt,
> >         .card_busy = msdc_card_busy,
> >         .execute_tuning = msdc_execute_tuning,
> > @@ -2147,6 +2189,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
> >         else
> >                 mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
> >
> > +       if (mmc->caps & MMC_CAP_SDIO_IRQ)
> > +               mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
> > +
> >         mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
> >         /* MMC core transfer sizes tunable parameters */
> >         mmc->max_segs = MAX_BD_NUM;
> > --
> > 1.9.1
> >



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support
  2018-11-27  9:27   ` Jjian Zhou
@ 2018-12-09  6:00     ` Nicolas Boichat
  0 siblings, 0 replies; 4+ messages in thread
From: Nicolas Boichat @ 2018-12-09  6:00 UTC (permalink / raw)
  To: jjian.zhou
  Cc: Ulf Hansson, Matthias Brugger, Chaotian Jing, Ryder.Lee,
	linux-mmc, linux-arm Mailing List, linux-mediatek,
	srv_heupstream, lkml, yong.mao, Hsin-Yi Wang, sean.wang

On Tue, Nov 27, 2018 at 5:27 PM Jjian Zhou <jjian.zhou@mediatek.com> wrote:
>
> On Mon, 2018-11-26 at 19:47 +0800, Nicolas Boichat wrote:
> > On Thu, Nov 22, 2018 at 4:03 PM Jjian Zhou <jjian.zhou@mediatek.com> wrote:
> > >
> > > MT8183 need SDIO driver. So it need add new code
> > > to support it.
> >
> > The description does not seem to match what is going on below: I don't
> > see anything that is obviously MT8183-specific. At first glance, this
> > seems like a patch that makes it possible to enable MMC_CAP_SDIO_IRQ
> > ("cap-sdio-irq" dt property).
> >
> > Can you describe in more detail what is going on here?
>
> Hi Nicolas,
>    Thank you for your comments.
>
> Host wants to use the new method to signal/process SDIO IRQs, must
> enable MMC_CAPS_SDIO_IRQ_NOTHREAD and implement the ->ack_sdio_irq()
> callback. The current driver doesn't support it. This code makes it
> possible to enable SDIO IRQs by using the new method. It is described as
> "MT8183 need SDIO driver". Because it is tested based on MT8183.
> How about the below commit message:
>
> This code wants to support SDIO IRQs. It enables MMC_CAP_SDIO_IRQ &
> MMC_CAP2_SDIO_IRQ_NOTHREAD and implement the ->ack_sdio_irq() callback.

Sorry, I forgot to reply earlier.

"This patch enables support for SDIO IRQs" sounds better to me, but
that's for the commit message.

For the commit _title_, you should not need to mention MT8183 (we have
a similar out-of-tree patch on chromeos-3.18 for MT8173:
https://crrev.com/c/319366, so I assume it'd be useful on many MTK
SoCs). But you can mention that this is tested on MT8183 in the commit
message.

I'd use "mmc: mediatek: Add MMC_CAP_SDIO_IRQ support" as commit title.

Thanks,

>    Thanks a lot.
>
> >
> > > Signed-off-by: Jjian Zhou <jjian.zhou@mediatek.com>
> > > Signed-off-by: Yong mao <yong.mao@mediatek.com>
> > > Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
> > > ---
> > >  drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 48 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > > index 6334cc7..da2a047 100644
> > > --- a/drivers/mmc/host/mtk-sd.c
> > > +++ b/drivers/mmc/host/mtk-sd.c
> > > @@ -1114,6 +1114,7 @@ static void msdc_start_command(struct msdc_host *host,
> > >                 struct mmc_request *mrq, struct mmc_command *cmd)
> > >  {
> > >         u32 rawcmd;
> > > +       unsigned long flags;
> > >
> > >         WARN_ON(host->cmd);
> > >         host->cmd = cmd;
> > > @@ -1131,7 +1132,12 @@ static void msdc_start_command(struct msdc_host *host,
> > >         cmd->error = 0;
> > >         rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
> > >
> > > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > > +               spin_lock_irqsave(&host->lock, flags);
> > >         sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> > > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > > +               spin_unlock_irqrestore(&host->lock, flags);
> > > +
> > >         writel(cmd->arg, host->base + SDC_ARG);
> > >         writel(rawcmd, host->base + SDC_CMD);
> > >  }
> > > @@ -1351,6 +1357,27 @@ static void msdc_request_timeout(struct work_struct *work)
> > >         }
> > >  }
> > >
> > > +static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
> > > +{
> > > +       unsigned long flags;
> > > +       struct msdc_host *host = mmc_priv(mmc);
> > > +
> > > +       if (enb)
> > > +               pm_runtime_get_sync(host->dev);
> > > +
> > > +       spin_lock_irqsave(&host->lock, flags);
> > > +       if (enb)
> > > +               sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> > > +       else
> > > +               sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> > > +       spin_unlock_irqrestore(&host->lock, flags);
> > > +
> > > +       if (!enb) {
> > > +               pm_runtime_mark_last_busy(host->dev);
> > > +               pm_runtime_put_autosuspend(host->dev);
> > > +       }
> > > +}
> > > +
> > >  static irqreturn_t msdc_irq(int irq, void *dev_id)
> > >  {
> > >         struct msdc_host *host = (struct msdc_host *) dev_id;
> > > @@ -1373,7 +1400,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
> > >                 data = host->data;
> > >                 spin_unlock_irqrestore(&host->lock, flags);
> > >
> > > -               if (!(events & event_mask))
> > > +               if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
> > > +                       msdc_enable_sdio_irq(host->mmc, 0);
> > > +                       sdio_signal_irq(host->mmc);
> > > +               }
> > > +
> > > +               if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
> > >                         break;
> > >
> > >                 if (!mrq) {
> > > @@ -1493,8 +1525,11 @@ static void msdc_init_hw(struct msdc_host *host)
> > >          */
> > >         sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
> > >
> > > -       /* disable detect SDIO device interrupt function */
> > > -       sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > > +       /* Config SDIO device detect interrupt function */
> > > +       if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
> > > +               sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > > +       else
> > > +               sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > >
> > >         /* Configure to default data timeout */
> > >         sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
> > > @@ -2013,6 +2048,11 @@ static void msdc_hw_reset(struct mmc_host *mmc)
> > >         sdr_clr_bits(host->base + EMMC_IOCON, 1);
> > >  }
> > >
> > > +static void msdc_ack_sdio_irq(struct mmc_host *mmc)
> > > +{
> > > +       msdc_enable_sdio_irq(mmc, 1);
> > > +}
> > > +
> > >  static const struct mmc_host_ops mt_msdc_ops = {
> > >         .post_req = msdc_post_req,
> > >         .pre_req = msdc_pre_req,
> > > @@ -2020,6 +2060,8 @@ static void msdc_hw_reset(struct mmc_host *mmc)
> > >         .set_ios = msdc_ops_set_ios,
> > >         .get_ro = mmc_gpio_get_ro,
> > >         .get_cd = mmc_gpio_get_cd,
> > > +       .enable_sdio_irq = msdc_enable_sdio_irq,
> > > +       .ack_sdio_irq = msdc_ack_sdio_irq,
> > >         .start_signal_voltage_switch = msdc_ops_switch_volt,
> > >         .card_busy = msdc_card_busy,
> > >         .execute_tuning = msdc_execute_tuning,
> > > @@ -2147,6 +2189,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
> > >         else
> > >                 mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
> > >
> > > +       if (mmc->caps & MMC_CAP_SDIO_IRQ)
> > > +               mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
> > > +
> > >         mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
> > >         /* MMC core transfer sizes tunable parameters */
> > >         mmc->max_segs = MAX_BD_NUM;
> > > --
> > > 1.9.1
> > >
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-12-09  6:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-22  8:03 [PATCH v2] mmc: mediatek: add MT8183 SDIO driver support Jjian Zhou
2018-11-26 11:47 ` Nicolas Boichat
2018-11-27  9:27   ` Jjian Zhou
2018-12-09  6:00     ` Nicolas Boichat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).