]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge remote-tracking branches 'asoc/topic/rt5665', 'asoc/topic/rt5677', 'asoc/topic...
authorMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:54 +0000 (16:36 +0000)
committerMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:54 +0000 (16:36 +0000)
1  2  3  4  5  6 
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/samsung/i2s.c
sound/soc/sunxi/sun4i-i2s.c

diff --combined sound/soc/codecs/Kconfig
index b456d31f7fc1bf2adf82028a68ed6bad0c585fe9,cfc108e5e5ec0477bb35fa40679bfb14194ca69e,9e1718a8cb1ce20a0fd68e2cbe797653b39aadeb,9e1718a8cb1ce20a0fd68e2cbe797653b39aadeb,9e1718a8cb1ce20a0fd68e2cbe797653b39aadeb,9e1718a8cb1ce20a0fd68e2cbe797653b39aadeb..e49e9da7f1f6e41028a0ca832e76e7dce0bc1c01
@@@@@@@ -45,7 -45,7 -45,7 -45,7 -45,7 -45,7 +45,7 @@@@@@@ config SND_SOC_ALL_CODEC
        select SND_SOC_ALC5623 if I2C
        select SND_SOC_ALC5632 if I2C
        select SND_SOC_BT_SCO
 -----  select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
 +++++  select SND_SOC_CQ0093VC
        select SND_SOC_CS35L32 if I2C
        select SND_SOC_CS35L33 if I2C
        select SND_SOC_CS35L34 if I2C
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_MC13783 if MFD_MC13XXX
        select SND_SOC_ML26124 if I2C
 +++++  select SND_SOC_NAU8540 if I2C
        select SND_SOC_NAU8810 if I2C
        select SND_SOC_NAU8825 if I2C
        select SND_SOC_HDMI_CODEC
        select SND_SOC_RT5651 if I2C
        select SND_SOC_RT5659 if I2C
        select SND_SOC_RT5660 if I2C
- ----  select SND_SOC_RT5665 if I2C
        select SND_SOC_RT5663 if I2C
+ ++++  select SND_SOC_RT5665 if I2C
        select SND_SOC_RT5670 if I2C
        select SND_SOC_RT5677 if I2C && SPI_MASTER
        select SND_SOC_SGTL5000 if I2C
@@@@@@@ -526,16 -525,14 -525,14 -525,14 -525,14 -525,14 +526,16 @@@@@@@ config SND_SOC_HDMI_CODE
        select HDMI
      
      config SND_SOC_ES8328
 -----  tristate "Everest Semi ES8328 CODEC"
 +++++  tristate
      
      config SND_SOC_ES8328_I2C
 -----  tristate
 +++++  tristate "Everest Semi ES8328 CODEC (I2C)"
 +++++  depends on I2C
        select SND_SOC_ES8328
      
      config SND_SOC_ES8328_SPI
 -----  tristate
 +++++  tristate "Everest Semi ES8328 CODEC (SPI)"
 +++++  depends on SPI_MASTER
        select SND_SOC_ES8328
      
      config SND_SOC_GTM601
@@@@@@@ -671,8 -668,8 -668,8 -668,8 -668,8 -668,8 +671,8 @@@@@@@ config SND_SOC_RL623
        default y if SND_SOC_RT5651=y
        default y if SND_SOC_RT5659=y
        default y if SND_SOC_RT5660=y
- ----  default y if SND_SOC_RT5665=y
        default y if SND_SOC_RT5663=y
+ ++++  default y if SND_SOC_RT5665=y
        default y if SND_SOC_RT5670=y
        default y if SND_SOC_RT5677=y
        default m if SND_SOC_RT5514=m
        default m if SND_SOC_RT5651=m
        default m if SND_SOC_RT5659=m
        default m if SND_SOC_RT5660=m
- ----  default m if SND_SOC_RT5665=m
        default m if SND_SOC_RT5663=m
+ ++++  default m if SND_SOC_RT5665=m
        default m if SND_SOC_RT5670=m
        default m if SND_SOC_RT5677=m
      
@@@@@@@ -731,10 -728,10 -728,10 -728,10 -728,10 -728,10 +731,10 @@@@@@@ config SND_SOC_RT565
      config SND_SOC_RT5660
        tristate
      
- ----config SND_SOC_RT5665
+ ++++config SND_SOC_RT5663
        tristate
      
- ----config SND_SOC_RT5663
+ ++++config SND_SOC_RT5665
        tristate
      
      config SND_SOC_RT5670
@@@@@@@ -1108,10 -1105,6 -1105,6 -1105,6 -1105,6 -1105,6 +1108,10 @@@@@@@ config SND_SOC_MC1378
      config SND_SOC_ML26124
        tristate
      
 +++++config SND_SOC_NAU8540
 +++++       tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
 +++++       depends on I2C
 +++++
      config SND_SOC_NAU8810
        tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
        depends on I2C
index 0a7f4ffe0d785cef79d5310785d6aaa08172f30d,2624c7324d4a3fc7dad1fe8dbca247ec25bc8a4c,7e1dad79610b39a6d5b83865c7022f09d53d3705,7e1dad79610b39a6d5b83865c7022f09d53d3705,7e1dad79610b39a6d5b83865c7022f09d53d3705,7e1dad79610b39a6d5b83865c7022f09d53d3705..1796cb987e712c78b0fe8f3aa8ec71177256b5b2
@@@@@@@ -90,7 -90,6 -90,6 -90,6 -90,6 -90,6 +90,7 @@@@@@@ snd-soc-mc13783-objs := mc13783.
      snd-soc-ml26124-objs := ml26124.o
      snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
      snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
 +++++snd-soc-nau8540-objs := nau8540.o
      snd-soc-nau8810-objs := nau8810.o
      snd-soc-nau8825-objs := nau8825.o
      snd-soc-hdmi-codec-objs := hdmi-codec.o
@@@@@@@ -119,8 -118,8 -118,8 -118,8 -118,8 -118,8 +119,8 @@@@@@@ snd-soc-rt5645-objs := rt5645.
      snd-soc-rt5651-objs := rt5651.o
      snd-soc-rt5659-objs := rt5659.o
      snd-soc-rt5660-objs := rt5660.o
- ----snd-soc-rt5665-objs := rt5665.o
      snd-soc-rt5663-objs := rt5663.o
+ ++++snd-soc-rt5665-objs := rt5665.o
      snd-soc-rt5670-objs := rt5670.o
      snd-soc-rt5677-objs := rt5677.o
      snd-soc-rt5677-spi-objs := rt5677-spi.o
@@@@@@@ -319,7 -318,6 -318,6 -318,6 -318,6 -318,6 +319,7 @@@@@@@ obj-$(CONFIG_SND_SOC_MC13783)  += snd-so
      obj-$(CONFIG_SND_SOC_ML26124)     += snd-soc-ml26124.o
      obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
      obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
 +++++obj-$(CONFIG_SND_SOC_NAU8540)   += snd-soc-nau8540.o
      obj-$(CONFIG_SND_SOC_NAU8810)   += snd-soc-nau8810.o
      obj-$(CONFIG_SND_SOC_NAU8825)   += snd-soc-nau8825.o
      obj-$(CONFIG_SND_SOC_HDMI_CODEC)  += snd-soc-hdmi-codec.o
@@@@@@@ -348,8 -346,8 -346,8 -346,8 -346,8 -346,8 +348,8 @@@@@@@ obj-$(CONFIG_SND_SOC_RT5645)   += snd-soc
      obj-$(CONFIG_SND_SOC_RT5651)      += snd-soc-rt5651.o
      obj-$(CONFIG_SND_SOC_RT5659)      += snd-soc-rt5659.o
      obj-$(CONFIG_SND_SOC_RT5660)      += snd-soc-rt5660.o
- ----obj-$(CONFIG_SND_SOC_RT5665)      += snd-soc-rt5665.o
      obj-$(CONFIG_SND_SOC_RT5663)      += snd-soc-rt5663.o
+ ++++obj-$(CONFIG_SND_SOC_RT5665)      += snd-soc-rt5665.o
      obj-$(CONFIG_SND_SOC_RT5670)      += snd-soc-rt5670.o
      obj-$(CONFIG_SND_SOC_RT5677)      += snd-soc-rt5677.o
      obj-$(CONFIG_SND_SOC_RT5677_SPI)  += snd-soc-rt5677-spi.o
diff --combined sound/soc/samsung/i2s.c
index 85324e61cbd56da5c07a55ae02151516ce4a8f00,e00974bc561670ff30413a85e5fe2644148617e3,e00974bc561670ff30413a85e5fe2644148617e3,2a5b92c672fbff67b869ccd2863d78993c6cb3a2,e00974bc561670ff30413a85e5fe2644148617e3,e00974bc561670ff30413a85e5fe2644148617e3..52a47ed292a4739d485c40a977099b186a649281
      
      #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
      
--- --enum samsung_dai_type {
--- --  TYPE_PRI,
--- --  TYPE_SEC,
--- --};
--- --
      struct samsung_i2s_variant_regs {
        unsigned int    bfs_off;
        unsigned int    rfs_off;
      };
      
      struct samsung_i2s_dai_data {
--- --  int dai_type;
        u32 quirks;
        const struct samsung_i2s_variant_regs *i2s_variant_regs;
      };
@@@@@@@ -483,6 -483,6 -483,6 -477,9 -483,6 -483,6 +477,9 @@@@@@@ static int i2s_set_sysclk(struct snd_so
        unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
        u32 mod, mask, val = 0;
        unsigned long flags;
+++ ++  int ret = 0;
+++ ++
+++ ++  pm_runtime_get_sync(dai->dev);
      
        spin_lock_irqsave(i2s->lock, flags);
        mod = readl(i2s->addr + I2SMOD);
                                        && (mod & cdcon_mask))))) {
                        dev_err(&i2s->pdev->dev,
                                "%s:%d Other DAI busy\n", __func__, __LINE__);
--- --                  return -EAGAIN;
+++ ++                  ret = -EAGAIN;
+++ ++                  goto err;
                }
      
                if (dir == SND_SOC_CLOCK_IN)
                                } else {
                                        i2s->rclk_srcrate =
                                                clk_get_rate(i2s->op_clk);
--- --                                  return 0;
+++ ++                                  goto done;
                                }
                        }
      
                                i2s->op_clk = clk_get(&i2s->pdev->dev,
                                                "i2s_opclk0");
      
--- --                  if (WARN_ON(IS_ERR(i2s->op_clk)))
--- --                          return PTR_ERR(i2s->op_clk);
+++ ++                  if (WARN_ON(IS_ERR(i2s->op_clk))) {
+++ ++                          ret = PTR_ERR(i2s->op_clk);
+++ ++                          i2s->op_clk = NULL;
+++ ++                          goto err;
+++ ++                  }
      
                        clk_prepare_enable(i2s->op_clk);
                        i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
                                || (clk_id && !(mod & rsrc_mask))) {
                        dev_err(&i2s->pdev->dev,
                                "%s:%d Other DAI busy\n", __func__, __LINE__);
--- --                  return -EAGAIN;
+++ ++                  ret = -EAGAIN;
+++ ++                  goto err;
                } else {
                        /* Call can't be on the active DAI */
                        i2s->op_clk = other->op_clk;
                        i2s->rclk_srcrate = other->rclk_srcrate;
--- --                  return 0;
+++ ++                  goto done;
                }
      
                if (clk_id == 1)
                break;
        default:
                dev_err(&i2s->pdev->dev, "We don't serve that!\n");
--- --          return -EINVAL;
+++ ++          ret = -EINVAL;
+++ ++          goto err;
        }
      
        spin_lock_irqsave(i2s->lock, flags);
        mod = (mod & ~mask) | val;
        writel(mod, i2s->addr + I2SMOD);
        spin_unlock_irqrestore(i2s->lock, flags);
+++ ++done:
+++ ++  pm_runtime_put(dai->dev);
      
        return 0;
+++ ++err:
+++ ++  pm_runtime_put(dai->dev);
+++ ++  return ret;
      }
      
      static int i2s_set_fmt(struct snd_soc_dai *dai,
                return -EINVAL;
        }
      
+++ ++  pm_runtime_get_sync(dai->dev);
        spin_lock_irqsave(i2s->lock, flags);
        mod = readl(i2s->addr + I2SMOD);
        /*
        if (any_active(i2s) &&
                ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) {
                spin_unlock_irqrestore(i2s->lock, flags);
+++ ++          pm_runtime_put(dai->dev);
                dev_err(&i2s->pdev->dev,
                                "%s:%d Other DAI busy\n", __func__, __LINE__);
                return -EAGAIN;
        mod |= tmp;
        writel(mod, i2s->addr + I2SMOD);
        spin_unlock_irqrestore(i2s->lock, flags);
+++ ++  pm_runtime_put(dai->dev);
      
        return 0;
      }
@@@@@@@ -681,6 -681,6 -681,6 -692,8 -681,6 -681,6 +692,8 @@@@@@@ static int i2s_hw_params(struct snd_pcm
        u32 mod, mask = 0, val = 0;
        unsigned long flags;
      
+++ ++  WARN_ON(!pm_runtime_active(dai->dev));
+++ ++
        if (!is_secondary(i2s))
                mask |= (MOD_DC2_EN | MOD_DC1_EN);
      
@@@@@@@ -769,6 -769,6 -769,6 -782,8 -769,6 -769,6 +782,8 @@@@@@@ static int i2s_startup(struct snd_pcm_s
        struct i2s_dai *other = get_other_dai(i2s);
        unsigned long flags;
      
+++ ++  pm_runtime_get_sync(dai->dev);
+++ ++
        spin_lock_irqsave(&lock, flags);
      
        i2s->mode |= DAI_OPENED;
@@@@@@@ -806,6 -806,6 -806,6 -821,8 -806,6 -806,6 +821,8 @@@@@@@ static void i2s_shutdown(struct snd_pcm
        i2s->bfs = 0;
      
        spin_unlock_irqrestore(&lock, flags);
+++ ++
+++ ++  pm_runtime_put(dai->dev);
      }
      
      static int config_setup(struct i2s_dai *i2s)
@@@@@@@ -880,6 -880,6 -880,6 -897,7 -880,6 -880,6 +897,7 @@@@@@@ static int i2s_trigger(struct snd_pcm_s
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+++ ++          pm_runtime_get_sync(dai->dev);
                spin_lock_irqsave(i2s->lock, flags);
      
                if (config_setup(i2s)) {
                }
      
                spin_unlock_irqrestore(i2s->lock, flags);
+++ ++          pm_runtime_put(dai->dev);
                break;
        }
      
@@@@@@@ -922,13 -922,13 -922,13 -941,16 -922,13 -922,13 +941,16 @@@@@@@ static int i2s_set_clkdiv(struct snd_so
      
        switch (div_id) {
        case SAMSUNG_I2S_DIV_BCLK:
+++ ++          pm_runtime_get_sync(dai->dev);
                if ((any_active(i2s) && div && (get_bfs(i2s) != div))
                        || (other && other->bfs && (other->bfs != div))) {
+++ ++                  pm_runtime_put(dai->dev);
                        dev_err(&i2s->pdev->dev,
                                "%s:%d Other DAI busy\n", __func__, __LINE__);
                        return -EAGAIN;
                }
                i2s->bfs = div;
+++ ++          pm_runtime_put(dai->dev);
                break;
        default:
                dev_err(&i2s->pdev->dev,
@@@@@@@ -947,6 -947,6 -947,6 -969,8 -947,6 -947,6 +969,8 @@@@@@@ i2s_delay(struct snd_pcm_substream *sub
        snd_pcm_sframes_t delay;
        const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
      
+++ ++  WARN_ON(!pm_runtime_active(dai->dev));
+++ ++
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
                delay = FIC_RXCOUNT(reg);
        else if (is_secondary(i2s))
      #ifdef CONFIG_PM
      static int i2s_suspend(struct snd_soc_dai *dai)
      {
--- --  struct i2s_dai *i2s = to_info(dai);
--- --
--- --  i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
--- --  i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
--- --  i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
--- --
--- --  return 0;
+++ ++  return pm_runtime_force_suspend(dai->dev);
      }
      
      static int i2s_resume(struct snd_soc_dai *dai)
      {
--- --  struct i2s_dai *i2s = to_info(dai);
--- --
--- --  writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
--- --  writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
--- --  writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
--- --
--- --  return 0;
+++ ++  return pm_runtime_force_resume(dai->dev);
      }
      #else
      #define i2s_suspend NULL
@@@@@@@ -990,6 -990,6 -990,6 -1002,8 -990,6 -990,6 +1002,8 @@@@@@@ static int samsung_i2s_dai_probe(struc
        struct i2s_dai *other = get_other_dai(i2s);
        unsigned long flags;
      
+++ ++  pm_runtime_get_sync(dai->dev);
+++ ++
        if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */
                snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback,
                                           NULL);
        if (!is_opened(other))
                i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
                                0, SND_SOC_CLOCK_IN);
+++ ++  pm_runtime_put(dai->dev);
      
        return 0;
      }
@@@@@@@ -1031,6 -1031,6 -1031,6 -1046,8 -1031,6 -1031,6 +1046,8 @@@@@@@ static int samsung_i2s_dai_remove(struc
        struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
        unsigned long flags;
      
+++ ++  pm_runtime_get_sync(dai->dev);
+++ ++
        if (!is_secondary(i2s)) {
                if (i2s->quirks & QUIRK_NEED_RSTCLR) {
                        spin_lock_irqsave(i2s->lock, flags);
                }
        }
      
+++ ++  pm_runtime_put(dai->dev);
+++ ++
        return 0;
      }
      
@@@@@@@ -1066,7 -1066,7 -1066,7 -1085,6 -1066,7 -1066,7 +1085,6 @@@@@@@ static const struct snd_soc_component_d
      static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
      {
        struct i2s_dai *i2s;
--- --  int ret;
      
        i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
        if (i2s == NULL)
                i2s->i2s_dai_drv.capture.channels_max = 2;
                i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
                i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
--- --          dev_set_drvdata(&i2s->pdev->dev, i2s);
--- --  } else {        /* Create a new platform_device for Secondary */
--- --          i2s->pdev = platform_device_alloc("samsung-i2s-sec", -1);
--- --          if (!i2s->pdev)
--- --                  return NULL;
--- --
--- --          i2s->pdev->dev.parent = &pdev->dev;
--- --
--- --          platform_set_drvdata(i2s->pdev, i2s);
--- --          ret = platform_device_add(i2s->pdev);
--- --          if (ret < 0)
--- --                  return NULL;
        }
--- --
        return i2s;
      }
      
--- --static void i2s_free_sec_dai(struct i2s_dai *i2s)
--- --{
--- --  platform_device_del(i2s->pdev);
--- --}
--- --
      #ifdef CONFIG_PM
      static int i2s_runtime_suspend(struct device *dev)
      {
        struct i2s_dai *i2s = dev_get_drvdata(dev);
      
+++ ++  i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
+++ ++  i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
+++ ++  i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+++ ++
+++ ++  if (i2s->op_clk)
+++ ++          clk_disable_unprepare(i2s->op_clk);
        clk_disable_unprepare(i2s->clk);
      
        return 0;
@@@@@@@ -1128,6 -1128,6 -1128,6 -1134,12 -1128,6 -1128,6 +1134,12 @@@@@@@ static int i2s_runtime_resume(struct de
        struct i2s_dai *i2s = dev_get_drvdata(dev);
      
        clk_prepare_enable(i2s->clk);
+++ ++  if (i2s->op_clk)
+++ ++          clk_prepare_enable(i2s->op_clk);
+++ ++
+++ ++  writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
+++ ++  writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
+++ ++  writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
      
        return 0;
      }
@@@@@@@ -1179,13 -1179,13 -1179,13 -1191,13 -1179,13 -1179,13 +1191,13 @@@@@@@ static int i2s_register_clock_provider(
                u32 val = readl(i2s->addr + I2SPSR);
                writel(val | PSR_PSREN, i2s->addr + I2SPSR);
      
--- --          i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(NULL,
+++ ++          i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
                                "i2s_rclksrc", p_names, ARRAY_SIZE(p_names),
                                CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
                                i2s->addr + I2SMOD, reg_info->rclksrc_off,
                                1, 0, i2s->lock);
      
--- --          i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(NULL,
+++ ++          i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
                                "i2s_presc", "i2s_rclksrc",
                                CLK_SET_RATE_PARENT,
                                i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
        of_property_read_string_index(dev->of_node,
                                "clock-output-names", 0, &clk_name[0]);
      
--- --  i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(NULL, clk_name[0],
+++ ++  i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev, clk_name[0],
                                p_names[0], CLK_SET_RATE_PARENT,
                                i2s->addr + I2SMOD, reg_info->cdclkcon_off,
                                CLK_GATE_SET_TO_DISABLE, i2s->lock);
@@@@@@@ -1218,7 -1218,7 -1218,7 -1230,6 -1218,7 -1218,7 +1230,6 @@@@@@@ static int samsung_i2s_probe(struct pla
      {
        struct i2s_dai *pri_dai, *sec_dai = NULL;
        struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
--- --  struct samsung_i2s *i2s_cfg = NULL;
        struct resource *res;
        u32 regs_base, quirks = 0, idma_addr = 0;
        struct device_node *np = pdev->dev.of_node;
                i2s_dai_data = (struct samsung_i2s_dai_data *)
                                platform_get_device_id(pdev)->driver_data;
      
--- --  /* Call during the secondary interface registration */
--- --  if (i2s_dai_data->dai_type == TYPE_SEC) {
--- --          sec_dai = dev_get_drvdata(&pdev->dev);
--- --          if (!sec_dai) {
--- --                  dev_err(&pdev->dev, "Unable to get drvdata\n");
--- --                  return -EFAULT;
--- --          }
--- --          ret = samsung_asoc_dma_platform_register(&pdev->dev,
--- --                                  sec_dai->filter, "tx-sec", NULL);
--- --          if (ret != 0)
--- --                  return ret;
--- --
--- --          return devm_snd_soc_register_component(&sec_dai->pdev->dev,
--- --                                          &samsung_i2s_component,
--- --                                          &sec_dai->i2s_dai_drv, 1);
--- --  }
      
        pri_dai = i2s_alloc_dai(pdev, false);
        if (!pri_dai) {
                pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
                pri_dai->filter = i2s_pdata->dma_filter;
      
--- --          if (&i2s_pdata->type)
--- --                  i2s_cfg = &i2s_pdata->type.i2s;
--- --
--- --          if (i2s_cfg) {
--- --                  quirks = i2s_cfg->quirks;
--- --                  idma_addr = i2s_cfg->idma_addr;
--- --          }
+++ ++          quirks = i2s_pdata->type.quirks;
+++ ++          idma_addr = i2s_pdata->type.idma_addr;
        } else {
                quirks = i2s_dai_data->quirks;
                if (of_property_read_u32(np, "samsung,idma-addr",
        }
        pri_dai->dma_playback.addr = regs_base + I2STXD;
        pri_dai->dma_capture.addr = regs_base + I2SRXD;
 +++++  pri_dai->dma_playback.chan_name = "tx";
 +++++  pri_dai->dma_capture.chan_name = "rx";
        pri_dai->dma_playback.addr_width = 4;
        pri_dai->dma_capture.addr_width = 4;
        pri_dai->quirks = quirks;
        if (ret < 0)
                goto err_disable_clk;
      
+++ ++  ret = devm_snd_soc_register_component(&pdev->dev,
+++ ++                                  &samsung_i2s_component,
+++ ++                                  &pri_dai->i2s_dai_drv, 1);
+++ ++  if (ret < 0)
+++ ++          goto err_disable_clk;
+++ ++
        if (quirks & QUIRK_SEC_DAI) {
                sec_dai = i2s_alloc_dai(pdev, true);
                if (!sec_dai) {
                sec_dai->lock = &pri_dai->spinlock;
                sec_dai->variant_regs = pri_dai->variant_regs;
                sec_dai->dma_playback.addr = regs_base + I2STXDS;
 +++++          sec_dai->dma_playback.chan_name = "tx-sec";
      
                if (!np) {
                        sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
                sec_dai->idma_playback.addr = idma_addr;
                sec_dai->pri_dai = pri_dai;
                pri_dai->sec_dai = sec_dai;
+++ ++
+++ ++          ret = samsung_asoc_dma_platform_register(&pdev->dev,
+++ ++                                  sec_dai->filter, "tx-sec", NULL);
+++ ++          if (ret < 0)
+++ ++                  goto err_disable_clk;
+++ ++
+++ ++          ret = devm_snd_soc_register_component(&pdev->dev,
+++ ++                                          &samsung_i2s_component,
+++ ++                                          &sec_dai->i2s_dai_drv, 1);
+++ ++          if (ret < 0)
+++ ++                  goto err_disable_clk;
        }
      
        if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
                goto err_disable_clk;
        }
      
--- --  ret = devm_snd_soc_register_component(&pri_dai->pdev->dev,
--- --                                  &samsung_i2s_component,
--- --                                  &pri_dai->i2s_dai_drv, 1);
--- --  if (ret < 0)
--- --          goto err_free_dai;
--- --
+++ ++  dev_set_drvdata(&pdev->dev, pri_dai);
      
+++ ++  pm_runtime_set_active(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
      
        ret = i2s_register_clock_provider(pdev);
                return 0;
      
        pm_runtime_disable(&pdev->dev);
--- --err_free_dai:
--- --  if (sec_dai)
--- --          i2s_free_sec_dai(sec_dai);
      err_disable_clk:
        clk_disable_unprepare(pri_dai->clk);
        return ret;
      
      static int samsung_i2s_remove(struct platform_device *pdev)
      {
--- --  struct i2s_dai *i2s, *other;
+++ ++  struct i2s_dai *pri_dai, *sec_dai;
      
--- --  i2s = dev_get_drvdata(&pdev->dev);
--- --  other = get_other_dai(i2s);
+++ ++  pri_dai = dev_get_drvdata(&pdev->dev);
+++ ++  sec_dai = pri_dai->sec_dai;
      
--- --  if (other) {
--- --          other->pri_dai = NULL;
--- --          other->sec_dai = NULL;
--- --  } else {
--- --          pm_runtime_disable(&pdev->dev);
--- --  }
+++ ++  pri_dai->sec_dai = NULL;
+++ ++  sec_dai->pri_dai = NULL;
      
--- --  if (!is_secondary(i2s)) {
--- --          i2s_unregister_clock_provider(pdev);
--- --          clk_disable_unprepare(i2s->clk);
--- --  }
+++ ++  pm_runtime_get_sync(&pdev->dev);
+++ ++  pm_runtime_disable(&pdev->dev);
      
--- --  i2s->pri_dai = NULL;
--- --  i2s->sec_dai = NULL;
+++ ++  i2s_unregister_clock_provider(pdev);
+++ ++  clk_disable_unprepare(pri_dai->clk);
+++ ++  pm_runtime_put_noidle(&pdev->dev);
      
        return 0;
      }
@@@@@@@ -1457,49 -1454,49 -1454,49 -1449,37 -1454,49 -1454,49 +1452,37 @@@@@@@ static const struct samsung_i2s_variant
      };
      
      static const struct samsung_i2s_dai_data i2sv3_dai_type = {
--- --  .dai_type = TYPE_PRI,
        .quirks = QUIRK_NO_MUXPSR,
        .i2s_variant_regs = &i2sv3_regs,
      };
      
      static const struct samsung_i2s_dai_data i2sv5_dai_type = {
--- --  .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_IDMA,
        .i2s_variant_regs = &i2sv3_regs,
      };
      
      static const struct samsung_i2s_dai_data i2sv6_dai_type = {
--- --  .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA,
        .i2s_variant_regs = &i2sv6_regs,
      };
      
      static const struct samsung_i2s_dai_data i2sv7_dai_type = {
--- --  .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_TDM,
        .i2s_variant_regs = &i2sv7_regs,
      };
      
      static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
--- --  .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR,
        .i2s_variant_regs = &i2sv5_i2s1_regs,
      };
      
--- --static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
--- --  .dai_type = TYPE_SEC,
--- --};
--- --
      static const struct platform_device_id samsung_i2s_driver_ids[] = {
        {
                .name           = "samsung-i2s",
                .driver_data    = (kernel_ulong_t)&i2sv3_dai_type,
--- --  }, {
--- --          .name           = "samsung-i2s-sec",
--- --          .driver_data    = (kernel_ulong_t)&samsung_dai_type_sec,
        },
        {},
      };
@@@@@@@ -1531,6 -1528,6 -1528,6 -1511,8 -1528,6 -1528,6 +1514,8 @@@@@@@ MODULE_DEVICE_TABLE(of, exynos_i2s_matc
      static const struct dev_pm_ops samsung_i2s_pm = {
        SET_RUNTIME_PM_OPS(i2s_runtime_suspend,
                                i2s_runtime_resume, NULL)
+++ ++  SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+++ ++                               pm_runtime_force_resume)
      };
      
      static struct platform_driver samsung_i2s_driver = {
index 4237323ef5945a37c11c0097f5f4ff62babca0f1,f24d19526603c2d2a31ef9af1cff07ed4dd8d1ca,f24d19526603c2d2a31ef9af1cff07ed4dd8d1ca,f24d19526603c2d2a31ef9af1cff07ed4dd8d1ca,f24d19526603c2d2a31ef9af1cff07ed4dd8d1ca,268f2bf691b33e6c1955d690f2e9bc4852686069..3635bbc72cbcd3f4053569195007f57762758e7f
      #include <linux/clk.h>
      #include <linux/dmaengine.h>
      #include <linux/module.h>
+++++ #include <linux/of_device.h>
      #include <linux/platform_device.h>
      #include <linux/pm_runtime.h>
      #include <linux/regmap.h>
+++++ #include <linux/reset.h>
      
      #include <sound/dmaengine_pcm.h>
      #include <sound/pcm_params.h>
@@@@@@@ -92,6 -92,6 -92,6 -92,6 -92,6 -94,7 +94,7 @@@@@@@ struct sun4i_i2s 
        struct clk      *bus_clk;
        struct clk      *mod_clk;
        struct regmap   *regmap;
+++++   struct reset_control *rst;
      
        unsigned int    mclk_freq;
      
@@@@@@@ -651,9 -651,9 -651,9 -651,9 -651,9 -654,22 +654,22 @@@@@@@ static int sun4i_i2s_runtime_suspend(st
        return 0;
      }
      
+++++ struct sun4i_i2s_quirks {
+++++   bool has_reset;
+++++ };
+++++ 
+++++ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
+++++   .has_reset      = false,
+++++ };
+++++ 
+++++ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
+++++   .has_reset      = true,
+++++ };
+++++ 
      static int sun4i_i2s_probe(struct platform_device *pdev)
      {
        struct sun4i_i2s *i2s;
+++++   const struct sun4i_i2s_quirks *quirks;
        struct resource *res;
        void __iomem *regs;
        int irq, ret;
                return irq;
        }
      
+++++   quirks = of_device_get_match_data(&pdev->dev);
+++++   if (!quirks) {
+++++           dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+++++           return -ENODEV;
+++++   }
+++++ 
        i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
        if (IS_ERR(i2s->bus_clk)) {
                dev_err(&pdev->dev, "Can't get our bus clock\n");
                dev_err(&pdev->dev, "Can't get our mod clock\n");
                return PTR_ERR(i2s->mod_clk);
        }
-----   
+++++ 
+++++   if (quirks->has_reset) {
+++++           i2s->rst = devm_reset_control_get(&pdev->dev, NULL);
+++++           if (IS_ERR(i2s->rst)) {
+++++                   dev_err(&pdev->dev, "Failed to get reset control\n");
+++++                   return PTR_ERR(i2s->rst);
+++++           }
+++++   }
+++++ 
+++++   if (!IS_ERR(i2s->rst)) {
+++++           ret = reset_control_deassert(i2s->rst);
+++++           if (ret) {
+++++                   dev_err(&pdev->dev,
+++++                           "Failed to deassert the reset control\n");
+++++                   return -EINVAL;
+++++           }
+++++   }
+++++ 
        i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
 -----  i2s->playback_dma_data.maxburst = 4;
 +++++  i2s->playback_dma_data.maxburst = 8;
      
        i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 -----  i2s->capture_dma_data.maxburst = 4;
 +++++  i2s->capture_dma_data.maxburst = 8;
      
        pm_runtime_enable(&pdev->dev);
        if (!pm_runtime_enabled(&pdev->dev)) {
@@@@@@@ -727,23 -727,23 -727,23 -727,23 -727,23 -766,37 +766,37 @@@@@@@ err_suspend
                sun4i_i2s_runtime_suspend(&pdev->dev);
      err_pm_disable:
        pm_runtime_disable(&pdev->dev);
+++++   if (!IS_ERR(i2s->rst))
+++++           reset_control_assert(i2s->rst);
      
        return ret;
      }
      
      static int sun4i_i2s_remove(struct platform_device *pdev)
      {
+++++   struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
+++++ 
        snd_dmaengine_pcm_unregister(&pdev->dev);
      
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                sun4i_i2s_runtime_suspend(&pdev->dev);
      
+++++   if (!IS_ERR(i2s->rst))
+++++           reset_control_assert(i2s->rst);
+++++ 
        return 0;
      }
      
      static const struct of_device_id sun4i_i2s_match[] = {
-----   { .compatible = "allwinner,sun4i-a10-i2s", },
+++++   {
+++++           .compatible = "allwinner,sun4i-a10-i2s",
+++++           .data = &sun4i_a10_i2s_quirks,
+++++   },
+++++   {
+++++           .compatible = "allwinner,sun6i-a31-i2s",
+++++           .data = &sun6i_a31_i2s_quirks,
+++++   },
        {}
      };
      MODULE_DEVICE_TABLE(of, sun4i_i2s_match);