Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rproc-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc

Pull remoteproc updates from Bjorn Andersson:

- move the crash recovery worker to the freezable work queue to avoid
interaction with other drivers during suspend & resume

- fix a couple of typos in comments

- add support for handling the audio DSP on SDM660

- fix a race between the Qualcomm wireless subsystem driver and the
associated driver for the RF chip

* tag 'rproc-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc:
remoteproc: q6v5_pas: Add sdm660 ADSP PIL compatible
dt-bindings: remoteproc: qcom: adsp: Add SDM660 ADSP
remoteproc: use freezable workqueue for crash notifications
remoteproc: fix kernel doc for struct rproc_ops
remoteproc: fix an typo in fw_elf_get_class code comments
remoteproc: qcom: wcnss: Fix race with iris probe

+96 -90
+1
Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml
··· 28 28 - qcom,sc8180x-adsp-pas 29 29 - qcom,sc8180x-cdsp-pas 30 30 - qcom,sc8180x-mpss-pas 31 + - qcom,sdm660-adsp-pas 31 32 - qcom,sdm845-adsp-pas 32 33 - qcom,sdm845-cdsp-pas 33 34 - qcom,sdx55-mpss-pas
+1
drivers/remoteproc/qcom_q6v5_pas.c
··· 833 833 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, 834 834 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, 835 835 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, 836 + { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, 836 837 { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init}, 837 838 { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, 838 839 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
+12 -37
drivers/remoteproc/qcom_wcnss.c
··· 142 142 .num_vregs = 1, 143 143 }; 144 144 145 - void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, 146 - struct qcom_iris *iris, 147 - bool use_48mhz_xo) 148 - { 149 - mutex_lock(&wcnss->iris_lock); 150 - 151 - wcnss->iris = iris; 152 - wcnss->use_48mhz_xo = use_48mhz_xo; 153 - 154 - mutex_unlock(&wcnss->iris_lock); 155 - } 156 - 157 145 static int wcnss_load(struct rproc *rproc, const struct firmware *fw) 158 146 { 159 147 struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; ··· 627 639 goto detach_pds; 628 640 } 629 641 642 + wcnss->iris = qcom_iris_probe(&pdev->dev, &wcnss->use_48mhz_xo); 643 + if (IS_ERR(wcnss->iris)) { 644 + ret = PTR_ERR(wcnss->iris); 645 + goto detach_pds; 646 + } 647 + 630 648 ret = rproc_add(rproc); 631 649 if (ret) 632 - goto detach_pds; 650 + goto remove_iris; 633 651 634 - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 652 + return 0; 635 653 654 + remove_iris: 655 + qcom_iris_remove(wcnss->iris); 636 656 detach_pds: 637 657 wcnss_release_pds(wcnss); 638 658 free_rproc: ··· 653 657 { 654 658 struct qcom_wcnss *wcnss = platform_get_drvdata(pdev); 655 659 656 - of_platform_depopulate(&pdev->dev); 660 + qcom_iris_remove(wcnss->iris); 657 661 658 662 rproc_del(wcnss->rproc); 659 663 ··· 682 686 }, 683 687 }; 684 688 685 - static int __init wcnss_init(void) 686 - { 687 - int ret; 688 - 689 - ret = platform_driver_register(&wcnss_driver); 690 - if (ret) 691 - return ret; 692 - 693 - ret = platform_driver_register(&qcom_iris_driver); 694 - if (ret) 695 - platform_driver_unregister(&wcnss_driver); 696 - 697 - return ret; 698 - } 699 - module_init(wcnss_init); 700 - 701 - static void __exit wcnss_exit(void) 702 - { 703 - platform_driver_unregister(&qcom_iris_driver); 704 - platform_driver_unregister(&wcnss_driver); 705 - } 706 - module_exit(wcnss_exit); 689 + module_platform_driver(wcnss_driver); 707 690 708 691 MODULE_DESCRIPTION("Qualcomm Peripheral Image Loader for Wireless Subsystem"); 709 692 MODULE_LICENSE("GPL v2");
+2 -2
drivers/remoteproc/qcom_wcnss.h
··· 17 17 bool super_turbo; 18 18 }; 19 19 20 + struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo); 21 + void qcom_iris_remove(struct qcom_iris *iris); 20 22 int qcom_iris_enable(struct qcom_iris *iris); 21 23 void qcom_iris_disable(struct qcom_iris *iris); 22 - 23 - void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, struct qcom_iris *iris, bool use_48mhz_xo); 24 24 25 25 #endif
+75 -45
drivers/remoteproc/qcom_wcnss_iris.c
··· 17 17 #include "qcom_wcnss.h" 18 18 19 19 struct qcom_iris { 20 - struct device *dev; 20 + struct device dev; 21 21 22 22 struct clk *xo_clk; 23 23 ··· 75 75 76 76 ret = clk_prepare_enable(iris->xo_clk); 77 77 if (ret) { 78 - dev_err(iris->dev, "failed to enable xo clk\n"); 78 + dev_err(&iris->dev, "failed to enable xo clk\n"); 79 79 goto disable_regulators; 80 80 } 81 81 ··· 93 93 regulator_bulk_disable(iris->num_vregs, iris->vregs); 94 94 } 95 95 96 - static int qcom_iris_probe(struct platform_device *pdev) 96 + static const struct of_device_id iris_of_match[] = { 97 + { .compatible = "qcom,wcn3620", .data = &wcn3620_data }, 98 + { .compatible = "qcom,wcn3660", .data = &wcn3660_data }, 99 + { .compatible = "qcom,wcn3660b", .data = &wcn3680_data }, 100 + { .compatible = "qcom,wcn3680", .data = &wcn3680_data }, 101 + {} 102 + }; 103 + 104 + static void qcom_iris_release(struct device *dev) 97 105 { 106 + struct qcom_iris *iris = container_of(dev, struct qcom_iris, dev); 107 + 108 + of_node_put(iris->dev.of_node); 109 + kfree(iris); 110 + } 111 + 112 + struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo) 113 + { 114 + const struct of_device_id *match; 98 115 const struct iris_data *data; 99 - struct qcom_wcnss *wcnss; 116 + struct device_node *of_node; 100 117 struct qcom_iris *iris; 101 118 int ret; 102 119 int i; 103 120 104 - iris = devm_kzalloc(&pdev->dev, sizeof(struct qcom_iris), GFP_KERNEL); 105 - if (!iris) 106 - return -ENOMEM; 121 + of_node = of_get_child_by_name(parent->of_node, "iris"); 122 + if (!of_node) { 123 + dev_err(parent, "No child node \"iris\" found\n"); 124 + return ERR_PTR(-EINVAL); 125 + } 107 126 108 - data = of_device_get_match_data(&pdev->dev); 109 - wcnss = dev_get_drvdata(pdev->dev.parent); 127 + iris = kzalloc(sizeof(*iris), GFP_KERNEL); 128 + if (!iris) { 129 + of_node_put(of_node); 130 + return ERR_PTR(-ENOMEM); 131 + } 110 132 111 - iris->xo_clk = devm_clk_get(&pdev->dev, "xo"); 133 + device_initialize(&iris->dev); 134 + iris->dev.parent = parent; 135 + iris->dev.release = qcom_iris_release; 136 + iris->dev.of_node = of_node; 137 + 138 + dev_set_name(&iris->dev, "%s.iris", dev_name(parent)); 139 + 140 + ret = device_add(&iris->dev); 141 + if (ret) { 142 + put_device(&iris->dev); 143 + return ERR_PTR(ret); 144 + } 145 + 146 + match = of_match_device(iris_of_match, &iris->dev); 147 + if (!match) { 148 + dev_err(&iris->dev, "no matching compatible for iris\n"); 149 + ret = -EINVAL; 150 + goto err_device_del; 151 + } 152 + 153 + data = match->data; 154 + 155 + iris->xo_clk = devm_clk_get(&iris->dev, "xo"); 112 156 if (IS_ERR(iris->xo_clk)) { 113 - if (PTR_ERR(iris->xo_clk) != -EPROBE_DEFER) 114 - dev_err(&pdev->dev, "failed to acquire xo clk\n"); 115 - return PTR_ERR(iris->xo_clk); 157 + ret = PTR_ERR(iris->xo_clk); 158 + if (ret != -EPROBE_DEFER) 159 + dev_err(&iris->dev, "failed to acquire xo clk\n"); 160 + goto err_device_del; 116 161 } 117 162 118 163 iris->num_vregs = data->num_vregs; 119 - iris->vregs = devm_kcalloc(&pdev->dev, 164 + iris->vregs = devm_kcalloc(&iris->dev, 120 165 iris->num_vregs, 121 166 sizeof(struct regulator_bulk_data), 122 167 GFP_KERNEL); 123 - if (!iris->vregs) 124 - return -ENOMEM; 168 + if (!iris->vregs) { 169 + ret = -ENOMEM; 170 + goto err_device_del; 171 + } 125 172 126 173 for (i = 0; i < iris->num_vregs; i++) 127 174 iris->vregs[i].supply = data->vregs[i].name; 128 175 129 - ret = devm_regulator_bulk_get(&pdev->dev, iris->num_vregs, iris->vregs); 176 + ret = devm_regulator_bulk_get(&iris->dev, iris->num_vregs, iris->vregs); 130 177 if (ret) { 131 - dev_err(&pdev->dev, "failed to get regulators\n"); 132 - return ret; 178 + dev_err(&iris->dev, "failed to get regulators\n"); 179 + goto err_device_del; 133 180 } 134 181 135 182 for (i = 0; i < iris->num_vregs; i++) { ··· 190 143 data->vregs[i].load_uA); 191 144 } 192 145 193 - qcom_wcnss_assign_iris(wcnss, iris, data->use_48mhz_xo); 146 + *use_48mhz_xo = data->use_48mhz_xo; 194 147 195 - return 0; 148 + return iris; 149 + 150 + err_device_del: 151 + device_del(&iris->dev); 152 + 153 + return ERR_PTR(ret); 196 154 } 197 155 198 - static int qcom_iris_remove(struct platform_device *pdev) 156 + void qcom_iris_remove(struct qcom_iris *iris) 199 157 { 200 - struct qcom_wcnss *wcnss = dev_get_drvdata(pdev->dev.parent); 201 - 202 - qcom_wcnss_assign_iris(wcnss, NULL, false); 203 - 204 - return 0; 158 + device_del(&iris->dev); 205 159 } 206 - 207 - static const struct of_device_id iris_of_match[] = { 208 - { .compatible = "qcom,wcn3620", .data = &wcn3620_data }, 209 - { .compatible = "qcom,wcn3660", .data = &wcn3660_data }, 210 - { .compatible = "qcom,wcn3660b", .data = &wcn3680_data }, 211 - { .compatible = "qcom,wcn3680", .data = &wcn3680_data }, 212 - {} 213 - }; 214 - MODULE_DEVICE_TABLE(of, iris_of_match); 215 - 216 - struct platform_driver qcom_iris_driver = { 217 - .probe = qcom_iris_probe, 218 - .remove = qcom_iris_remove, 219 - .driver = { 220 - .name = "qcom-iris", 221 - .of_match_table = iris_of_match, 222 - }, 223 - };
+2 -2
drivers/remoteproc/remoteproc_core.c
··· 2750 2750 dev_err(&rproc->dev, "crash detected in %s: type %s\n", 2751 2751 rproc->name, rproc_crash_to_string(type)); 2752 2752 2753 - /* create a new task to handle the error */ 2754 - schedule_work(&rproc->crash_handler); 2753 + /* Have a worker handle the error; ensure system is not suspended */ 2754 + queue_work(system_freezable_wq, &rproc->crash_handler); 2755 2755 } 2756 2756 EXPORT_SYMBOL(rproc_report_crash); 2757 2757
+1 -1
drivers/remoteproc/remoteproc_elf_helpers.h
··· 15 15 * fw_elf_get_class - Get elf class 16 16 * @fw: the ELF firmware image 17 17 * 18 - * Note that we use and elf32_hdr to access the class since the start of the 18 + * Note that we use elf32_hdr to access the class since the start of the 19 19 * struct is the same for both elf class 20 20 * 21 21 * Return: elf class of the firmware
+2 -3
include/linux/remoteproc.h
··· 369 369 * @da_to_va: optional platform hook to perform address translations 370 370 * @parse_fw: parse firmware to extract information (e.g. resource table) 371 371 * @handle_rsc: optional platform hook to handle vendor resources. Should return 372 - * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled and a 373 - * negative value on error 374 - * @load_rsc_table: load resource table from firmware image 372 + * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled 373 + * and a negative value on error 375 374 * @find_loaded_rsc_table: find the loaded resource table from firmware image 376 375 * @get_loaded_rsc_table: get resource table installed in memory 377 376 * by external entity