static int exynos_sata_phy_probe(struct platform_device *pdev)
{
	struct exynos_sata_phy *sataphy;
	struct device *dev = &pdev->dev;
	int ret = 0;
	sataphy = devm_kzalloc(dev, sizeof(struct exynos_sata_phy), GFP_KERNEL);
	if (!sataphy) {
		dev_err(dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	sataphy->mmio = of_iomap(dev->of_node, 0);
	if (!sataphy->mmio) {
		dev_err(dev, "failed to remap IO\n");
		return -EADDRNOTAVAIL;
	}

	ret = exynos_sataphy_parse_dt(dev, sataphy);
	if (ret != 0)
		goto err_iomap;

	sataphy->clk = devm_clk_get(dev, "sata_phyctrl");
	if (IS_ERR(sataphy->clk)) {
		dev_err(dev, "failed to get clk for PHY\n");
		ret = PTR_ERR(sataphy->clk);
		goto err_pmu;
	}

	sataphy->phy.init = exynos_sataphy_init;
	sataphy->phy.shutdown = exynos_sataphy_shutdown;
	sataphy->phy.dev = dev;

	ret = sata_add_phy(&sataphy->phy);
	if (ret < 0) {
		dev_err(dev, "PHY not registered with framework\n");
		goto err_iomap;
	}

	ret = i2c_add_driver(&sataphy_i2c_driver);
	if (ret < 0)
		goto err_phy;

	platform_set_drvdata(pdev, sataphy);

	return ret;

 err_phy:
	sata_remove_phy(&sataphy->phy);

 err_pmu:
	iounmap(sataphy->pmureg);

 err_iomap:
	iounmap(sataphy->mmio);

	return ret;
}
static int exynos_sata_phy_remove(struct platform_device *pdev)
{
	struct exynos_sata_phy *sataphy;

	sataphy = platform_get_drvdata(pdev);
	iounmap(sataphy->mmio);
	i2c_del_driver(&sataphy_i2c_driver);
	sata_remove_phy(&sataphy->phy);

	return 0;
}
static int sata_phy_remove(struct platform_device *pdev)
{
	struct sata_phy *phy;
	struct exynos_sata_phy *sataphy;

	phy = platform_get_drvdata(pdev);

	sataphy = (struct exynos_sata_phy *)phy->priv_data;
	sata_remove_phy(phy);

	kfree(sataphy);
	kfree(phy);

	return 0;
}
static int __init sata_phy_probe(struct platform_device *pdev)
{
	struct exynos_sata_phy *sataphy;
	struct sata_phy *phy;
	struct resource *res;
	struct device *dev = &pdev->dev;
	int ret = 0;

	phy = kzalloc(sizeof(struct sata_phy), GFP_KERNEL);
	if (!phy) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		ret = -ENOMEM;
		goto out;
	}

	sataphy = kzalloc(sizeof(struct exynos_sata_phy), GFP_KERNEL);
	if (!sataphy) {
		dev_err(dev, "failed to allocate memory\n");
		ret = -ENOMEM;
		goto err0;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "Could not find IO resource\n");
		ret = -EINVAL;
		goto err1;
	}

	sataphy->mem = devm_request_mem_region(dev, res->start,
					resource_size(res), pdev->name);
	if (!sataphy->mem) {
		dev_err(dev, "Could not request IO resource\n");
		ret = -EINVAL;
		goto err1;
	}

	sataphy->mmio =
	    devm_ioremap(dev, res->start, resource_size(res));
	if (!sataphy->mmio) {
		dev_err(dev, "failed to remap IO\n");
		ret = -ENOMEM;
		goto err2;
	}

	sataphy->clk = devm_clk_get(dev, "sata-phy");
	if (IS_ERR(sataphy->clk)) {
		dev_err(dev, "failed to get clk for PHY\n");
		ret = PTR_ERR(sataphy->clk);
		goto err3;
	}

	phy->init = sataphy_init;
	phy->shutdown = sataphy_shutdown;
	phy->priv_data = (void *)sataphy;
	phy->dev = dev;

	ret = sata_add_phy(phy, SATA_PHY_GENERATION3);
	if (ret < 0)
		goto err4;

	ret = i2c_add_driver(&sataphy_i2c_driver);
	if (ret < 0)
		goto err5;

	platform_set_drvdata(pdev, phy);

	return ret;

 err5:
	sata_remove_phy(phy);

 err4:
	clk_disable(sataphy->clk);
	devm_clk_put(dev, sataphy->clk);

 err3:
	devm_iounmap(dev, sataphy->mmio);

 err2:
	devm_release_mem_region(dev, res->start, resource_size(res));

 err1:
	kfree(sataphy);

 err0:
	kfree(phy);

 out:
	return ret;
}