Merge tag 'JH7110_515_SDK_v4.0.0-rc2' into vf2-515-devel
authorAndy Hu <andy.hu@starfivetech.com>
Wed, 11 Jan 2023 15:29:35 +0000 (23:29 +0800)
committerAndy Hu <andy.hu@starfivetech.com>
Wed, 11 Jan 2023 15:29:35 +0000 (23:29 +0800)
version JH7110_515_SDK_v4.0.0-rc2 for JH7110 EVB board
1. Fix hibernation issue: spdif, pwmdac, tdm, pdm, wave511, wave420l, jpu, can, isp, clk tree, gmac, gpio
2. Porting the upstream opensbi and add pm patch for hibernation
3. #3120 omx fix low probability of segment fault when decoding finish

18 files changed:
drivers/clk/starfive/clk-starfive-jh7110-gen.c
drivers/clk/starfive/clk-starfive-jh7110.h [changed mode: 0755->0644]
drivers/input/touchscreen/tinker_ft5406.c
drivers/media/platform/starfive/v4l2_driver/stf_video.c
drivers/media/platform/starfive/v4l2_driver/stf_video.h
drivers/media/platform/starfive/v4l2_driver/stf_vin.h
drivers/media/platform/starfive/v4l2_driver/stfcamss.c
drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
drivers/pinctrl/starfive/pinctrl-starfive.c
drivers/pinctrl/starfive/pinctrl-starfive.h
drivers/usb/cdns3/cdns3-starfive.c
sound/soc/starfive/pwmdac.h [changed mode: 0755->0644]
sound/soc/starfive/starfive_pwmdac.c
sound/soc/starfive/starfive_spdif.c
sound/soc/starfive/starfive_spdif.h
sound/soc/starfive/starfive_spdif_pcm.c
sound/soc/starfive/starfive_tdm.c
sound/soc/starfive/starfive_tdm.h

index d852c0a..26cbe07 100644 (file)
@@ -239,11 +239,145 @@ static void jh7110_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
 #define jh7110_clk_debug_init NULL
 #endif
 
+#ifdef CONFIG_PM_SLEEP
+static int jh7110_clk_save_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+       void __iomem *reg = jh7110_clk_reg_addr_get(clk);
+       struct jh7110_clk_priv *priv = jh7110_priv_from(clk);
+
+       if (!clk || !priv)
+               return 0;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return 0;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return 0;
+
+       spin_lock(&priv->rmw_lock);
+       clk->saved_reg_value = readl_relaxed(reg);
+       spin_unlock(&priv->rmw_lock);
+
+       return 0;
+}
+
+static void jh7110_clk_gate_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_ENABLE, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_div_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_DIV_MASK, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_mux_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_MUX_MASK, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_inv_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_INVERT, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_gdiv_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_div_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_gmux_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_mdiv_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_div_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_gmd_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_div_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+#endif
+
 static const struct clk_ops jh7110_clk_gate_ops = {
        .enable = jh7110_clk_enable,
        .disable = jh7110_clk_disable,
        .is_enabled = jh7110_clk_is_enabled,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gate_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_div_ops = {
@@ -251,6 +385,10 @@ static const struct clk_ops jh7110_clk_div_ops = {
        .determine_rate = jh7110_clk_determine_rate,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_div_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gdiv_ops = {
@@ -261,6 +399,10 @@ static const struct clk_ops jh7110_clk_gdiv_ops = {
        .determine_rate = jh7110_clk_determine_rate,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gdiv_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_mux_ops = {
@@ -268,6 +410,10 @@ static const struct clk_ops jh7110_clk_mux_ops = {
        .set_parent = jh7110_clk_set_parent,
        .get_parent = jh7110_clk_get_parent,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_mux_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gmux_ops = {
@@ -278,6 +424,10 @@ static const struct clk_ops jh7110_clk_gmux_ops = {
        .set_parent = jh7110_clk_set_parent,
        .get_parent = jh7110_clk_get_parent,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gmux_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_mdiv_ops = {
@@ -287,6 +437,10 @@ static const struct clk_ops jh7110_clk_mdiv_ops = {
        .set_parent = jh7110_clk_set_parent,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_mdiv_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gmd_ops = {
@@ -299,12 +453,20 @@ static const struct clk_ops jh7110_clk_gmd_ops = {
        .set_parent = jh7110_clk_set_parent,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gmd_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_inv_ops = {
        .get_phase = jh7110_clk_get_phase,
        .set_phase = jh7110_clk_set_phase,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_inv_restore_context,
+#endif
 };
 
 const struct clk_ops *starfive_jh7110_clk_ops(u32 max)
@@ -335,6 +497,25 @@ const struct clk_ops *starfive_jh7110_clk_ops(u32 max)
 }
 EXPORT_SYMBOL_GPL(starfive_jh7110_clk_ops);
 
+#ifdef CONFIG_PM_SLEEP
+static int clk_starfive_jh7110_gen_system_suspend(struct device *dev)
+{
+       return clk_save_context();
+}
+
+static int clk_starfive_jh7110_gen_system_resume(struct device *dev)
+{
+       clk_restore_context();
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops clk_starfive_jh7110_gen_pm_ops = {
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(clk_starfive_jh7110_gen_system_suspend,
+                                    clk_starfive_jh7110_gen_system_resume)
+};
+
 static struct clk_hw *jh7110_clk_get(struct of_phandle_args *clkspec,
                                                void *data)
 {
@@ -369,6 +550,8 @@ static int __init clk_starfive_jh7110_probe(struct platform_device *pdev)
        spin_lock_init(&priv->rmw_lock);
        priv->dev = &pdev->dev;
 
+       pm_runtime_enable(priv->dev);
+
 #ifdef CONFIG_CLK_STARFIVE_JH7110_PLL
        ret = clk_starfive_jh7110_pll_init(pdev, priv->pll_priv);
        if (ret)
@@ -439,6 +622,7 @@ static struct platform_driver clk_starfive_jh7110_driver = {
        .driver = {
                .name = "clk-starfive-jh7110",
                .of_match_table = clk_starfive_jh7110_match,
+               .pm = &clk_starfive_jh7110_gen_pm_ops,
        },
 };
 builtin_platform_driver_probe(clk_starfive_jh7110_driver,
old mode 100755 (executable)
new mode 100644 (file)
index 4560b75..c776ab3
@@ -59,6 +59,7 @@ struct jh7110_clk {
        unsigned int idx;
        unsigned int max_div;
        unsigned int reg_flags;
+       u32 saved_reg_value;
 };
 
 struct jh7110_clk_priv {
index 256e2ba..64ba057 100644 (file)
 #include <linux/module.h>
 #include <linux/workqueue.h>
 
-#define LOG_DBG(fmt, arg...) pr_debug("tinker-ft5406: %s: "fmt, __func__, ##arg)
-#define LOG_INFO(fmt, arg...) pr_info("tinker-ft5406: %s: "fmt, __func__, ##arg)
-#define LOG_ERR(fmt, arg...) pr_err("tinker-ft5406: %s: "fmt, __func__, ##arg)
-
 #define RETRY_COUNT 10
 #define FT_ONE_TCH_LEN 6
 
@@ -38,7 +34,7 @@
 #define FT_REG_FW_SUB_MIN_VER  0xB3
 
 #define VALID_TD_STATUS_VAL            10
-#define MAX_TOUCH_POINTS               1
+#define MAX_TOUCH_POINTS               5
 
 #define FT_PRESS                       0x7F
 #define FT_MAX_ID                      0x0F
@@ -110,7 +106,7 @@ static int fts_i2c_read(struct i2c_client *client, char *writebuf,
                };
                ret = i2c_transfer(client->adapter, msgs, 2);
                if (ret < 0)
-                       LOG_ERR("i2c read error, %d\n", ret);
+                       dev_err(&client->dev, "i2c read error, %d\n", ret);
        } else {
                struct i2c_msg msgs[] = {
                        {
@@ -122,7 +118,7 @@ static int fts_i2c_read(struct i2c_client *client, char *writebuf,
                };
                ret = i2c_transfer(client->adapter, msgs, 1);
                if (ret < 0)
-                       LOG_ERR("i2c read error, %d\n", ret);
+                       dev_err(&client->dev, "i2c read error, %d\n", ret);
        }
 
        return ret;
@@ -153,7 +149,8 @@ static int fts_check_fw_ver(struct i2c_client *client)
        if (ret < 0)
                goto error;
 
-       LOG_INFO("Firmware version = %d.%d.%d\n", fw_ver[0], fw_ver[1], fw_ver[2]);
+       dev_info(&client->dev, "Firmware version = %d.%d.%d\n",
+                       fw_ver[0], fw_ver[1], fw_ver[2]);
        return 0;
 
 error:
@@ -167,7 +164,8 @@ static int fts_read_td_status(struct tinker_ft5406_data *ts_data)
 
        ret = fts_read_reg(ts_data->client, FT_TD_STATUS_REG, &td_status);
        if (ret < 0) {
-               LOG_ERR("get reg td_status failed, %d\n", ret);
+               dev_err(&ts_data->client->dev,
+                               "Get reg td_status failed, %d\n", ret);
                return ret;
        }
        return (int)td_status;
@@ -184,7 +182,7 @@ static int fts_read_touchdata(struct tinker_ft5406_data *ts_data)
                reg_addr = FT_TOUCH_X_H_REG + (i * FT_ONE_TCH_LEN);
                ret = fts_i2c_read(ts_data->client, &reg_addr, 1, buf, FT_ONE_TCH_LEN-2);
                if (ret < 0) {
-                       LOG_ERR("read touchdata failed.\n");
+                       dev_err(&ts_data->client->dev, "Read touchdata failed.\n");
                        return ret;
                }
 
@@ -226,7 +224,7 @@ static void fts_report_value(struct tinker_ft5406_data *ts_data)
                                        event->au16_y[i]);
 
                        if (!((1 << event->au8_finger_id[i]) & ts_data->known_ids))
-                               LOG_DBG("Touch id-%d: x = %d, y = %d\n",
+                               dev_dbg(&ts_data->client->dev, "Touch id-%d: x = %d, y = %d\n",
                                        event->au8_finger_id[i],
                                        event->au16_x[i],
                                        event->au16_y[i]);
@@ -236,7 +234,7 @@ static void fts_report_value(struct tinker_ft5406_data *ts_data)
        released_ids = ts_data->known_ids & ~modified_ids;
        for (i = 0; released_ids && i < MAX_TOUCH_POINTS; i++) {
                if (released_ids & (1<<i)) {
-                       LOG_DBG("Release id-%d, known = %x modified = %x\n",
+                       dev_dbg(&ts_data->client->dev, "Release id-%d, known = %x modified = %x\n",
                                        i, ts_data->known_ids, modified_ids);
                        input_mt_slot(ts_data->input_dev, i);
                        input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false);
@@ -257,12 +255,13 @@ static void fts_retry_clear(struct tinker_ft5406_data *ts_data)
 static int fts_retry_wait(struct tinker_ft5406_data *ts_data)
 {
        if (ts_data->retry_count < RETRY_COUNT) {
-               LOG_INFO("wait and retry, count = %d\n", ts_data->retry_count);
+               dev_info(&ts_data->client->dev,
+                       "Wait and retry, count = %d\n", ts_data->retry_count);
                ts_data->retry_count++;
                msleep(1000);
                return 1;
        }
-       LOG_ERR("attach retry count\n");
+       dev_err(&ts_data->client->dev, "Attach retry count\n");
        return 0;
 }
 
@@ -277,7 +276,7 @@ static void tinker_ft5406_work(struct work_struct *work)
                if (td_status < 0) {
                        ret = fts_retry_wait(g_ts_data);
                        if (ret == 0) {
-                               LOG_ERR("stop touch polling\n");
+                               dev_err(&g_ts_data->client->dev, "Stop touch polling\n");
                                break;
                        }
                } else if (td_status < VALID_TD_STATUS_VAL + 1 &&
@@ -312,11 +311,11 @@ static int tinker_ft5406_probe(struct i2c_client *client,
        struct input_dev *input_dev;
        int ret = 0;
 
-       LOG_INFO("address = 0x%x\n", client->addr);
+       dev_info(&client->dev, "Address = 0x%x\n", client->addr);
 
        g_ts_data = kzalloc(sizeof(struct tinker_ft5406_data), GFP_KERNEL);
        if (g_ts_data == NULL) {
-               LOG_ERR("no memory for device\n");
+               dev_err(&client->dev, "No memory for device\n");
                return -ENOMEM;
        }
 
@@ -327,18 +326,18 @@ static int tinker_ft5406_probe(struct i2c_client *client,
        g_ts_data->screen_height = 480;
        g_ts_data->xy_reverse = 1;
 
-       LOG_INFO("width = %d, height = %d, reverse = %d\n",
+       dev_info(&client->dev, "width = %d, height = %d, reverse = %d\n",
                        g_ts_data->screen_width, g_ts_data->screen_height, g_ts_data->xy_reverse);
 
        ret = fts_check_fw_ver(g_ts_data->client);
        if (ret) {
-               LOG_ERR("checking touch ic failed\n");
+               dev_err(&client->dev, "Checking touch ic failed\n");
                goto check_fw_err;
        }
 
        input_dev = input_allocate_device();
        if (!input_dev) {
-               LOG_ERR("failed to allocate input device\n");
+               dev_err(&client->dev, "Failed to allocate input device\n");
                goto input_allocate_failed;
        }
        input_dev->name = "fts_ts";
@@ -361,7 +360,7 @@ static int tinker_ft5406_probe(struct i2c_client *client,
 
        ret = input_register_device(input_dev);
        if (ret) {
-               LOG_ERR("Input device registration failed\n");
+               dev_err(&client->dev, "Input device registration failed\n");
                goto input_register_failed;
        }
 
@@ -371,8 +370,6 @@ static int tinker_ft5406_probe(struct i2c_client *client,
 
        return 0;
 
-check_fw_failed:
-       input_unregister_device(g_ts_data->input_dev);
 input_register_failed:
        input_free_device(input_dev);
 input_allocate_failed:
index 7a634e9..9aef386 100644 (file)
@@ -11,8 +11,6 @@
 #include <media/videobuf2-vmalloc.h>
 #include <media/videobuf2-dma-contig.h>
 
-#define USE_MEDIA_PIPELINE
-
 static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
        { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
          { { 1, 1 } }, { { 1, 1 } }, { 16 } },
@@ -552,15 +550,13 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
        struct v4l2_subdev *subdev;
        int ret;
 
-#ifdef USE_MEDIA_PIPELINE
-       // ret = media_pipeline_start(&vdev->entity, &video->pipe);
        ret = media_pipeline_start(&vdev->entity, &video->stfcamss->pipe);
        if (ret < 0) {
                st_err(ST_VIDEO,
                        "Failed to media_pipeline_start: %d\n", ret);
                return ret;
        }
-#endif
+
        ret = video_check_format(video);
        if (ret < 0)
                goto error;
@@ -584,9 +580,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
        return 0;
 
 error:
-#ifdef USE_MEDIA_PIPELINE
        media_pipeline_stop(&vdev->entity);
-#endif
        video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
        return ret;
 }
@@ -615,9 +609,7 @@ static void video_stop_streaming(struct vb2_queue *q)
                v4l2_subdev_call(subdev, video, s_stream, 0);
        }
 
-#ifdef USE_MEDIA_PIPELINE
        media_pipeline_stop(&vdev->entity);
-#endif
        video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
 }
 
@@ -1619,59 +1611,21 @@ static int video_open(struct file *file)
 
        file->private_data = vfh;
 
-#ifdef USE_MEDIA_PIPELINE
-       ret = v4l2_pipeline_pm_get(&vdev->entity);
-       if (ret < 0) {
-               st_err(ST_VIDEO,
-                       "Failed to power up pipeline: %d\n", ret);
-               goto error_pm_use;
+       if (!video->pm_count) {
+               ret = v4l2_pipeline_pm_get(&vdev->entity);
+               if (ret < 0) {
+                       st_err(ST_VIDEO,
+                               "Failed to power up pipeline: %d\n", ret);
+                       goto error_pm_use;
+               }
        }
-#else
-       struct media_entity *entity;
-       struct media_pad *pad;
-       struct v4l2_subdev *subdev;
-       int i = 0;
-
-       entity = &vdev->entity;
-       while (1) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
 
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
+       video->pm_count++;
 
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
-
-               ret = v4l2_subdev_call(subdev, core, s_power, 1);
-               if (ret < 0 && ret != -ENOIOCTLCMD)
-                       goto error_power;
-               i++;
-       }
-#endif
        mutex_unlock(&video->lock);
 
        return 0;
-#ifndef USE_MEDIA_PIPELINE
-error_power:
-       entity = &vdev->entity;
-       while (i--) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
 
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
-
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
-
-               v4l2_subdev_call(subdev, core, s_power, 0);
-       }
-#endif
 error_pm_use:
        v4l2_fh_release(file);
 error_alloc:
@@ -1682,31 +1636,15 @@ error_alloc:
 static int video_release(struct file *file)
 {
        struct video_device *vdev = video_devdata(file);
+       struct stfcamss_video *video = video_drvdata(file);
 
        vb2_fop_release(file);
-#ifdef USE_MEDIA_PIPELINE
-       v4l2_pipeline_pm_put(&vdev->entity);
-#else
-       struct media_entity *entity;
-       struct media_pad *pad;
-       struct v4l2_subdev *subdev;
 
-       entity = &vdev->entity;
-       while (1) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
-
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
+       video->pm_count--;
 
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
+       if (!video->pm_count)
+               v4l2_pipeline_pm_put(&vdev->entity);
 
-               v4l2_subdev_call(subdev, core, s_power, 0);
-       }
-#endif
        file->private_data = NULL;
 
        return 0;
index d134ee6..6037d0e 100644 (file)
@@ -69,6 +69,7 @@ struct stfcamss_video {
        const struct stfcamss_format_info *formats;
        unsigned int nformats;
        unsigned int is_mp;
+       unsigned int pm_count;
 };
 
 int stf_video_register(struct stfcamss_video *video,
index 5625621..492bffe 100644 (file)
@@ -82,6 +82,10 @@ struct vin_line {
        spinlock_t output_lock;
        const struct vin2_format *formats;
        unsigned int nformats;
+#ifdef CONFIG_PM_SLEEP
+       int pm_stream_count;
+       int pm_power_count;
+#endif
 };
 
 struct stf_vin2_dev;
index 11dbb85..d9213cb 100644 (file)
@@ -1201,31 +1201,43 @@ static int stfcamss_suspend(struct device *dev)
        struct stfcamss_video *video;
        struct video_device *vdev;
        int i = 0;
+       int pm_power_count;
+       int pm_stream_count;
 
        for (i = 0; i < VIN_LINE_MAX; i++) {
-               if (vin_dev->line[i].stream_count) {
-                       vin_dev->line[i].stream_count ++;
-                       video = &vin_dev->line[i].video_out;
-                       vdev = &vin_dev->line[i].video_out.vdev;
-                       entity = &vdev->entity;
-                       while (1) {
-                               pad = &entity->pads[0];
-                               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                                       break;
-
-                               pad = media_entity_remote_pad(pad);
-                               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                                       break;
-
-                               entity = pad->entity;
-                               subdev = media_entity_to_v4l2_subdev(entity);
-
-                               v4l2_subdev_call(subdev, video, s_stream, 0);
+               video = &vin_dev->line[i].video_out;
+               vdev = &vin_dev->line[i].video_out.vdev;
+               vin_dev->line[i].pm_power_count = vin_dev->line[i].power_count;
+               vin_dev->line[i].pm_stream_count = vin_dev->line[i].stream_count;
+               pm_power_count = vin_dev->line[i].pm_power_count;
+               pm_stream_count = vin_dev->line[i].pm_stream_count;
+
+               if (pm_stream_count) {
+                       while (pm_stream_count--) {
+                               entity = &vdev->entity;
+                               while (1) {
+                                       pad = &entity->pads[0];
+                                       if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                                               break;
+
+                                       pad = media_entity_remote_pad(pad);
+                                       if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+                                               break;
+
+                                       entity = pad->entity;
+                                       subdev = media_entity_to_v4l2_subdev(entity);
+
+                                       v4l2_subdev_call(subdev, video, s_stream, 0);
+                               }
                        }
                        media_pipeline_stop(&vdev->entity);
                        video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
-                       v4l2_pipeline_pm_put(&vdev->entity);
                }
+
+               if (!pm_power_count)
+                       continue;
+
+               v4l2_pipeline_pm_put(&vdev->entity);
        }
 
        return pm_runtime_force_suspend(dev);
@@ -1241,40 +1253,48 @@ static int stfcamss_resume(struct device *dev)
        struct stfcamss_video *video;
        struct video_device *vdev;
        int i = 0;
+       int pm_power_count;
+       int pm_stream_count;
        int ret = 0;
 
        pm_runtime_force_resume(dev);
 
        for (i = 0; i < VIN_LINE_MAX; i++) {
-               if (vin_dev->line[i].stream_count) {
-                       vin_dev->line[i].stream_count--;
-                       video = &vin_dev->line[i].video_out;
-                       vdev = &vin_dev->line[i].video_out.vdev;
+               video = &vin_dev->line[i].video_out;
+               vdev = &vin_dev->line[i].video_out.vdev;
+               pm_power_count = vin_dev->line[i].pm_power_count;
+               pm_stream_count = vin_dev->line[i].pm_stream_count;
 
-                       ret = v4l2_pipeline_pm_get(&vdev->entity);
-                       if (ret < 0)
-                               goto err;
+               if (!pm_power_count)
+                       continue;
 
+               ret = v4l2_pipeline_pm_get(&vdev->entity);
+               if (ret < 0)
+                       goto err;
+
+               if (pm_stream_count) {
                        ret = media_pipeline_start(&vdev->entity, &video->stfcamss->pipe);
                        if (ret < 0)
                                goto err_pm_put;
 
-                       entity = &vdev->entity;
-                       while (1) {
-                               pad = &entity->pads[0];
-                               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                                       break;
+                       while (pm_stream_count--) {
+                               entity = &vdev->entity;
+                               while (1) {
+                                       pad = &entity->pads[0];
+                                       if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                                               break;
 
-                               pad = media_entity_remote_pad(pad);
-                               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                                       break;
+                                       pad = media_entity_remote_pad(pad);
+                                       if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+                                               break;
 
-                               entity = pad->entity;
-                               subdev = media_entity_to_v4l2_subdev(entity);
+                                       entity = pad->entity;
+                                       subdev = media_entity_to_v4l2_subdev(entity);
 
-                               ret = v4l2_subdev_call(subdev, video, s_stream, 1);
-                               if (ret < 0 && ret != -ENOIOCTLCMD)
-                                       goto err_pipeline_stop;
+                                       ret = v4l2_subdev_call(subdev, video, s_stream, 1);
+                                       if (ret < 0 && ret != -ENOIOCTLCMD)
+                                               goto err_pipeline_stop;
+                               }
                        }
                }
        }
index d7adf8b..091f366 100755 (executable)
@@ -1663,6 +1663,43 @@ static int starfive_jh7110_pinctrl_probe(struct platform_device *pdev)
        return starfive_pinctrl_probe(pdev, pinctrl_info);
 }
 
+static int __maybe_unused starfive_pinctrl_suspend(struct device *dev)
+{
+       struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
+       u8 i;
+
+       for (i = 0 ; i < SYS_IRQ_REG_SUSPENDED_NUM ; i++)
+               pctl->sys_irq_reg_suspended[i] =
+                       readl_relaxed(pctl->padctl_base + GPIO_EN + OFFSET_PER_REG * i);
+
+       for (i = 0 ; i < AON_IRQ_REG_SUSPENDED_NUM ; i++)
+               pctl->aon_irq_reg_suspended[i] =
+                       readl_relaxed(pctl->padctl_base + AON_GPIO_EN_REG + OFFSET_PER_REG * i);
+
+       return pinctrl_force_sleep(pctl->pctl_dev);
+}
+
+static int __maybe_unused starfive_pinctrl_resume(struct device *dev)
+{
+       struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
+       u8 i;
+
+       for (i = 0 ; i < SYS_IRQ_REG_SUSPENDED_NUM ; i++)
+               writel_relaxed(pctl->sys_irq_reg_suspended[i],
+                              pctl->padctl_base + GPIO_EN + OFFSET_PER_REG * i);
+
+       for (i = 0 ; i < AON_IRQ_REG_SUSPENDED_NUM ; i++)
+               writel_relaxed(pctl->aon_irq_reg_suspended[i],
+                              pctl->padctl_base + AON_GPIO_EN_REG + OFFSET_PER_REG * i);
+
+       return pinctrl_force_default(pctl->pctl_dev);
+}
+
+const struct dev_pm_ops starfive_pinctrl_pm_ops = {
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(starfive_pinctrl_suspend,
+                                    starfive_pinctrl_resume)
+};
+
 static struct platform_driver starfive_jh7110_pinctrl_driver = {
        .driver = {
                .name = "starfive_jh7110-pinctrl",
index 262f573..127053f 100644 (file)
@@ -474,25 +474,6 @@ int starfive_pinctrl_probe(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(starfive_pinctrl_probe);
 
-static int __maybe_unused starfive_pinctrl_suspend(struct device *dev)
-{
-       struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
-
-       return pinctrl_force_sleep(pctl->pctl_dev);
-}
-
-static int __maybe_unused starfive_pinctrl_resume(struct device *dev)
-{
-       struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
-
-       return pinctrl_force_default(pctl->pctl_dev);
-}
-
-const struct dev_pm_ops starfive_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(starfive_pinctrl_suspend,
-                                       starfive_pinctrl_resume)
-};
-EXPORT_SYMBOL_GPL(starfive_pinctrl_pm_ops);
 MODULE_DESCRIPTION("Pinctrl driver for StarFive JH7110 SoC");
 MODULE_AUTHOR("jenny.zhang <jenny.zhang@starfivetech.com>");
 MODULE_LICENSE("GPL v2");
index 2db9df9..ed79d72 100644 (file)
 
 #define STARFIVE_USE_SCU                       BIT(0)
 
+#define SYS_IRQ_REG_SUSPENDED_NUM              11
+#define AON_IRQ_REG_SUSPENDED_NUM              6
+
 struct platform_device;
 
 extern const struct pinmux_ops starfive_pmx_ops;
-extern const struct dev_pm_ops starfive_pinctrl_pm_ops;
 
 struct starfive_pin_config {
        unsigned long io_config;
@@ -75,6 +77,9 @@ struct starfive_pinctrl {
        struct pinctrl_gpio_range gpios;
        unsigned long enabled;
        unsigned int trigger[MAX_GPIO];
+
+       u32 sys_irq_reg_suspended[SYS_IRQ_REG_SUSPENDED_NUM];
+       u32 aon_irq_reg_suspended[AON_IRQ_REG_SUSPENDED_NUM];
 };
 
 struct starfive_pinctrl_soc_info {
index 9d1147b..d05bf61 100644 (file)
@@ -74,6 +74,8 @@ struct cdns_starfive {
        u32 stg_offset_500;
        bool usb2_only;
        enum usb_dr_mode mode;
+       void __iomem *phybase_20;
+       void __iomem *phybase_30;
 };
 
 static int cdns_mode_init(struct platform_device *pdev,
@@ -194,39 +196,44 @@ exit:
        return ret;
 }
 
+static void cdns_starfive_set_phy(struct cdns_starfive *data)
+{
+       unsigned int val;
+
+       if (data->mode != USB_DR_MODE_PERIPHERAL) {
+               /* Enable the LS speed keep-alive signal */
+               val = readl(data->phybase_20 + USB_LS_KEEPALIVE_OFF);
+               val |= BIT(USB_LS_KEEPALIVE_ENABLE);
+               writel(val, data->phybase_20 + USB_LS_KEEPALIVE_OFF);
+       }
+
+       if (!data->usb2_only) {
+               /* Configuare spread-spectrum mode: down-spread-spectrum */
+               writel(BIT(4), data->phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF);
+       }
+}
+
 static int cdns_starfive_phy_init(struct platform_device *pdev,
                                                        struct cdns_starfive *data)
 {
        struct device *dev = &pdev->dev;
-       void __iomem *phybase_20, *phybase_30;
-       unsigned int val;
        int ret = 0;
 
-       phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
-       if (IS_ERR(phybase_20)) {
+       data->phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
+       if (IS_ERR(data->phybase_20)) {
                dev_err(dev, "Can't map phybase_20 IOMEM resource\n");
-               ret = PTR_ERR(phybase_20);
+               ret = PTR_ERR(data->phybase_20);
                goto get_res_err;
        }
 
-       phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
-       if (IS_ERR(phybase_30)) {
+       data->phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
+       if (IS_ERR(data->phybase_30)) {
                dev_err(dev, "Can't map phybase_30 IOMEM resource\n");
-               ret = PTR_ERR(phybase_30);
+               ret = PTR_ERR(data->phybase_30);
                goto get_res_err;
        }
 
-       if (data->mode != USB_DR_MODE_PERIPHERAL) {
-               /* Enable the LS speed keep-alive signal */
-               val = readl(phybase_20 + USB_LS_KEEPALIVE_OFF);
-               val |= BIT(USB_LS_KEEPALIVE_ENABLE);
-               writel(val, phybase_20 + USB_LS_KEEPALIVE_OFF);
-       }
-
-       if (!data->usb2_only) {
-               /* Configuare spread-spectrum mode: down-spread-spectrum */
-               writel(BIT(4), (phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF));
-       }
+       cdns_starfive_set_phy(data);
 
 get_res_err:
        return ret;
@@ -351,6 +358,10 @@ static int cdns_starfive_resume(struct device *dev)
                goto err;
 
        ret = reset_control_deassert(data->resets);
+       if (ret)
+               goto err;
+
+       cdns_starfive_set_phy(data);
 err:
        return ret;
 }
old mode 100755 (executable)
new mode 100644 (file)
index 8b93d7d..d4742f9
@@ -34,9 +34,6 @@
 #define PWMDAC_DUTY_CYCLE_LOW  2
 #define PWMDAC_DUTY_CYCLE_HIGH 3
 
-
-
-
 #define PWMDAC_MCLK    4096000
 
 enum pwmdac_lr_change{
@@ -86,7 +83,6 @@ enum pwmdac_sample_count{
        PWMDAC_SAMPLE_CNT_511 = 511,
 };
 
-
 enum data_shift{
        PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
        PWMDAC_DATA_LEFT_SHIFT_BIT_1,
@@ -144,11 +140,10 @@ struct sf_pwmdac_dev {
        struct clk *audio_src;
        struct clk *pwmdac_apb;
        struct clk *pwmdac_mclk;
+       unsigned int pwmdac_ctrl_data;
 };
 
-
-
-#if IS_ENABLED(CONFIG_SND_STARFIVE_PWMDAC_PCM)
+#if IS_ENABLED(CONFIG_SND_SOC_STARFIVE_PWMDAC_PCM)
 void sf_pwmdac_pcm_push_tx(struct sf_pwmdac_dev *dev);
 void sf_pwmdac_pcm_pop_rx(struct sf_pwmdac_dev *dev);
 int sf_pwmdac_pcm_register(struct platform_device *pdev);
index 1e7a438..fba58e2 100644 (file)
@@ -761,12 +761,25 @@ static int sf_pwmdac_dai_probe(struct snd_soc_dai *dai)
 #ifdef CONFIG_PM_SLEEP
 static int starfive_pwmdac_system_suspend(struct device *dev)
 {
+       struct sf_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
+
+       /* save the register value */
+       pwmdac->pwmdac_ctrl_data = pwmdc_read_reg(pwmdac->pwmdac_base, PWMDAC_CTRL);
        return pm_runtime_force_suspend(dev);
 }
 
 static int starfive_pwmdac_system_resume(struct device *dev)
 {
-       return pm_runtime_force_resume(dev);
+       struct sf_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               return ret;
+
+       /* restore the register value */
+       pwmdc_write_reg(pwmdac->pwmdac_base, PWMDAC_CTRL, pwmdac->pwmdac_ctrl_data);
+       return 0;
 }
 #endif
 
index ee97627..d7886d3 100644 (file)
@@ -423,12 +423,34 @@ static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
 #ifdef CONFIG_PM_SLEEP
 static int spdif_system_suspend(struct device *dev)
 {
+       struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
+
+       /* save the register value */
+       regmap_read(spdif->regmap, SPDIF_CTRL, &spdif->reg_spdif_ctrl);
+       regmap_read(spdif->regmap, SPDIF_INT_REG, &spdif->reg_spdif_int);
+       regmap_read(spdif->regmap, SPDIF_FIFO_CTRL, &spdif->reg_spdif_fifo_ctrl);
+
        return pm_runtime_force_suspend(dev);
 }
 
 static int spdif_system_resume(struct device *dev)
 {
-       return pm_runtime_force_resume(dev);
+       struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               return ret;
+
+       /* restore the register value */
+       regmap_update_bits(spdif->regmap, SPDIF_CTRL,
+                          ALLBITMASK, spdif->reg_spdif_ctrl);
+       regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
+                          ALLBITMASK, spdif->reg_spdif_int);
+       regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
+                          ALLBITMASK, spdif->reg_spdif_fifo_ctrl);
+
+       return 0;
 }
 #endif
 
@@ -453,7 +475,6 @@ static const struct dev_pm_ops spdif_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(spdif_system_suspend, spdif_system_resume)
 };
 
-
 #define SF_PCM_RATE_44100_192000  (SNDRV_PCM_RATE_44100 | \
                                   SNDRV_PCM_RATE_48000 | \
                                   SNDRV_PCM_RATE_96000 | \
index bc1cc96..a0c91ae 100644 (file)
@@ -156,6 +156,9 @@ struct sf_spdif_dev {
        struct clk *mclk;
        struct clk *mclk_ext;
        struct reset_control *rst_apb;
+       unsigned int reg_spdif_ctrl;
+       unsigned int reg_spdif_int;
+       unsigned int reg_spdif_fifo_ctrl;
 
        struct snd_dmaengine_dai_dma_data dma_data;
 };
@@ -173,5 +176,4 @@ int sf_spdif_pcm_register(struct platform_device *pdev)
 }
 #endif
 
-
 #endif /* __SND_SOC_STARFIVE_SPDIF_H */
index 5823837..78ed55a 100644 (file)
@@ -149,7 +149,9 @@ static const struct snd_pcm_hardware sf_pcm_hardware = {
        .info = SNDRV_PCM_INFO_INTERLEAVED |
                SNDRV_PCM_INFO_MMAP |
                SNDRV_PCM_INFO_MMAP_VALID |
-               SNDRV_PCM_INFO_BLOCK_TRANSFER,
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_PAUSE |
+               SNDRV_PCM_INFO_RESUME,
        .rates = SNDRV_PCM_RATE_8000 |
                SNDRV_PCM_RATE_11025 |
                SNDRV_PCM_RATE_16000 |
index bd7372e..a3506e7 100644 (file)
@@ -30,6 +30,22 @@ static inline void sf_tdm_writel(struct sf_tdm_dev *dev, u16 reg, u32 val)
        writel_relaxed(val, dev->tdm_base + reg);
 }
 
+static void sf_tdm_save_context(struct sf_tdm_dev *dev)
+{
+       dev->saved_reg_value[0] = sf_tdm_readl(dev, TDM_PCMGBCR);
+       dev->saved_reg_value[1] = sf_tdm_readl(dev, TDM_PCMTXCR);
+       dev->saved_reg_value[2] = sf_tdm_readl(dev, TDM_PCMRXCR);
+       dev->saved_reg_value[3] = sf_tdm_readl(dev, TDM_PCMDIV);
+}
+
+static void sf_tdm_restore_context(struct sf_tdm_dev *dev)
+{
+       sf_tdm_writel(dev, TDM_PCMGBCR, dev->saved_reg_value[0]);
+       sf_tdm_writel(dev, TDM_PCMTXCR, dev->saved_reg_value[1]);
+       sf_tdm_writel(dev, TDM_PCMRXCR, dev->saved_reg_value[2]);
+       sf_tdm_writel(dev, TDM_PCMDIV, dev->saved_reg_value[3]);
+}
+
 static void sf_tdm_start(struct sf_tdm_dev *dev, struct snd_pcm_substream *substream)
 {
        u32 data;
@@ -60,6 +76,10 @@ static void sf_tdm_stop(struct sf_tdm_dev *dev, struct snd_pcm_substream *substr
                val &= ~PCMRXCR_RXEN;
                sf_tdm_writel(dev, TDM_PCMRXCR, val);
        }
+
+       val = sf_tdm_readl(dev, TDM_PCMGBCR);
+       val &= ~PCMGBCR_ENABLE;
+       sf_tdm_writel(dev, TDM_PCMGBCR, val);
 }
 
 static int sf_tdm_syncdiv(struct sf_tdm_dev *dev)
@@ -129,7 +149,9 @@ static void sf_tdm_clk_disable(struct sf_tdm_dev *priv)
        clk_disable_unprepare(priv->clk_tdm_ext);
        clk_disable_unprepare(priv->clk_tdm_internal);
        clk_disable_unprepare(priv->clk_tdm_apb);
+       clk_disable_unprepare(priv->clk_apb0);
        clk_disable_unprepare(priv->clk_tdm_ahb);
+       clk_disable_unprepare(priv->clk_ahb0);
        clk_disable_unprepare(priv->clk_mclk_inner);
 }
 
@@ -153,12 +175,24 @@ static int sf_tdm_runtime_resume(struct device *dev)
                return ret;
        }
 
+       ret = clk_prepare_enable(priv->clk_ahb0);
+       if (ret) {
+               dev_err(dev, "Failed to prepare enable clk_ahb0\n");
+               return ret;
+       }
+
        ret = clk_prepare_enable(priv->clk_tdm_ahb);
        if (ret) {
                dev_err(dev, "Failed to prepare enable clk_tdm_ahb\n");
                goto dis_mclk_inner;
        }
 
+       ret = clk_prepare_enable(priv->clk_apb0);
+       if (ret) {
+               dev_err(dev, "Failed to prepare enable clk_apb0\n");
+               return ret;
+       }
+       
        ret = clk_prepare_enable(priv->clk_tdm_apb);
        if (ret) {
                dev_err(dev, "Failed to prepare enable clk_tdm_apb\n");
@@ -183,8 +217,16 @@ static int sf_tdm_runtime_resume(struct device *dev)
                goto dis_tdm_ext;
        }
 
+       ret = reset_control_deassert(priv->resets);
+       if (ret) {
+               dev_err(dev, "Failed to deassert tdm resets\n");
+               goto err_reset;
+       }
+
        return 0;
 
+err_reset:
+       clk_disable_unprepare(priv->clk_tdm);   
 dis_tdm_ext:
        clk_disable_unprepare(priv->clk_tdm_ext);
 dis_tdm_internal:
@@ -385,6 +427,7 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
        }
 
        sf_tdm_config(dev, substream);
+       sf_tdm_save_context(dev);
 
        return 0;
 }
@@ -400,6 +443,7 @@ static int sf_tdm_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                dev->active++;
+               sf_tdm_restore_context(dev);
                sf_tdm_start(dev, substream);
                break;
 
@@ -485,6 +529,8 @@ static struct snd_soc_dai_driver sf_tdm_dai = {
 static const struct snd_pcm_hardware jh71xx_pcm_hardware = {
        .info                   = (SNDRV_PCM_INFO_MMAP          |
                                   SNDRV_PCM_INFO_MMAP_VALID    |
+                                  SNDRV_PCM_INFO_PAUSE         |
+                                  SNDRV_PCM_INFO_RESUME        |
                                   SNDRV_PCM_INFO_INTERLEAVED   |
                                   SNDRV_PCM_INFO_BLOCK_TRANSFER),
        .buffer_bytes_max       = 192512,
@@ -628,7 +674,7 @@ static int sf_tdm_clk_reset_init(struct platform_device *pdev, struct sf_tdm_dev
                dev_err(&pdev->dev, "Failed to deassert tdm resets\n");
                goto dis_tdm_clk;
        }
-
+       
        return 0;
 
 dis_tdm_clk:
index dfba82f..e435e1e 100644 (file)
@@ -149,6 +149,7 @@ struct sf_tdm_dev {
        /* data related to DMA transfers b/w tdm and DMAC */
        struct snd_dmaengine_dai_dma_data play_dma_data;
        struct snd_dmaengine_dai_dma_data capture_dma_data;
+       u32 saved_reg_value[4];
 };
 
 #endif /* __SND_SOC_STARFIVE_TDM_H */