static int knav_queue_init_qmgrs()

in ti/knav_qmss_queue.c [1391:1491]


static int knav_queue_init_qmgrs(struct knav_device *kdev,
					struct device_node *qmgrs)
{
	struct device *dev = kdev->dev;
	struct knav_qmgr_info *qmgr;
	struct device_node *child;
	u32 temp[2];
	int ret;

	for_each_child_of_node(qmgrs, child) {
		qmgr = devm_kzalloc(dev, sizeof(*qmgr), GFP_KERNEL);
		if (!qmgr) {
			of_node_put(child);
			dev_err(dev, "out of memory allocating qmgr\n");
			return -ENOMEM;
		}

		ret = of_property_read_u32_array(child, "managed-queues",
						 temp, 2);
		if (!ret) {
			qmgr->start_queue = temp[0];
			qmgr->num_queues = temp[1];
		} else {
			dev_err(dev, "invalid qmgr queue range\n");
			devm_kfree(dev, qmgr);
			continue;
		}

		dev_info(dev, "qmgr start queue %d, number of queues %d\n",
			 qmgr->start_queue, qmgr->num_queues);

		qmgr->reg_peek =
			knav_queue_map_reg(kdev, child,
					   KNAV_QUEUE_PEEK_REG_INDEX);

		if (kdev->version == QMSS) {
			qmgr->reg_status =
				knav_queue_map_reg(kdev, child,
						   KNAV_QUEUE_STATUS_REG_INDEX);
		}

		qmgr->reg_config =
			knav_queue_map_reg(kdev, child,
					   (kdev->version == QMSS_66AK2G) ?
					   KNAV_L_QUEUE_CONFIG_REG_INDEX :
					   KNAV_QUEUE_CONFIG_REG_INDEX);
		qmgr->reg_region =
			knav_queue_map_reg(kdev, child,
					   (kdev->version == QMSS_66AK2G) ?
					   KNAV_L_QUEUE_REGION_REG_INDEX :
					   KNAV_QUEUE_REGION_REG_INDEX);

		qmgr->reg_push =
			knav_queue_map_reg(kdev, child,
					   (kdev->version == QMSS_66AK2G) ?
					    KNAV_L_QUEUE_PUSH_REG_INDEX :
					    KNAV_QUEUE_PUSH_REG_INDEX);

		if (kdev->version == QMSS) {
			qmgr->reg_pop =
				knav_queue_map_reg(kdev, child,
						   KNAV_QUEUE_POP_REG_INDEX);
		}

		if (IS_ERR(qmgr->reg_peek) ||
		    ((kdev->version == QMSS) &&
		    (IS_ERR(qmgr->reg_status) || IS_ERR(qmgr->reg_pop))) ||
		    IS_ERR(qmgr->reg_config) || IS_ERR(qmgr->reg_region) ||
		    IS_ERR(qmgr->reg_push)) {
			dev_err(dev, "failed to map qmgr regs\n");
			if (kdev->version == QMSS) {
				if (!IS_ERR(qmgr->reg_status))
					devm_iounmap(dev, qmgr->reg_status);
				if (!IS_ERR(qmgr->reg_pop))
					devm_iounmap(dev, qmgr->reg_pop);
			}
			if (!IS_ERR(qmgr->reg_peek))
				devm_iounmap(dev, qmgr->reg_peek);
			if (!IS_ERR(qmgr->reg_config))
				devm_iounmap(dev, qmgr->reg_config);
			if (!IS_ERR(qmgr->reg_region))
				devm_iounmap(dev, qmgr->reg_region);
			if (!IS_ERR(qmgr->reg_push))
				devm_iounmap(dev, qmgr->reg_push);
			devm_kfree(dev, qmgr);
			continue;
		}

		/* Use same push register for pop as well */
		if (kdev->version == QMSS_66AK2G)
			qmgr->reg_pop = qmgr->reg_push;

		list_add_tail(&qmgr->list, &kdev->qmgrs);
		dev_info(dev, "added qmgr start queue %d, num of queues %d, reg_peek %p, reg_status %p, reg_config %p, reg_region %p, reg_push %p, reg_pop %p\n",
			 qmgr->start_queue, qmgr->num_queues,
			 qmgr->reg_peek, qmgr->reg_status,
			 qmgr->reg_config, qmgr->reg_region,
			 qmgr->reg_push, qmgr->reg_pop);
	}
	return 0;
}