static int sti_pwm_probe()

in pwm-sti.c [537:647]


static int sti_pwm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sti_pwm_compat_data *cdata;
	struct sti_pwm_chip *pc;
	unsigned int i;
	int irq, ret;

	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
	if (!pc)
		return -ENOMEM;

	cdata = devm_kzalloc(dev, sizeof(*cdata), GFP_KERNEL);
	if (!cdata)
		return -ENOMEM;

	pc->mmio = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(pc->mmio))
		return PTR_ERR(pc->mmio);

	pc->regmap = devm_regmap_init_mmio(dev, pc->mmio,
					   &sti_pwm_regmap_config);
	if (IS_ERR(pc->regmap))
		return PTR_ERR(pc->regmap);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0,
			       pdev->name, pc);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to request IRQ\n");
		return ret;
	}

	/*
	 * Setup PWM data with default values: some values could be replaced
	 * with specific ones provided from Device Tree.
	 */
	cdata->reg_fields = sti_pwm_regfields;
	cdata->max_prescale = 0xff;
	cdata->max_pwm_cnt = 255;
	cdata->pwm_num_devs = 0;
	cdata->cpt_num_devs = 0;

	pc->cdata = cdata;
	pc->dev = dev;
	pc->en_count = 0;
	mutex_init(&pc->sti_pwm_lock);

	ret = sti_pwm_probe_dt(pc);
	if (ret)
		return ret;

	if (cdata->pwm_num_devs) {
		pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm");
		if (IS_ERR(pc->pwm_clk)) {
			dev_err(dev, "failed to get PWM clock\n");
			return PTR_ERR(pc->pwm_clk);
		}

		ret = clk_prepare(pc->pwm_clk);
		if (ret) {
			dev_err(dev, "failed to prepare clock\n");
			return ret;
		}
	}

	if (cdata->cpt_num_devs) {
		pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture");
		if (IS_ERR(pc->cpt_clk)) {
			dev_err(dev, "failed to get PWM capture clock\n");
			return PTR_ERR(pc->cpt_clk);
		}

		ret = clk_prepare(pc->cpt_clk);
		if (ret) {
			dev_err(dev, "failed to prepare clock\n");
			return ret;
		}
	}

	pc->chip.dev = dev;
	pc->chip.ops = &sti_pwm_ops;
	pc->chip.npwm = pc->cdata->pwm_num_devs;

	ret = pwmchip_add(&pc->chip);
	if (ret < 0) {
		clk_unprepare(pc->pwm_clk);
		clk_unprepare(pc->cpt_clk);
		return ret;
	}

	for (i = 0; i < cdata->cpt_num_devs; i++) {
		struct sti_cpt_ddata *ddata;

		ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
		if (!ddata)
			return -ENOMEM;

		init_waitqueue_head(&ddata->wait);
		mutex_init(&ddata->lock);

		pwm_set_chip_data(&pc->chip.pwms[i], ddata);
	}

	platform_set_drvdata(pdev, pc);

	return 0;
}