diff options
author | Arnd Bergmann <arnd@arndb.de> | 2024-09-04 09:32:52 +0000 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2024-09-04 09:47:35 +0000 |
commit | b1cd063981de572f010092b7afde5ff4b3d923eb (patch) | |
tree | 1d26f8c432adab97c38ad45b10b4bc4393461dac /drivers/soc | |
parent | d205c06a326e435057c807bf1e962327de53bb52 (diff) | |
parent | 68123510b7c1c610387dd306f92ff539c3c546b5 (diff) |
Merge tag 'ti-driver-soc-for-v6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux into soc/drivers
TI SoC driver updates for v6.12
- pm33xx/knav_qmss_queue/pruss: Cleanups around device_node scope based cleanups
- knav: Additional fixes around of property
- k3-ringacc: Optimizations for data structure
* tag 'ti-driver-soc-for-v6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux:
soc: ti: pm33xx: do device_node auto cleanup
soc: ti: knav_qmss_queue: do device_node auto cleanup
soc: ti: pruss: do device_node auto cleanup
soc: ti: pruss: factor out memories setup
soc: ti: knav: Use of_property_read_variable_u32_array()
soc: ti: knav: Drop unnecessary check for property presence
soc: ti: k3-ringacc: Constify struct k3_ring_ops
Link: https://lore.kernel.org/r/20240903155632.525twuumykwnfkiz@subtitle
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/ti/k3-ringacc.c | 12 | ||||
-rw-r--r-- | drivers/soc/ti/knav_dma.c | 22 | ||||
-rw-r--r-- | drivers/soc/ti/knav_qmss_queue.c | 105 | ||||
-rw-r--r-- | drivers/soc/ti/pm33xx.c | 52 | ||||
-rw-r--r-- | drivers/soc/ti/pruss.c | 176 |
5 files changed, 166 insertions, 201 deletions
diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c index fd4251d75935..8c0102968351 100644 --- a/drivers/soc/ti/k3-ringacc.c +++ b/drivers/soc/ti/k3-ringacc.c @@ -161,7 +161,7 @@ struct k3_ring { struct k3_ringacc_proxy_target_regs __iomem *proxy; dma_addr_t ring_mem_dma; void *ring_mem_virt; - struct k3_ring_ops *ops; + const struct k3_ring_ops *ops; u32 size; enum k3_ring_size elm_size; enum k3_ring_mode mode; @@ -268,17 +268,17 @@ static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem); static int k3_dmaring_fwd_pop(struct k3_ring *ring, void *elem); static int k3_dmaring_reverse_pop(struct k3_ring *ring, void *elem); -static struct k3_ring_ops k3_ring_mode_ring_ops = { +static const struct k3_ring_ops k3_ring_mode_ring_ops = { .push_tail = k3_ringacc_ring_push_mem, .pop_head = k3_ringacc_ring_pop_mem, }; -static struct k3_ring_ops k3_dmaring_fwd_ops = { +static const struct k3_ring_ops k3_dmaring_fwd_ops = { .push_tail = k3_ringacc_ring_push_mem, .pop_head = k3_dmaring_fwd_pop, }; -static struct k3_ring_ops k3_dmaring_reverse_ops = { +static const struct k3_ring_ops k3_dmaring_reverse_ops = { /* Reverse side of the DMA ring can only be popped by SW */ .pop_head = k3_dmaring_reverse_pop, }; @@ -288,7 +288,7 @@ static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem); static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void *elem); static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem); -static struct k3_ring_ops k3_ring_mode_msg_ops = { +static const struct k3_ring_ops k3_ring_mode_msg_ops = { .push_tail = k3_ringacc_ring_push_io, .push_head = k3_ringacc_ring_push_head_io, .pop_tail = k3_ringacc_ring_pop_tail_io, @@ -300,7 +300,7 @@ static int k3_ringacc_ring_push_tail_proxy(struct k3_ring *ring, void *elem); static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem); static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem); -static struct k3_ring_ops k3_ring_mode_proxy_ops = { +static const struct k3_ring_ops k3_ring_mode_proxy_ops = { .push_tail = k3_ringacc_ring_push_tail_proxy, .push_head = k3_ringacc_ring_push_head_proxy, .pop_tail = k3_ringacc_ring_pop_tail_proxy, diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 6023006685fc..fb0746d8caad 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -602,7 +602,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node) unsigned max_tx_chan, max_rx_chan, max_rx_flow, max_tx_sched; struct device_node *node = dma_node; struct knav_dma_device *dma; - int ret, len, num_chan = 0; + int ret, num_chan = 0; resource_size_t size; u32 timeout; u32 i; @@ -615,25 +615,13 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node) INIT_LIST_HEAD(&dma->list); INIT_LIST_HEAD(&dma->chan_list); - if (!of_find_property(cloud, "ti,navigator-cloud-address", &len)) { - dev_err(kdev->dev, "unspecified navigator cloud addresses\n"); - return -ENODEV; - } - - dma->logical_queue_managers = len / sizeof(u32); - if (dma->logical_queue_managers > DMA_MAX_QMS) { - dev_warn(kdev->dev, "too many queue mgrs(>%d) rest ignored\n", - dma->logical_queue_managers); - dma->logical_queue_managers = DMA_MAX_QMS; - } - - ret = of_property_read_u32_array(cloud, "ti,navigator-cloud-address", - dma->qm_base_address, - dma->logical_queue_managers); - if (ret) { + ret = of_property_read_variable_u32_array(cloud, "ti,navigator-cloud-address", + dma->qm_base_address, 1, DMA_MAX_QMS); + if (ret < 0) { dev_err(kdev->dev, "invalid navigator cloud addresses\n"); return -ENODEV; } + dma->logical_queue_managers = ret; dma->reg_global = pktdma_get_regs(dma, node, 0, &size); if (IS_ERR(dma->reg_global)) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index f2055a76f84c..6c98738e548a 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -1076,14 +1076,20 @@ static const char *knav_queue_find_name(struct device_node *node) } static int knav_queue_setup_regions(struct knav_device *kdev, - struct device_node *regions) + struct device_node *node) { struct device *dev = kdev->dev; + struct device_node *regions __free(device_node) = + of_get_child_by_name(node, "descriptor-regions"); struct knav_region *region; struct device_node *child; u32 temp[2]; int ret; + if (!regions) + return dev_err_probe(dev, -ENODEV, + "descriptor-regions not specified\n"); + for_each_child_of_node(regions, child) { region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL); if (!region) { @@ -1104,11 +1110,6 @@ static int knav_queue_setup_regions(struct knav_device *kdev, continue; } - if (!of_get_property(child, "link-index", NULL)) { - dev_err(dev, "No link info for %s\n", region->name); - devm_kfree(dev, region); - continue; - } ret = of_property_read_u32(child, "link-index", ®ion->link_index); if (ret) { @@ -1121,10 +1122,9 @@ static int knav_queue_setup_regions(struct knav_device *kdev, INIT_LIST_HEAD(®ion->pools); list_add_tail(®ion->list, &kdev->regions); } - if (list_empty(&kdev->regions)) { - dev_err(dev, "no valid region information found\n"); - return -ENODEV; - } + if (list_empty(&kdev->regions)) + return dev_err_probe(dev, -ENODEV, + "no valid region information found\n"); /* Next, we run through the regions and set things up */ for_each_region(kdev, region) @@ -1306,10 +1306,16 @@ static int knav_setup_queue_range(struct knav_device *kdev, } static int knav_setup_queue_pools(struct knav_device *kdev, - struct device_node *queue_pools) + struct device_node *node) { + struct device_node *queue_pools __free(device_node) = + of_get_child_by_name(node, "queue-pools"); struct device_node *type, *range; + if (!queue_pools) + return dev_err_probe(kdev->dev, -ENODEV, + "queue-pools not specified\n"); + for_each_child_of_node(queue_pools, type) { for_each_child_of_node(type, range) { /* return value ignored, we init the rest... */ @@ -1318,10 +1324,9 @@ static int knav_setup_queue_pools(struct knav_device *kdev, } /* ... and barf if they all failed! */ - if (list_empty(&kdev->queue_ranges)) { - dev_err(kdev->dev, "no valid queue range found\n"); - return -ENODEV; - } + if (list_empty(&kdev->queue_ranges)) + return dev_err_probe(kdev->dev, -ENODEV, + "no valid queue range found\n"); return 0; } @@ -1389,14 +1394,20 @@ static void __iomem *knav_queue_map_reg(struct knav_device *kdev, } static int knav_queue_init_qmgrs(struct knav_device *kdev, - struct device_node *qmgrs) + struct device_node *node) { struct device *dev = kdev->dev; + struct device_node *qmgrs __free(device_node) = + of_get_child_by_name(node, "qmgrs"); struct knav_qmgr_info *qmgr; struct device_node *child; u32 temp[2]; int ret; + if (!qmgrs) + return dev_err_probe(dev, -ENODEV, + "queue manager info not specified\n"); + for_each_child_of_node(qmgrs, child) { qmgr = devm_kzalloc(dev, sizeof(*qmgr), GFP_KERNEL); if (!qmgr) { @@ -1668,6 +1679,26 @@ static int knav_queue_start_pdsps(struct knav_device *kdev) return 0; } +static int knav_queue_setup_pdsps(struct knav_device *kdev, + struct device_node *node) +{ + struct device_node *pdsps __free(device_node) = + of_get_child_by_name(node, "pdsps"); + + if (pdsps) { + int ret; + + ret = knav_queue_init_pdsps(kdev, pdsps); + if (ret) + return ret; + + ret = knav_queue_start_pdsps(kdev); + if (ret) + return ret; + } + return 0; +} + static inline struct knav_qmgr_info *knav_find_qmgr(unsigned id) { struct knav_qmgr_info *qmgr; @@ -1755,7 +1786,6 @@ MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); static int knav_queue_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct device_node *qmgrs, *queue_pools, *regions, *pdsps; struct device *dev = &pdev->dev; u32 temp[2]; int ret; @@ -1799,39 +1829,17 @@ static int knav_queue_probe(struct platform_device *pdev) kdev->num_queues = temp[1]; /* Initialize queue managers using device tree configuration */ - qmgrs = of_get_child_by_name(node, "qmgrs"); - if (!qmgrs) { - dev_err(dev, "queue manager info not specified\n"); - ret = -ENODEV; - goto err; - } - ret = knav_queue_init_qmgrs(kdev, qmgrs); - of_node_put(qmgrs); + ret = knav_queue_init_qmgrs(kdev, node); if (ret) goto err; /* get pdsp configuration values from device tree */ - pdsps = of_get_child_by_name(node, "pdsps"); - if (pdsps) { - ret = knav_queue_init_pdsps(kdev, pdsps); - if (ret) - goto err; - - ret = knav_queue_start_pdsps(kdev); - if (ret) - goto err; - } - of_node_put(pdsps); + ret = knav_queue_setup_pdsps(kdev, node); + if (ret) + goto err; /* get usable queue range values from device tree */ - queue_pools = of_get_child_by_name(node, "queue-pools"); - if (!queue_pools) { - dev_err(dev, "queue-pools not specified\n"); - ret = -ENODEV; - goto err; - } - ret = knav_setup_queue_pools(kdev, queue_pools); - of_node_put(queue_pools); + ret = knav_setup_queue_pools(kdev, node); if (ret) goto err; @@ -1853,14 +1861,7 @@ static int knav_queue_probe(struct platform_device *pdev) if (ret) goto err; - regions = of_get_child_by_name(node, "descriptor-regions"); - if (!regions) { - dev_err(dev, "descriptor-regions not specified\n"); - ret = -ENODEV; - goto err; - } - ret = knav_queue_setup_regions(kdev, regions); - of_node_put(regions); + ret = knav_queue_setup_regions(kdev, node); if (ret) goto err; diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c index 3a56bbf3268a..8169885ab1e0 100644 --- a/drivers/soc/ti/pm33xx.c +++ b/drivers/soc/ti/pm33xx.c @@ -383,54 +383,44 @@ static void am33xx_pm_free_sram(void) */ static int am33xx_pm_alloc_sram(void) { - struct device_node *np; - int ret = 0; + struct device_node *np __free(device_node) = + of_find_compatible_node(NULL, NULL, "ti,omap3-mpu"); - np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu"); if (!np) { np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu"); - if (!np) { - dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n", - __func__); - return -ENODEV; - } + if (!np) + return dev_err_probe(pm33xx_dev, -ENODEV, + "PM: %s: Unable to find device node for mpu\n", + __func__); } sram_pool = of_gen_pool_get(np, "pm-sram", 0); - if (!sram_pool) { - dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n", - __func__); - ret = -ENODEV; - goto mpu_put_node; - } + if (!sram_pool) + return dev_err_probe(pm33xx_dev, -ENODEV, + "PM: %s: Unable to get sram pool for ocmcram\n", + __func__); sram_pool_data = of_gen_pool_get(np, "pm-sram", 1); - if (!sram_pool_data) { - dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n", - __func__); - ret = -ENODEV; - goto mpu_put_node; - } + if (!sram_pool_data) + return dev_err_probe(pm33xx_dev, -ENODEV, + "PM: %s: Unable to get sram data pool for ocmcram\n", + __func__); ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz); - if (!ocmcram_location) { - dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n", - __func__); - ret = -ENOMEM; - goto mpu_put_node; - } + if (!ocmcram_location) + return dev_err_probe(pm33xx_dev, -ENOMEM, + "PM: %s: Unable to allocate memory from ocmcram\n", + __func__); ocmcram_location_data = gen_pool_alloc(sram_pool_data, sizeof(struct emif_regs_amx3)); if (!ocmcram_location_data) { - dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n"); gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz); - ret = -ENOMEM; + return dev_err_probe(pm33xx_dev, -ENOMEM, + "PM: Unable to allocate memory from ocmcram\n"); } -mpu_put_node: - of_node_put(np); - return ret; + return 0; } static int am33xx_pm_rtc_setup(void) diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c index 24a42e0b645c..3ec758f50e24 100644 --- a/drivers/soc/ti/pruss.c +++ b/drivers/soc/ti/pruss.c @@ -380,39 +380,81 @@ put_clk_mux_np: static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node) { - const struct pruss_private_data *data; - struct device_node *clks_np; struct device *dev = pruss->dev; - int ret = 0; - - data = of_device_get_match_data(dev); + struct device_node *clks_np __free(device_node) = + of_get_child_by_name(cfg_node, "clocks"); + const struct pruss_private_data *data = of_device_get_match_data(dev); + int ret; - clks_np = of_get_child_by_name(cfg_node, "clocks"); - if (!clks_np) { - dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node); - return -ENODEV; - } + if (!clks_np) + return dev_err_probe(dev, -ENODEV, + "%pOF is missing its 'clocks' node\n", + cfg_node); if (data && data->has_core_mux_clock) { ret = pruss_clk_mux_setup(pruss, pruss->core_clk_mux, "coreclk-mux", clks_np); - if (ret) { - dev_err(dev, "failed to setup coreclk-mux\n"); - goto put_clks_node; - } + if (ret) + return dev_err_probe(dev, ret, + "failed to setup coreclk-mux\n"); } ret = pruss_clk_mux_setup(pruss, pruss->iep_clk_mux, "iepclk-mux", clks_np); - if (ret) { - dev_err(dev, "failed to setup iepclk-mux\n"); - goto put_clks_node; - } + if (ret) + return dev_err_probe(dev, ret, "failed to setup iepclk-mux\n"); -put_clks_node: - of_node_put(clks_np); + return 0; +} - return ret; +static int pruss_of_setup_memories(struct device *dev, struct pruss *pruss) +{ + struct device_node *np = dev_of_node(dev); + struct device_node *child __free(device_node) = + of_get_child_by_name(np, "memories"); + const struct pruss_private_data *data = of_device_get_match_data(dev); + const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" }; + int i; + + if (!child) + return dev_err_probe(dev, -ENODEV, + "%pOF is missing its 'memories' node\n", + child); + + for (i = 0; i < PRUSS_MEM_MAX; i++) { + struct resource res; + int index; + + /* + * On AM437x one of two PRUSS units don't contain Shared RAM, + * skip it + */ + if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2) + continue; + + index = of_property_match_string(child, "reg-names", + mem_names[i]); + if (index < 0) + return index; + + if (of_address_to_resource(child, index, &res)) + return -EINVAL; + + pruss->mem_regions[i].va = devm_ioremap(dev, res.start, + resource_size(&res)); + if (!pruss->mem_regions[i].va) + return dev_err_probe(dev, -ENOMEM, + "failed to parse and map memory resource %d %s\n", + i, mem_names[i]); + pruss->mem_regions[i].pa = res.start; + pruss->mem_regions[i].size = resource_size(&res); + + dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n", + mem_names[i], &pruss->mem_regions[i].pa, + pruss->mem_regions[i].size, pruss->mem_regions[i].va); + } + + return 0; } static struct regmap_config regmap_conf = { @@ -424,26 +466,21 @@ static struct regmap_config regmap_conf = { static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss) { struct device_node *np = dev_of_node(dev); - struct device_node *child; + struct device_node *child __free(device_node) = + of_get_child_by_name(np, "cfg"); struct resource res; int ret; - child = of_get_child_by_name(np, "cfg"); - if (!child) { - dev_err(dev, "%pOF is missing its 'cfg' node\n", child); - return -ENODEV; - } + if (!child) + return dev_err_probe(dev, -ENODEV, + "%pOF is missing its 'cfg' node\n", child); - if (of_address_to_resource(child, 0, &res)) { - ret = -ENOMEM; - goto node_put; - } + if (of_address_to_resource(child, 0, &res)) + return -ENOMEM; pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); - if (!pruss->cfg_base) { - ret = -ENOMEM; - goto node_put; - } + if (!pruss->cfg_base) + return -ENOMEM; regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child, (u64)res.start); @@ -452,34 +489,22 @@ static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss) pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, ®map_conf); kfree(regmap_conf.name); - if (IS_ERR(pruss->cfg_regmap)) { - dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n", - PTR_ERR(pruss->cfg_regmap)); - ret = PTR_ERR(pruss->cfg_regmap); - goto node_put; - } + if (IS_ERR(pruss->cfg_regmap)) + return dev_err_probe(dev, PTR_ERR(pruss->cfg_regmap), + "regmap_init_mmio failed for cfg\n"); ret = pruss_clk_init(pruss, child); if (ret) - dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); + return dev_err_probe(dev, ret, "pruss_clk_init failed\n"); -node_put: - of_node_put(child); - return ret; + return 0; } static int pruss_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev_of_node(dev); - struct device_node *child; struct pruss *pruss; - struct resource res; - int ret, i, index; - const struct pruss_private_data *data; - const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" }; - - data = of_device_get_match_data(&pdev->dev); + int ret; ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); if (ret) { @@ -494,48 +519,9 @@ static int pruss_probe(struct platform_device *pdev) pruss->dev = dev; mutex_init(&pruss->lock); - child = of_get_child_by_name(np, "memories"); - if (!child) { - dev_err(dev, "%pOF is missing its 'memories' node\n", child); - return -ENODEV; - } - - for (i = 0; i < PRUSS_MEM_MAX; i++) { - /* - * On AM437x one of two PRUSS units don't contain Shared RAM, - * skip it - */ - if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2) - continue; - - index = of_property_match_string(child, "reg-names", - mem_names[i]); - if (index < 0) { - of_node_put(child); - return index; - } - - if (of_address_to_resource(child, index, &res)) { - of_node_put(child); - return -EINVAL; - } - - pruss->mem_regions[i].va = devm_ioremap(dev, res.start, - resource_size(&res)); - if (!pruss->mem_regions[i].va) { - dev_err(dev, "failed to parse and map memory resource %d %s\n", - i, mem_names[i]); - of_node_put(child); - return -ENOMEM; - } - pruss->mem_regions[i].pa = res.start; - pruss->mem_regions[i].size = resource_size(&res); - - dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n", - mem_names[i], &pruss->mem_regions[i].pa, - pruss->mem_regions[i].size, pruss->mem_regions[i].va); - } - of_node_put(child); + ret = pruss_of_setup_memories(dev, pruss); + if (ret < 0) + return ret; platform_set_drvdata(pdev, pruss); |