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;
}