Пример #1
0
static int __init migor_init(void)
{
	int ret;

	ret = clk_register(&siumckb_clk);
	if (ret < 0)
		return ret;

	/* Port number used on this machine: port B */
	migor_snd_device = platform_device_alloc("soc-audio", 1);
	if (!migor_snd_device) {
		ret = -ENOMEM;
		goto epdevalloc;
	}

	platform_set_drvdata(migor_snd_device, &snd_soc_migor);

	ret = platform_device_add(migor_snd_device);
	if (ret)
		goto epdevadd;

	return 0;

epdevadd:
	platform_device_put(migor_snd_device);
epdevalloc:
	clk_unregister(&siumckb_clk);
	return ret;
}
Пример #2
0
static void dw_i2c_acpi_unconfigure(struct platform_device *pdev)
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
	const struct acpi_device_id *id;

	id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
	if (id && id->driver_data)
		clk_unregister(dev->clk);
}
Пример #3
0
void clk_unregister_fixed_factor(struct clk *clk)
{
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	clk_unregister(clk);
	kfree(to_clk_fixed_factor(hw));
}
Пример #4
0
static int fsl_dcu_drm_remove(struct platform_device *pdev)
{
	struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);

	drm_dev_unregister(fsl_dev->drm);
	drm_dev_unref(fsl_dev->drm);
	clk_disable_unprepare(fsl_dev->clk);
	clk_unregister(fsl_dev->pix_clk);

	return 0;
}
Пример #5
0
static int clk_wzrd_remove(struct platform_device *pdev)
{
	int i;
	struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev);

	of_clk_del_provider(pdev->dev.of_node);

	for (i = 0; i < WZRD_NUM_OUTPUTS; i++)
		clk_unregister(clk_wzrd->clkout[i]);
	for (i = 0; i < wzrd_clk_int_max; i++)
		clk_unregister(clk_wzrd->clks_internal[i]);

	if (clk_wzrd->speed_grade) {
		clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb);
		clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb);
	}

	clk_disable_unprepare(clk_wzrd->axi_clk);

	return 0;
}
Пример #6
0
static __exit void realview_clk_exit(void)
{
	u32_t i;

	for(i=0; i< ARRAY_SIZE(realview_clocks); i++)
	{
		if(!clk_unregister(&realview_clocks[i]))
		{
			LOG_E("failed to unregister clock '%s'", realview_clocks[i].name);
		}
	}
}
Пример #7
0
static void __init of_dra7_atl_clock_setup(struct device_node *node)
{
	struct dra7_atl_desc *clk_hw = NULL;
	struct clk_init_data init = { NULL };
	const char **parent_names = NULL;
	struct clk *clk;
	int ret;

	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
	if (!clk_hw) {
		pr_err("%s: could not allocate dra7_atl_desc\n", __func__);
		return;
	}

	clk_hw->hw.init = &init;
	clk_hw->divider = 1;
	init.name = node->name;
	init.ops = &atl_clk_ops;
	init.flags = CLK_IGNORE_UNUSED;
	init.num_parents = of_clk_get_parent_count(node);

	if (init.num_parents != 1) {
		pr_err("%s: atl clock %s must have 1 parent\n", __func__,
		       node->name);
		goto cleanup;
	}

	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);

	if (!parent_names)
		goto cleanup;

	parent_names[0] = of_clk_get_parent_name(node, 0);

	init.parent_names = parent_names;

	clk = ti_clk_register(NULL, &clk_hw->hw, node->name);

	if (!IS_ERR(clk)) {
		ret = ti_clk_add_alias(NULL, clk, node->name);
		if (ret) {
			clk_unregister(clk);
			goto cleanup;
		}
		of_clk_add_provider(node, of_clk_src_simple_get, clk);
		kfree(parent_names);
		return;
	}
cleanup:
	kfree(parent_names);
	kfree(clk_hw);
}
Пример #8
0
void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
					struct clk **clks, u32 num_clks)
{
	of_clk_del_provider(pdev->dev.of_node);

	if (!num_clks || !clks)
		return;

	do {
		clk_unregister(clks[--num_clks]);
		clks[num_clks] = NULL;
	} while (num_clks);
}
Пример #9
0
static int exynos_audss_clk_remove(struct platform_device *pdev)
{
	int i;

	of_clk_del_provider(pdev->dev.of_node);

	for (i = 0; i < clk_data.clk_num; i++) {
		if (!IS_ERR(clk_table[i]))
			clk_unregister(clk_table[i]);
	}

	return 0;
}
void clk_unregister_gate(struct clk *clk)
{
	struct clk_gate *gate;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	gate = to_clk_gate(hw);

	clk_unregister(clk);
	kfree(gate);
}
Пример #11
0
void clk_unregister_composite(struct clk *clk)
{
	struct clk_composite *composite;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	composite = to_clk_composite(hw);

	clk_unregister(clk);
	kfree(composite);
}
Пример #12
0
static void kona_clk_teardown(struct clk *clk)
{
	struct clk_hw *hw;
	struct kona_clk *bcm_clk;

	if (!clk)
		return;

	hw = __clk_get_hw(clk);
	if (!hw) {
		pr_err("%s: clk %p has null hw pointer\n", __func__, clk);
		return;
	}
	clk_unregister(clk);

	bcm_clk = to_kona_clk(hw);
	bcm_clk_teardown(bcm_clk);
}
Пример #13
0
bool_t clk_fixed_factor_unregister(struct clk_fixed_factor_t * fclk)
{
	struct clk_t * clk;

	if(!fclk || !fclk->name)
		return FALSE;

	clk = clk_search(fclk->name);
	if(!clk)
		return FALSE;

	if(clk_unregister(clk))
	{
		free(clk);
		return TRUE;
	}

	return FALSE;
}
Пример #14
0
bool_t clk_pll_unregister(struct clk_pll_t * pclk)
{
	struct clk_t * clk;

	if(!pclk || !pclk->name)
		return FALSE;

	clk = clk_search(pclk->name);
	if(!clk)
		return FALSE;

	if(clk_unregister(clk))
	{
		free(clk);
		return TRUE;
	}

	return FALSE;
}
Пример #15
0
bool_t clk_mux_unregister(struct clk_mux_t * mclk)
{
	struct clk_t * clk;

	if(!mclk || !mclk->name)
		return FALSE;

	clk = clk_search(mclk->name);
	if(!clk)
		return FALSE;

	if(clk_unregister(clk))
	{
		free(clk);
		return TRUE;
	}

	return FALSE;
}
Пример #16
0
bool_t clk_gate_unregister(struct clk_gate_t * gclk)
{
	struct clk_t * clk;

	if(!gclk || !gclk->name)
		return FALSE;

	clk = clk_search(gclk->name);
	if(!clk)
		return FALSE;

	if(clk_unregister(clk))
	{
		free(clk);
		return TRUE;
	}

	return FALSE;
}
Пример #17
0
static int fsl_dcu_drm_probe(struct platform_device *pdev)
{
	struct fsl_dcu_drm_device *fsl_dev;
	struct drm_device *drm;
	struct device *dev = &pdev->dev;
	struct resource *res;
	void __iomem *base;
	struct drm_driver *driver = &fsl_dcu_drm_driver;
	struct clk *pix_clk_in;
	char pix_clk_name[32];
	const char *pix_clk_in_name;
	const struct of_device_id *id;
	int ret;
	u8 div_ratio_shift = 0;

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

	id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
	if (!id)
		return -ENODEV;
	fsl_dev->soc = id->data;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base)) {
		ret = PTR_ERR(base);
		return ret;
	}

	fsl_dev->irq = platform_get_irq(pdev, 0);
	if (fsl_dev->irq < 0) {
		dev_err(dev, "failed to get irq\n");
		return fsl_dev->irq;
	}

	fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
			&fsl_dcu_regmap_config);
	if (IS_ERR(fsl_dev->regmap)) {
		dev_err(dev, "regmap init failed\n");
		return PTR_ERR(fsl_dev->regmap);
	}

	fsl_dev->clk = devm_clk_get(dev, "dcu");
	if (IS_ERR(fsl_dev->clk)) {
		dev_err(dev, "failed to get dcu clock\n");
		return PTR_ERR(fsl_dev->clk);
	}
	ret = clk_prepare_enable(fsl_dev->clk);
	if (ret < 0) {
		dev_err(dev, "failed to enable dcu clk\n");
		return ret;
	}

	pix_clk_in = devm_clk_get(dev, "pix");
	if (IS_ERR(pix_clk_in)) {
		/* legancy binding, use dcu clock as pixel clock input */
		pix_clk_in = fsl_dev->clk;
	}

	if (of_property_read_bool(dev->of_node, "big-endian"))
		div_ratio_shift = 24;

	pix_clk_in_name = __clk_get_name(pix_clk_in);
	snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
	fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
			pix_clk_in_name, 0, base + DCU_DIV_RATIO,
			div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
	if (IS_ERR(fsl_dev->pix_clk)) {
		dev_err(dev, "failed to register pix clk\n");
		ret = PTR_ERR(fsl_dev->pix_clk);
		goto disable_clk;
	}

	fsl_dev->tcon = fsl_tcon_init(dev);

	drm = drm_dev_alloc(driver, dev);
	if (IS_ERR(drm)) {
		ret = PTR_ERR(drm);
		goto unregister_pix_clk;
	}

	fsl_dev->dev = dev;
	fsl_dev->drm = drm;
	fsl_dev->np = dev->of_node;
	drm->dev_private = fsl_dev;
	dev_set_drvdata(dev, fsl_dev);

	ret = drm_dev_register(drm, 0);
	if (ret < 0)
		goto unref;

	return 0;

unref:
	drm_dev_unref(drm);
unregister_pix_clk:
	clk_unregister(fsl_dev->pix_clk);
disable_clk:
	clk_disable_unprepare(fsl_dev->clk);
	return ret;
}
Пример #18
0
static int clk_wzrd_probe(struct platform_device *pdev)
{
	int i, ret;
	u32 reg;
	unsigned long rate;
	const char *clk_name;
	struct clk_wzrd *clk_wzrd;
	struct resource *mem;
	struct device_node *np = pdev->dev.of_node;

	clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL);
	if (!clk_wzrd)
		return -ENOMEM;
	platform_set_drvdata(pdev, clk_wzrd);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	clk_wzrd->base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(clk_wzrd->base))
		return PTR_ERR(clk_wzrd->base);

	ret = of_property_read_u32(np, "speed-grade", &clk_wzrd->speed_grade);
	if (!ret) {
		if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) {
			dev_warn(&pdev->dev, "invalid speed grade '%d'\n",
				 clk_wzrd->speed_grade);
			clk_wzrd->speed_grade = 0;
		}
	}

	clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
	if (IS_ERR(clk_wzrd->clk_in1)) {
		if (clk_wzrd->clk_in1 != ERR_PTR(-EPROBE_DEFER))
			dev_err(&pdev->dev, "clk_in1 not found\n");
		return PTR_ERR(clk_wzrd->clk_in1);
	}

	clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
	if (IS_ERR(clk_wzrd->axi_clk)) {
		if (clk_wzrd->axi_clk != ERR_PTR(-EPROBE_DEFER))
			dev_err(&pdev->dev, "s_axi_aclk not found\n");
		return PTR_ERR(clk_wzrd->axi_clk);
	}
	ret = clk_prepare_enable(clk_wzrd->axi_clk);
	if (ret) {
		dev_err(&pdev->dev, "enabling s_axi_aclk failed\n");
		return ret;
	}
	rate = clk_get_rate(clk_wzrd->axi_clk);
	if (rate > WZRD_ACLK_MAX_FREQ) {
		dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n",
			rate);
		ret = -EINVAL;
		goto err_disable_clk;
	}

	/* we don't support fractional div/mul yet */
	reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
		    WZRD_CLKFBOUT_FRAC_EN;
	reg |= readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2)) &
		     WZRD_CLKOUT0_FRAC_EN;
	if (reg)
		dev_warn(&pdev->dev, "fractional div/mul not supported\n");

	/* register multiplier */
	reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
		     WZRD_CLKFBOUT_MULT_MASK) >> WZRD_CLKFBOUT_MULT_SHIFT;
	clk_name = kasprintf(GFP_KERNEL, "%s_mul", dev_name(&pdev->dev));
	if (!clk_name) {
		ret = -ENOMEM;
		goto err_disable_clk;
	}
	clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor(
			&pdev->dev, clk_name,
			__clk_get_name(clk_wzrd->clk_in1),
			0, reg, 1);
	kfree(clk_name);
	if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) {
		dev_err(&pdev->dev, "unable to register fixed-factor clock\n");
		ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]);
		goto err_disable_clk;
	}

	/* register div */
	reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
			WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
	clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev));
	if (!clk_name) {
		ret = -ENOMEM;
		goto err_rm_int_clk;
	}

	clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor(
			&pdev->dev, clk_name,
			__clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
			0, 1, reg);
	if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
		dev_err(&pdev->dev, "unable to register divider clock\n");
		ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
		goto err_rm_int_clk;
	}

	/* register div per output */
	for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
		const char *clkout_name;

		if (of_property_read_string_index(np, "clock-output-names", i,
						  &clkout_name)) {
			dev_err(&pdev->dev,
				"clock output name not specified\n");
			ret = -EINVAL;
			goto err_rm_int_clks;
		}
		reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2) + i * 12);
		reg &= WZRD_CLKOUT_DIVIDE_MASK;
		reg >>= WZRD_CLKOUT_DIVIDE_SHIFT;
		clk_wzrd->clkout[i] = clk_register_fixed_factor(&pdev->dev,
				clkout_name, clk_name, 0, 1, reg);
		if (IS_ERR(clk_wzrd->clkout[i])) {
			int j;

			for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++)
				clk_unregister(clk_wzrd->clkout[j]);
			dev_err(&pdev->dev,
				"unable to register divider clock\n");
			ret = PTR_ERR(clk_wzrd->clkout[i]);
			goto err_rm_int_clks;
		}
	}

	kfree(clk_name);

	clk_wzrd->clk_data.clks = clk_wzrd->clkout;
	clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout);
	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data);

	if (clk_wzrd->speed_grade) {
		clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier;

		ret = clk_notifier_register(clk_wzrd->clk_in1,
					    &clk_wzrd->nb);
		if (ret)
			dev_warn(&pdev->dev,
				 "unable to register clock notifier\n");

		ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb);
		if (ret)
			dev_warn(&pdev->dev,
				 "unable to register clock notifier\n");
	}

	return 0;

err_rm_int_clks:
	clk_unregister(clk_wzrd->clks_internal[1]);
err_rm_int_clk:
	kfree(clk_name);
	clk_unregister(clk_wzrd->clks_internal[0]);
err_disable_clk:
	clk_disable_unprepare(clk_wzrd->axi_clk);

	return ret;
}
static void __init sun8i_a23_mbus_setup(struct device_node *node)
{
	int num_parents = of_clk_get_parent_count(node);
	const char **parents;
	const char *clk_name = node->name;
	struct resource res;
	struct clk_divider *div;
	struct clk_gate *gate;
	struct clk_mux *mux;
	struct clk *clk;
	void __iomem *reg;
	int err;

	parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL);
	if (!parents)
		return;

	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(reg)) {
		pr_err("Could not get registers for sun8i-mbus-clk\n");
		goto err_free_parents;
	}

	div = kzalloc(sizeof(*div), GFP_KERNEL);
	if (!div)
		goto err_unmap;

	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
	if (!mux)
		goto err_free_div;

	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
	if (!gate)
		goto err_free_mux;

	of_property_read_string(node, "clock-output-names", &clk_name);
	of_clk_parent_fill(node, parents, num_parents);

	gate->reg = reg;
	gate->bit_idx = SUN8I_MBUS_ENABLE;
	gate->lock = &sun8i_a23_mbus_lock;

	div->reg = reg;
	div->shift = SUN8I_MBUS_DIV_SHIFT;
	div->width = SUN8I_MBUS_DIV_WIDTH;
	div->lock = &sun8i_a23_mbus_lock;

	mux->reg = reg;
	mux->shift = SUN8I_MBUS_MUX_SHIFT;
	mux->mask = SUN8I_MBUS_MUX_MASK;
	mux->lock = &sun8i_a23_mbus_lock;

	clk = clk_register_composite(NULL, clk_name, parents, num_parents,
				     &mux->hw, &clk_mux_ops,
				     &div->hw, &clk_divider_ops,
				     &gate->hw, &clk_gate_ops,
				     0);
	if (IS_ERR(clk))
		goto err_free_gate;

	err = of_clk_add_provider(node, of_clk_src_simple_get, clk);
	if (err)
		goto err_unregister_clk;

	kfree(parents); /* parents is deep copied */
	/* The MBUS clocks needs to be always enabled */
	__clk_get(clk);
	clk_prepare_enable(clk);

	return;

err_unregister_clk:
	/* TODO: The composite clock stuff will leak a bit here. */
	clk_unregister(clk);
err_free_gate:
	kfree(gate);
err_free_mux:
	kfree(mux);
err_free_div:
	kfree(div);
err_unmap:
	iounmap(reg);
	of_address_to_resource(node, 0, &res);
	release_mem_region(res.start, resource_size(&res));
err_free_parents:
	kfree(parents);
}
Пример #20
0
/* register exynos_audss clocks */
static int exynos_audss_clk_probe(struct platform_device *pdev)
{
	int i, ret = 0;
	struct resource *res;
	const char *mout_audss_p[] = {"fin_pll", "fout_epll"};
	const char *mout_i2s_p[] = {"mout_audss", "cdclk0", "sclk_audio0"};
	const char *sclk_pcm_p = "sclk_pcm0";
	struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
	const struct of_device_id *match;
	enum exynos_audss_clk_type variant;

	match = of_match_node(exynos_audss_clk_of_match, pdev->dev.of_node);
	if (!match)
		return -EINVAL;
	variant = (enum exynos_audss_clk_type)match->data;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(reg_base)) {
		dev_err(&pdev->dev, "failed to map audss registers\n");
		return PTR_ERR(reg_base);
	}

	clk_table = devm_kzalloc(&pdev->dev,
				sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
				GFP_KERNEL);
	if (!clk_table)
		return -ENOMEM;

	clk_data.clks = clk_table;
	if (variant == TYPE_EXYNOS5420)
		clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
	else
		clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS - 1;

	pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
	pll_in = devm_clk_get(&pdev->dev, "pll_in");
	if (!IS_ERR(pll_ref))
		mout_audss_p[0] = __clk_get_name(pll_ref);
	if (!IS_ERR(pll_in))
		mout_audss_p[1] = __clk_get_name(pll_in);
	clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
				mout_audss_p, ARRAY_SIZE(mout_audss_p),
				CLK_SET_RATE_NO_REPARENT,
				reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);

	cdclk = devm_clk_get(&pdev->dev, "cdclk");
	sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio");
	if (!IS_ERR(cdclk))
		mout_i2s_p[1] = __clk_get_name(cdclk);
	if (!IS_ERR(sclk_audio))
		mout_i2s_p[2] = __clk_get_name(sclk_audio);
	clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
				mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
				CLK_SET_RATE_NO_REPARENT,
				reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);

	clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
				"mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
				0, &lock);

	clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL,
				"dout_aud_bus", "dout_srp", 0,
				reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);

	clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s",
				"mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
				&lock);

	clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk",
				"dout_srp", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 0, 0, &lock);

	clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus",
				"dout_aud_bus", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 2, 0, &lock);

	clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s",
				"dout_i2s", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 3, 0, &lock);

	clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus",
				 "sclk_pcm", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 4, 0, &lock);

	sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in");
	if (!IS_ERR(sclk_pcm_in))
		sclk_pcm_p = __clk_get_name(sclk_pcm_in);
	clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm",
				sclk_pcm_p, CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 5, 0, &lock);

	if (variant == TYPE_EXYNOS5420) {
		clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma",
				"dout_srp", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 9, 0, &lock);
	}

	for (i = 0; i < clk_data.clk_num; i++) {
		if (IS_ERR(clk_table[i])) {
			dev_err(&pdev->dev, "failed to register clock %d\n", i);
			ret = PTR_ERR(clk_table[i]);
			goto unregister;
		}
	}

	ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
					&clk_data);
	if (ret) {
		dev_err(&pdev->dev, "failed to add clock provider\n");
		goto unregister;
	}

#ifdef CONFIG_PM_SLEEP
	register_syscore_ops(&exynos_audss_clk_syscore_ops);
#endif

	dev_info(&pdev->dev, "setup completed\n");

	return 0;

unregister:
	for (i = 0; i < clk_data.clk_num; i++) {
		if (!IS_ERR(clk_table[i]))
			clk_unregister(clk_table[i]);
	}

	return ret;
}
void __exit csi_cleanup_module(void)
{
	clk_disable(&csi_mclk);
	clk_unregister(&csi_mclk);
}
Пример #22
0
static int fsl_dcu_drm_probe(struct platform_device *pdev)
{
	struct fsl_dcu_drm_device *fsl_dev;
	struct drm_device *drm;
	struct device *dev = &pdev->dev;
	struct resource *res;
	void __iomem *base;
	struct drm_driver *driver = &fsl_dcu_drm_driver;
	struct clk *pix_clk_in;
	char pix_clk_name[32];
	const char *pix_clk_in_name;
	const struct of_device_id *id;
	int ret;

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

	id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
	if (!id)
		return -ENODEV;
	fsl_dev->soc = id->data;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "could not get memory IO resource\n");
		return -ENODEV;
	}

	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base)) {
		ret = PTR_ERR(base);
		return ret;
	}

	fsl_dev->irq = platform_get_irq(pdev, 0);
	if (fsl_dev->irq < 0) {
		dev_err(dev, "failed to get irq\n");
		return -ENXIO;
	}

	fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
			&fsl_dcu_regmap_config);
	if (IS_ERR(fsl_dev->regmap)) {
		dev_err(dev, "regmap init failed\n");
		return PTR_ERR(fsl_dev->regmap);
	}

	fsl_dev->clk = devm_clk_get(dev, "dcu");
	if (IS_ERR(fsl_dev->clk)) {
		dev_err(dev, "failed to get dcu clock\n");
		return PTR_ERR(fsl_dev->clk);
	}
	ret = clk_prepare_enable(fsl_dev->clk);
	if (ret < 0) {
		dev_err(dev, "failed to enable dcu clk\n");
		return ret;
	}

	pix_clk_in = devm_clk_get(dev, "pix");
	if (IS_ERR(pix_clk_in)) {
		/* legancy binding, use dcu clock as pixel clock input */
		pix_clk_in = fsl_dev->clk;
	}

	pix_clk_in_name = __clk_get_name(pix_clk_in);
	snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
	fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
			pix_clk_in_name, 0, base + DCU_DIV_RATIO,
			0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
	if (IS_ERR(fsl_dev->pix_clk)) {
		dev_err(dev, "failed to register pix clk\n");
		ret = PTR_ERR(fsl_dev->pix_clk);
		goto disable_clk;
	}

	ret = clk_prepare_enable(fsl_dev->pix_clk);
	if (ret < 0) {
		dev_err(dev, "failed to enable pix clk\n");
		goto unregister_pix_clk;
	}

	fsl_dev->tcon = fsl_tcon_init(dev);

	drm = drm_dev_alloc(driver, dev);
	if (!drm) {
		ret = -ENOMEM;
		goto disable_pix_clk;
	}

	fsl_dev->dev = dev;
	fsl_dev->drm = drm;
	fsl_dev->np = dev->of_node;
	drm->dev_private = fsl_dev;
	dev_set_drvdata(dev, fsl_dev);

	ret = drm_dev_register(drm, 0);
	if (ret < 0)
		goto unref;

	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name,
		 driver->major, driver->minor, driver->patchlevel,
		 driver->date, drm->primary->index);

	return 0;

unref:
	drm_dev_unref(drm);
disable_pix_clk:
	clk_disable_unprepare(fsl_dev->pix_clk);
unregister_pix_clk:
	clk_unregister(fsl_dev->pix_clk);
disable_clk:
	clk_disable_unprepare(fsl_dev->clk);
	return ret;
}
Пример #23
0
static void __exit migor_exit(void)
{
	clk_unregister(&siumckb_clk);
	platform_device_unregister(migor_snd_device);
}