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 'qcom-drivers-for-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers

Qualcomm driver updates for v7.1

Add ECS LIVA QC710, Glymur CRD, Mahua CRD, Purwa IoT EVK, and Asus
Vivobook to the QSEECOM allow-list, to enable UEFI variable access
through uefisecapp.

Register the Gunyah watchdog device if the SCM driver finds itself
running under Gunyah. Clean up some locking using guards.

Handle possible cases where AOSS cooling state is given a non-boolean
state.

Replace LLCC per-slice activation bitmap with reference counting. Also
add SDM670 support.

Improve probe deferral handling in the OCMEM driver.

Add Milos, QCS615, Eliza, Glymur, and Mahua support to the pd-mapper.

Add support for SoCCP-based pmic-glink, as found in Glymur and
Kaanapali.

Add common QMI service ids to the main qmi headerfile, to avoid
spreading these constants in various drivers.

Add support for version 2 of SMP2P and implement the irqchip state
reading support.

Add CQ7790, SA8650P, SM7450, SM7450P, and IPQ5210 SoC and the PM7550BA
PMIC identifiers to the socinfo driver.

Add Eliza and Mahua support to the UBWC driver, introduce helpers for
drivers to read out min_acc length and other programmable values, and
disable bank swizzling for Glymur.

Simplify the logic related to allocation of NV download request in the
WCNSS control driver.

* tag 'qcom-drivers-for-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (51 commits)
soc: qcom: ubwc: add helpers to get programmable values
soc: qcom: ubwc: add helper to get min_acc length
firmware: qcom: scm: Register gunyah watchdog device
soc: qcom: socinfo: Add SoC ID for SA8650P
dt-bindings: arm: qcom,ids: Add SoC ID for SA8650P
firmware: qcom: scm: Allow QSEECOM on Mahua CRD
soc: qcom: wcnss: simplify allocation of req
soc: qcom: pd-mapper: Add support for Eliza
soc: qcom: aoss: compare against normalized cooling state
soc: qcom: llcc: fix v1 SB syndrome register offset
dt-bindings: firmware: qcom,scm: Document ipq9650 SCM
soc: qcom: ubwc: Add support for Mahua
soc: qcom: pd-mapper: Add support for Glymur and Mahua
soc: qcom: ubwc: Add configuration Eliza SoC
soc: qcom: ubwc: Remove redundant x1e80100_data
dt-bindings: firmware: qcom,scm: document Eliza SCM Firmware Interface
soc: qcom: ocmem: return -EPROBE_DEFER is ocmem is not available
soc: qcom: ocmem: register reasons for probe deferrals
soc: qcom: ocmem: make the core clock optional
soc: qcom: ubwc: disable bank swizzling for Glymur platform
...

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+480 -139
+2
Documentation/devicetree/bindings/cache/qcom,llcc.yaml
··· 33 33 - qcom,sc7280-llcc 34 34 - qcom,sc8180x-llcc 35 35 - qcom,sc8280xp-llcc 36 + - qcom,sdm670-llcc 36 37 - qcom,sdm845-llcc 37 38 - qcom,sm6350-llcc 38 39 - qcom,sm7150-llcc ··· 205 204 contains: 206 205 enum: 207 206 - qcom,sc7280-llcc 207 + - qcom,sdm670-llcc 208 208 then: 209 209 properties: 210 210 reg:
+4
Documentation/devicetree/bindings/firmware/qcom,scm.yaml
··· 23 23 - enum: 24 24 - qcom,scm-apq8064 25 25 - qcom,scm-apq8084 26 + - qcom,scm-eliza 26 27 - qcom,scm-glymur 27 28 - qcom,scm-ipq4019 28 29 - qcom,scm-ipq5018 30 + - qcom,scm-ipq5210 29 31 - qcom,scm-ipq5332 30 32 - qcom,scm-ipq5424 31 33 - qcom,scm-ipq6018 32 34 - qcom,scm-ipq806x 33 35 - qcom,scm-ipq8074 34 36 - qcom,scm-ipq9574 37 + - qcom,scm-ipq9650 35 38 - qcom,scm-kaanapali 36 39 - qcom,scm-mdm9607 37 40 - qcom,scm-milos ··· 207 204 compatible: 208 205 contains: 209 206 enum: 207 + - qcom,scm-eliza 210 208 - qcom,scm-kaanapali 211 209 - qcom,scm-milos 212 210 - qcom,scm-sm8450
+2
Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml
··· 23 23 oneOf: 24 24 - items: 25 25 - enum: 26 + - qcom,glymur-pmic-glink 27 + - qcom,kaanapali-pmic-glink 26 28 - qcom,qcm6490-pmic-glink 27 29 - qcom,sc8180x-pmic-glink 28 30 - qcom,sc8280xp-pmic-glink
+4 -5
drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
··· 699 699 700 700 static int qcuefi_set_reference(struct qcuefi_client *qcuefi) 701 701 { 702 - mutex_lock(&__qcuefi_lock); 702 + guard(mutex)(&__qcuefi_lock); 703 703 704 - if (qcuefi && __qcuefi) { 705 - mutex_unlock(&__qcuefi_lock); 704 + if (qcuefi && __qcuefi) 706 705 return -EEXIST; 707 - } 708 706 709 707 __qcuefi = qcuefi; 710 708 711 - mutex_unlock(&__qcuefi_lock); 712 709 return 0; 713 710 } 714 711 715 712 static struct qcuefi_client *qcuefi_acquire(void) 713 + __acquires(__qcuefi_lock) 716 714 { 717 715 mutex_lock(&__qcuefi_lock); 718 716 if (!__qcuefi) { ··· 721 723 } 722 724 723 725 static void qcuefi_release(void) 726 + __releases(__qcuefi_lock) 724 727 { 725 728 mutex_unlock(&__qcuefi_lock); 726 729 }
+63 -7
drivers/firmware/qcom/qcom_scm.c
··· 199 199 if (!__scm->path) 200 200 return 0; 201 201 202 - mutex_lock(&__scm->scm_bw_lock); 202 + guard(mutex)(&__scm->scm_bw_lock); 203 + 203 204 if (!__scm->scm_vote_count) { 204 205 ret = icc_set_bw(__scm->path, 0, UINT_MAX); 205 206 if (ret < 0) { 206 207 dev_err(__scm->dev, "failed to set bandwidth request\n"); 207 - goto err_bw; 208 + return ret; 208 209 } 209 210 } 210 211 __scm->scm_vote_count++; 211 - err_bw: 212 - mutex_unlock(&__scm->scm_bw_lock); 213 212 214 - return ret; 213 + return 0; 215 214 } 216 215 217 216 static void qcom_scm_bw_disable(void) ··· 922 923 goto free_input_rt; 923 924 } 924 925 925 - tbl_ptr = kzalloc(size, GFP_KERNEL); 926 + tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL); 926 927 if (!tbl_ptr) { 927 928 qcom_tzmem_free(output_rt_tzm); 928 929 ret = -ENOMEM; 929 930 goto free_input_rt; 930 931 } 931 932 932 - memcpy(tbl_ptr, output_rt_tzm, size); 933 933 *output_rt_size = size; 934 934 qcom_tzmem_free(output_rt_tzm); 935 935 ··· 2288 2290 */ 2289 2291 static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { 2290 2292 { .compatible = "asus,vivobook-s15" }, 2293 + { .compatible = "asus,vivobook-s15-x1p4" }, 2291 2294 { .compatible = "asus,zenbook-a14-ux3407qa" }, 2292 2295 { .compatible = "asus,zenbook-a14-ux3407ra" }, 2293 2296 { .compatible = "dell,inspiron-14-plus-7441" }, 2294 2297 { .compatible = "dell,latitude-7455" }, 2295 2298 { .compatible = "dell,xps13-9345" }, 2299 + { .compatible = "ecs,liva-qc710" }, 2296 2300 { .compatible = "hp,elitebook-ultra-g1q" }, 2297 2301 { .compatible = "hp,omnibook-x14" }, 2298 2302 { .compatible = "huawei,gaokun3" }, ··· 2309 2309 { .compatible = "microsoft,denali", }, 2310 2310 { .compatible = "microsoft,romulus13", }, 2311 2311 { .compatible = "microsoft,romulus15", }, 2312 + { .compatible = "qcom,glymur-crd" }, 2312 2313 { .compatible = "qcom,hamoa-iot-evk" }, 2314 + { .compatible = "qcom,mahua-crd" }, 2315 + { .compatible = "qcom,purwa-iot-evk" }, 2313 2316 { .compatible = "qcom,sc8180x-primus" }, 2314 2317 { .compatible = "qcom,x1e001de-devkit" }, 2315 2318 { .compatible = "qcom,x1e80100-crd" }, ··· 2469 2466 return 0; 2470 2467 } 2471 2468 EXPORT_SYMBOL(qcom_scm_qtee_callback_response); 2469 + 2470 + static void qcom_scm_gunyah_wdt_free(void *data) 2471 + { 2472 + struct platform_device *gunyah_wdt_dev = data; 2473 + 2474 + platform_device_unregister(gunyah_wdt_dev); 2475 + } 2476 + 2477 + static void qcom_scm_gunyah_wdt_init(struct qcom_scm *scm) 2478 + { 2479 + struct platform_device *gunyah_wdt_dev; 2480 + struct device_node *np; 2481 + bool of_wdt_available; 2482 + int i; 2483 + static const uuid_t gunyah_uuid = UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb, 2484 + 0x92, 0x65, 0xce, 0x36, 2485 + 0x67, 0x3d, 0x5f, 0x14); 2486 + static const char * const of_wdt_compatible[] = { 2487 + "qcom,kpss-wdt", 2488 + "arm,sbsa-gwdt", 2489 + }; 2490 + 2491 + /* Bail out if we are not running under Gunyah */ 2492 + if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) || 2493 + !arm_smccc_hypervisor_has_uuid(&gunyah_uuid)) 2494 + return; 2495 + 2496 + /* 2497 + * Gunyah emulates either of Qualcomm watchdog or ARM SBSA watchdog on 2498 + * newer platforms. Bail out if we find them in the devicetree. 2499 + */ 2500 + for (i = 0; i < ARRAY_SIZE(of_wdt_compatible); i++) { 2501 + np = of_find_compatible_node(NULL, NULL, of_wdt_compatible[i]); 2502 + of_wdt_available = of_device_is_available(np); 2503 + of_node_put(np); 2504 + if (of_wdt_available) 2505 + return; 2506 + } 2507 + 2508 + gunyah_wdt_dev = platform_device_register_simple("gunyah-wdt", -1, 2509 + NULL, 0); 2510 + if (IS_ERR(gunyah_wdt_dev)) { 2511 + dev_err(scm->dev, "Failed to register Gunyah watchdog device: %ld\n", 2512 + PTR_ERR(gunyah_wdt_dev)); 2513 + return; 2514 + } 2515 + 2516 + devm_add_action_or_reset(scm->dev, qcom_scm_gunyah_wdt_free, 2517 + gunyah_wdt_dev); 2518 + } 2472 2519 2473 2520 static void qcom_scm_qtee_free(void *data) 2474 2521 { ··· 2863 2810 2864 2811 /* Initialize the QTEE object interface. */ 2865 2812 qcom_scm_qtee_init(scm); 2813 + 2814 + /* Initialize the Gunyah watchdog platform device. */ 2815 + qcom_scm_gunyah_wdt_init(scm); 2866 2816 2867 2817 return 0; 2868 2818 }
+140 -48
drivers/soc/qcom/llcc-qcom.c
··· 5 5 */ 6 6 7 7 #include <linux/bitfield.h> 8 - #include <linux/bitmap.h> 9 8 #include <linux/bitops.h> 10 9 #include <linux/cleanup.h> 11 10 #include <linux/device.h> ··· 1778 1779 .bonus_ways = 0xfff, 1779 1780 .cache_mode = 0, 1780 1781 .activate_on_init = true, 1782 + }, 1783 + }; 1784 + 1785 + static const struct llcc_slice_config sdm670_data[] = { 1786 + { 1787 + .usecase_id = LLCC_CPUSS, 1788 + .slice_id = 1, 1789 + .max_cap = 512, 1790 + .priority = 1, 1791 + .bonus_ways = 0xf, 1792 + .res_ways = 0x0, 1793 + .cache_mode = 0, 1794 + .dis_cap_alloc = true, 1795 + .retain_on_pc = true, 1796 + .activate_on_init = true, 1797 + }, { 1798 + .usecase_id = LLCC_ROTATOR, 1799 + .slice_id = 4, 1800 + .max_cap = 384, 1801 + .priority = 2, 1802 + .fixed_size = true, 1803 + .bonus_ways = 0x0, 1804 + .res_ways = 0xe, 1805 + .cache_mode = 2, 1806 + .dis_cap_alloc = true, 1807 + .retain_on_pc = true, 1808 + }, { 1809 + .usecase_id = LLCC_VOICE, 1810 + .slice_id = 5, 1811 + .max_cap = 512, 1812 + .priority = 1, 1813 + .bonus_ways = 0xf, 1814 + .res_ways = 0x0, 1815 + .cache_mode = 0, 1816 + .dis_cap_alloc = true, 1817 + .retain_on_pc = true, 1818 + }, { 1819 + .usecase_id = LLCC_AUDIO, 1820 + .slice_id = 6, 1821 + .max_cap = 512, 1822 + .priority = 1, 1823 + .bonus_ways = 0xf, 1824 + .res_ways = 0x0, 1825 + .cache_mode = 0, 1826 + .dis_cap_alloc = true, 1827 + .retain_on_pc = true, 1828 + }, { 1829 + .usecase_id = LLCC_MDM, 1830 + .slice_id = 8, 1831 + .max_cap = 512, 1832 + .priority = 1, 1833 + .bonus_ways = 0xf, 1834 + .res_ways = 0x0, 1835 + .cache_mode = 0, 1836 + .dis_cap_alloc = true, 1837 + .retain_on_pc = true, 1838 + }, { 1839 + .usecase_id = LLCC_GPU, 1840 + .slice_id = 12, 1841 + .max_cap = 384, 1842 + .priority = 1, 1843 + .fixed_size = true, 1844 + .bonus_ways = 0x0, 1845 + .res_ways = 0x0, 1846 + .cache_mode = 0, 1847 + .dis_cap_alloc = true, 1848 + .retain_on_pc = true, 1849 + }, { 1850 + .usecase_id = LLCC_MMUHWT, 1851 + .slice_id = 13, 1852 + .max_cap = 512, 1853 + .priority = 1, 1854 + .bonus_ways = 0xf, 1855 + .res_ways = 0x0, 1856 + .cache_mode = 0, 1857 + .dis_cap_alloc = true, 1858 + .activate_on_init = true, 1859 + }, { 1860 + .usecase_id = LLCC_AUDHW, 1861 + .slice_id = 22, 1862 + .max_cap = 512, 1863 + .priority = 1, 1864 + .fixed_size = true, 1865 + .bonus_ways = 0xf, 1866 + .res_ways = 0x0, 1867 + .cache_mode = 0, 1868 + .dis_cap_alloc = true, 1869 + .retain_on_pc = true, 1781 1870 }, 1782 1871 }; 1783 1872 ··· 4030 3943 static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = { 4031 3944 .trp_ecc_error_status0 = 0x20344, 4032 3945 .trp_ecc_error_status1 = 0x20348, 4033 - .trp_ecc_sb_err_syn0 = 0x2304c, 3946 + .trp_ecc_sb_err_syn0 = 0x2034c, 4034 3947 .trp_ecc_db_err_syn0 = 0x20370, 4035 3948 .trp_ecc_error_cntr_clear = 0x20440, 4036 3949 .trp_interrupt_0_status = 0x20480, ··· 4283 4196 }, 4284 4197 }; 4285 4198 4199 + static const struct qcom_llcc_config sdm670_cfg[] = { 4200 + { 4201 + .sct_data = sdm670_data, 4202 + .size = ARRAY_SIZE(sdm670_data), 4203 + .skip_llcc_cfg = true, 4204 + .reg_offset = llcc_v1_reg_offset, 4205 + .edac_reg_offset = &llcc_v1_edac_reg_offset, 4206 + .no_edac = true, 4207 + }, 4208 + }; 4209 + 4286 4210 static const struct qcom_llcc_config sdm845_cfg[] = { 4287 4211 { 4288 4212 .sct_data = sdm845_data, ··· 4462 4364 .num_config = ARRAY_SIZE(sc8280xp_cfg), 4463 4365 }; 4464 4366 4367 + static const struct qcom_sct_config sdm670_cfgs = { 4368 + .llcc_config = sdm670_cfg, 4369 + .num_config = ARRAY_SIZE(sdm670_cfg), 4370 + }; 4371 + 4465 4372 static const struct qcom_sct_config sdm845_cfgs = { 4466 4373 .llcc_config = sdm845_cfg, 4467 4374 .num_config = ARRAY_SIZE(sdm845_cfg), ··· 4534 4431 struct llcc_slice_desc *llcc_slice_getd(u32 uid) 4535 4432 { 4536 4433 const struct llcc_slice_config *cfg; 4537 - struct llcc_slice_desc *desc; 4538 - u32 sz, count; 4434 + u32 sz, i; 4539 4435 4540 4436 if (IS_ERR(drv_data)) 4541 4437 return ERR_CAST(drv_data); ··· 4542 4440 cfg = drv_data->cfg; 4543 4441 sz = drv_data->cfg_size; 4544 4442 4545 - for (count = 0; cfg && count < sz; count++, cfg++) 4443 + for (i = 0; cfg && i < sz; i++, cfg++) 4546 4444 if (cfg->usecase_id == uid) 4547 4445 break; 4548 4446 4549 - if (count == sz || !cfg) 4447 + if (i == sz) 4550 4448 return ERR_PTR(-ENODEV); 4551 4449 4552 - desc = kzalloc_obj(*desc); 4553 - if (!desc) 4554 - return ERR_PTR(-ENOMEM); 4555 - 4556 - desc->slice_id = cfg->slice_id; 4557 - desc->slice_size = cfg->max_cap; 4558 - 4559 - return desc; 4450 + return &drv_data->desc[i]; 4560 4451 } 4561 4452 EXPORT_SYMBOL_GPL(llcc_slice_getd); 4562 4453 ··· 4560 4465 void llcc_slice_putd(struct llcc_slice_desc *desc) 4561 4466 { 4562 4467 if (!IS_ERR_OR_NULL(desc)) 4563 - kfree(desc); 4468 + return; 4564 4469 } 4565 4470 EXPORT_SYMBOL_GPL(llcc_slice_putd); 4566 4471 ··· 4635 4540 if (IS_ERR_OR_NULL(desc)) 4636 4541 return -EINVAL; 4637 4542 4638 - mutex_lock(&drv_data->lock); 4639 - if (test_bit(desc->slice_id, drv_data->bitmap)) { 4640 - mutex_unlock(&drv_data->lock); 4543 + guard(mutex)(&drv_data->lock); 4544 + /* Already active; try to take another reference. */ 4545 + if (refcount_inc_not_zero(&desc->refcount)) 4641 4546 return 0; 4642 - } 4643 4547 4644 4548 act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT; 4645 - 4646 4549 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, 4647 4550 DEACTIVATE); 4648 - if (ret) { 4649 - mutex_unlock(&drv_data->lock); 4551 + if (ret) 4650 4552 return ret; 4651 - } 4652 4553 4653 - __set_bit(desc->slice_id, drv_data->bitmap); 4654 - mutex_unlock(&drv_data->lock); 4554 + /* Set first reference */ 4555 + refcount_set(&desc->refcount, 1); 4655 4556 4656 - return ret; 4557 + return 0; 4657 4558 } 4658 4559 EXPORT_SYMBOL_GPL(llcc_slice_activate); 4659 4560 ··· 4671 4580 if (IS_ERR_OR_NULL(desc)) 4672 4581 return -EINVAL; 4673 4582 4674 - mutex_lock(&drv_data->lock); 4675 - if (!test_bit(desc->slice_id, drv_data->bitmap)) { 4676 - mutex_unlock(&drv_data->lock); 4583 + guard(mutex)(&drv_data->lock); 4584 + /* refcount > 1, drop one ref and we’re done. */ 4585 + if (refcount_dec_not_one(&desc->refcount)) 4677 4586 return 0; 4678 - } 4679 - act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT; 4680 4587 4588 + act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT; 4681 4589 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, 4682 4590 ACTIVATE); 4683 - if (ret) { 4684 - mutex_unlock(&drv_data->lock); 4591 + if (ret) 4685 4592 return ret; 4686 - } 4687 4593 4688 - __clear_bit(desc->slice_id, drv_data->bitmap); 4689 - mutex_unlock(&drv_data->lock); 4594 + /* Finalize: atomically transition 1 -> 0 */ 4595 + WARN_ON_ONCE(!refcount_dec_if_one(&desc->refcount)); 4690 4596 4691 - return ret; 4597 + return 0; 4692 4598 } 4693 4599 EXPORT_SYMBOL_GPL(llcc_slice_deactivate); 4694 4600 ··· 4726 4638 u32 attr1_val; 4727 4639 u32 attr0_val; 4728 4640 u32 max_cap_cacheline; 4729 - struct llcc_slice_desc desc; 4641 + struct llcc_slice_desc *desc; 4730 4642 4731 4643 attr1_val = config->cache_mode; 4732 4644 attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT; ··· 4875 4787 } 4876 4788 4877 4789 if (config->activate_on_init) { 4878 - desc.slice_id = config->slice_id; 4879 - ret = llcc_slice_activate(&desc); 4790 + desc = llcc_slice_getd(config->usecase_id); 4791 + if (IS_ERR(desc)) 4792 + return PTR_ERR(desc); 4793 + 4794 + ret = llcc_slice_activate(desc); 4880 4795 } 4881 4796 4882 4797 return ret; ··· 5192 5101 5193 5102 llcc_cfg = cfg->sct_data; 5194 5103 sz = cfg->size; 5195 - 5196 - for (i = 0; i < sz; i++) 5197 - if (llcc_cfg[i].slice_id > drv_data->max_slices) 5198 - drv_data->max_slices = llcc_cfg[i].slice_id; 5199 - 5200 - drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices, 5201 - GFP_KERNEL); 5202 - if (!drv_data->bitmap) { 5104 + drv_data->desc = devm_kcalloc(dev, sz, sizeof(struct llcc_slice_desc), GFP_KERNEL); 5105 + if (!drv_data->desc) { 5203 5106 ret = -ENOMEM; 5204 5107 goto err; 5108 + } 5109 + 5110 + for (i = 0; i < sz; i++) { 5111 + drv_data->desc[i].slice_id = llcc_cfg[i].slice_id; 5112 + drv_data->desc[i].slice_size = llcc_cfg[i].max_cap; 5113 + refcount_set(&drv_data->desc[i].refcount, 0); 5205 5114 } 5206 5115 5207 5116 drv_data->cfg = llcc_cfg; ··· 5251 5160 { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs }, 5252 5161 { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs }, 5253 5162 { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfgs }, 5163 + { .compatible = "qcom,sdm670-llcc", .data = &sdm670_cfgs }, 5254 5164 { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfgs }, 5255 5165 { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfgs }, 5256 5166 { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfgs },
+8 -9
drivers/soc/qcom/ocmem.c
··· 196 196 } 197 197 198 198 pdev = of_find_device_by_node(devnode->parent); 199 - if (!pdev) { 200 - dev_err(dev, "Cannot find device node %s\n", devnode->name); 201 - return ERR_PTR(-EPROBE_DEFER); 202 - } 199 + if (!pdev) 200 + return dev_err_ptr_probe(dev, -EPROBE_DEFER, 201 + "Cannot find device node %s\n", 202 + devnode->name); 203 203 204 204 ocmem = platform_get_drvdata(pdev); 205 205 put_device(&pdev->dev); 206 - if (!ocmem) { 207 - dev_err(dev, "Cannot get ocmem\n"); 208 - return ERR_PTR(-ENODEV); 209 - } 206 + if (!ocmem) 207 + return dev_err_ptr_probe(dev, -EPROBE_DEFER, "Cannot get ocmem\n"); 208 + 210 209 return ocmem; 211 210 } 212 211 EXPORT_SYMBOL_GPL(of_get_ocmem); ··· 307 308 ocmem->dev = dev; 308 309 ocmem->config = device_get_match_data(dev); 309 310 310 - ocmem->core_clk = devm_clk_get(dev, "core"); 311 + ocmem->core_clk = devm_clk_get_optional(dev, "core"); 311 312 if (IS_ERR(ocmem->core_clk)) 312 313 return dev_err_probe(dev, PTR_ERR(ocmem->core_clk), 313 314 "Unable to get core clock\n");
+2 -2
drivers/soc/qcom/pdr_interface.c
··· 523 523 if (!pds) 524 524 return ERR_PTR(-ENOMEM); 525 525 526 - pds->service = SERVREG_NOTIFIER_SERVICE; 526 + pds->service = QMI_SERVICE_ID_SERVREG_NOTIF; 527 527 strscpy(pds->service_name, service_name, sizeof(pds->service_name)); 528 528 strscpy(pds->service_path, service_path, sizeof(pds->service_path)); 529 529 pds->need_locator_lookup = true; ··· 678 678 if (ret < 0) 679 679 goto destroy_indack; 680 680 681 - ret = qmi_add_lookup(&pdr->locator_hdl, SERVREG_LOCATOR_SERVICE, 1, 1); 681 + ret = qmi_add_lookup(&pdr->locator_hdl, QMI_SERVICE_ID_SERVREG_LOC, 1, 1); 682 682 if (ret < 0) 683 683 goto release_qmi_handle; 684 684
-3
drivers/soc/qcom/pdr_internal.h
··· 4 4 5 5 #include <linux/soc/qcom/pdr.h> 6 6 7 - #define SERVREG_LOCATOR_SERVICE 0x40 8 - #define SERVREG_NOTIFIER_SERVICE 0x42 9 - 10 7 #define SERVREG_REGISTER_LISTENER_REQ 0x20 11 8 #define SERVREG_GET_DOMAIN_LIST_REQ 0x21 12 9 #define SERVREG_STATE_UPDATED_IND_ID 0x22
+42 -24
drivers/soc/qcom/pmic_glink.c
··· 23 23 PMIC_GLINK_CLIENT_UCSI, 24 24 }; 25 25 26 + struct pmic_glink_data { 27 + unsigned long client_mask; 28 + const char *charger_pdr_service_name; 29 + const char *charger_pdr_service_path; 30 + }; 31 + 26 32 struct pmic_glink { 27 33 struct device *dev; 28 34 struct pdr_handle *pdr; 29 35 30 36 struct rpmsg_endpoint *ept; 31 37 32 - unsigned long client_mask; 38 + const struct pmic_glink_data *data; 33 39 34 40 struct auxiliary_device altmode_aux; 35 41 struct auxiliary_device ps_aux; ··· 298 292 299 293 static int pmic_glink_probe(struct platform_device *pdev) 300 294 { 301 - const unsigned long *match_data; 302 295 struct pdr_service *service; 303 296 struct pmic_glink *pg; 304 297 int ret; ··· 314 309 spin_lock_init(&pg->client_lock); 315 310 mutex_init(&pg->state_lock); 316 311 317 - match_data = (unsigned long *)of_device_get_match_data(&pdev->dev); 318 - if (!match_data) 312 + pg->data = of_device_get_match_data(&pdev->dev); 313 + if (!pg->data) 319 314 return -EINVAL; 320 - 321 - pg->client_mask = *match_data; 322 315 323 316 pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg); 324 317 if (IS_ERR(pg->pdr)) { ··· 325 322 return ret; 326 323 } 327 324 328 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { 325 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { 329 326 ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi"); 330 327 if (ret) 331 328 goto out_release_pdr_handle; 332 329 } 333 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { 330 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { 334 331 ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); 335 332 if (ret) 336 333 goto out_release_ucsi_aux; 337 334 } 338 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { 335 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { 339 336 ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); 340 337 if (ret) 341 338 goto out_release_altmode_aux; 342 339 } 343 340 344 - service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd"); 345 - if (IS_ERR(service)) { 346 - ret = dev_err_probe(&pdev->dev, PTR_ERR(service), 347 - "failed adding pdr lookup for charger_pd\n"); 348 - goto out_release_aux_devices; 341 + if (pg->data->charger_pdr_service_name && pg->data->charger_pdr_service_path) { 342 + service = pdr_add_lookup(pg->pdr, pg->data->charger_pdr_service_name, 343 + pg->data->charger_pdr_service_path); 344 + if (IS_ERR(service)) { 345 + ret = dev_err_probe(&pdev->dev, PTR_ERR(service), 346 + "failed adding pdr lookup for charger_pd\n"); 347 + goto out_release_aux_devices; 348 + } 349 349 } 350 350 351 351 mutex_lock(&__pmic_glink_lock); ··· 358 352 return 0; 359 353 360 354 out_release_aux_devices: 361 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 355 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 362 356 pmic_glink_del_aux_device(pg, &pg->ps_aux); 363 357 out_release_altmode_aux: 364 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 358 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 365 359 pmic_glink_del_aux_device(pg, &pg->altmode_aux); 366 360 out_release_ucsi_aux: 367 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 361 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 368 362 pmic_glink_del_aux_device(pg, &pg->ucsi_aux); 369 363 out_release_pdr_handle: 370 364 pdr_handle_release(pg->pdr); ··· 378 372 379 373 pdr_handle_release(pg->pdr); 380 374 381 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 375 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 382 376 pmic_glink_del_aux_device(pg, &pg->ps_aux); 383 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 377 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 384 378 pmic_glink_del_aux_device(pg, &pg->altmode_aux); 385 - if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 379 + if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 386 380 pmic_glink_del_aux_device(pg, &pg->ucsi_aux); 387 381 388 382 guard(mutex)(&__pmic_glink_lock); 389 383 __pmic_glink = NULL; 390 384 } 391 385 392 - static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | 393 - BIT(PMIC_GLINK_CLIENT_ALTMODE) | 394 - BIT(PMIC_GLINK_CLIENT_UCSI); 386 + static const struct pmic_glink_data pmic_glink_adsp_data = { 387 + .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | 388 + BIT(PMIC_GLINK_CLIENT_ALTMODE) | 389 + BIT(PMIC_GLINK_CLIENT_UCSI), 390 + .charger_pdr_service_name = "tms/servreg", 391 + .charger_pdr_service_path = "msm/adsp/charger_pd", 392 + }; 393 + 394 + static const struct pmic_glink_data pmic_glink_soccp_data = { 395 + .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | 396 + BIT(PMIC_GLINK_CLIENT_ALTMODE) | 397 + BIT(PMIC_GLINK_CLIENT_UCSI), 398 + }; 395 399 396 400 static const struct of_device_id pmic_glink_of_match[] = { 397 - { .compatible = "qcom,pmic-glink", .data = &pmic_glink_sm8450_client_mask }, 401 + { .compatible = "qcom,glymur-pmic-glink", .data = &pmic_glink_soccp_data }, 402 + { .compatible = "qcom,kaanapali-pmic-glink", .data = &pmic_glink_soccp_data }, 403 + { .compatible = "qcom,pmic-glink", .data = &pmic_glink_adsp_data }, 398 404 {} 399 405 }; 400 406 MODULE_DEVICE_TABLE(of, pmic_glink_of_match);
+1 -1
drivers/soc/qcom/qcom_aoss.c
··· 355 355 /* Normalize state */ 356 356 cdev_state = !!state; 357 357 358 - if (qmp_cdev->state == state) 358 + if (qmp_cdev->state == cdev_state) 359 359 return 0; 360 360 361 361 ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
+25 -8
drivers/soc/qcom/qcom_pd_mapper.c
··· 360 360 }, 361 361 }; 362 362 363 + static const struct qcom_pdm_domain_data *glymur_domains[] = { 364 + &adsp_audio_pd, 365 + &adsp_root_pd, 366 + &adsp_sensor_pd, 367 + &cdsp_root_pd, 368 + NULL, 369 + }; 370 + 363 371 static const struct qcom_pdm_domain_data *kaanapali_domains[] = { 364 372 &adsp_audio_pd, 365 373 &adsp_root_pd, ··· 400 392 }; 401 393 402 394 static const struct qcom_pdm_domain_data *qcs404_domains[] = { 395 + &adsp_audio_pd, 396 + &adsp_root_pd, 397 + &adsp_sensor_pd, 398 + &cdsp_root_pd, 399 + &mpss_root_pd, 400 + &mpss_wlan_pd, 401 + NULL, 402 + }; 403 + 404 + static const struct qcom_pdm_domain_data *qcs615_domains[] = { 403 405 &adsp_audio_pd, 404 406 &adsp_root_pd, 405 407 &adsp_sensor_pd, ··· 578 560 { .compatible = "qcom,apq8064", .data = NULL, }, 579 561 { .compatible = "qcom,apq8074", .data = NULL, }, 580 562 { .compatible = "qcom,apq8084", .data = NULL, }, 563 + { .compatible = "qcom,eliza", .data = sm8550_domains, }, 581 564 { .compatible = "qcom,apq8096", .data = msm8996_domains, }, 565 + { .compatible = "qcom,glymur", .data = glymur_domains, }, 582 566 { .compatible = "qcom,kaanapali", .data = kaanapali_domains, }, 567 + { .compatible = "qcom,mahua", .data = glymur_domains, }, 568 + { .compatible = "qcom,milos", .data = sm8550_domains, }, 583 569 { .compatible = "qcom,msm8226", .data = NULL, }, 584 570 { .compatible = "qcom,msm8909", .data = NULL, }, 585 571 { .compatible = "qcom,msm8916", .data = NULL, }, ··· 594 572 { .compatible = "qcom,qcm2290", .data = qcm2290_domains, }, 595 573 { .compatible = "qcom,qcm6490", .data = sc7280_domains, }, 596 574 { .compatible = "qcom,qcs404", .data = qcs404_domains, }, 575 + { .compatible = "qcom,qcs615", .data = qcs615_domains, }, 597 576 { .compatible = "qcom,sc7180", .data = sc7180_domains, }, 598 577 { .compatible = "qcom,sc7280", .data = sc7280_domains, }, 599 578 { .compatible = "qcom,sc8180x", .data = sc8180x_domains, }, ··· 638 615 const struct qcom_pdm_domain_data * const *domains; 639 616 const struct of_device_id *match; 640 617 struct qcom_pdm_data *data; 641 - struct device_node *root; 642 618 int ret, i; 643 619 644 - root = of_find_node_by_path("/"); 645 - if (!root) 646 - return ERR_PTR(-ENODEV); 647 - 648 - match = of_match_node(qcom_pdm_domains, root); 649 - of_node_put(root); 620 + match = of_match_node(qcom_pdm_domains, of_root); 650 621 if (!match) { 651 622 pr_notice("PDM: no support for the platform, userspace daemon might be required.\n"); 652 623 return ERR_PTR(-ENODEV); ··· 673 656 goto err_stop; 674 657 } 675 658 676 - ret = qmi_add_server(&data->handle, SERVREG_LOCATOR_SERVICE, 659 + ret = qmi_add_server(&data->handle, QMI_SERVICE_ID_SERVREG_LOC, 677 660 SERVREG_QMI_VERSION, SERVREG_QMI_INSTANCE); 678 661 if (ret) { 679 662 pr_err("PDM: error adding server %d\n", ret);
+99 -4
drivers/soc/qcom/smp2p.c
··· 36 36 * The driver uses the Linux GPIO and interrupt framework to expose a virtual 37 37 * GPIO for each outbound entry and a virtual interrupt controller for each 38 38 * inbound entry. 39 + * 40 + * V2 of SMP2P allows remote processors to write to outbound smp2p items before 41 + * the full smp2p connection is negotiated. This is important for processors 42 + * started before linux runs. 39 43 */ 40 44 41 45 #define SMP2P_MAX_ENTRY 16 ··· 51 47 52 48 #define SMP2P_MAGIC 0x504d5324 53 49 #define SMP2P_ALL_FEATURES SMP2P_FEATURE_SSR_ACK 50 + #define MAX_VERSION 2 54 51 55 52 /** 56 53 * struct smp2p_smem_item - in memory communication structure 57 54 * @magic: magic number 58 - * @version: version - must be 1 55 + * @version: version 59 56 * @features: features flag - currently unused 60 57 * @local_pid: processor id of sending end 61 58 * @remote_pid: processor id of receiving end ··· 185 180 static bool qcom_smp2p_check_ssr(struct qcom_smp2p *smp2p) 186 181 { 187 182 struct smp2p_smem_item *in = smp2p->in; 183 + struct smp2p_entry *entry; 184 + bool restart_done; 188 185 bool restart; 189 186 190 187 if (!smp2p->ssr_ack_enabled) 191 188 return false; 192 189 193 - restart = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT); 190 + restart_done = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT); 191 + restart = restart_done != smp2p->ssr_ack; 192 + list_for_each_entry(entry, &smp2p->inbound, node) { 193 + if (!entry->value) 194 + continue; 195 + entry->last_value = 0; 196 + } 194 197 195 - return restart != smp2p->ssr_ack; 198 + return restart; 196 199 } 197 200 198 201 static void qcom_smp2p_do_ssr_ack(struct qcom_smp2p *smp2p) ··· 232 219 233 220 smp2p->negotiation_done = true; 234 221 trace_smp2p_negotiate(smp2p->dev, out->features); 222 + } else if (in->version && in->version < out->version) { 223 + out->version = in->version; 224 + qcom_smp2p_kick(smp2p); 235 225 } 226 + } 227 + 228 + static int qcom_smp2p_in_version(struct qcom_smp2p *smp2p) 229 + { 230 + unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND]; 231 + unsigned int pid = smp2p->remote_pid; 232 + struct smp2p_smem_item *in; 233 + size_t size; 234 + 235 + in = qcom_smem_get(pid, smem_id, &size); 236 + if (IS_ERR(in)) 237 + return 0; 238 + 239 + return in->version; 240 + } 241 + 242 + static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p) 243 + { 244 + unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND]; 245 + unsigned int pid = smp2p->remote_pid; 246 + char buf[SMP2P_MAX_ENTRY_NAME]; 247 + struct smp2p_smem_item *in; 248 + struct smp2p_entry *entry; 249 + size_t size; 250 + int i; 251 + 252 + in = qcom_smem_get(pid, smem_id, &size); 253 + if (IS_ERR(in)) 254 + return; 255 + 256 + smp2p->in = in; 257 + 258 + /* Check if version is initialized by the remote. */ 259 + if (in->version == 0) 260 + return; 261 + 262 + for (i = smp2p->valid_entries; i < in->valid_entries; i++) { 263 + list_for_each_entry(entry, &smp2p->inbound, node) { 264 + memcpy(buf, in->entries[i].name, sizeof(buf)); 265 + if (!strcmp(buf, entry->name)) { 266 + entry->value = &in->entries[i].value; 267 + entry->last_value = readl(entry->value); 268 + break; 269 + } 270 + } 271 + } 272 + smp2p->valid_entries = i; 236 273 } 237 274 238 275 static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) ··· 431 368 seq_printf(p, "%8s", dev_name(entry->smp2p->dev)); 432 369 } 433 370 371 + static int smp2p_irq_get_irqchip_state(struct irq_data *irqd, enum irqchip_irq_state which, 372 + bool *state) 373 + { 374 + struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd); 375 + u32 val; 376 + 377 + if (which != IRQCHIP_STATE_LINE_LEVEL) 378 + return -EINVAL; 379 + 380 + if (!entry->value) 381 + return -ENODEV; 382 + 383 + val = readl(entry->value); 384 + *state = !!(val & BIT(irqd_to_hwirq(irqd))); 385 + 386 + return 0; 387 + } 388 + 434 389 static struct irq_chip smp2p_irq_chip = { 435 390 .name = "smp2p", 436 391 .irq_mask = smp2p_mask_irq, 437 392 .irq_unmask = smp2p_unmask_irq, 438 393 .irq_set_type = smp2p_set_irq_type, 439 394 .irq_print_chip = smp2p_irq_print_chip, 395 + .irq_get_irqchip_state = smp2p_irq_get_irqchip_state, 440 396 }; 441 397 442 398 static int smp2p_irq_map(struct irq_domain *d, ··· 546 464 struct smp2p_smem_item *out; 547 465 unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND]; 548 466 unsigned pid = smp2p->remote_pid; 467 + u8 in_version; 549 468 int ret; 550 469 551 470 ret = qcom_smem_alloc(pid, smem_id, sizeof(*out)); ··· 568 485 out->valid_entries = 0; 569 486 out->features = SMP2P_ALL_FEATURES; 570 487 488 + in_version = qcom_smp2p_in_version(smp2p); 489 + if (in_version > MAX_VERSION) { 490 + dev_err(smp2p->dev, "Unsupported smp2p version %d\n", in_version); 491 + return -EINVAL; 492 + } 493 + 571 494 /* 572 495 * Make sure the rest of the header is written before we validate the 573 496 * item by writing a valid version number. 574 497 */ 575 498 wmb(); 576 - out->version = 1; 499 + if (in_version && in_version <= 2) 500 + out->version = in_version; 501 + else 502 + out->version = 2; 577 503 578 504 qcom_smp2p_kick(smp2p); 579 505 ··· 709 617 list_add(&entry->node, &smp2p->outbound); 710 618 } 711 619 } 620 + 621 + /* Check inbound entries in the case of early boot processor */ 622 + qcom_smp2p_start_in(smp2p); 712 623 713 624 /* Kick the outgoing edge after allocating entries */ 714 625 qcom_smp2p_kick(smp2p);
+11
drivers/soc/qcom/socinfo.c
··· 182 182 [72] = "PMR735D", 183 183 [73] = "PM8550", 184 184 [74] = "PMK8550", 185 + [76] = "PM7550BA", 185 186 [78] = "PMM8650AU", 186 187 [79] = "PMM8650AU_PSAIL", 187 188 [80] = "PM7550", ··· 474 473 { qcom_board_id(IPQ5000) }, 475 474 { qcom_board_id(IPQ0509) }, 476 475 { qcom_board_id(IPQ0518) }, 476 + { qcom_board_id(SM7450) }, 477 477 { qcom_board_id(SM6375) }, 478 478 { qcom_board_id(IPQ9514) }, 479 479 { qcom_board_id(IPQ9550) }, ··· 490 488 { qcom_board_id(SM8475) }, 491 489 { qcom_board_id(SM8475P) }, 492 490 { qcom_board_id(SA8255P) }, 491 + { qcom_board_id(SA8650P) }, 493 492 { qcom_board_id(SA8775P) }, 494 493 { qcom_board_id(QRU1000) }, 495 494 { qcom_board_id(SM8475_2) }, 496 495 { qcom_board_id(QDU1000) }, 496 + { qcom_board_id(SM7450P) }, 497 497 { qcom_board_id(X1E80100) }, 498 498 { qcom_board_id(SM8650) }, 499 499 { qcom_board_id(SM4450) }, ··· 526 522 { qcom_board_id(QCS8275) }, 527 523 { qcom_board_id(QCS9075) }, 528 524 { qcom_board_id(QCS615) }, 525 + { qcom_board_id(CQ7790M) }, 526 + { qcom_board_id(CQ7790S) }, 527 + { qcom_board_id(IPQ5200) }, 528 + { qcom_board_id(IPQ5210) }, 529 + { qcom_board_id(QCF2200) }, 530 + { qcom_board_id(QCF3200) }, 531 + { qcom_board_id(QCF3210) }, 529 532 }; 530 533 531 534 static const char *socinfo_machine(struct device *dev, unsigned int id)
+16 -15
drivers/soc/qcom/ubwc_config.c
··· 16 16 /* no UBWC, no HBB */ 17 17 }; 18 18 19 + static const struct qcom_ubwc_cfg_data eliza_data = { 20 + .ubwc_enc_version = UBWC_5_0, 21 + .ubwc_dec_version = UBWC_5_0, 22 + .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | 23 + UBWC_SWIZZLE_ENABLE_LVL3, 24 + .ubwc_bank_spread = true, 25 + /* TODO: highest_bank_bit = 14 for LP_DDR4 */ 26 + .highest_bank_bit = 15, 27 + .macrotile_mode = true, 28 + }; 29 + 19 30 static const struct qcom_ubwc_cfg_data kaanapali_data = { 20 31 .ubwc_enc_version = UBWC_6_0, 21 32 .ubwc_dec_version = UBWC_6_0, ··· 228 217 .macrotile_mode = true, 229 218 }; 230 219 231 - static const struct qcom_ubwc_cfg_data x1e80100_data = { 232 - .ubwc_enc_version = UBWC_4_0, 233 - .ubwc_dec_version = UBWC_4_3, 234 - .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | 235 - UBWC_SWIZZLE_ENABLE_LVL3, 236 - .ubwc_bank_spread = true, 237 - /* TODO: highest_bank_bit = 15 for LP_DDR4 */ 238 - .highest_bank_bit = 16, 239 - .macrotile_mode = true, 240 - }; 241 - 242 220 static const struct qcom_ubwc_cfg_data glymur_data = { 243 221 .ubwc_enc_version = UBWC_5_0, 244 222 .ubwc_dec_version = UBWC_5_0, 245 - .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | 246 - UBWC_SWIZZLE_ENABLE_LVL3, 223 + .ubwc_swizzle = 0, 247 224 .ubwc_bank_spread = true, 248 225 /* TODO: highest_bank_bit = 15 for LP_DDR4 */ 249 226 .highest_bank_bit = 16, ··· 243 244 { .compatible = "qcom,apq8026", .data = &no_ubwc_data }, 244 245 { .compatible = "qcom,apq8074", .data = &no_ubwc_data }, 245 246 { .compatible = "qcom,apq8096", .data = &msm8998_data }, 247 + { .compatible = "qcom,eliza", .data = &eliza_data, }, 246 248 { .compatible = "qcom,kaanapali", .data = &kaanapali_data, }, 247 249 { .compatible = "qcom,glymur", .data = &glymur_data}, 250 + { .compatible = "qcom,mahua", .data = &glymur_data }, 248 251 { .compatible = "qcom,msm8226", .data = &no_ubwc_data }, 249 252 { .compatible = "qcom,msm8916", .data = &no_ubwc_data }, 250 253 { .compatible = "qcom,msm8917", .data = &no_ubwc_data }, ··· 295 294 { .compatible = "qcom,sm8550", .data = &sm8550_data, }, 296 295 { .compatible = "qcom,sm8650", .data = &sm8550_data, }, 297 296 { .compatible = "qcom,sm8750", .data = &sm8750_data, }, 298 - { .compatible = "qcom,x1e80100", .data = &x1e80100_data, }, 299 - { .compatible = "qcom,x1p42100", .data = &x1e80100_data, }, 297 + { .compatible = "qcom,x1e80100", .data = &sm8550_data, }, 298 + { .compatible = "qcom,x1p42100", .data = &sm8550_data, }, 300 299 { } 301 300 }; 302 301
+9 -8
drivers/soc/qcom/wcnss_ctrl.c
··· 94 94 u16 seq; 95 95 u16 last; 96 96 u32 frag_size; 97 - u8 fragment[]; 97 + u8 fragment[] __counted_by(frag_size); 98 98 } __packed; 99 99 100 100 /** ··· 201 201 { 202 202 const struct firmware *fw; 203 203 struct device *dev = wcnss->dev; 204 + struct wcnss_download_nv_req *req; 204 205 const char *nvbin = NVBIN_FILE; 205 206 const void *data; 206 207 ssize_t left; 207 208 int ret; 208 - 209 - struct wcnss_download_nv_req *req __free(kfree) = kzalloc(sizeof(*req) + NV_FRAGMENT_SIZE, 210 - GFP_KERNEL); 211 - if (!req) 212 - return -ENOMEM; 213 209 214 210 ret = of_property_read_string(dev->of_node, "firmware-name", &nvbin); 215 211 if (ret < 0 && ret != -EINVAL) ··· 220 224 data = fw->data; 221 225 left = fw->size; 222 226 227 + req = kzalloc_flex(*req, fragment, NV_FRAGMENT_SIZE); 228 + if (!req) 229 + return -ENOMEM; 230 + 231 + req->frag_size = NV_FRAGMENT_SIZE; 223 232 req->hdr.type = WCNSS_DOWNLOAD_NV_REQ; 224 - req->hdr.len = sizeof(*req) + NV_FRAGMENT_SIZE; 233 + req->hdr.len = struct_size(req, fragment, NV_FRAGMENT_SIZE); 225 234 226 235 req->last = 0; 227 - req->frag_size = NV_FRAGMENT_SIZE; 228 236 229 237 req->seq = 0; 230 238 do { ··· 264 264 265 265 release_fw: 266 266 release_firmware(fw); 267 + kfree(req); 267 268 268 269 return ret; 269 270 }
+10
include/dt-bindings/arm/qcom,ids.h
··· 245 245 #define QCOM_ID_IPQ5000 503 246 246 #define QCOM_ID_IPQ0509 504 247 247 #define QCOM_ID_IPQ0518 505 248 + #define QCOM_ID_SM7450 506 248 249 #define QCOM_ID_SM6375 507 249 250 #define QCOM_ID_IPQ9514 510 250 251 #define QCOM_ID_IPQ9550 511 ··· 261 260 #define QCOM_ID_SM8475 530 262 261 #define QCOM_ID_SM8475P 531 263 262 #define QCOM_ID_SA8255P 532 263 + #define QCOM_ID_SA8650P 533 264 264 #define QCOM_ID_SA8775P 534 265 265 #define QCOM_ID_QRU1000 539 266 266 #define QCOM_ID_SM8475_2 540 267 267 #define QCOM_ID_QDU1000 545 268 + #define QCOM_ID_SM7450P 547 268 269 #define QCOM_ID_X1E80100 555 269 270 #define QCOM_ID_SM8650 557 270 271 #define QCOM_ID_SM4450 568 ··· 297 294 #define QCOM_ID_QCS8275 675 298 295 #define QCOM_ID_QCS9075 676 299 296 #define QCOM_ID_QCS615 680 297 + #define QCOM_ID_CQ7790M 731 298 + #define QCOM_ID_CQ7790S 732 299 + #define QCOM_ID_IPQ5200 765 300 + #define QCOM_ID_IPQ5210 766 301 + #define QCOM_ID_QCF2200 767 302 + #define QCOM_ID_QCF3200 768 303 + #define QCOM_ID_QCF3210 769 300 304 301 305 /* 302 306 * The board type and revision information, used by Qualcomm bootloaders and
+4 -4
include/linux/soc/qcom/llcc-qcom.h
··· 91 91 * struct llcc_slice_desc - Cache slice descriptor 92 92 * @slice_id: llcc slice id 93 93 * @slice_size: Size allocated for the llcc slice 94 + * @refcount: Atomic counter to track activate/deactivate calls 94 95 */ 95 96 struct llcc_slice_desc { 96 97 u32 slice_id; 97 98 size_t slice_size; 99 + refcount_t refcount; 98 100 }; 99 101 100 102 /** ··· 154 152 * @edac_reg_offset: Offset of the LLCC EDAC registers 155 153 * @lock: mutex associated with each slice 156 154 * @cfg_size: size of the config data table 157 - * @max_slices: max slices as read from device tree 158 155 * @num_banks: Number of llcc banks 159 - * @bitmap: Bit map to track the active slice ids 160 156 * @ecc_irq: interrupt for llcc cache error detection and reporting 161 157 * @ecc_irq_configured: 'True' if firmware has already configured the irq propagation 158 + * @desc: Array pointer of pre-allocated LLCC slice descriptors 162 159 * @version: Indicates the LLCC version 163 160 */ 164 161 struct llcc_drv_data { ··· 168 167 const struct llcc_edac_reg_offset *edac_reg_offset; 169 168 struct mutex lock; 170 169 u32 cfg_size; 171 - u32 max_slices; 172 170 u32 num_banks; 173 - unsigned long *bitmap; 174 171 int ecc_irq; 175 172 bool ecc_irq_configured; 176 173 u32 version; 174 + struct llcc_slice_desc *desc; 177 175 }; 178 176 179 177 #if IS_ENABLED(CONFIG_QCOM_LLCC)
+12
include/linux/soc/qcom/qmi.h
··· 92 92 #define QMI_ERR_INCOMPATIBLE_STATE_V01 90 93 93 #define QMI_ERR_NOT_SUPPORTED_V01 94 94 94 95 + /* 96 + * Enumerate the IDs of the QMI services 97 + */ 98 + #define QMI_SERVICE_ID_TEST 0x0f /* 15 */ 99 + #define QMI_SERVICE_ID_SSCTL 0x2b /* 43 */ 100 + #define QMI_SERVICE_ID_IPA 0x31 /* 49 */ 101 + #define QMI_SERVICE_ID_SERVREG_LOC 0x40 /* 64 */ 102 + #define QMI_SERVICE_ID_SERVREG_NOTIF 0x42 /* 66 */ 103 + #define QMI_SERVICE_ID_WLFW 0x45 /* 69 */ 104 + #define QMI_SERVICE_ID_SLIMBUS 0x301 /* 769 */ 105 + #define QMI_SERVICE_ID_USB_AUDIO_STREAM 0x41d /* 1053 */ 106 + 95 107 /** 96 108 * struct qmi_response_type_v01 - common response header (decoded) 97 109 * @result: result of the transaction
+25
include/linux/soc/qcom/ubwc.h
··· 74 74 return ret; 75 75 } 76 76 77 + /* 78 + * This is the best guess, based on the MDSS driver, which worked so far. 79 + */ 80 + static inline bool qcom_ubwc_min_acc_length_64b(const struct qcom_ubwc_cfg_data *cfg) 81 + { 82 + return cfg->ubwc_enc_version == UBWC_1_0 && 83 + (cfg->ubwc_dec_version == UBWC_2_0 || 84 + cfg->ubwc_dec_version == UBWC_3_0); 85 + } 86 + 87 + static inline bool qcom_ubwc_macrotile_mode(const struct qcom_ubwc_cfg_data *cfg) 88 + { 89 + return cfg->macrotile_mode; 90 + } 91 + 92 + static inline bool qcom_ubwc_bank_spread(const struct qcom_ubwc_cfg_data *cfg) 93 + { 94 + return cfg->ubwc_bank_spread; 95 + } 96 + 97 + static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) 98 + { 99 + return cfg->ubwc_swizzle; 100 + } 101 + 77 102 #endif /* __QCOM_UBWC_H__ */
+1 -1
samples/qmi/qmi_sample_client.c
··· 592 592 if (ret < 0) 593 593 goto err_unregister_driver; 594 594 595 - qmi_add_lookup(&lookup_client, 15, 0, 0); 595 + qmi_add_lookup(&lookup_client, QMI_SERVICE_ID_TEST, 0, 0); 596 596 597 597 return 0; 598 598