in pwm-samsung.c [523:592]
static int pwm_samsung_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct samsung_pwm_chip *chip;
unsigned int chan;
int ret;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->chip.dev = &pdev->dev;
chip->chip.ops = &pwm_samsung_ops;
chip->chip.npwm = SAMSUNG_PWM_NUM;
chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
ret = pwm_samsung_parse_dt(chip);
if (ret)
return ret;
} else {
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "no platform data specified\n");
return -EINVAL;
}
memcpy(&chip->variant, pdev->dev.platform_data,
sizeof(chip->variant));
}
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
chip->base_clk = devm_clk_get(&pdev->dev, "timers");
if (IS_ERR(chip->base_clk)) {
dev_err(dev, "failed to get timer base clk\n");
return PTR_ERR(chip->base_clk);
}
ret = clk_prepare_enable(chip->base_clk);
if (ret < 0) {
dev_err(dev, "failed to enable base clock\n");
return ret;
}
for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
if (chip->variant.output_mask & BIT(chan))
pwm_samsung_set_invert(chip, chan, true);
/* Following clocks are optional. */
chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
platform_set_drvdata(pdev, chip);
ret = pwmchip_add(&chip->chip);
if (ret < 0) {
dev_err(dev, "failed to register PWM chip\n");
clk_disable_unprepare(chip->base_clk);
return ret;
}
dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
clk_get_rate(chip->base_clk),
!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
return 0;
}