static int __devinit tdm_fsl_starlite_probe(struct of_device *ofdev,
			      const struct of_device_id *match)
{
	int ret = 0;
	struct tdm_priv *priv;
	struct resource res;

	priv = kmalloc(sizeof(struct tdm_priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	dev_set_drvdata(&ofdev->dev, priv);
	priv->device = &ofdev->dev;

	ret = of_address_to_resource(ofdev->node, 0, &res);
	if (ret) {
		ret = -EINVAL;
		goto err_resource;
	}
	priv->ptdm_base = res.start;

	priv->tdm_regs = of_iomap(ofdev->node, 0);
	if (!priv->tdm_regs) {
		ret = -ENOMEM;
		goto err_tdmregs;
	}

	priv->dmac_regs = of_iomap(ofdev->node, 1);
	if (!priv->dmac_regs) {
		ret = -ENOMEM;
		goto err_dmacreg;
	}

	/* tdmrd tmdtd at immrbar+0x16100 */
	priv->data_regs =
	    (struct tdm_data *)(TDM_DATAREG_OFFSET + (u8 *)priv->tdm_regs);
	/* TDMCLK_DIV_VAL_RX/TX at TDMBASE+0x180 */
	priv->clk_regs =
	    (struct tdm_clock *)(TDM_CLKREG_OFFSET + (u8 *)priv->tdm_regs);

	/* irqs mapping for tdm err/dmac err, dmac done */
	priv->tdm_err_intr = irq_of_parse_and_map(ofdev->node, 0);
	if (priv->tdm_err_intr == NO_IRQ) {
		ret = -EINVAL;
		goto err_tdmerr_irqmap;
	}

	priv->dmac_done_intr = irq_of_parse_and_map(ofdev->node, 1);
	if (priv->dmac_done_intr == NO_IRQ) {
		ret = -EINVAL;
		goto err_dmacdone_irqmap;
	}
	ret =
	    request_irq(priv->tdm_err_intr, tdm_err_isr, 0, "tdm_err_isr",
			priv);
	if (ret)
		goto err_tdmerrisr;

	ret =
	    request_irq(priv->dmac_done_intr, dmac_done_isr, 0, "dmac_done_isr",
			priv);
	if (ret)
		goto err_dmacdoneisr;

	priv->cfg.loopback = e_TDM_PROCESS_NORMAL;
	priv->cfg.num_ch = TDM_ACTIVE_CHANNELS;
	priv->cfg.ch_type = TDM_CHANNEL_TYPE;
	priv->cfg.ch_width = TDM_SLOT_WIDTH;
	priv->cfg.num_frames = NUM_OF_FRAMES;

	priv->adap = &tdm_fsl_starlite_ops;

	/* Wait q initilization */
	priv->adap->tdm_rx_flag = 0;
	/* todo - these should be configured by dts or init time */
	priv->adap->adap_mode = e_TDM_ADAPTER_MODE_NONE;
	priv->adap->tdm_mode = priv->cfg.loopback;

	priv->adap->max_num_ports = priv->cfg.num_ch;

	tdm_set_adapdata(priv->adap, priv);
	priv->adap->parent = &ofdev->dev;

	ret = 0;
	ret = tdm_add_adapter(priv->adap);
	if (ret < 0) {
		dev_err(priv->device, "failed to add adapter\n");
		goto fail_adapter;
	}

	ret = init_tdm(priv);
	if (ret)
		goto err_tdminit;

	ret = tdm_fsl_starlite_reg_init(priv);
	if (ret)
		goto err_tdminit;

	spin_lock_init(&priv->tdmlock);
	spin_lock(&priv->tdmlock);
	priv->tdm_active = 0;
	spin_unlock(&priv->tdmlock);

	if (tdmen) {
		ret = tdm_fsl_starlite_enable(priv->adap);
		if (!ret)
			goto err_tdminit;
	}

	return 0;

err_tdminit:
fail_adapter:
	free_irq(priv->dmac_done_intr, priv);
err_dmacdoneisr:
	free_irq(priv->tdm_err_intr, priv);
err_tdmerrisr:
	irq_dispose_mapping(priv->dmac_done_intr);
err_dmacdone_irqmap:
	irq_dispose_mapping(priv->tdm_err_intr);
err_tdmerr_irqmap:
	iounmap(priv->dmac_regs);
err_dmacreg:
	iounmap(priv->tdm_regs);
err_tdmregs:
err_resource:
	dev_set_drvdata(&ofdev->dev, NULL);
	kfree(priv);
err_alloc:
	return ret;
}
Example #2
0
static int tdm_fsl_probe(struct platform_device *ofdev)
{
	int ret = 0;
	struct tdm_priv *priv;
	struct resource res;

	priv = kzalloc(sizeof(struct tdm_priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	dev_set_drvdata(&ofdev->dev, priv);
	priv->device = &ofdev->dev;
	ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
	if (ret) {
		ret = -EINVAL;
		goto err_resource;
	}

	priv->ptdm_base = (u32)res.start;
	priv->tdm_regs = of_iomap(ofdev->dev.of_node, 0);
	if (!priv->tdm_regs) {
		ret = -ENOMEM;
		goto err_tdmregs;
	}

	priv->dmac_regs = of_iomap(ofdev->dev.of_node, 1);
	if (!priv->dmac_regs) {
		ret = -ENOMEM;
		goto err_dmacreg;
	}

	/* tdmrd tmdtd at immrbar+0x16100 */
	priv->data_regs =
	    (struct tdm_data *)(TDM_DATAREG_OFFSET + (u8 *)priv->tdm_regs);
	/* TDMCLK_DIV_VAL_RX/TX at TDMBASE+0x180 */
	priv->clk_regs =
	    (struct tdm_clock *)(TDM_CLKREG_OFFSET + (u8 *)priv->tdm_regs);

	priv->dmac_done_intr = irq_of_parse_and_map(ofdev->dev.of_node, 0);
	if (priv->dmac_done_intr ==  NO_IRQ) {
		ret = -EINVAL;
		goto err_dmacdone_irqmap;
	}
	ret =
	    request_irq(priv->dmac_done_intr, dmac_done_isr, 0, "dmac_done_isr",
			priv);
	if (ret)
		goto err_dmacdoneisr;


	priv->adap = &tdm_fsl_ops;

	/* Wait q initilization */
	priv->adap->tdm_rx_flag = 0;
	/* todo - these should be configured by dts or init time */
	tdm_set_adapdata(priv->adap, priv);
	priv->adap->parent = &ofdev->dev;

	ret = tdm_add_adapter(priv->adap);
	if (ret < 0) {
		dev_err(priv->device, "failed to add adapter\n");
		goto fail_adapter;
	}


	ret = init_tdm(priv);
	if (ret)
		goto err_tdminit;

	ret = tdm_fsl_reg_init(priv);
	if (ret)
		goto err_tdminit;

	spin_lock_init(&priv->tdmlock);
	spin_lock(&priv->tdmlock);
	priv->tdm_active = 0;
	spin_unlock(&priv->tdmlock);

	if (tdmen) {
		ret = tdm_fsl_enable(priv->adap);
		if (!ret)
			goto err_tdminit;
	}

	return 0;

err_tdminit:
fail_adapter:
	free_irq(priv->dmac_done_intr, priv);
err_dmacdoneisr:
	free_irq(priv->tdm_err_intr, priv);
err_dmacdone_irqmap:
	irq_dispose_mapping(priv->dmac_done_intr);
err_dmacreg:
	iounmap(priv->dmac_regs);
err_tdmregs:
err_resource:
	dev_set_drvdata(&ofdev->dev, NULL);
	kfree(priv);
err_alloc:
	return ret;
}