static int micro_usb_power_control_remove(struct platform_device *pdev)
{
	struct micro_usb_power_control_platform_data *pdata = NULL;
	pdata = pdev->dev.platform_data;
	if(pdata->exit_gpio)
	{
		pdata->exit_gpio();
	}
	if(get_product_feature(PROD_FEATURE_DETECT_MHL_CHIP))
	{
		free_irq(pdata->usb_id_detect_gpio, usb_power_control_dev);
		gpio_free(pdata->usb_id_detect_gpio);
	}
	free_irq(pdata->usb_current_warning_gpio, usb_power_control_dev);
	gpio_free(pdata->usb_current_warning_gpio);
    if(usb_power_control_dev->micro_usb_power_wq)
    {
	    destroy_workqueue(usb_power_control_dev->micro_usb_power_wq);
    }
	sysfs_remove_group(&usb_power_control_dev->dev.kobj,&micro_usb_power_defattr_group);
	kfree(usb_power_control_dev);
	if(pdata->io_mux_block_exit)
	{
		pdata->io_mux_block_exit(pdata);
	}
	usb_power_control_dev = NULL;
	return 0;
}
static int __devinit micro_usb_power_control_probe(struct platform_device *pdev)
{
	struct micro_usb_power_control_platform_data *pdata = NULL;
	struct micro_usb_power_control_device *dev = NULL;

	int ret = 0;

	pdata = pdev->dev.platform_data;

	printk(KERN_INFO " micro_usb_power_control_probe in\n");

	if(!pdata)
	{
		printk(KERN_ERR "micro_usb_power_control pdata is NULL,retrun -EINVAL\n");
		return -EINVAL;
	}
	if(pdata->io_mux_block_init)
	{
		ret = pdata->io_mux_block_init(pdata);
		if(ret)
		{
			printk(KERN_ERR " micro_usb_power_control io_mux_block init fail 0x%x\n",ret);
			goto io_mux_block_init_fail;
		}
	}
	
	dev = kzalloc(sizeof(struct micro_usb_power_control_device), GFP_KERNEL);
	if (!dev) 
	{
		dev_err(&pdev->dev, "Error: No memory\n");
		ret =  -ENOMEM;
		goto err_alloc_data_failed;
	}
    dev->dev = pdev->dev;
    if (sysfs_create_group(&dev->dev.kobj, &micro_usb_power_defattr_group))
	{
		dev_err(&pdev->dev, "Error: Sysfs create group fail\n");
		ret = -ENOMEM;
		goto create_group_fail;
    }
	dev->micro_usb_power_wq = create_singlethread_workqueue(USB_CURRENT_WARNING_WQ_NAME);
	if (!dev->micro_usb_power_wq) 
	{
		dev_err(&pdev->dev, "Error: Create usb current warning workqueue fail\n");
		ret = -ENOMEM;
		goto err_creat_workqueue;
	}

	INIT_WORK(&dev->current_warning_work, current_warning_work_func);
	dev->current_warning_name = USB_CURRENT_WARNING_NAME;
	dev->usb_current_warning_irq = gpio_to_irq(pdata->usb_current_warning_gpio);


	ret = gpio_request(pdata->usb_current_warning_gpio, dev->current_warning_name);
	if (ret < 0) 
	{
		dev_err(&pdev->dev, "Error: Request current warning gpio fail\n");
		ret = -EIO;
		goto err_request_current_warning_irq;
	}

	gpio_direction_input(pdata->usb_current_warning_gpio);	

	ret = request_irq(dev->usb_current_warning_irq, current_warning_irq_handler,
			pdata->irq_type, dev->current_warning_name, dev);
	if (!ret) 
	{
		printk("Request current warning irq success\n");
	}
	else 
	{
		dev_err(&pdev->dev, "Error: Request current warning irq fail\n");
		goto request_current_warning_irq_fail;
	}

	if(get_product_feature(PROD_FEATURE_DETECT_MHL_CHIP))
	{

		INIT_WORK(&dev->usb_id_detect_work, usb_id_detect_work_func);
		dev->usb_id_detect_name = USB_ID_DETECT_NAME;
		dev->usb_id_detect_irq = gpio_to_irq(pdata->usb_id_detect_gpio);


		ret = gpio_request(pdata->usb_id_detect_gpio, dev->usb_id_detect_name);
		if (ret < 0) 
		{
			printk("Error: Request current warning gpio fail\n");
			dev_err(&pdev->dev, "Error: Request current warning gpio fail\n");
			ret = -EIO;
			goto err_request_usb_id_detect_irq;
		}

		gpio_direction_input(pdata->usb_id_detect_gpio);	

		ret = request_irq(dev->usb_id_detect_irq, usb_id_detect_irq_handler,
			pdata->usb_id_detect_irq_type, dev->usb_id_detect_name, dev);
		if (!ret) 
		{
			printk("Request usb id detect irq success\n");
		}
		else 
		{
			dev_err(&pdev->dev, "Error: Request usb id detect irq fail\n");
			goto request_usb_id_detect_irq_fail;
		}
	}

	/*set ap5v gpio high*/
	if(pdata->init_gpio)
	{
		ret = pdata->init_gpio();
		if(ret<0)
		{
			printk(KERN_ERR " micro_usb_power_control request gpio fail 0x%x\n",ret);
			goto init_gpio_fail;				
		}
	}
	dev->modem_usb_ctrl_gpio = pdata->modem_usb_control_gpio;
	dev->ap5v_en_gpio = pdata->usb_ap5v_en_gpio;	
	dev->out5v_en_gpio = pdata->usb_vbus5v_en_gpio;
	usb_power_control_dev = dev;
	return 0;

init_gpio_fail:
	if(get_product_feature(PROD_FEATURE_DETECT_MHL_CHIP))
	{
		free_irq(pdata->usb_id_detect_gpio, dev);
	}
request_usb_id_detect_irq_fail:
	if(get_product_feature(PROD_FEATURE_DETECT_MHL_CHIP))
	{
		gpio_free(pdata->usb_id_detect_gpio);
	}
err_request_usb_id_detect_irq:	
	free_irq(pdata->usb_current_warning_gpio, dev);
request_current_warning_irq_fail:
	gpio_free(pdata->usb_current_warning_gpio);
err_request_current_warning_irq:
	destroy_workqueue(dev->micro_usb_power_wq);
err_creat_workqueue:	
	sysfs_remove_group(&dev->dev.kobj,&micro_usb_power_defattr_group);
create_group_fail:	
	kfree(dev);	
err_alloc_data_failed:
	pdata->io_mux_block_exit(pdata);
io_mux_block_init_fail:
	return ret;	
	
}
예제 #3
0
int k3v2_dcdc_gpu_probe(struct platform_device *pdev)
{
	int err = 0;
	struct plat_data *ipps_init_data = NULL;
	struct resource *pmctrl_res = NULL;
	struct device *dev = NULL;
	struct ipps_gpu *ipps_gpu = NULL;

#ifdef CONFIG_EXTRAL_DYNAMIC_DCDC
	if(!get_product_feature(PROD_FEATURE_GPU_DCDC_SUPPLY)) {
		dev_err(&pdev->dev, "hardware version is invalid.\n");
		return -EINVAL;
	}
#endif	

	dev = &pdev->dev;
	ipps_init_data = pdev->dev.platform_data;
	if (!ipps_init_data) {
		dev_err(&pdev->dev, "failed to get driver data.\n");
		return -EINVAL;
	}
    
	pmctrl_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!pmctrl_res) {
		dev_err(&pdev->dev, "failed to get pm I/O memory.\n");
		return -ENXIO;
	}

	ipps_gpu = kzalloc(sizeof(struct ipps_gpu), GFP_KERNEL);
	if (!ipps_gpu) {
		dev_err(&pdev->dev, "failed to kzalloc memory for dcdc gpu.\n");
		return -ENOMEM;
	}

	ipps_gpu->pmctrl_base = ioremap(pmctrl_res->start, resource_size(pmctrl_res));
	if (!ipps_gpu->pmctrl_base) {
		dev_err(&pdev->dev, "failed to remap pm_base I/O memory.\n");
		err = -ENXIO;
		goto err_free_mem;
	}

	ipps_gpu->regulator_dcdc = regulator_get(NULL, "gpu-vcc");
	if (IS_ERR(ipps_gpu->regulator_dcdc)) {
		dev_err(&pdev->dev, "regulator_get gpu dcdc failed.\n");
		err = PTR_ERR(ipps_gpu->regulator_dcdc);
		goto err_iounmap_pmsctrl_base;
	}

	/*get gpu dcdc*/
	ipps_gpu->clk_hdmipll = clk_get(NULL, "clk_pll4");
	if (IS_ERR(ipps_gpu->clk_hdmipll)) {
		dev_err(&pdev->dev, "hdmipll clock get failed.\n");
		err = PTR_ERR(ipps_gpu->clk_hdmipll);
		goto err_regulator_put;
	}

	ipps_gpu->curr_profile = ipps_init_data->cur_profile;
	ipps_gpu->curr_mode = ipps_init_data->mode;
	ipps_gpu->curr_policy = ipps_init_data->policy;
	ipps_gpu->gpu.freq.max = ipps_init_data->max;
	ipps_gpu->gpu.freq.min = ipps_init_data->min;
	ipps_gpu->gpu.freq.safe = ipps_init_data->safe;
	ipps_gpu->temp_enable = TEMP_MON_DISABLE;
	ipps_gpu->uptimes = 0;
	ipps_gpu->downtimes = 0;
	ipps_gpu->idev = ipps_alloc_device(sizeof(struct ipps_device));
	if (NULL == ipps_gpu->idev) {
		dev_err(&pdev->dev, "failed to alloc idev mem!\n");
		err = PTR_ERR(ipps_gpu->idev);
		goto err_regulator_put;
	}
	ipps_gpu->idev->command = k3v2_dcdc_gpu_cmd;
	ipps_gpu->idev->object = ipps_init_data->obj;
	ipps_gpu->idev->dev = dev;

	g_ipps_gpu = ipps_gpu;
	if (((POWERSAVE_POLICY <= ipps_gpu->curr_policy) && (ipps_gpu->curr_policy <=SPEC0B_POLICY)) ||
			(ipps_gpu->curr_policy == NORMAL_POLICY) || (ipps_gpu->curr_policy == PERF_POLICY)) {
		g_ipps_policy = policy_table[ipps_gpu->curr_policy];
	} else {
		err = -EINVAL;
		WARN(1, "K3V2 DCDC GPU:policy is invalid.\n");
		goto err_free_idev;
	}

	/*
	 *ipps_register_device() uses g_ipps_gpu pointer
	 *to excute client->add()
	 */
	err = ipps_register_device(ipps_gpu->idev);
	if (err) {
		dev_err(&pdev->dev, "ipps device register failed!\n");
		goto err_free_idev;
	}

	err = sysfs_create_group(&dev->kobj, &k3_dcdc_gpu_attr_group);
	if (err) {
		dev_err(dev, "failed to creat sysfs file\n");
		goto err_idev_unregister;
	}
#if 1
	ipps_gpu->gpu_dvfs_wq = create_singlethread_workqueue("gpudvfs");
	if (ipps_gpu->gpu_dvfs_wq == NULL) {
		dev_err(&pdev->dev, "create_workqueue failed for gpu dcdc\n");
		err = PTR_ERR(ipps_gpu->gpu_dvfs_wq);
		goto err_remove_sysfs_group;
	}
#endif
	mutex_init(&reg_lock_mutex);
	gpu_dvfs_init();
	return 0;
err_remove_sysfs_group:
	sysfs_remove_group(&pdev->dev.kobj, &k3_dcdc_gpu_attr_group);
err_idev_unregister:
	ipps_unregister_device(ipps_gpu->idev);
err_free_idev:
	ipps_dealloc_device(ipps_gpu->idev);
err_regulator_put:
	regulator_put(ipps_gpu->regulator_dcdc);
err_iounmap_pmsctrl_base:
	iounmap(ipps_gpu->pmctrl_base);
err_free_mem:
	kfree(ipps_gpu);

	return err;
}