Unverified Commit b1cd0639 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'ti-driver-soc-for-v6.12' of...

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: default avatarArnd Bergmann <arnd@arndb.de>
parents d205c06a 68123510
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -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,
+5 −17
Original line number Diff line number Diff line
@@ -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))
+53 −52
Original line number Diff line number Diff line
@@ -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",
					   &region->link_index);
		if (ret) {
@@ -1121,10 +1122,9 @@ static int knav_queue_setup_regions(struct knav_device *kdev,
		INIT_LIST_HEAD(&region->pools);
		list_add_tail(&region->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);
	ret = knav_queue_setup_pdsps(kdev, node);
	if (ret)
		goto err;

		ret = knav_queue_start_pdsps(kdev);
		if (ret)
			goto err;
	}
	of_node_put(pdsps);

	/* 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;

+21 −31
Original line number Diff line number Diff line
@@ -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",
		if (!np)
			return dev_err_probe(pm33xx_dev, -ENODEV,
					     "PM: %s: Unable to find device node for mpu\n",
					     __func__);
			return -ENODEV;
		}
	}

	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",
	if (!sram_pool)
		return dev_err_probe(pm33xx_dev, -ENODEV,
				     "PM: %s: Unable to get sram pool for ocmcram\n",
				     __func__);
		ret = -ENODEV;
		goto mpu_put_node;
	}

	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",
	if (!sram_pool_data)
		return dev_err_probe(pm33xx_dev, -ENODEV,
				     "PM: %s: Unable to get sram data pool for ocmcram\n",
				     __func__);
		ret = -ENODEV;
		goto mpu_put_node;
	}

	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",
	if (!ocmcram_location)
		return dev_err_probe(pm33xx_dev, -ENOMEM,
				     "PM: %s: Unable to allocate memory from ocmcram\n",
				     __func__);
		ret = -ENOMEM;
		goto mpu_put_node;
	}

	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)
+81 −95
Original line number Diff line number Diff line
@@ -380,39 +380,81 @@ static int pruss_clk_mux_setup(struct pruss *pruss, struct clk *clk_mux,

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");

	return 0;
}

put_clks_node:
	of_node_put(clks_np);
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);

	return ret;
	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,
						  &regmap_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);