Loading Documentation/devicetree/bindings/spi/spi_qsd.txt +7 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,13 @@ Optional properties: - qcom,rt-priority : whether spi message queue is set to run as a realtime task. With this spi transaction message pump with high (realtime) priority to reduce the transfer latency on the bus by minimising the delay between a transfer request - qcom,shared : whether this qup is shared with other ee's - qcom,shared : whether this qup is shared with other ee's and client driver is not in control of the spi driver get_sync/put_sync_suspend. Spi driver will take care of resources management like clock, gpios and bam for EE switching. - qcom,shared_ee : whether this qup is used by other ee's and client driver is in control of the spi driver get_sync/put_sync_suspend. Resources management of clock, gpios and bam for EE switching will be taken care when client calls spi get_sync/put_sync_suspend APIs. Optional properties which are required for support of BAM-mode: - qcom,ver-reg-exists : Boolean. When present, allows driver to verify if HW Loading drivers/spi/spi_qsd.c +83 −16 Original line number Diff line number Diff line /* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1703,28 +1703,82 @@ static int msm_spi_transfer_one(struct spi_master *master, return status_error; } static int msm_spi_prepare_transfer_hardware(struct spi_master *master) static int msm_spi_pm_get_sync(struct device *dev) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state = 0; resume_state = pm_runtime_get_sync(dd->dev); if (resume_state < 0) goto spi_finalize; int ret; /* * Counter-part of system-suspend when runtime-pm is not enabled. * This way, resume can be left empty and device will be put in * active mode only if client requests anything on the bus */ if (!pm_runtime_enabled(dd->dev)) resume_state = msm_spi_pm_resume_runtime(dd->dev); if (!pm_runtime_enabled(dev)) { dev_info(dev, "%s: pm_runtime not enabled\n", __func__); ret = msm_spi_pm_resume_runtime(dev); } else { ret = pm_runtime_get_sync(dev); } return ret; } static int msm_spi_pm_put_sync(struct device *dev) { int ret = 0; if (!pm_runtime_enabled(dev)) { dev_info(dev, "%s: pm_runtime not enabled\n", __func__); ret = msm_spi_pm_suspend_runtime(dev); } else { pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); } return ret; } static int msm_spi_prepare_message(struct spi_master *master, struct spi_message *spi_msg) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state; resume_state = msm_spi_pm_get_sync(dd->dev); if (resume_state < 0) return resume_state; return 0; } static int msm_spi_unprepare_message(struct spi_master *master, struct spi_message *spi_msg) { struct msm_spi *dd = spi_master_get_devdata(master); int ret; ret = msm_spi_pm_put_sync(dd->dev); if (ret < 0) return ret; return 0; } static int msm_spi_prepare_transfer_hardware(struct spi_master *master) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state; if (!dd->pdata->shared_ee) { resume_state = msm_spi_pm_get_sync(dd->dev); if (resume_state < 0) goto spi_finalize; if (dd->suspended) { resume_state = -EBUSY; goto spi_finalize; } } return 0; spi_finalize: Loading @@ -1735,9 +1789,14 @@ static int msm_spi_prepare_transfer_hardware(struct spi_master *master) static int msm_spi_unprepare_transfer_hardware(struct spi_master *master) { struct msm_spi *dd = spi_master_get_devdata(master); int ret; if (!dd->pdata->shared_ee) { ret = msm_spi_pm_put_sync(dd->dev); if (ret < 0) return ret; } pm_runtime_mark_last_busy(dd->dev); pm_runtime_put_autosuspend(dd->dev); return 0; } Loading Loading @@ -2233,6 +2292,8 @@ static struct msm_spi_platform_data *msm_spi_dt_to_pdata( &pdata->rt_priority, DT_OPT, DT_BOOL, 0}, {"qcom,shared", &pdata->is_shared, DT_OPT, DT_BOOL, 0}, {"qcom,shared_ee", &pdata->shared_ee, DT_OPT, DT_BOOL, 0}, {NULL, NULL, 0, 0, 0}, }; Loading Loading @@ -2558,6 +2619,12 @@ static int msm_spi_probe(struct platform_device *pdev) goto err_probe_reqmem; } /* This property is required for Dual EE use case of spi */ if (dd->pdata->shared_ee) { master->prepare_message = msm_spi_prepare_message; master->unprepare_message = msm_spi_unprepare_message; } pm_runtime_set_autosuspend_delay(&pdev->dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); Loading include/linux/spi/qcom-spi.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,7 +34,10 @@ * @bam_producer_pipe_index BAM producer pipe * @rt_priority true if RT thread * @use_pinctrl true if pinctrl library is used * @is_shared true when qup is shared between ee's * @is_shared true when qup is shared between ee's and client driver is not in control of spi pm_runtime_get_sync/put_sync. * @shared_ee true when qup is shared between ee's and client driver is in control of spi pm_runtime_get_sync/put_sync. */ struct msm_spi_platform_data { u32 max_clock_speed; Loading @@ -53,4 +56,5 @@ struct msm_spi_platform_data { bool rt_priority; bool use_pinctrl; bool is_shared; bool shared_ee; }; Loading
Documentation/devicetree/bindings/spi/spi_qsd.txt +7 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,13 @@ Optional properties: - qcom,rt-priority : whether spi message queue is set to run as a realtime task. With this spi transaction message pump with high (realtime) priority to reduce the transfer latency on the bus by minimising the delay between a transfer request - qcom,shared : whether this qup is shared with other ee's - qcom,shared : whether this qup is shared with other ee's and client driver is not in control of the spi driver get_sync/put_sync_suspend. Spi driver will take care of resources management like clock, gpios and bam for EE switching. - qcom,shared_ee : whether this qup is used by other ee's and client driver is in control of the spi driver get_sync/put_sync_suspend. Resources management of clock, gpios and bam for EE switching will be taken care when client calls spi get_sync/put_sync_suspend APIs. Optional properties which are required for support of BAM-mode: - qcom,ver-reg-exists : Boolean. When present, allows driver to verify if HW Loading
drivers/spi/spi_qsd.c +83 −16 Original line number Diff line number Diff line /* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1703,28 +1703,82 @@ static int msm_spi_transfer_one(struct spi_master *master, return status_error; } static int msm_spi_prepare_transfer_hardware(struct spi_master *master) static int msm_spi_pm_get_sync(struct device *dev) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state = 0; resume_state = pm_runtime_get_sync(dd->dev); if (resume_state < 0) goto spi_finalize; int ret; /* * Counter-part of system-suspend when runtime-pm is not enabled. * This way, resume can be left empty and device will be put in * active mode only if client requests anything on the bus */ if (!pm_runtime_enabled(dd->dev)) resume_state = msm_spi_pm_resume_runtime(dd->dev); if (!pm_runtime_enabled(dev)) { dev_info(dev, "%s: pm_runtime not enabled\n", __func__); ret = msm_spi_pm_resume_runtime(dev); } else { ret = pm_runtime_get_sync(dev); } return ret; } static int msm_spi_pm_put_sync(struct device *dev) { int ret = 0; if (!pm_runtime_enabled(dev)) { dev_info(dev, "%s: pm_runtime not enabled\n", __func__); ret = msm_spi_pm_suspend_runtime(dev); } else { pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); } return ret; } static int msm_spi_prepare_message(struct spi_master *master, struct spi_message *spi_msg) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state; resume_state = msm_spi_pm_get_sync(dd->dev); if (resume_state < 0) return resume_state; return 0; } static int msm_spi_unprepare_message(struct spi_master *master, struct spi_message *spi_msg) { struct msm_spi *dd = spi_master_get_devdata(master); int ret; ret = msm_spi_pm_put_sync(dd->dev); if (ret < 0) return ret; return 0; } static int msm_spi_prepare_transfer_hardware(struct spi_master *master) { struct msm_spi *dd = spi_master_get_devdata(master); int resume_state; if (!dd->pdata->shared_ee) { resume_state = msm_spi_pm_get_sync(dd->dev); if (resume_state < 0) goto spi_finalize; if (dd->suspended) { resume_state = -EBUSY; goto spi_finalize; } } return 0; spi_finalize: Loading @@ -1735,9 +1789,14 @@ static int msm_spi_prepare_transfer_hardware(struct spi_master *master) static int msm_spi_unprepare_transfer_hardware(struct spi_master *master) { struct msm_spi *dd = spi_master_get_devdata(master); int ret; if (!dd->pdata->shared_ee) { ret = msm_spi_pm_put_sync(dd->dev); if (ret < 0) return ret; } pm_runtime_mark_last_busy(dd->dev); pm_runtime_put_autosuspend(dd->dev); return 0; } Loading Loading @@ -2233,6 +2292,8 @@ static struct msm_spi_platform_data *msm_spi_dt_to_pdata( &pdata->rt_priority, DT_OPT, DT_BOOL, 0}, {"qcom,shared", &pdata->is_shared, DT_OPT, DT_BOOL, 0}, {"qcom,shared_ee", &pdata->shared_ee, DT_OPT, DT_BOOL, 0}, {NULL, NULL, 0, 0, 0}, }; Loading Loading @@ -2558,6 +2619,12 @@ static int msm_spi_probe(struct platform_device *pdev) goto err_probe_reqmem; } /* This property is required for Dual EE use case of spi */ if (dd->pdata->shared_ee) { master->prepare_message = msm_spi_prepare_message; master->unprepare_message = msm_spi_unprepare_message; } pm_runtime_set_autosuspend_delay(&pdev->dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); Loading
include/linux/spi/qcom-spi.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,7 +34,10 @@ * @bam_producer_pipe_index BAM producer pipe * @rt_priority true if RT thread * @use_pinctrl true if pinctrl library is used * @is_shared true when qup is shared between ee's * @is_shared true when qup is shared between ee's and client driver is not in control of spi pm_runtime_get_sync/put_sync. * @shared_ee true when qup is shared between ee's and client driver is in control of spi pm_runtime_get_sync/put_sync. */ struct msm_spi_platform_data { u32 max_clock_speed; Loading @@ -53,4 +56,5 @@ struct msm_spi_platform_data { bool rt_priority; bool use_pinctrl; bool is_shared; bool shared_ee; };