diff mbox series

[v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe()

Message ID 20210729103234.480743-1-yoshihiro.shimoda.uh@renesas.com
State New
Headers show
Series [v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe() | expand

Commit Message

Yoshihiro Shimoda July 29, 2021, 10:32 a.m. UTC
Refactor renesas_sdhi_probe() to avoid increasing numbers of
sdhi_quirks_match[] entry when we add other stable SoCs like
r8a779m*.

Note that the sdhi_quirks_match[] is only needed on
renesas_sdhi_internal_dmac.c so that of_data of
renesas_sdhi_sys_dmac.c keeps as-is.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 Changes from v3:
 - Add Reviewed-by tag (Geert-san, thanks!)
 - Remove Reported-by tag.
 - Modify renesas_sdhi_internal_dmac_probe() for readability.
 https://lore.kernel.org/linux-mmc/20210702112956.1065875-1-yoshihiro.shimoda.uh@renesas.com/

 Changes from RFC v2:
 - Remove "RFC" mark from the subject.
 - Add a comment to the Reported-by tag.
 - Move all quirks to internal_dmac.c so that expands the renesas_sdhi_probe()
   arguments. So, update the commit subject and description.
 - Don't modify the renesas_sdhi_sys_dmac.c's of_data.
 - Replace tabs with a space in of_data_with_quirks variables.
 https://lore.kernel.org/linux-renesas-soc/20210629102033.847369-1-yoshihiro.shimoda.uh@renesas.com/

 Changes from RFC v1:
 - Fix build error in sys_dmac.c, reported by kernel test robot, so that
   add Reported-by tag.
 - Always set quirks, not using else statement.
 - Fix a NULL dereference if of_device_get_match_data() returns NULL.
 https://lore.kernel.org/linux-renesas-soc/20210625075508.664674-1-yoshihiro.shimoda.uh@renesas.com/

 drivers/mmc/host/renesas_sdhi.h               |   9 +-
 drivers/mmc/host/renesas_sdhi_core.c          |  90 +-----------
 drivers/mmc/host/renesas_sdhi_internal_dmac.c | 135 +++++++++++++++++-
 drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   3 +-
 4 files changed, 141 insertions(+), 96 deletions(-)

Comments

Wolfram Sang Aug. 11, 2021, 8:28 a.m. UTC | #1
On Thu, Jul 29, 2021 at 07:32:34PM +0900, Yoshihiro Shimoda wrote:
> Refactor renesas_sdhi_probe() to avoid increasing numbers of

> sdhi_quirks_match[] entry when we add other stable SoCs like

> r8a779m*.

> 

> Note that the sdhi_quirks_match[] is only needed on

> renesas_sdhi_internal_dmac.c so that of_data of

> renesas_sdhi_sys_dmac.c keeps as-is.

> 

> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>


I like this change! Not only does it avoid the white listing, but it
also puts things where they belong! Looks much more sorted to me.

I think we can base even further cleanup on this. Like merging
soc_dma_quirks into the other quirks. But we can do this incrementally.

Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>


I also tested this on H3 ES1.0, M3-W ES1.0, M3-N, and E3 with some debug
output. It all made sense and SDHI still works:

I also tested H3 ES2.0 without debug output. SDHI still worked.

Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Ulf Hansson Aug. 16, 2021, 1:59 p.m. UTC | #2
On Thu, 29 Jul 2021 at 12:32, Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
>

> Refactor renesas_sdhi_probe() to avoid increasing numbers of

> sdhi_quirks_match[] entry when we add other stable SoCs like

> r8a779m*.

>

> Note that the sdhi_quirks_match[] is only needed on

> renesas_sdhi_internal_dmac.c so that of_data of

> renesas_sdhi_sys_dmac.c keeps as-is.

>

> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>


Applied for next, thanks!

Kind regards
Uffe


> ---

>  Changes from v3:

>  - Add Reviewed-by tag (Geert-san, thanks!)

>  - Remove Reported-by tag.

>  - Modify renesas_sdhi_internal_dmac_probe() for readability.

>  https://lore.kernel.org/linux-mmc/20210702112956.1065875-1-yoshihiro.shimoda.uh@renesas.com/

>

>  Changes from RFC v2:

>  - Remove "RFC" mark from the subject.

>  - Add a comment to the Reported-by tag.

>  - Move all quirks to internal_dmac.c so that expands the renesas_sdhi_probe()

>    arguments. So, update the commit subject and description.

>  - Don't modify the renesas_sdhi_sys_dmac.c's of_data.

>  - Replace tabs with a space in of_data_with_quirks variables.

>  https://lore.kernel.org/linux-renesas-soc/20210629102033.847369-1-yoshihiro.shimoda.uh@renesas.com/

>

>  Changes from RFC v1:

>  - Fix build error in sys_dmac.c, reported by kernel test robot, so that

>    add Reported-by tag.

>  - Always set quirks, not using else statement.

>  - Fix a NULL dereference if of_device_get_match_data() returns NULL.

>  https://lore.kernel.org/linux-renesas-soc/20210625075508.664674-1-yoshihiro.shimoda.uh@renesas.com/

>

>  drivers/mmc/host/renesas_sdhi.h               |   9 +-

>  drivers/mmc/host/renesas_sdhi_core.c          |  90 +-----------

>  drivers/mmc/host/renesas_sdhi_internal_dmac.c | 135 +++++++++++++++++-

>  drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   3 +-

>  4 files changed, 141 insertions(+), 96 deletions(-)

>

> diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h

> index 53eded81a53e..0c45e82ff0de 100644

> --- a/drivers/mmc/host/renesas_sdhi.h

> +++ b/drivers/mmc/host/renesas_sdhi.h

> @@ -42,6 +42,11 @@ struct renesas_sdhi_quirks {

>         const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];

>  };

>

> +struct renesas_sdhi_of_data_with_quirks {

> +       const struct renesas_sdhi_of_data *of_data;

> +       const struct renesas_sdhi_quirks *quirks;

> +};

> +

>  struct tmio_mmc_dma {

>         enum dma_slave_buswidth dma_buswidth;

>         bool (*filter)(struct dma_chan *chan, void *arg);

> @@ -78,6 +83,8 @@ struct renesas_sdhi {

>         container_of((host)->pdata, struct renesas_sdhi, mmc_data)

>

>  int renesas_sdhi_probe(struct platform_device *pdev,

> -                      const struct tmio_mmc_dma_ops *dma_ops);

> +                      const struct tmio_mmc_dma_ops *dma_ops,

> +                      const struct renesas_sdhi_of_data *of_data,

> +                      const struct renesas_sdhi_quirks *quirks);

>  int renesas_sdhi_remove(struct platform_device *pdev);

>  #endif

> diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c

> index e49ca0f7fe9a..6fc4cf3c9dce 100644

> --- a/drivers/mmc/host/renesas_sdhi_core.c

> +++ b/drivers/mmc/host/renesas_sdhi_core.c

> @@ -305,27 +305,6 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,

>  #define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK     0x1f

>  #define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE         BIT(7)

>

> -static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> -       { 3,  3,  3,  3,  3,  3,  3,  4,  4,  5,  6,  7,  8,  9, 10, 15,

> -        16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },

> -       { 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  7,  8, 11,

> -        12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }

> -};

> -

> -static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> -       { 1,  2,  6,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15, 15, 16,

> -        17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },

> -       { 2,  3,  4,  4,  5,  6,  7,  9, 10, 11, 12, 13, 14, 15, 16, 17,

> -        17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }

> -};

> -

> -static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> -       { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

> -         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },

> -       { 0,  0,  0,  1,  2,  3,  3,  4,  4,  4,  5,  5,  6,  8,  9, 10,

> -        11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }

> -};

> -

>  static inline u32 sd_scc_read32(struct tmio_mmc_host *host,

>                                 struct renesas_sdhi *priv, int addr)

>  {

> @@ -895,69 +874,12 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)

>         renesas_sdhi_sdbuf_width(host, enable ? width : 16);

>  }

>

> -static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {

> -       .hs400_disabled = true,

> -       .hs400_4taps = true,

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {

> -       .hs400_4taps = true,

> -       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {

> -       .hs400_disabled = true,

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {

> -       .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {

> -       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {

> -       .hs400_4taps = true,

> -       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> -       .hs400_calib_table = r8a7796_es13_calib_table,

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {

> -       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> -       .hs400_calib_table = r8a77965_calib_table,

> -};

> -

> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {

> -       .hs400_calib_table = r8a77990_calib_table,

> -};

> -

> -/*

> - * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.

> - * So, we want to treat them equally and only have a match for ES1.2 to enforce

> - * this if there ever will be a way to distinguish ES1.2.

> - */

> -static const struct soc_device_attribute sdhi_quirks_match[]  = {

> -       { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },

> -       { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },

> -       { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },

> -       { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },

> -       { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },

> -       { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },

> -       { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 },

> -       { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 },

> -       { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },

> -       { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 },

> -       { /* Sentinel. */ },

> -};

> -

>  int renesas_sdhi_probe(struct platform_device *pdev,

> -                      const struct tmio_mmc_dma_ops *dma_ops)

> +                      const struct tmio_mmc_dma_ops *dma_ops,

> +                      const struct renesas_sdhi_of_data *of_data,

> +                      const struct renesas_sdhi_quirks *quirks)

>  {

>         struct tmio_mmc_data *mmd = pdev->dev.platform_data;

> -       const struct renesas_sdhi_quirks *quirks = NULL;

> -       const struct renesas_sdhi_of_data *of_data;

> -       const struct soc_device_attribute *attr;

>         struct tmio_mmc_data *mmc_data;

>         struct tmio_mmc_dma *dma_priv;

>         struct tmio_mmc_host *host;

> @@ -966,12 +888,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,

>         struct resource *res;

>         u16 ver;

>

> -       of_data = of_device_get_match_data(&pdev->dev);

> -

> -       attr = soc_device_match(sdhi_quirks_match);

> -       if (attr)

> -               quirks = attr->data;

> -

>         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

>         if (!res)

>                 return -EINVAL;

> diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c

> index e8f4863d8f1a..7660f7ea74dd 100644

> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c

> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c

> @@ -15,6 +15,7 @@

>  #include <linux/mmc/host.h>

>  #include <linux/mod_devicetable.h>

>  #include <linux/module.h>

> +#include <linux/of_device.h>

>  #include <linux/pagemap.h>

>  #include <linux/scatterlist.h>

>  #include <linux/sys_soc.h>

> @@ -92,7 +93,7 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {

>         },

>  };

>

> -static const struct renesas_sdhi_of_data of_rza2_compatible = {

> +static const struct renesas_sdhi_of_data of_data_rza2 = {

>         .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |

>                           TMIO_MMC_HAVE_CBSY,

>         .tmio_ocr_mask  = MMC_VDD_32_33,

> @@ -107,7 +108,11 @@ static const struct renesas_sdhi_of_data of_rza2_compatible = {

>         .max_segs       = 1,

>  };

>

> -static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {

> +static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = {

> +       .of_data        = &of_data_rza2,

> +};

> +

> +static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {

>         .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |

>                           TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,

>         .capabilities   = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |

> @@ -122,11 +127,116 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {

>         .max_segs       = 1,

>  };

>

> +static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> +       { 3,  3,  3,  3,  3,  3,  3,  4,  4,  5,  6,  7,  8,  9, 10, 15,

> +        16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },

> +       { 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  7,  8, 11,

> +        12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }

> +};

> +

> +static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> +       { 1,  2,  6,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15, 15, 16,

> +        17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },

> +       { 2,  3,  4,  4,  5,  6,  7,  9, 10, 11, 12, 13, 14, 15, 16, 17,

> +        17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }

> +};

> +

> +static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {

> +       { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

> +         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },

> +       { 0,  0,  0,  1,  2,  3,  3,  4,  4,  4,  5,  5,  6,  8,  9, 10,

> +        11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {

> +       .hs400_disabled = true,

> +       .hs400_4taps = true,

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {

> +       .hs400_4taps = true,

> +       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {

> +       .hs400_disabled = true,

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {

> +       .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {

> +       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {

> +       .hs400_4taps = true,

> +       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> +       .hs400_calib_table = r8a7796_es13_calib_table,

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {

> +       .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),

> +       .hs400_calib_table = r8a77965_calib_table,

> +};

> +

> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {

> +       .hs400_calib_table = r8a77990_calib_table,

> +};

> +

> +/*

> + * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.

> + * So, we want to treat them equally and only have a match for ES1.2 to enforce

> + * this if there ever will be a way to distinguish ES1.2.

> + */

> +static const struct soc_device_attribute sdhi_quirks_match[]  = {

> +       { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },

> +       { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },

> +       { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },

> +       { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },

> +       { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },

> +       { /* Sentinel. */ },

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +       .quirks = &sdhi_quirks_bad_taps2367,

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +       .quirks = &sdhi_quirks_bad_taps1357,

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +       .quirks = &sdhi_quirks_r8a77965,

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +       .quirks = &sdhi_quirks_nohs400,

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +       .quirks = &sdhi_quirks_r8a77990,

> +};

> +

> +static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = {

> +       .of_data = &of_data_rcar_gen3,

> +};

> +

>  static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {

>         { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },

>         { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },

> -       { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },

> +       { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, },

>         { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },

> +       { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },

> +       { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },

> +       { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },

> +       { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },

>         { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },

>         {},

>  };

> @@ -405,16 +515,27 @@ static const struct soc_device_attribute soc_dma_quirks[] = {

>

>  static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)

>  {

> -       const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks);

> +       const struct soc_device_attribute *attr;

> +       const struct renesas_sdhi_of_data_with_quirks *of_data_quirks;

> +       const struct renesas_sdhi_quirks *quirks;

>         struct device *dev = &pdev->dev;

>

> -       if (soc)

> -               global_flags |= (unsigned long)soc->data;

> +       of_data_quirks = of_device_get_match_data(&pdev->dev);

> +       quirks = of_data_quirks->quirks;

> +

> +       attr = soc_device_match(soc_dma_quirks);

> +       if (attr)

> +               global_flags |= (unsigned long)attr->data;

> +

> +       attr = soc_device_match(sdhi_quirks_match);

> +       if (attr)

> +               quirks = attr->data;

>

>         /* value is max of SD_SECCNT. Confirmed by HW engineers */

>         dma_set_max_seg_size(dev, 0xffffffff);

>

> -       return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);

> +       return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops,

> +                                 of_data_quirks->of_data, quirks);

>  }

>

>  static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {

> diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c

> index 6956b83469c8..99e3426df702 100644

> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c

> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c

> @@ -451,7 +451,8 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_sys_dmac_dma_ops = {

>

>  static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev)

>  {

> -       return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops);

> +       return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops,

> +                                 of_device_get_match_data(&pdev->dev), NULL);

>  }

>

>  static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = {

> --

> 2.25.1

>
diff mbox series

Patch

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 53eded81a53e..0c45e82ff0de 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -42,6 +42,11 @@  struct renesas_sdhi_quirks {
 	const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
 };
 
+struct renesas_sdhi_of_data_with_quirks {
+	const struct renesas_sdhi_of_data *of_data;
+	const struct renesas_sdhi_quirks *quirks;
+};
+
 struct tmio_mmc_dma {
 	enum dma_slave_buswidth dma_buswidth;
 	bool (*filter)(struct dma_chan *chan, void *arg);
@@ -78,6 +83,8 @@  struct renesas_sdhi {
 	container_of((host)->pdata, struct renesas_sdhi, mmc_data)
 
 int renesas_sdhi_probe(struct platform_device *pdev,
-		       const struct tmio_mmc_dma_ops *dma_ops);
+		       const struct tmio_mmc_dma_ops *dma_ops,
+		       const struct renesas_sdhi_of_data *of_data,
+		       const struct renesas_sdhi_quirks *quirks);
 int renesas_sdhi_remove(struct platform_device *pdev);
 #endif
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e49ca0f7fe9a..6fc4cf3c9dce 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -305,27 +305,6 @@  static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
 #define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK	0x1f
 #define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE		BIT(7)
 
-static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
-	{ 3,  3,  3,  3,  3,  3,  3,  4,  4,  5,  6,  7,  8,  9, 10, 15,
-	 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
-	{ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  7,  8, 11,
-	 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
-};
-
-static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
-	{ 1,  2,  6,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
-	 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
-	{ 2,  3,  4,  4,  5,  6,  7,  9, 10, 11, 12, 13, 14, 15, 16, 17,
-	 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
-};
-
-static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
-	{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
-	{ 0,  0,  0,  1,  2,  3,  3,  4,  4,  4,  5,  5,  6,  8,  9, 10,
-	 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
-};
-
 static inline u32 sd_scc_read32(struct tmio_mmc_host *host,
 				struct renesas_sdhi *priv, int addr)
 {
@@ -895,69 +874,12 @@  static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
 	renesas_sdhi_sdbuf_width(host, enable ? width : 16);
 }
 
-static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
-	.hs400_disabled = true,
-	.hs400_4taps = true,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
-	.hs400_4taps = true,
-	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
-	.hs400_disabled = true,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
-	.hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
-	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
-	.hs400_4taps = true,
-	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-	.hs400_calib_table = r8a7796_es13_calib_table,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
-	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-	.hs400_calib_table = r8a77965_calib_table,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
-	.hs400_calib_table = r8a77990_calib_table,
-};
-
-/*
- * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
- * So, we want to treat them equally and only have a match for ES1.2 to enforce
- * this if there ever will be a way to distinguish ES1.2.
- */
-static const struct soc_device_attribute sdhi_quirks_match[]  = {
-	{ .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
-	{ .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
-	{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
-	{ .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
-	{ .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
-	{ .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
-	{ .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 },
-	{ .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 },
-	{ .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
-	{ .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 },
-	{ /* Sentinel. */ },
-};
-
 int renesas_sdhi_probe(struct platform_device *pdev,
-		       const struct tmio_mmc_dma_ops *dma_ops)
+		       const struct tmio_mmc_dma_ops *dma_ops,
+		       const struct renesas_sdhi_of_data *of_data,
+		       const struct renesas_sdhi_quirks *quirks)
 {
 	struct tmio_mmc_data *mmd = pdev->dev.platform_data;
-	const struct renesas_sdhi_quirks *quirks = NULL;
-	const struct renesas_sdhi_of_data *of_data;
-	const struct soc_device_attribute *attr;
 	struct tmio_mmc_data *mmc_data;
 	struct tmio_mmc_dma *dma_priv;
 	struct tmio_mmc_host *host;
@@ -966,12 +888,6 @@  int renesas_sdhi_probe(struct platform_device *pdev,
 	struct resource *res;
 	u16 ver;
 
-	of_data = of_device_get_match_data(&pdev->dev);
-
-	attr = soc_device_match(sdhi_quirks_match);
-	if (attr)
-		quirks = attr->data;
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -EINVAL;
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index e8f4863d8f1a..7660f7ea74dd 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -15,6 +15,7 @@ 
 #include <linux/mmc/host.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/pagemap.h>
 #include <linux/scatterlist.h>
 #include <linux/sys_soc.h>
@@ -92,7 +93,7 @@  static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
 	},
 };
 
-static const struct renesas_sdhi_of_data of_rza2_compatible = {
+static const struct renesas_sdhi_of_data of_data_rza2 = {
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
 			  TMIO_MMC_HAVE_CBSY,
 	.tmio_ocr_mask	= MMC_VDD_32_33,
@@ -107,7 +108,11 @@  static const struct renesas_sdhi_of_data of_rza2_compatible = {
 	.max_segs	= 1,
 };
 
-static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
+static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = {
+	.of_data	= &of_data_rza2,
+};
+
+static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
 			  TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
 	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
@@ -122,11 +127,116 @@  static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
 	.max_segs	= 1,
 };
 
+static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 3,  3,  3,  3,  3,  3,  3,  4,  4,  5,  6,  7,  8,  9, 10, 15,
+	 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
+	{ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  7,  8, 11,
+	 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
+};
+
+static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 1,  2,  6,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
+	 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
+	{ 2,  3,  4,  4,  5,  6,  7,  9, 10, 11, 12, 13, 14, 15, 16, 17,
+	 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
+};
+
+static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+	{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
+	{ 0,  0,  0,  1,  2,  3,  3,  4,  4,  4,  5,  5,  6,  8,  9, 10,
+	 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
+	.hs400_disabled = true,
+	.hs400_4taps = true,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
+	.hs400_4taps = true,
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
+	.hs400_disabled = true,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
+	.hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
+	.hs400_4taps = true,
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+	.hs400_calib_table = r8a7796_es13_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
+	.hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+	.hs400_calib_table = r8a77965_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
+	.hs400_calib_table = r8a77990_calib_table,
+};
+
+/*
+ * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
+ * So, we want to treat them equally and only have a match for ES1.2 to enforce
+ * this if there ever will be a way to distinguish ES1.2.
+ */
+static const struct soc_device_attribute sdhi_quirks_match[]  = {
+	{ .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+	{ .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
+	{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
+	{ .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+	{ .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
+	{ /* Sentinel. */ },
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {
+	.of_data = &of_data_rcar_gen3,
+	.quirks = &sdhi_quirks_bad_taps2367,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = {
+	.of_data = &of_data_rcar_gen3,
+	.quirks = &sdhi_quirks_bad_taps1357,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
+	.of_data = &of_data_rcar_gen3,
+	.quirks = &sdhi_quirks_r8a77965,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {
+	.of_data = &of_data_rcar_gen3,
+	.quirks = &sdhi_quirks_nohs400,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = {
+	.of_data = &of_data_rcar_gen3,
+	.quirks = &sdhi_quirks_r8a77990,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = {
+	.of_data = &of_data_rcar_gen3,
+};
+
 static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
 	{ .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },
 	{ .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },
-	{ .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
+	{ .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, },
 	{ .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
+	{ .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
+	{ .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
+	{ .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },
+	{ .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
 	{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
 	{},
 };
@@ -405,16 +515,27 @@  static const struct soc_device_attribute soc_dma_quirks[] = {
 
 static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
 {
-	const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks);
+	const struct soc_device_attribute *attr;
+	const struct renesas_sdhi_of_data_with_quirks *of_data_quirks;
+	const struct renesas_sdhi_quirks *quirks;
 	struct device *dev = &pdev->dev;
 
-	if (soc)
-		global_flags |= (unsigned long)soc->data;
+	of_data_quirks = of_device_get_match_data(&pdev->dev);
+	quirks = of_data_quirks->quirks;
+
+	attr = soc_device_match(soc_dma_quirks);
+	if (attr)
+		global_flags |= (unsigned long)attr->data;
+
+	attr = soc_device_match(sdhi_quirks_match);
+	if (attr)
+		quirks = attr->data;
 
 	/* value is max of SD_SECCNT. Confirmed by HW engineers */
 	dma_set_max_seg_size(dev, 0xffffffff);
 
-	return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
+	return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops,
+				  of_data_quirks->of_data, quirks);
 }
 
 static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index 6956b83469c8..99e3426df702 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -451,7 +451,8 @@  static const struct tmio_mmc_dma_ops renesas_sdhi_sys_dmac_dma_ops = {
 
 static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev)
 {
-	return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops);
+	return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops,
+				  of_device_get_match_data(&pdev->dev), NULL);
 }
 
 static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = {