static int fsl_qman_probe()

in fsl/qbman/qman_ccsr.c [752:899]


static int fsl_qman_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct resource *res;
	int ret, err_irq;
	u16 id;
	u8 major, minor;

	__qman_probed = -1;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
			node);
		return -ENXIO;
	}
	qm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
	if (!qm_ccsr_start)
		return -ENXIO;

	qm_get_version(&id, &major, &minor);
	if (major == 1 && minor == 0) {
		dev_err(dev, "Rev1.0 on P4080 rev1 is not supported!\n");
			return -ENODEV;
	} else if (major == 1 && minor == 1)
		qman_ip_rev = QMAN_REV11;
	else if	(major == 1 && minor == 2)
		qman_ip_rev = QMAN_REV12;
	else if (major == 2 && minor == 0)
		qman_ip_rev = QMAN_REV20;
	else if (major == 3 && minor == 0)
		qman_ip_rev = QMAN_REV30;
	else if (major == 3 && minor == 1)
		qman_ip_rev = QMAN_REV31;
	else if (major == 3 && minor == 2)
		qman_ip_rev = QMAN_REV32;
	else {
		dev_err(dev, "Unknown QMan version\n");
		return -ENODEV;
	}

	if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
		qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
		qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
	}

	if (fqd_a) {
#ifdef CONFIG_PPC
		/*
		 * For PPC backward DT compatibility
		 * FQD memory MUST be zero'd by software
		 */
		zero_priv_mem(fqd_a, fqd_sz);
#else
		WARN(1, "Unexpected architecture using non shared-dma-mem reservations");
#endif
	} else {
		/*
		 * Order of memory regions is assumed as FQD followed by PFDR
		 * in order to ensure allocations from the correct regions the
		 * driver initializes then allocates each piece in order
		 */
		ret = qbman_init_private_mem(dev, 0, &fqd_a, &fqd_sz);
		if (ret) {
			dev_err(dev, "qbman_init_private_mem() for FQD failed 0x%x\n",
				ret);
			return -ENODEV;
		}
	}
	dev_dbg(dev, "Allocated FQD 0x%llx 0x%zx\n", fqd_a, fqd_sz);

	if (!pfdr_a) {
		/* Setup PFDR memory */
		ret = qbman_init_private_mem(dev, 1, &pfdr_a, &pfdr_sz);
		if (ret) {
			dev_err(dev, "qbman_init_private_mem() for PFDR failed 0x%x\n",
				ret);
			return -ENODEV;
		}
	}
	dev_dbg(dev, "Allocated PFDR 0x%llx 0x%zx\n", pfdr_a, pfdr_sz);

	ret = qman_init_ccsr(dev);
	if (ret) {
		dev_err(dev, "CCSR setup failed\n");
		return ret;
	}

	err_irq = platform_get_irq(pdev, 0);
	if (err_irq <= 0) {
		dev_info(dev, "Can't get %pOF property 'interrupts'\n",
			 node);
		return -ENODEV;
	}
	ret = devm_request_irq(dev, err_irq, qman_isr, IRQF_SHARED, "qman-err",
			       dev);
	if (ret)  {
		dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
			ret, node);
		return ret;
	}

	/*
	 * Write-to-clear any stale bits, (eg. starvation being asserted prior
	 * to resource allocation during driver init).
	 */
	qm_ccsr_out(REG_ERR_ISR, 0xffffffff);
	/* Enable Error Interrupts */
	qm_ccsr_out(REG_ERR_IER, 0xffffffff);

	qm_fqalloc = devm_gen_pool_create(dev, 0, -1, "qman-fqalloc");
	if (IS_ERR(qm_fqalloc)) {
		ret = PTR_ERR(qm_fqalloc);
		dev_err(dev, "qman-fqalloc pool init failed (%d)\n", ret);
		return ret;
	}

	qm_qpalloc = devm_gen_pool_create(dev, 0, -1, "qman-qpalloc");
	if (IS_ERR(qm_qpalloc)) {
		ret = PTR_ERR(qm_qpalloc);
		dev_err(dev, "qman-qpalloc pool init failed (%d)\n", ret);
		return ret;
	}

	qm_cgralloc = devm_gen_pool_create(dev, 0, -1, "qman-cgralloc");
	if (IS_ERR(qm_cgralloc)) {
		ret = PTR_ERR(qm_cgralloc);
		dev_err(dev, "qman-cgralloc pool init failed (%d)\n", ret);
		return ret;
	}

	ret = qman_resource_init(dev);
	if (ret)
		return ret;

	ret = qman_alloc_fq_table(qm_get_fqid_maxcnt());
	if (ret)
		return ret;

	ret = qman_wq_alloc();
	if (ret)
		return ret;

	__qman_probed = 1;

	return 0;
}