in rockchip/phy-rockchip-inno-hdmi.c [1143:1247]
static int inno_hdmi_phy_probe(struct platform_device *pdev)
{
struct inno_hdmi_phy *inno;
struct phy_provider *phy_provider;
void __iomem *regs;
int ret;
inno = devm_kzalloc(&pdev->dev, sizeof(*inno), GFP_KERNEL);
if (!inno)
return -ENOMEM;
inno->dev = &pdev->dev;
inno->plat_data = of_device_get_match_data(inno->dev);
if (!inno->plat_data || !inno->plat_data->ops)
return -EINVAL;
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
inno->sysclk = devm_clk_get(inno->dev, "sysclk");
if (IS_ERR(inno->sysclk)) {
ret = PTR_ERR(inno->sysclk);
dev_err(inno->dev, "failed to get sysclk: %d\n", ret);
return ret;
}
inno->refpclk = devm_clk_get(inno->dev, "refpclk");
if (IS_ERR(inno->refpclk)) {
ret = PTR_ERR(inno->refpclk);
dev_err(inno->dev, "failed to get ref clock: %d\n", ret);
return ret;
}
inno->refoclk = devm_clk_get(inno->dev, "refoclk");
if (IS_ERR(inno->refoclk)) {
ret = PTR_ERR(inno->refoclk);
dev_err(inno->dev, "failed to get oscillator-ref clock: %d\n",
ret);
return ret;
}
ret = clk_prepare_enable(inno->sysclk);
if (ret) {
dev_err(inno->dev, "Cannot enable inno phy sysclk: %d\n", ret);
return ret;
}
/*
* Refpclk needs to be on, on at least the rk3328 for still
* unknown reasons.
*/
ret = clk_prepare_enable(inno->refpclk);
if (ret) {
dev_err(inno->dev, "failed to enable refpclk\n");
clk_disable_unprepare(inno->sysclk);
return ret;
}
ret = devm_add_action_or_reset(inno->dev, inno_hdmi_phy_action,
inno);
if (ret)
return ret;
inno->regmap = devm_regmap_init_mmio(inno->dev, regs,
&inno_hdmi_phy_regmap_config);
if (IS_ERR(inno->regmap))
return PTR_ERR(inno->regmap);
/* only the newer rk3328 hdmiphy has an interrupt */
inno->irq = platform_get_irq(pdev, 0);
if (inno->irq > 0) {
ret = devm_request_threaded_irq(inno->dev, inno->irq,
inno_hdmi_phy_rk3328_hardirq,
inno_hdmi_phy_rk3328_irq,
IRQF_SHARED,
dev_name(inno->dev), inno);
if (ret)
return ret;
}
inno->phy = devm_phy_create(inno->dev, NULL, &inno_hdmi_phy_ops);
if (IS_ERR(inno->phy)) {
dev_err(inno->dev, "failed to create HDMI PHY\n");
return PTR_ERR(inno->phy);
}
phy_set_drvdata(inno->phy, inno);
phy_set_bus_width(inno->phy, 8);
if (inno->plat_data->ops->init) {
ret = inno->plat_data->ops->init(inno);
if (ret)
return ret;
}
ret = inno_hdmi_phy_clk_register(inno);
if (ret)
return ret;
phy_provider = devm_of_phy_provider_register(inno->dev,
of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}