static int intel_cbphy_fwnode_parse()

in intel/phy-intel-lgm-combo.c [406:516]


static int intel_cbphy_fwnode_parse(struct intel_combo_phy *cbphy)
{
	struct device *dev = cbphy->dev;
	struct platform_device *pdev = to_platform_device(dev);
	struct fwnode_handle *fwnode = dev_fwnode(dev);
	struct fwnode_reference_args ref;
	int ret;
	u32 val;

	cbphy->core_clk = devm_clk_get(dev, NULL);
	if (IS_ERR(cbphy->core_clk)) {
		ret = PTR_ERR(cbphy->core_clk);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Get clk failed:%d!\n", ret);
		return ret;
	}

	cbphy->core_rst = devm_reset_control_get_optional(dev, "core");
	if (IS_ERR(cbphy->core_rst)) {
		ret = PTR_ERR(cbphy->core_rst);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Get core reset control err: %d!\n", ret);
		return ret;
	}

	cbphy->phy_rst = devm_reset_control_get_optional(dev, "phy");
	if (IS_ERR(cbphy->phy_rst)) {
		ret = PTR_ERR(cbphy->phy_rst);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Get PHY reset control err: %d!\n", ret);
		return ret;
	}

	cbphy->iphy[0].app_rst = devm_reset_control_get_optional(dev, "iphy0");
	if (IS_ERR(cbphy->iphy[0].app_rst)) {
		ret = PTR_ERR(cbphy->iphy[0].app_rst);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Get phy0 reset control err: %d!\n", ret);
		return ret;
	}

	cbphy->iphy[1].app_rst = devm_reset_control_get_optional(dev, "iphy1");
	if (IS_ERR(cbphy->iphy[1].app_rst)) {
		ret = PTR_ERR(cbphy->iphy[1].app_rst);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Get phy1 reset control err: %d!\n", ret);
		return ret;
	}

	cbphy->app_base = devm_platform_ioremap_resource_byname(pdev, "app");
	if (IS_ERR(cbphy->app_base))
		return PTR_ERR(cbphy->app_base);

	cbphy->cr_base = devm_platform_ioremap_resource_byname(pdev, "core");
	if (IS_ERR(cbphy->cr_base))
		return PTR_ERR(cbphy->cr_base);

	/*
	 * syscfg and hsiocfg variables stores the handle of the registers set
	 * in which ComboPhy subsystem specific registers are subset. Using
	 * Register map framework to access the registers set.
	 */
	ret = fwnode_property_get_reference_args(fwnode, "intel,syscfg", NULL,
						 1, 0, &ref);
	if (ret < 0)
		return ret;

	cbphy->id = ref.args[0];
	cbphy->syscfg = device_node_to_regmap(to_of_node(ref.fwnode));
	fwnode_handle_put(ref.fwnode);

	ret = fwnode_property_get_reference_args(fwnode, "intel,hsio", NULL, 1,
						 0, &ref);
	if (ret < 0)
		return ret;

	cbphy->bid = ref.args[0];
	cbphy->hsiocfg = device_node_to_regmap(to_of_node(ref.fwnode));
	fwnode_handle_put(ref.fwnode);

	ret = fwnode_property_read_u32_array(fwnode, "intel,phy-mode", &val, 1);
	if (ret)
		return ret;

	switch (val) {
	case PHY_TYPE_PCIE:
		cbphy->phy_mode = PHY_PCIE_MODE;
		break;

	case PHY_TYPE_SATA:
		cbphy->phy_mode = PHY_SATA_MODE;
		break;

	case PHY_TYPE_XPCS:
		cbphy->phy_mode = PHY_XPCS_MODE;
		break;

	default:
		dev_err(dev, "Invalid PHY mode: %u\n", val);
		return -EINVAL;
	}

	cbphy->clk_rate = intel_iphy_clk_rates[cbphy->phy_mode];

	if (fwnode_property_present(fwnode, "intel,aggregation"))
		cbphy->aggr_mode = PHY_DL_MODE;
	else
		cbphy->aggr_mode = PHY_SL_MODE;

	return 0;
}