Esempio n. 1
0
static int bcm_kona_usb2_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct bcm_kona_usb *phy;
	struct resource *res;
	struct phy *gphy;
	struct phy_provider *phy_provider;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	phy->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(phy->regs))
		return PTR_ERR(phy->regs);

	platform_set_drvdata(pdev, phy);

	gphy = devm_phy_create(dev, NULL, &ops, NULL);
	if (IS_ERR(gphy))
		return PTR_ERR(gphy);

	/* The Kona PHY supports an 8-bit wide UTMI interface */
	phy_set_bus_width(gphy, 8);

	phy_set_drvdata(gphy, phy);

	phy_provider = devm_of_phy_provider_register(dev,
			of_phy_simple_xlate);

	return PTR_ERR_OR_ZERO(phy_provider);
}
Esempio n. 2
0
static int stm32_usbphyc_probe(struct platform_device *pdev)
{
	struct stm32_usbphyc *usbphyc;
	struct device *dev = &pdev->dev;
	struct device_node *child, *np = dev->of_node;
	struct resource *res;
	struct phy_provider *phy_provider;
	u32 version;
	int ret, port = 0;

	usbphyc = devm_kzalloc(dev, sizeof(*usbphyc), GFP_KERNEL);
	if (!usbphyc)
		return -ENOMEM;
	usbphyc->dev = dev;
	dev_set_drvdata(dev, usbphyc);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	usbphyc->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(usbphyc->base))
		return PTR_ERR(usbphyc->base);

	usbphyc->clk = devm_clk_get(dev, 0);
	if (IS_ERR(usbphyc->clk)) {
		ret = PTR_ERR(usbphyc->clk);
		dev_err(dev, "clk get failed: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(usbphyc->clk);
	if (ret) {
		dev_err(dev, "clk enable failed: %d\n", ret);
		return ret;
	}

	usbphyc->rst = devm_reset_control_get(dev, 0);
	if (!IS_ERR(usbphyc->rst)) {
		reset_control_assert(usbphyc->rst);
		udelay(2);
		reset_control_deassert(usbphyc->rst);
	}

	usbphyc->switch_setup = -EINVAL;
	usbphyc->nphys = of_get_child_count(np);
	usbphyc->phys = devm_kcalloc(dev, usbphyc->nphys,
				     sizeof(*usbphyc->phys), GFP_KERNEL);
	if (!usbphyc->phys) {
		ret = -ENOMEM;
		goto clk_disable;
	}

	for_each_child_of_node(np, child) {
		struct stm32_usbphyc_phy *usbphyc_phy;
		struct phy *phy;
		u32 index;
		int i;

		phy = devm_phy_create(dev, child, &stm32_usbphyc_phy_ops);
		if (IS_ERR(phy)) {
			ret = PTR_ERR(phy);
			if (ret != -EPROBE_DEFER)
				dev_err(dev, "failed to create phy%d: %d\n",
					port, ret);
			goto put_child;
		}

		usbphyc_phy = devm_kzalloc(dev, sizeof(*usbphyc_phy),
					   GFP_KERNEL);
		if (!usbphyc_phy) {
			ret = -ENOMEM;
			goto put_child;
		}

		for (i = 0; i < NUM_SUPPLIES; i++)
			usbphyc_phy->supplies[i].supply = supplies_names[i];

		ret = devm_regulator_bulk_get(&phy->dev, NUM_SUPPLIES,
					      usbphyc_phy->supplies);
		if (ret) {
			if (ret != -EPROBE_DEFER)
				dev_err(&phy->dev,
					"failed to get regulators: %d\n", ret);
			goto put_child;
		}

		ret = of_property_read_u32(child, "reg", &index);
		if (ret || index > usbphyc->nphys) {
			dev_err(&phy->dev, "invalid reg property: %d\n", ret);
			goto put_child;
		}

		usbphyc->phys[port] = usbphyc_phy;
		phy_set_bus_width(phy, 8);
		phy_set_drvdata(phy, usbphyc_phy);

		usbphyc->phys[port]->phy = phy;
		usbphyc->phys[port]->usbphyc = usbphyc;
		usbphyc->phys[port]->index = index;
		usbphyc->phys[port]->active = false;

		port++;
	}

	phy_provider = devm_of_phy_provider_register(dev,
						     stm32_usbphyc_of_xlate);
	if (IS_ERR(phy_provider)) {
		ret = PTR_ERR(phy_provider);
		dev_err(dev, "failed to register phy provider: %d\n", ret);
		goto clk_disable;
	}

	version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION);
	dev_info(dev, "registered rev:%lu.%lu\n",
		 FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version));

	return 0;

put_child:
	of_node_put(child);
clk_disable:
	clk_disable_unprepare(usbphyc->clk);

	return ret;
}
Esempio n. 3
0
static int samsung_usb2_phy_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct samsung_usb2_phy_config *cfg;
	struct device *dev = &pdev->dev;
	struct phy_provider *phy_provider;
	struct resource *mem;
	struct samsung_usb2_phy_driver *drv;
	int i, ret;

	if (!pdev->dev.of_node) {
		dev_err(dev, "This driver is required to be instantiated from device tree\n");
		return -EINVAL;
	}

	match = of_match_node(samsung_usb2_phy_of_match, pdev->dev.of_node);
	if (!match) {
		dev_err(dev, "of_match_node() failed\n");
		return -EINVAL;
	}
	cfg = match->data;

	drv = devm_kzalloc(dev, sizeof(struct samsung_usb2_phy_driver) +
		cfg->num_phys * sizeof(struct samsung_usb2_phy_instance),
								GFP_KERNEL);
	if (!drv)
		return -ENOMEM;

	dev_set_drvdata(dev, drv);
	spin_lock_init(&drv->lock);

	drv->cfg = cfg;
	drv->dev = dev;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	drv->reg_phy = devm_ioremap_resource(dev, mem);
	if (IS_ERR(drv->reg_phy)) {
		dev_err(dev, "Failed to map register memory (phy)\n");
		return PTR_ERR(drv->reg_phy);
	}

	drv->reg_pmu = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
		"samsung,pmureg-phandle");
	if (IS_ERR(drv->reg_pmu)) {
		dev_err(dev, "Failed to map PMU registers (via syscon)\n");
		return PTR_ERR(drv->reg_pmu);
	}

	if (drv->cfg->has_mode_switch) {
		drv->reg_sys = syscon_regmap_lookup_by_phandle(
				pdev->dev.of_node, "samsung,sysreg-phandle");
		if (IS_ERR(drv->reg_sys)) {
			dev_err(dev, "Failed to map system registers (via syscon)\n");
			return PTR_ERR(drv->reg_sys);
		}
	}

	drv->clk = devm_clk_get(dev, "phy");
	if (IS_ERR(drv->clk)) {
		dev_err(dev, "Failed to get clock of phy controller\n");
		return PTR_ERR(drv->clk);
	}

	drv->ref_clk = devm_clk_get(dev, "ref");
	if (IS_ERR(drv->ref_clk)) {
		dev_err(dev, "Failed to get reference clock for the phy controller\n");
		return PTR_ERR(drv->ref_clk);
	}

	drv->ref_rate = clk_get_rate(drv->ref_clk);
	if (drv->cfg->rate_to_clk) {
		ret = drv->cfg->rate_to_clk(drv->ref_rate, &drv->ref_reg_val);
		if (ret)
			return ret;
	}

	for (i = 0; i < drv->cfg->num_phys; i++) {
		char *label = drv->cfg->phys[i].label;
		struct samsung_usb2_phy_instance *p = &drv->instances[i];

		dev_dbg(dev, "Creating phy \"%s\"\n", label);
		p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops,
					 NULL);
		if (IS_ERR(p->phy)) {
			dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n",
				label);
			return PTR_ERR(p->phy);
		}

		p->cfg = &drv->cfg->phys[i];
		p->drv = drv;
		phy_set_bus_width(p->phy, 8);
		phy_set_drvdata(p->phy, p);
	}

	phy_provider = devm_of_phy_provider_register(dev,
							samsung_usb2_phy_xlate);
	if (IS_ERR(phy_provider)) {
		dev_err(drv->dev, "Failed to register phy provider\n");
		return PTR_ERR(phy_provider);
	}

	return 0;
}