示例#1
0
static int da8xx_rproc_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rproc *rproc = platform_get_drvdata(pdev);
	struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv;

	/*
	 * It's important to place the DSP in reset before going away,
	 * since a subsequent insmod of this module may enable the DSP's
	 * clock before its program/boot-address has been loaded and
	 * before this module's probe has had a chance to reset the DSP.
	 * Without the reset, the DSP can lockup permanently when it
	 * begins executing garbage.
	 */
	reset_assert(dev);

	/*
	 * The devm subsystem might end up releasing things before
	 * freeing the irq, thus allowing an interrupt to sneak in while
	 * the device is being removed.  This should prevent that.
	 */
	disable_irq(drproc->irq);

	devm_clk_put(dev, drproc->dsp_clk);

	rproc_del(rproc);
	rproc_put(rproc);

	return 0;
}
static int hi6401_irq_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct hi6401_irq *irq = platform_get_drvdata(pdev);

	if(irq->pll_delay_wq) {
		cancel_delayed_work(&irq->pll_delay_work);
		flush_workqueue(irq->pll_delay_wq);
		destroy_workqueue(irq->pll_delay_wq);
	}
	if(irq->hi6401_irq_delay_wq) {
		cancel_delayed_work(&irq->hi6401_irq_delay_work);
		flush_workqueue(irq->hi6401_irq_delay_wq);
		destroy_workqueue(irq->hi6401_irq_delay_wq);
	}
	free_irq(irq->irq, irq);
	gpio_free(irq->gpio);

	clk_disable_unprepare(irq->pmu_audio_clk);
	devm_clk_put(dev, irq->pmu_audio_clk);
	clk_disable_unprepare(irq->codec_ssi_clk);
	devm_clk_put(dev, irq->codec_ssi_clk);
	codec_ssi_iomux_idle(irq->pctrl);
	pinctrl_put(irq->pctrl);

	devm_iounmap(dev, irq->reg_base_addr);
	devm_release_mem_region(dev, irq->res->start,
				resource_size(irq->res));
	devm_kfree(dev, irq);
	platform_set_drvdata(pdev, NULL);
	if (g_dump_buf)
	{
		kfree(g_dump_buf);
		g_dump_buf = NULL;
	}

	return 0;
}
示例#3
0
static int uart_clps711x_remove(struct platform_device *pdev)
{
	struct clps711x_port *s = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < UART_CLPS711X_NR; i++)
		uart_remove_one_port(&s->uart, &s->port[i]);

	devm_clk_put(&pdev->dev, s->uart_clk);
	uart_unregister_driver(&s->uart);
	platform_set_drvdata(pdev, NULL);

	return 0;
}
/*************************************************
Function:       bluetooth_power_probe
Description:    bluetooth power driver probe function
Calls:          bluetooth_power_rfkill_probe
Input:          platform_device *pdev
Output:         
Return:         int ret
Others:         NA
*************************************************/
static int bluetooth_power_probe(struct platform_device *pdev){
	struct device *bluetooth_power_dev = &pdev->dev;
	struct device_node *np = bluetooth_power_dev->of_node;
	struct bluetooth_power_private_data *pdev_bluetooth_power_data = NULL;
	int ret;

	pdev_bluetooth_power_data = devm_kzalloc(bluetooth_power_dev, sizeof(struct bluetooth_power_private_data), GFP_KERNEL);
	if ( pdev_bluetooth_power_data == NULL ) {
		dev_err(bluetooth_power_dev, "failed to allocate bluetooth_power_private_data\n");
		return -ENOMEM;
	}

	printk(KERN_INFO "bluetooth_power probe in \n");

	of_property_read_u32(np, "huawei,bt_en", &(pdev_bluetooth_power_data->gpio_enable.gpio));

	of_property_read_u32(np, "huawei,bt_wake_host", &(pdev_bluetooth_power_data->gpio_bt_wake_host.gpio));

	of_property_read_u32(np, "huawei,host_wake_bt", &(pdev_bluetooth_power_data->gpio_host_wake_bt.gpio));

	printk(KERN_INFO "devm clk get \n");

	pdev_bluetooth_power_data->clk = devm_clk_get(bluetooth_power_dev, NULL);
	printk(KERN_INFO "clk is 0x%x\n", (int)pdev_bluetooth_power_data->clk);
	if (IS_ERR( pdev_bluetooth_power_data->clk)) {
		printk(KERN_INFO "Get bt 32k clk failed\n");
		ret = PTR_ERR( pdev_bluetooth_power_data->clk );
		goto err_free_clk_ret;
	}

	/*printk(KERN_INFO "regulator_get in\n");
	pdev_bluetooth_power_data->vdd = regulator_get(bluetooth_power_dev,"huawei,bt_power");   // regulator is ldo14
	if (IS_ERR( pdev_bluetooth_power_data->vdd )) {
		printk(KERN_INFO "bt regulator_get failed\n");
		pdev_bluetooth_power_data->vdd = NULL;
		ret	= -ENOMEM;
		goto err_free_clk_ret; // free memory
	}
	printk(KERN_INFO "regulator_get out\n");*/

	ret	= gpio_request( pdev_bluetooth_power_data->gpio_enable.gpio , "bt_gpio_enable" );
	if (ret < 0) {
		pr_err("%s: gpio_request %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_enable.gpio ,ret);
		goto err_free_clk_ret;
	}

	ret	= gpio_request( pdev_bluetooth_power_data->gpio_host_wake_bt.gpio , "host_wake_bt" );
	if (ret < 0) {
		pr_err("%s: gpio_request %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_host_wake_bt.gpio ,ret);
		goto err_free_clk_ret;
	}

	ret	= gpio_request( pdev_bluetooth_power_data->gpio_bt_wake_host.gpio , "bt_wake_host" );
	if (ret < 0) {
		pr_err("%s: gpio_request %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_bt_wake_host.gpio ,ret);
		goto err_free_clk_ret;
	}

	ret	= gpio_direction_output( pdev_bluetooth_power_data->gpio_enable.gpio , 0);
	if (ret < 0) {
		pr_err("%s: gpio_direction_output %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_enable.gpio ,ret);
		goto err_free_clk_ret;
	}

	ret	= gpio_direction_output( pdev_bluetooth_power_data->gpio_host_wake_bt.gpio , 0);
	if (ret < 0) {
		pr_err("%s: gpio_direction_output %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_host_wake_bt.gpio ,ret);
		goto err_free_clk_ret;
	}

	ret	= gpio_direction_input( pdev_bluetooth_power_data->gpio_bt_wake_host.gpio);
	if (ret < 0) {
		pr_err("%s: gpio_direction_output %d  failed, ret:%d .\n", __func__, pdev_bluetooth_power_data->gpio_bt_wake_host.gpio ,ret);
		goto err_free_clk_ret;
	}

	/* set bluetooth vddio voltage to 1.8V */
	/*printk(KERN_INFO "regulator_set_voltage in\n");
	ret	= regulator_set_voltage( pdev_bluetooth_power_data->vdd, BT_VDDIO_LDO_18V, BT_VDDIO_LDO_18V );
	printk(KERN_INFO "regulator_set_voltage out\n");
	if (ret) {
		dev_err(&pdev->dev,	"%s: bluetooth regulator_set_voltage err %d\n", __func__, ret);
		goto err_free_clk_ret;
	}*/

	ret	= bluetooth_power_rfkill_probe(pdev, pdev_bluetooth_power_data);
	if (ret) {
		dev_err(&pdev->dev,	"bluetooth_power_rfkill_probe failed, ret:%d\n", ret);
		goto err_free_clk_ret;
	}

	// other code
	platform_set_drvdata(pdev, pdev_bluetooth_power_data);
	
	printk(KERN_INFO "bluetooth_power probe out \n");

	return ret;
	
err_free_clk_ret:
	devm_clk_put(&pdev->dev, pdev_bluetooth_power_data->clk);

	return ret;
}
示例#5
0
static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
{
	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
	struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
	struct kirkwood_dma_data *priv;
	struct resource *mem;
	struct device_node *np = pdev->dev.of_node;
	int err;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "allocation failed\n");
		return -ENOMEM;
	}
	dev_set_drvdata(&pdev->dev, priv);

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

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

	if (np) {
		priv->burst = 128;		/* might be 32 or 128 */
	} else if (data) {
		priv->burst = data->burst;
	} else {
		dev_err(&pdev->dev, "no DT nor platform data ?!\n");
		return -EINVAL;
	}

	priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "no clock\n");
		return PTR_ERR(priv->clk);
	}

	err = clk_prepare_enable(priv->clk);
	if (err < 0)
		return err;

	priv->extclk = devm_clk_get(&pdev->dev, "extclk");
	if (IS_ERR(priv->extclk)) {
		if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
	} else {
		if (priv->extclk == priv->clk) {
			devm_clk_put(&pdev->dev, priv->extclk);
			priv->extclk = ERR_PTR(-EINVAL);
		} else {
			dev_info(&pdev->dev, "found external clock\n");
			clk_prepare_enable(priv->extclk);
			soc_dai = kirkwood_i2s_dai_extclk;
		}
	}

	/* Some sensible defaults - this reflects the powerup values */
	priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
	priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;

	/* Select the burst size */
	if (priv->burst == 32) {
		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
	} else {
		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
	}

	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
					 soc_dai, 2);
	if (err) {
		dev_err(&pdev->dev, "snd_soc_register_component failed\n");
		goto err_component;
	}

	err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
	if (err) {
		dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
		goto err_platform;
	}

	kirkwood_i2s_init(priv);

	return 0;
 err_platform:
	snd_soc_unregister_component(&pdev->dev);
 err_component:
	if (!IS_ERR(priv->extclk))
		clk_disable_unprepare(priv->extclk);
	clk_disable_unprepare(priv->clk);

	return err;
}
static int sp2529_sensor_power(struct device *dev, int on)
{
	int cam_enable, cam_reset;
	int ret;

	/* Get the regulators and never put it */
	/*
	 * The regulators is for sensor and should be in sensor driver
	 * As SoC camera does not support device tree,  leave it here
	 */
	mclk = devm_clk_get(dev, "SC2MCLK");
	if (IS_ERR(mclk))
		return PTR_ERR(mclk);
	if (!avdd_2v8) {
		avdd_2v8 = regulator_get(dev, "avdd_2v8");
		if (IS_ERR(avdd_2v8)) {
			dev_warn(dev, "Failed to get regulator avdd_2v8\n");
			avdd_2v8 = NULL;
		}
	}

	if (!dovdd_1v8) {
		dovdd_1v8 = regulator_get(dev, "dovdd_1v8");
		if (IS_ERR(dovdd_1v8)) {
			dev_warn(dev, "Failed to get regulator dovdd_1v8\n");
			dovdd_1v8 = NULL;
		}
	}

	if (!af_2v8) {
		af_2v8 = regulator_get(dev, "af_2v8");
		if (IS_ERR(af_2v8)) {
			dev_warn(dev, "Failed to get regulator af_2v8\n");
			af_2v8 = NULL;
		}
	}

	if (!dvdd_1v2) {
		dvdd_1v2 = regulator_get(dev, "dvdd_1v2");
		if (IS_ERR(dvdd_1v2)) {
			dev_warn(dev, "Failed to get regulator dvdd_1v2\n");
			dvdd_1v2 = NULL;
		}
	}

	cam_enable = of_get_named_gpio(dev->of_node, "pwdn-gpios", 0);
	if (gpio_is_valid(cam_enable)) {
		if (gpio_request(cam_enable, "CAM2_POWER")) {
			dev_err(dev, "Request GPIO %d failed\n", cam_enable);
			goto cam_enable_failed;
		}
	} else {
		dev_err(dev, "invalid pwdn gpio %d\n", cam_enable);
		goto cam_enable_failed;
	}

	cam_reset = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
	if (gpio_is_valid(cam_reset)) {
		if (gpio_request(cam_reset, "CAM2_RESET")) {
			dev_err(dev, "Request GPIO %d failed\n", cam_reset);
			goto cam_reset_failed;
		}
	} else {
		dev_err(dev, "invalid pwdn gpio %d\n", cam_reset);
		goto cam_reset_failed;
	}

	if (on) {
		gpio_direction_output(cam_enable, 0);
		usleep_range(500, 1000);

		if (avdd_2v8) {
			regulator_set_voltage(avdd_2v8, 2800000, 2800000);
			ret = regulator_enable(avdd_2v8);
			if (ret)
				goto cam_regulator_enable_failed;
		}

		if (af_2v8) {
			regulator_set_voltage(af_2v8, 2800000, 2800000);
			ret = regulator_enable(af_2v8);
			if (ret)
				goto cam_regulator_enable_failed;
		}
		usleep_range(500, 1000);

		if (dovdd_1v8) {
			regulator_set_voltage(dovdd_1v8,
					1800000, 1800000);
			ret = regulator_enable(dovdd_1v8);
			if (ret)
				goto cam_regulator_enable_failed;
		}

		if (dvdd_1v2) {
			regulator_set_voltage(dvdd_1v2,
					1200000, 1200000);
			ret = regulator_enable(dvdd_1v2);
			if (ret)
				goto cam_regulator_enable_failed;
		}

		clk_set_rate(mclk, 26000000);
		clk_prepare_enable(mclk);
		gpio_direction_output(cam_reset, 0);
		usleep_range(5000, 20000);
		gpio_direction_output(cam_enable, 1);
		usleep_range(5000, 20000);
		gpio_direction_output(cam_enable, 0);
		usleep_range(5000, 20000);
		gpio_direction_output(cam_reset, 1);
		usleep_range(5000, 20000);
	} else {
		gpio_direction_output(cam_reset, 0);
		usleep_range(5000, 20000);
		gpio_direction_output(cam_enable, 0);
		usleep_range(5000, 20000);
		gpio_direction_output(cam_enable, 1);
		clk_disable_unprepare(mclk);
		devm_clk_put(dev, mclk);
		if (dovdd_1v8)
			regulator_disable(dovdd_1v8);
		if (dvdd_1v2)
			regulator_disable(dvdd_1v2);
		if (avdd_2v8)
			regulator_disable(avdd_2v8);
		if (af_2v8)
			regulator_disable(af_2v8);

	}
	gpio_free(cam_enable);
	gpio_free(cam_reset);

	return 0;

cam_reset_failed:
	gpio_free(cam_enable);
cam_enable_failed:
	ret = -EIO;
cam_regulator_enable_failed:
	if (dvdd_1v2)
		regulator_put(dvdd_1v2);
	dvdd_1v2 = NULL;
	if (af_2v8)
		regulator_put(af_2v8);
	af_2v8 = NULL;
	if (dovdd_1v8)
		regulator_put(dovdd_1v8);
	dovdd_1v8 = NULL;
	if (avdd_2v8)
		regulator_put(avdd_2v8);
	avdd_2v8 = NULL;

	return ret;
}
示例#7
0
static int uart_clps711x_probe(struct platform_device *pdev)
{
	struct clps711x_port *s;
	int ret, i;

	s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL);
	if (!s) {
		dev_err(&pdev->dev, "Error allocating port structure\n");
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, s);

	s->uart_clk = devm_clk_get(&pdev->dev, "uart");
	if (IS_ERR(s->uart_clk)) {
		dev_err(&pdev->dev, "Can't get UART clocks\n");
		ret = PTR_ERR(s->uart_clk);
		goto err_out;
	}

	s->uart.owner		= THIS_MODULE;
	s->uart.dev_name	= "ttyCL";
	s->uart.major		= UART_CLPS711X_MAJOR;
	s->uart.minor		= UART_CLPS711X_MINOR;
	s->uart.nr		= UART_CLPS711X_NR;
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
	s->uart.cons		= &s->console;
	s->uart.cons->device	= uart_console_device;
	s->uart.cons->write	= uart_clps711x_console_write;
	s->uart.cons->setup	= uart_clps711x_console_setup;
	s->uart.cons->flags	= CON_PRINTBUFFER;
	s->uart.cons->index	= -1;
	s->uart.cons->data	= s;
	strcpy(s->uart.cons->name, "ttyCL");
#endif
	ret = uart_register_driver(&s->uart);
	if (ret) {
		dev_err(&pdev->dev, "Registering UART driver failed\n");
		devm_clk_put(&pdev->dev, s->uart_clk);
		goto err_out;
	}

	for (i = 0; i < UART_CLPS711X_NR; i++) {
		s->port[i].line		= i;
		s->port[i].dev		= &pdev->dev;
		s->port[i].irq		= TX_IRQ(&s->port[i]);
		s->port[i].iobase	= SYSCON(&s->port[i]);
		s->port[i].type		= PORT_CLPS711X;
		s->port[i].fifosize	= 16;
		s->port[i].flags	= UPF_SKIP_TEST | UPF_FIXED_TYPE;
		s->port[i].uartclk	= clk_get_rate(s->uart_clk);
		s->port[i].ops		= &uart_clps711x_ops;
		WARN_ON(uart_add_one_port(&s->uart, &s->port[i]));
	}

	return 0;

err_out:
	platform_set_drvdata(pdev, NULL);

	return ret;
}
static int mmphw_probe(struct platform_device *pdev)
{
	struct mmp_mach_plat_info *mi;
	struct resource *res;
	int ret, i, size, irq;
	struct mmphw_path_plat *path_plat;
	struct mmphw_ctrl *ctrl = NULL;

	/* get resources from platform data */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "%s: no IO memory defined\n", __func__);
		ret = -ENOENT;
		goto failed;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__);
		ret = -ENOENT;
		goto failed;
	}

	/* get configs from platform data */
	mi = pdev->dev.platform_data;
	if (mi == NULL || !mi->path_num || !mi->paths) {
		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
		ret = -EINVAL;
		goto failed;
	}

	/* allocate */
	size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) *
	       mi->path_num;
	ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
	if (!ctrl) {
		ret = -ENOMEM;
		goto failed;
	}

	ctrl->name = mi->name;
	ctrl->path_num = mi->path_num;
	ctrl->dev = &pdev->dev;
	ctrl->irq = irq;
	platform_set_drvdata(pdev, ctrl);
	mutex_init(&ctrl->access_ok);

	/* map registers.*/
	if (!devm_request_mem_region(ctrl->dev, res->start,
			resource_size(res), ctrl->name)) {
		dev_err(ctrl->dev,
			"can't request region for resource %pR\n", res);
		ret = -EINVAL;
		goto failed;
	}

	ctrl->reg_base = devm_ioremap_nocache(ctrl->dev,
			res->start, resource_size(res));
	if (ctrl->reg_base == NULL) {
		dev_err(ctrl->dev, "%s: res %x - %x map failed\n", __func__,
			res->start, res->end);
		ret = -ENOMEM;
		goto failed;
	}

	/* request irq */
	ret = devm_request_irq(ctrl->dev, ctrl->irq, ctrl_handle_irq,
		IRQF_SHARED, "lcd_controller", ctrl);
	if (ret < 0) {
		dev_err(ctrl->dev, "%s unable to request IRQ %d\n",
				__func__, ctrl->irq);
		ret = -ENXIO;
		goto failed;
	}

	/* get clock */
	ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name);
	if (IS_ERR(ctrl->clk)) {
		dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name);
		ret = -ENOENT;
		goto failed_get_clk;
	}
	clk_prepare_enable(ctrl->clk);

	/* init global regs */
	ctrl_set_default(ctrl);

	/* init pathes from machine info and register them */
	for (i = 0; i < ctrl->path_num; i++) {
		/* get from config and machine info */
		path_plat = &ctrl->path_plats[i];
		path_plat->id = i;
		path_plat->ctrl = ctrl;

		/* path init */
		if (!path_init(path_plat, &mi->paths[i])) {
			ret = -EINVAL;
			goto failed_path_init;
		}
	}

#ifdef CONFIG_MMP_DISP_SPI
	ret = lcd_spi_register(ctrl);
	if (ret < 0)
		goto failed_path_init;
#endif

	dev_info(ctrl->dev, "device init done\n");

	return 0;

failed_path_init:
	for (i = 0; i < ctrl->path_num; i++) {
		path_plat = &ctrl->path_plats[i];
		path_deinit(path_plat);
	}

	if (ctrl->clk) {
		devm_clk_put(ctrl->dev, ctrl->clk);
		clk_disable_unprepare(ctrl->clk);
	}
failed_get_clk:
	devm_free_irq(ctrl->dev, ctrl->irq, ctrl);
failed:
	if (ctrl) {
		if (ctrl->reg_base)
			devm_iounmap(ctrl->dev, ctrl->reg_base);
		devm_release_mem_region(ctrl->dev, res->start,
				resource_size(res));
		devm_kfree(ctrl->dev, ctrl);
	}

	platform_set_drvdata(pdev, NULL);
	dev_err(&pdev->dev, "device init failed\n");

	return ret;
}
示例#9
0
int es705_enable_ext_clk(struct device *dev, int enable)
{
	static struct clk *es705_codec_clk = NULL;
	int rc = 0;

	dev_info(dev, "%s: clk enable=%d\n", __func__, enable);

#ifdef CONFIG_ARCH_EXYNOS
	if (enable) {
		if (es705_codec_clk) {
			dev_info(dev, "%s: clk is already On", __func__);
			return 0;
		}

		es705_codec_clk = devm_clk_get(dev, "mclk");
		if (IS_ERR(es705_codec_clk)) {
			dev_err(dev, "%s: Device tree node not found for mclk", __func__);
			es705_codec_clk = NULL;
		}

		if(es705_codec_clk) {
			rc = clk_prepare_enable(es705_codec_clk);
			if (rc) {
				dev_err(dev, "%s: Failed to prepare or enable clock, err=%d\n", __func__, rc);
				goto err;
			}
		} else
			exynos5_audio_set_mclk(true, 0);
	} else {
		if(es705_codec_clk) {
			clk_disable_unprepare(es705_codec_clk);
			devm_clk_put(dev, es705_codec_clk);
			es705_codec_clk = NULL;
		} else
			exynos5_audio_set_mclk(false, 0);
	}
	return 0;
err:
	devm_clk_put(dev, es705_codec_clk);
	es705_codec_clk = NULL;
#else
	es705_codec_clk = clk_get(dev, "osr_clk");
	if (!es705_codec_clk) {
		dev_err(dev, "%s: clk_get osr_clk FAIL\n", __func__);
		return -ENODEV;
	}

	if (enable) {
		rc = clk_prepare_enable(es705_codec_clk);
		if (rc) {
			dev_err(dev,
				"Failed to prepare or enable clock, err=%d\n",
				rc);
			goto err;
		}
	} else {
		clk_disable_unprepare(es705_codec_clk);
		clk_put(es705_codec_clk);
	}

	return 0;

err:
	clk_put(es705_codec_clk);
#endif
	return rc;
}
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;
}
static int hi6401_irq_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct hi6401_irq *irq = NULL;
	enum of_gpio_flags flags;
	unsigned int virq;
	int ret = 0;
	int i;

	irq = devm_kzalloc(dev, sizeof(*irq), GFP_KERNEL);
	if (!irq) {
		dev_err(dev, "cannot allocate hi6401_irq device info\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, irq);

	/* get resources */
	irq->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!irq->res) {
		dev_err(dev, "platform_get_resource err\n");
		goto err_exit;
	}

	if (!devm_request_mem_region(dev, irq->res->start,
				     resource_size(irq->res),
				     pdev->name)) {
		dev_err(dev, "cannot claim register memory\n");
		goto err_exit;
	}

	irq->reg_base_addr = devm_ioremap(dev, irq->res->start,
					  resource_size(irq->res));
	if (!irq->reg_base_addr) {
		dev_err(dev, "cannot map register memory\n");
		goto ioremap_err;
	}


	/* get pinctrl */
	irq->pctrl = devm_pinctrl_get(dev);
	if (IS_ERR(irq->pctrl)) {
		dev_err(dev, "could not get pinctrl\n");
		goto codec_ssi_get_err;
	}
	ret = codec_ssi_iomux_default(irq->pctrl);
	if (0 != ret)
		goto codec_ssi_iomux_err;

	/* get codec ssi clk */
	irq->codec_ssi_clk = devm_clk_get(dev, "clk_codecssi");
	if (IS_ERR(irq->codec_ssi_clk)) {
		pr_err("clk_get: codecssi clk not found!\n");
		ret = PTR_ERR(irq->codec_ssi_clk);
		goto codec_ssi_clk_err;
	}
	ret = clk_prepare_enable(irq->codec_ssi_clk);
	if (0 != ret) {
		pr_err("codec_ssi_clk :clk prepare enable failed !\n");
		goto codec_ssi_clk_enable_err;
	}

	/* get pmu audio clk */
	irq->pmu_audio_clk = devm_clk_get(dev, "clk_pmuaudioclk");
	if (IS_ERR(irq->pmu_audio_clk)) {
		pr_err("_clk_get: pmu_audio_clk not found!\n");
		ret = PTR_ERR(irq->pmu_audio_clk);
		goto pmu_audio_clk_err;
	}
	ret = clk_prepare_enable(irq->pmu_audio_clk);
	if (0 != ret) {
		pr_err("pmu_audio_clk :clk prepare enable failed !\n");
		goto pmu_audio_clk_enable_err;
	}

	spin_lock_init(&irq->lock);
	spin_lock_init(&irq->rw_lock);
	mutex_init(&irq->sr_mutex);
	mutex_init(&irq->pll_mutex);
	wake_lock_init(&irq->wake_lock, WAKE_LOCK_SUSPEND, "hi6401-irq");

	irq->dev = dev;

	/* clear IRQ status */
	hi6401_irq_write(irq, HI6401_REG_IRQ_0, 0xFF);
	hi6401_irq_write(irq, HI6401_REG_IRQ_1, 0xFF);
	/* mask all irqs */
	hi6401_irq_write(irq, HI6401_REG_IRQM_0, 0xFF);
	hi6401_irq_write(irq, HI6401_REG_IRQM_1, 0xFF);

	irq->gpio = of_get_gpio_flags(np, 0, &flags);
	if (0 > irq->gpio) {
		dev_err(dev, "get gpio flags error\n");
		ret = irq->gpio;
		goto get_gpio_err;
	}

	if (!gpio_is_valid(irq->gpio)) {
		dev_err(dev, "gpio is invalid\n");
		ret = -EINVAL;
		goto get_gpio_err;
	}

	ret = gpio_request_one(irq->gpio, GPIOF_IN, "hi6401_irq");
	if (0 > ret) {
		dev_err(dev, "failed to request gpio%d\n", irq->gpio);
		goto get_gpio_err;
	}

	irq->irq = gpio_to_irq(irq->gpio);

	irq->domain = irq_domain_add_simple(np, HI6401_MAX_IRQS, 0,
					    &hi6401_domain_ops, irq);
	if (!irq->domain) {
		dev_err(dev, "irq domain error\n");
		ret = -ENODEV;
		goto gpio_err;
	}

	for (i = 0; i < HI6401_MAX_IRQS; i++) {
		virq = irq_create_mapping(irq->domain, i);
		if (virq == NO_IRQ) {
			dev_err(dev, "Failed mapping hwirq\n");
			ret = -ENOSPC;
			goto gpio_err;
		}
		irq->irqs[i] = virq;
	}

	ret = request_irq(irq->irq, hi6401_irq_handler,
				   IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND,
				   "hi6401_irq", irq);
	if (0 > ret) {
		dev_err(dev, "could not claim irq %d\n", ret);
		ret = -ENODEV;
		goto gpio_err;
	}
	irq->hi6401_irq_delay_wq = create_singlethread_workqueue("hi6401_irq_delay_wq");
	if (!(irq->hi6401_irq_delay_wq)) {
		pr_err("%s(%u) : workqueue create failed", __FUNCTION__,__LINE__);
		ret = -ENOMEM;
		goto irq_delay_wq_err;
	}
	INIT_DELAYED_WORK(&irq->hi6401_irq_delay_work, hi6401_irq_work_func);

	irq->pll_delay_wq = create_singlethread_workqueue("pll_delay_wq");
	if (!(irq->pll_delay_wq)) {
		pr_err("%s : pll_delay_wq create failed", __FUNCTION__);
		ret = -ENOMEM;
		goto pll_delay_wq_err;
	}
	INIT_DELAYED_WORK(&irq->pll_delay_work, hi6401_pll_work_func);

	g_dump_buf = (char*)kmalloc(sizeof(char)*Hi6401_SIZE_MAX, GFP_KERNEL);
	if (!g_dump_buf)
	{
		pr_err("%s : couldn't malloc buffer.\n",__FUNCTION__);
		ret = -ENOMEM;
		goto g_dump_buf_kmalloc_err;
	}
	memset(g_dump_buf, 0, Hi6401_SIZE_MAX);
	/* populate sub nodes */
	of_platform_populate(np, of_hi6401_irq_child_match_tbl, NULL, dev);

	if (!hi6401_client) {
		hi6401_client = dsm_register_client(&dsm_hi6401);
	}
	return 0;

g_dump_buf_kmalloc_err:
	if(irq->pll_delay_wq) {
		cancel_delayed_work(&irq->pll_delay_work);
		flush_workqueue(irq->pll_delay_wq);
		destroy_workqueue(irq->pll_delay_wq);
	}
pll_delay_wq_err:
	if(irq->hi6401_irq_delay_wq) {
		cancel_delayed_work(&irq->hi6401_irq_delay_work);
		flush_workqueue(irq->hi6401_irq_delay_wq);
		destroy_workqueue(irq->hi6401_irq_delay_wq);
	}
irq_delay_wq_err:
	free_irq(irq->irq, irq);
gpio_err:
	gpio_free(irq->gpio);
get_gpio_err:

	clk_disable_unprepare(irq->pmu_audio_clk);
pmu_audio_clk_enable_err:
	devm_clk_put(dev, irq->pmu_audio_clk);
pmu_audio_clk_err:
	clk_disable_unprepare(irq->codec_ssi_clk);
codec_ssi_clk_enable_err:
	devm_clk_put(dev, irq->codec_ssi_clk);
codec_ssi_clk_err:
	codec_ssi_iomux_idle(irq->pctrl);
codec_ssi_iomux_err:
	pinctrl_put(irq->pctrl);
codec_ssi_get_err:

	devm_iounmap(dev, irq->reg_base_addr);
ioremap_err:
	devm_release_mem_region(dev, irq->res->start,
				resource_size(irq->res));
err_exit:
	devm_kfree(dev, irq);

	return ret;
}
示例#12
0
static int __init exynos_sata_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ata_port_info pi = ahci_port_info;
	const struct ata_port_info *ppi[] = { &pi, NULL };
	struct ahci_host_priv *hpriv;
	struct exynos_sata *sata;
	struct ata_host *host;
	struct resource *mem;
	int n_ports, i, ret;

	sata = devm_kzalloc(dev, sizeof(*sata), GFP_KERNEL);
	if (!sata) {
		dev_err(dev, "can't alloc sata\n");
		return -EINVAL;
	}

	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
	if (!hpriv) {
		dev_err(dev, "can't alloc ahci_host_priv\n");
		ret = -ENOMEM;
		goto err1;
	}

	hpriv->flags |= (unsigned long)pi.private_data;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(dev, "no mmio space\n");
		ret = -EINVAL;
		goto err2;
	}

	sata->irq = platform_get_irq(pdev, 0);
	if (sata->irq <= 0) {
		dev_err(dev, "no irq\n");
		ret = -EINVAL;
		goto err2;
	}

	hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
	if (!hpriv->mmio) {
		dev_err(dev, "can't map %pR\n", mem);
		ret = -ENOMEM;
		goto err2;
	}

	exynos_sata_parse_dt(dev->of_node, sata);
	if (!sata->freq) {
		dev_err(dev, "can't determine sata frequency \n");
		ret = -ENOMEM;
		goto err2;
	}

	sata->sclk = devm_clk_get(dev, "sclk_sata");
	if (IS_ERR(sata->sclk)) {
		dev_err(dev, "failed to get sclk_sata\n");
		ret = PTR_ERR(sata->sclk);
		goto err3;
	}
	clk_enable(sata->sclk);

	clk_set_rate(sata->sclk, sata->freq * MHZ);

	sata->clk = devm_clk_get(dev, "sata");
	if (IS_ERR(sata->clk)) {
		dev_err(dev, "failed to get sata clock\n");
		ret = PTR_ERR(sata->clk);
		goto err4;
	}
	clk_enable(sata->clk);

	/*  Get a gen 3 PHY controller */

	sata->phy = sata_get_phy(SATA_PHY_GENERATION3);
	if (!sata->phy) {
		dev_err(dev, "failed to get sata phy\n");
		ret = -EPROBE_DEFER;
		goto err5;
	}

	/* Initialize the controller */

	ret = sata_init_phy(sata->phy);
	if (ret < 0) {
		dev_err(dev, "failed to initialize sata phy\n");
		goto err6;
	}

	ahci_save_initial_config(dev, hpriv, 0, 0);

	/* prepare host */
	if (hpriv->cap & HOST_CAP_NCQ)
		pi.flags |= ATA_FLAG_NCQ;

	if (hpriv->cap & HOST_CAP_PMP)
		pi.flags |= ATA_FLAG_PMP;

	ahci_set_em_messages(hpriv, &pi);

	/* CAP.NP sometimes indicate the index of the last enabled
	 * port, at other times, that of the last possible port, so
	 * determining the maximum port number requires looking at
	 * both CAP.NP and port_map.
	 */
	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));

	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
	if (!host) {
		ret = -ENOMEM;
		goto err7;
	}

	host->private_data = hpriv;

	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
		host->flags |= ATA_HOST_PARALLEL_SCAN;
	else
		pr_info(KERN_INFO
		       "ahci: SSS flag set, parallel bus scan disabled\n");

	if (pi.flags & ATA_FLAG_EM)
		ahci_reset_em(host);

	for (i = 0; i < host->n_ports; i++) {
		struct ata_port *ap = host->ports[i];

		ata_port_desc(ap, "mmio %pR", mem);
		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);

		/* set enclosure management message type */
		if (ap->flags & ATA_FLAG_EM)
			ap->em_message_type = hpriv->em_msg_type;

		/* disabled/not-implemented port */
		if (!(hpriv->port_map & (1 << i)))
			ap->ops = &ata_dummy_port_ops;
	}

	ret = ahci_reset_controller(host);
	if (ret)
		goto err7;

	ahci_init_controller(host);
	ahci_print_info(host, "platform");

	ret = ata_host_activate(host, sata->irq, ahci_interrupt, IRQF_SHARED,
				&ahci_platform_sht);
	if (ret)
		goto err7;

	platform_set_drvdata(pdev, sata);

	return 0;

 err7:
	sata_shutdown_phy(sata->phy);

 err6:
	sata_put_phy(sata->phy);

 err5:
	clk_disable(sata->clk);
	devm_clk_put(dev, sata->clk);

 err4:
	clk_disable(sata->sclk);
	devm_clk_put(dev, sata->sclk);

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

 err2:
	devm_kfree(dev, hpriv);

 err1:
	devm_kfree(dev, sata);

	return ret;
}