示例#1
0
static int __f2fs_setxattr(struct inode *inode, int name_index,
			const char *name, const void *value, size_t value_len,
			struct page *ipage)
{
	struct f2fs_inode_info *fi = F2FS_I(inode);
	struct f2fs_xattr_entry *here, *last;
	void *base_addr;
	int found, newsize;
	size_t name_len;
	__u32 new_hsize;
	int error = -ENOMEM;

	if (name == NULL)
		return -EINVAL;

	if (value == NULL)
		value_len = 0;

	name_len = strlen(name);

	if (name_len > F2FS_NAME_LEN || value_len > MAX_VALUE_LEN(inode))
		return -ERANGE;

	base_addr = read_all_xattrs(inode, ipage);
	if (!base_addr)
		goto exit;

	/* find entry with wanted name. */
	here = __find_xattr(base_addr, name_index, name_len, name);

	found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1;
	last = here;

	while (!IS_XATTR_LAST_ENTRY(last))
		last = XATTR_NEXT_ENTRY(last);

	newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
			name_len + value_len);

	/* 1. Check space */
	if (value) {
		int free;
		/*
		 * If value is NULL, it is remove operation.
		 * In case of update operation, we caculate free.
		 */
		free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr);
		if (found)
			free = free + ENTRY_SIZE(here);

		if (free < newsize) {
			error = -ENOSPC;
			goto exit;
		}
	}

	/* 2. Remove old entry */
	if (found) {
		/*
		 * If entry is found, remove old entry.
		 * If not found, remove operation is not needed.
		 */
		struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
		int oldsize = ENTRY_SIZE(here);

		memmove(here, next, (char *)last - (char *)next);
		last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
		memset(last, 0, oldsize);
	}

	new_hsize = (char *)last - (char *)base_addr;

	/* 3. Write new entry */
	if (value) {
		char *pval;
		/*
		 * Before we come here, old entry is removed.
		 * We just write new entry.
		 */
		memset(last, 0, newsize);
		last->e_name_index = name_index;
		last->e_name_len = name_len;
		memcpy(last->e_name, name, name_len);
		pval = last->e_name + name_len;
		memcpy(pval, value, value_len);
		last->e_value_size = cpu_to_le16(value_len);
		new_hsize += newsize;
	}

	error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
	if (error)
		goto exit;

	if (is_inode_flag_set(fi, FI_ACL_MODE)) {
		inode->i_mode = fi->i_acl_mode;
		inode->i_ctime = CURRENT_TIME;
		clear_inode_flag(fi, FI_ACL_MODE);
	}

	if (ipage)
		update_inode(inode, ipage);
	else
		update_inode_page(inode);
exit:
	kzfree(base_addr);
	return error;
}
int camera_init_v4l2(struct device *dev, unsigned int *session)
{
	struct msm_video_device *pvdev;
	struct v4l2_device *v4l2_dev;
	int rc = 0;

	pvdev = kzalloc(sizeof(struct msm_video_device),
		GFP_KERNEL);
	if (WARN_ON(!pvdev)) {
		rc = -ENOMEM;
		goto init_end;
	}

	pvdev->vdev = video_device_alloc();
	if (WARN_ON(!pvdev->vdev)) {
		rc = -ENOMEM;
		goto video_fail;
	}

	v4l2_dev = kzalloc(sizeof(struct v4l2_device), GFP_KERNEL);
	if (WARN_ON(!v4l2_dev)) {
		rc = -ENOMEM;
		goto v4l2_fail;
	}

#if defined(CONFIG_MEDIA_CONTROLLER)
	v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
							 GFP_KERNEL);
	if (!v4l2_dev->mdev) {
		rc = -ENOMEM;
		goto mdev_fail;
	}
	strlcpy(v4l2_dev->mdev->model, MSM_CAMERA_NAME,
			sizeof(v4l2_dev->mdev->model));

	v4l2_dev->mdev->dev = dev;

	rc = media_device_register(v4l2_dev->mdev);
	if (WARN_ON(rc < 0))
		goto media_fail;

	rc = media_entity_init(&pvdev->vdev->entity, 0, NULL, 0);
	if (WARN_ON(rc < 0))
		goto entity_fail;
	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
#endif

	v4l2_dev->notify = NULL;
	pvdev->vdev->v4l2_dev = v4l2_dev;

	rc = v4l2_device_register(dev, pvdev->vdev->v4l2_dev);
	if (WARN_ON(rc < 0))
		goto register_fail;

	strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name));
	pvdev->vdev->release  = video_device_release;
	pvdev->vdev->fops     = &camera_v4l2_fops;
	pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops;
	pvdev->vdev->minor     = -1;
	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
	rc = video_register_device(pvdev->vdev,
		VFL_TYPE_GRABBER, -1);
	if (WARN_ON(rc < 0))
		goto video_register_fail;
#if defined(CONFIG_MEDIA_CONTROLLER)
	/* FIXME: How to get rid of this messy? */
	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
#endif

	*session = pvdev->vdev->num;
	atomic_set(&pvdev->opened, 0);
	video_set_drvdata(pvdev->vdev, pvdev);
	device_init_wakeup(&pvdev->vdev->dev, 1);
	goto init_end;

video_register_fail:
	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
register_fail:
#if defined(CONFIG_MEDIA_CONTROLLER)
	media_entity_cleanup(&pvdev->vdev->entity);
entity_fail:
	media_device_unregister(v4l2_dev->mdev);
media_fail:
	kzfree(v4l2_dev->mdev);
mdev_fail:
#endif
	kzfree(v4l2_dev);
v4l2_fail:
	video_device_release(pvdev->vdev);
video_fail:
	kzfree(pvdev);
init_end:
	return rc;
}
static int32_t msm_led_cci_get_dt_led_data(struct msm_led_cci_ctrl_t *fctrl,
    struct device_node *of_node, uint32_t index)
{
	int32_t rc = 0;
    struct msm_led_cci_led_info_t *led_info;
    const char *flash_name;
    char *flash_name1;

    led_info = kzalloc(sizeof(struct msm_led_cci_led_info_t), GFP_KERNEL);

    flash_name = flash_name1 = kzalloc(16, GFP_KERNEL);
	rc = of_property_read_string(of_node,
		"qcom,name", &flash_name);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
    CDBG("flash name is %s\n", flash_name);
    strcpy(led_info->name, flash_name);
    kzfree(flash_name1);
    flash_name = flash_name1 = NULL;

	rc = of_property_read_u32(of_node,
		"qcom,cci-master", &led_info->cci_master);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,slave-id", &led_info->slave_id);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,chip-id-reg", &led_info->chip_id_reg);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,chip-id", &led_info->chip_id);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,fault-info-reg", &led_info->fault_info_reg);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,max-torch-current", &led_info->max_torch_current);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,max-flash-current", &led_info->max_flash_current);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}
	rc = of_property_read_u32(of_node,
		"qcom,gpio-en", &led_info->gpio_en);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
	}
	rc = of_property_read_u32(of_node,
		"qcom,gpio-torch-en", &led_info->gpio_torch_en);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
	}
	rc = of_property_read_u32(of_node,
		"qcom,gpio-strobe-en", &led_info->gpio_strobe_en);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
	}
	rc = of_property_read_string(of_node,
		"qcom,regulator-name", &led_info->regulator_name);
	if (rc < 0) {
		pr_err("failed of_property_read\n");
		return -EINVAL;
	}

    CDBG("name is %s, regulator name %s, gpio en-%d torch-%d strobe-%d\n",
        led_info->name, led_info->regulator_name, led_info->gpio_en, led_info->gpio_torch_en, led_info->gpio_strobe_en);

    fctrl->led_info = led_info;
	return 0;

}
static int32_t msm_led_cci_query_ic(struct msm_led_cci_ctrl_t *fctrl, struct device_node *of_node)
{
    int32_t i, rc, ret = 0;
	uint32_t count = 0;
    uint16_t chip_id_reg, chip_id;
    bool matched = false;
    struct regulator *cci_regulator = NULL;
	struct msm_camera_i2c_client *cci_i2c_client = NULL;
	struct device_node *flash_src_node = NULL;
    
	CDBG("called\n");

    if (!of_get_property(of_node, "qcom,flash-cci-source", &count)) {
        pr_err("can not get qcom,flash-source\n");
        return -EINVAL;
    }
    count /= sizeof(uint32_t);
	CDBG("count %d\n", count);

    for (i=0; i<count && !matched; i++) {
        fctrl->led_info = NULL;
        /*get led info form dt*/
        flash_src_node = of_parse_phandle(of_node,
            "qcom,flash-cci-source", i);
        if (!flash_src_node) {
            continue;
        }
        rc = msm_led_cci_get_dt_led_data(fctrl, flash_src_node, i);
        if (rc < 0) {
            pr_err("get dt data failed\n");
            of_node_put(flash_src_node);
            goto FAILED;
        }
        of_node_put(flash_src_node);

        /*get power*/
        cci_regulator = regulator_get(&fctrl->pdev->dev, fctrl->led_info->regulator_name);
        if (IS_ERR_OR_NULL(cci_regulator)) {
            pr_err("regulator_get failed\n");
            goto FAILED;
        }
        /*enable power*/
        rc = regulator_enable(cci_regulator);
        if (rc < 0) {
            pr_err("regulator_enable failed\n");
            regulator_put(cci_regulator);
            goto FAILED;
        }
        /*request gpio*/
        rc = gpio_request(fctrl->led_info->gpio_en, "msm_led_cci");
        if (rc < 0) {
            pr_err("get gpio failed\n");
        }
        rc = gpio_direction_output(fctrl->led_info->gpio_en, 1);
        if (rc < 0)
            pr_err("set gpio to 1 failed\n");
        

        /*init cci*/
        fctrl->flash_i2c_client->cci_client->sid = fctrl->led_info->slave_id;
        fctrl->flash_i2c_client->cci_client->cci_i2c_master =
            fctrl->led_info->cci_master;
        cci_i2c_client = fctrl->flash_i2c_client;
        rc = cci_i2c_client->i2c_func_tbl->i2c_util(
    			cci_i2c_client, MSM_CCI_INIT);
    	if (rc < 0) {
    	    pr_err("cci init failed\n");
    	}
    	/*read id*/
    	chip_id_reg = fctrl->led_info->chip_id_reg;
        rc = cci_i2c_client->i2c_func_tbl->i2c_read(
    			cci_i2c_client, chip_id_reg, &chip_id, MSM_CAMERA_I2C_BYTE_DATA);
    	if (rc < 0) {
    	    pr_err("cci read failed\n");
            kzfree(fctrl->led_info);
            ret = -EINVAL;
    	} else {
            if (chip_id == fctrl->led_info->chip_id) {
        	    pr_err("chip id match: 0x%x", chip_id);
        	    matched = true;
        	    ret = 0;
    	    } else {
        	    pr_err("chip id not match: 0x%x", chip_id);
        	    if (fctrl->led_info) {
        	        kzfree(fctrl->led_info);
        	    }
        	    ret = -EINVAL;
    	    }
    	}
    	/*release cci*/
        rc = fctrl->flash_i2c_client->i2c_func_tbl->i2c_util(
            fctrl->flash_i2c_client, MSM_CCI_RELEASE);
    	if (rc < 0) {
    	    pr_err("cci release failed\n");
    	}

        /*release gpio*/
        rc = gpio_direction_output(fctrl->led_info->gpio_en, 0);
        if (!rc)
            gpio_free(fctrl->led_info->gpio_en);
        else
            pr_err("set gpio to 0 failed\n");
        
    	/*disable power*/
        rc = regulator_disable(cci_regulator);
        if (rc < 0) {
            pr_err("regulator_disable failed\n");
            regulator_put(cci_regulator);
            goto FAILED;
        }
        regulator_put(cci_regulator);
    }

    return ret;
FAILED:
    if (fctrl->led_info) {
        kzfree(fctrl->led_info);
        fctrl->led_info = NULL;
    }
    return -EINVAL;
}
static int pn547_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct pn547_dev *dev;
	struct pn547_i2c_platform_data *pdata;
	struct pinctrl *pinctrl;
	struct clk *nfc_clk = NULL;
	int ret = 0;

	pdata = kzalloc(sizeof(struct pn547_i2c_platform_data),
			GFP_KERNEL);
	if (!pdata) {
		dev_err(&client->dev, "failed to get allocate memory\n");
		ret = -ENOMEM;
		goto probe_pdata;
	}

	pinctrl = devm_pinctrl_get(&client->dev);
	if (IS_ERR(pinctrl)) {
		dev_err(&client->dev, "devm_pinctrl_get error\n");
		goto probe_pinctrl;
	}

	ret = pn547_parse_dt(&client->dev, pdata);
	if (ret < 0) {
		dev_err(&client->dev, "failed to parse device tree: %d\n", ret);
		goto probe_parse_dt;
	}

	ret = pn547_gpio_request(&client->dev, pdata);
	if (ret) {
		dev_err(&client->dev, "failed to request gpio\n");
		goto probe_gpio_request;
	}
	dev_dbg(&client->dev, "%s:\n", __func__);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check failed\n", __func__);
		ret = -ENODEV;
		goto probe_i2c;
	}

	dev = kzalloc(sizeof(struct pn547_dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&client->dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto probe_mem;
	}
	dev->i2c_client = client;
	dev->dev = &client->dev;
	dev->pdata = pdata;
	dev->pinctrl = pinctrl;
	init_waitqueue_head(&dev->wq);
	wake_lock_init(&dev->wake_lock, WAKE_LOCK_SUSPEND, "pn547");
	i2c_set_clientdata(client, dev);
	dev->state = PN547_STATE_UNKNOWN;

	ret = request_threaded_irq(client->irq, NULL, pn547_dev_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_ONESHOT, client->name, dev);
	if (IS_ERR_VALUE(ret)) {
		dev_err(&client->dev, "%s: irq request err %d\n",
			__func__, ret);
		goto probe_irq;
	}

	nfc_clk = clk_get(&client->dev, "nfc_clk");
	if (IS_ERR(nfc_clk)) {
		dev_err(&client->dev, "Couldn't get nfc_clk\n");
		goto probe_clk;
	}
	ret = clk_prepare_enable(nfc_clk);
	if (ret) {
		dev_err(&client->dev, "nfc_clk enable is failed\n");
		goto probe_clk_enable;
	}

	ret = pn547_dev_create_sysfs_entries(dev->i2c_client);
	if (IS_ERR_VALUE(ret)) {
		dev_err(&client->dev, "%s: create sysfs entries err %d\n",
			__func__, ret);
		goto probe_sysfs;
	}
	return ret;

probe_sysfs:
	free_irq(client->irq, dev);
probe_clk_enable:
	clk_put(nfc_clk);
probe_clk:
probe_irq:
	i2c_set_clientdata(client, NULL);
	wake_lock_destroy(&dev->wake_lock);
	kzfree(dev);
probe_mem:
probe_i2c:
	pn547_gpio_release(pdata);
probe_gpio_request:
probe_parse_dt:
	devm_pinctrl_put(pinctrl);
probe_pinctrl:
	kzfree(pdata);
probe_pdata:
	dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	return ret;
}
示例#6
0
static int htc_35mm_probe(struct platform_device *pdev)
{
	int ret;

	pd = pdev->dev.platform_data;

	pr_info("H2W: htc_35mm_jack driver register\n");

	hi = kzalloc(sizeof(struct h35_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->ext_35mm_status = 0;
	hi->is_ext_insert = 0;
	hi->mic_bias_state = 0;

	mutex_init(&hi->mutex_lock);

	wake_lock_init(&hi->headset_wake_lock, WAKE_LOCK_SUSPEND, "headset");

	hi->hs_change.name = "h2w";
	hi->hs_change.print_name = h35mm_print_name;
	ret = switch_dev_register(&hi->hs_change);
	if (ret < 0)
		goto err_switch_dev_register;

	detect_wq = create_workqueue("detection");
	if (detect_wq  == NULL) {
		ret = -ENOMEM;
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("button");
	if (button_wq  == NULL) {
			ret = -ENOMEM;
			goto err_create_button_work_queue;
	}

	hi->input = input_allocate_device();
	if (!hi->input) {
		ret = -ENOMEM;
		goto err_request_input_dev;
	}

	hi->input->name = "h2w headset";
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(KEY_MEDIA, hi->input->keybit);
	set_bit(KEY_NEXTSONG, hi->input->keybit);
	set_bit(KEY_PLAYPAUSE, hi->input->keybit);
	set_bit(KEY_PREVIOUSSONG, hi->input->keybit);
	set_bit(KEY_MUTE, hi->input->keybit);
	set_bit(KEY_VOLUMEUP, hi->input->keybit);
	set_bit(KEY_VOLUMEDOWN, hi->input->keybit);
	set_bit(KEY_END, hi->input->keybit);
	set_bit(KEY_SEND, hi->input->keybit);

	ret = input_register_device(hi->input);
	if (ret < 0)
	goto err_register_input_dev;

	/* Enable plug events*/
	if (pd->plug_event_enable == NULL) {
		ret = -ENOMEM;
		goto err_enable_plug_event;
	}
	if (pd->plug_event_enable() != 1)  {
		ret = -ENOMEM;
		goto err_enable_plug_event;
	}

	return 0;

err_enable_plug_event:
err_register_input_dev:
	input_free_device(hi->input);
err_request_input_dev:
	destroy_workqueue(button_wq);
err_create_button_work_queue:
	destroy_workqueue(detect_wq);
err_create_detect_work_queue:
	switch_dev_unregister(&hi->hs_change);
err_switch_dev_register:
	kzfree(hi);
	pr_err("H2W: Failed to register driver\n");

	return ret;
}
示例#7
0
static int __init hub_proxi_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int ret;
	struct hub_proxi_data *data;
	struct device *dev = &client->dev;

	// 20100827 [email protected] [START_LGE]
	hub_proximity_client = client;
	// 20100827 [email protected] [END_LGE]

	//Event_to_application(client);

	data = kzalloc(sizeof(struct hub_proxi_data), GFP_KERNEL);
	if (!data) {
		return -ENOMEM;
	}

	// 20100810 [email protected] GPIO Initialization [START_LGE]
	omap_mux_init_gpio(PROXI_LDO_EN, OMAP_PIN_OUTPUT);
	omap_mux_init_gpio(PROXI_OUT, OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);

	ret = gpio_request(PROXI_LDO_EN, "proximity enable gpio");
	if(ret < 0) {	
		printk("can't get hub proximity enable GPIO\n");
		kzfree(data);
		return -ENOSYS;
	}

	data->use_int_mode = true; //interrupt mode
	//	gpio_request(proxi_output_1, "proxi int gpio");
	//	gpio_direction_input(proxi_output_1); 
	//	request_irq(client->irq, hub_proxi_sleep_int_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "proxi_driver", data); 
	//	enable_irq_wake(client->irq); //wake up irq

	if (data->use_int_mode) {

/* LGE_CHANGE_S, [email protected], 2011-04-06, Disable Proximity Log */
		//printk(KERN_WARNING"%s() : interrupt mode. START\n", __func__);
/* LGE_CHANGE_E, [email protected], 2011-04-06, Disable Proximity Log */

		if (gpio_request(PROXI_OUT, "proxi interrupt gpio") < 0) {
			printk("can't get hub proxi irq GPIO\n");
			kzfree(data);
			return -ENOSYS;
		}

		ret = gpio_direction_input(PROXI_OUT); 

		ret = request_irq(gpio_to_irq(PROXI_OUT), hub_proxi_int_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "proximity_interrupt", data); 
		if (ret < 0){
			printk(KERN_INFO "[Proximity INT] GPIO 14 IRQ line set up failed!\n");
			free_irq(gpio_to_irq(PROXI_OUT), data);
			return -ENOSYS;
		}	

		/* Make the interrupt on wake up OMAP which is in suspend mode */		
		ret = enable_irq_wake(gpio_to_irq(PROXI_OUT));		
		if(ret < 0){
			printk(KERN_INFO "[Proximity INT] GPIO 14 wake up source setting failed!\n");
			disable_irq_wake(gpio_to_irq(PROXI_OUT));
			return -ENOSYS;
		}

/* LGE_CHANGE_S, [email protected], 2011-04-06, Disable Proximity Log */
		//printk(KERN_WARNING"%s() : interrupt mode. END\n", __func__);
/* LGE_CHANGE_E, [email protected], 2011-04-06, Disable Proximity Log */

		//		ret = request_irq(client->irq, hub_proxi_int_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "proxi_driver", data); 
	} 
	else {
		hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		data->timer.function = hub_proxi_timer_func;
		data->delay = PROXI_DEFAULT_DELAY_NS;
		//hrtimer_start(&data->timer, ktime_set(0, data->delay), HRTIMER_MODE_REL);
	}
	INIT_WORK(&data->work, hub_proxi_det_work);

	/*LGE_CHANGE_S [[email protected]] 2010-01-04, ldoc control*/

#if defined(CONFIG_MACH_LGE_HEAVEN_REV_A)
	reg = regulator_get(dev, "vaux3");
	if (reg == NULL) {
		printk(KERN_ERR": Failed to get PROXI power resources !! \n");
		return -ENODEV;
	}
#elif defined(CONFIG_MACH_LGE_HUB)
	reg = regulator_get(dev, "vaux2");
	if (reg == NULL) {
		printk(KERN_ERR": Failed to get PROXI power resources !! \n");
		return -ENODEV;
	}
#endif
	/*LGE_CHANGE_S [[email protected]] 2010-01-04, ldoc control*/

	//hub_proxi_power_onoff(1);
	//hub_proxi_i2c_init(client);

	data->client = client;
	i2c_set_clientdata(client, data);

	data->input_dev = input_allocate_device();
	if (data->input_dev == NULL) {
		printk(KERN_ERR "%s: input_allocate: not enough memory\n",
				__FUNCTION__);
		return -ENOMEM;
	}

	set_bit(EV_KEY, data->input_dev->evbit);
	set_bit(KEY_POWER, data->input_dev->keybit);
	set_bit(EV_ABS, data->input_dev->evbit);
	input_set_abs_params(data->input_dev, ABS_DISTANCE, 0, 1, 0, 0);
	data->input_dev->name = "proximity";
// 20101004 [email protected], fix initial operation of proximity sensor [START_LGE]
	data->input_dev->abs[ABS_DISTANCE] = -1;
// 20101004 [email protected], fix initial operation of proximity sensor [END_LGE]
	ret = input_register_device(data->input_dev);
	if (ret) {
		printk(KERN_ERR "%s: Fail to register device\n", __FUNCTION__);
		goto ERROR1;
	}

	if ((ret = sysfs_create_group(&dev->kobj, &hub_proxi_group)))
		goto ERROR3;

/* LGE_CHANGE_S, [email protected], 2011-04-13, Sync with P970 */
#ifdef CONFIG_HAS_EARLYSUSPEND /* 20110304 [email protected] late_resume_lcd [START] */
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
	data->early_suspend.suspend = hub_proxi_early_suspend;
	data->early_suspend.resume = hub_proxi_late_resume;
	register_early_suspend(&data->early_suspend);
#endif /* 20110304 [email protected] late_resume_lcd [END] */
/* LGE_CHANGE_E, [email protected], 2011-04-13, Sync with P970 */

	return 0;

ERROR3:
	input_unregister_device(data->input_dev);
ERROR1:
	kfree(data);

	return ret;
}
示例#8
0
int gpio_amlogic_name_to_num(const char *name)
{
	int i,tmp=100,num=0;
	int len=0;
	char *p=NULL;
	char *start=NULL;
	if(!name)
		return -1;
	if(!strcmp(name,"GPIO_BSD_EN"))
		return GPIO_BSD_EN;
	if(!strcmp(name,"GPIO_TEST_N"))
		return GPIO_TEST_N;
	if (sscanf(name, "DIF_TTL_%d_P", &num))
		return DIF_TTL_0_P+num*2;
	if (sscanf(name, "DIF_TTL_%d_N", &num))
		return DIF_TTL_0_N+num*2;
	if (sscanf(name, "HDMI_TTL_%d_P", &num))
		return HDMI_TTL_0_P+num*2;
	if (sscanf(name, "HDMI_TTL_%d_N", &num))
		return HDMI_TTL_0_N+num*2;
	if(!strcmp(name,"HDMI_TTL_CK_P"))
		return HDMI_TTL_CK_P;
	if(!strcmp(name,"HDMI_TTL_CK_N"))
		return HDMI_TTL_CK_N;
	len=strlen(name);
	p=kzalloc(len+1,GFP_KERNEL);
	start=p;
	if(!p)
	{
		printk("%s:malloc error\n",__func__);
		return -1;
	}
	p=strcpy(p,name);
	for(i=0;i<len;p++,i++){
		if(*p=='_'){
			*p='\0';
			tmp=i;
		}
		if(i>tmp&&*p>='0'&&*p<='9')
			num=num*10+*p-'0';
	}
	p=start;
	if(!strcmp(p,"GPIOAO"))
		num=num+0;
	else if(!strcmp(p,"GPIOH"))
		num=num+14;
	else if(!strcmp(p,"BOOT"))
		num=num+24;
	else if(!strcmp(p,"CARD"))
		num=num+43;
	else if(!strcmp(p,"GPIODV"))
		num=num+50;
	else if(!strcmp(p,"GPIOY"))
		num=num+80;
	else if(!strcmp(p,"GPIOX"))
		num=num+97;
	else
		num= -1;
	kzfree(start);
	return num;
}
示例#9
0
文件: dh.c 项目: AlexShiLucky/linux
static void dh_free_data(struct dh *dh)
{
	kzfree(dh->key);
	kzfree(dh->p);
	kzfree(dh->g);
}
static int __devinit msm_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct msm_rng_device *msm_rng_dev = NULL;
	void __iomem *base = NULL;
	int error = 0;
	int ret = 0;
	struct device *dev;

	struct msm_bus_scale_pdata *qrng_platform_support = NULL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "invalid address\n");
		error = -EFAULT;
		goto err_exit;
	}

	msm_rng_dev = kzalloc(sizeof(struct msm_rng_device), GFP_KERNEL);
	if (!msm_rng_dev) {
		dev_err(&pdev->dev, "cannot allocate memory\n");
		error = -ENOMEM;
		goto err_exit;
	}

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		error = -ENOMEM;
		goto err_iomap;
	}
	msm_rng_dev->base = base;

	msm_rng_dev->drbg_ctx = kzalloc(sizeof(struct fips_drbg_ctx_s),
					GFP_KERNEL);
	if (!msm_rng_dev->drbg_ctx) {
		dev_err(&pdev->dev, "cannot allocate memory\n");
		error = -ENOMEM;
		goto err_clk_get;
	}

	/* create a handle for clock control */
	if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
					"qcom,msm-rng-iface-clk")))
		msm_rng_dev->prng_clk = clk_get(&pdev->dev,
							"iface_clk");
	else
		msm_rng_dev->prng_clk = clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(msm_rng_dev->prng_clk)) {
		dev_err(&pdev->dev, "failed to register clock source\n");
		error = -EPERM;
		goto err_clk_get;
	}

	/* save away pdev and register driver data */
	msm_rng_dev->pdev = pdev;
	platform_set_drvdata(pdev, msm_rng_dev);

	if (pdev->dev.of_node) {
		/* Register bus client */
		qrng_platform_support = msm_bus_cl_get_pdata(pdev);
		msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
						qrng_platform_support);
		msm_rng_device_info.qrng_perf_client =
					msm_rng_dev->qrng_perf_client;
		if (!msm_rng_dev->qrng_perf_client)
			pr_err("Unable to register bus client\n");
	}

	/* Enable rng h/w */
	error = msm_rng_enable_hw(msm_rng_dev);

	if (error)
		goto rollback_clk;

	/* register with hwrng framework */
	msm_rng.priv = (unsigned long) msm_rng_dev;
	error = hwrng_register(&msm_rng);
	if (error) {
		dev_err(&pdev->dev, "failed to register hwrng\n");
		error = -EPERM;
		goto rollback_clk;
	}
	ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);

	msm_rng_class = class_create(THIS_MODULE, "msm-rng");
	if (IS_ERR(msm_rng_class)) {
		pr_err("class_create failed\n");
		return PTR_ERR(msm_rng_class);
	}

	dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
				NULL, "msm-rng");
	if (IS_ERR(dev)) {
		pr_err("Device create failed\n");
		error = PTR_ERR(dev);
		goto unregister_chrdev;
	}
	cdev_init(&msm_rng_cdev, &msm_rng_fops);

	sema_init(&msm_rng_dev->drbg_sem, 1);

	_first_msm_drbg_init(msm_rng_dev);

	return error;

unregister_chrdev:
	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
rollback_clk:
	clk_put(msm_rng_dev->prng_clk);
err_clk_get:
	iounmap(msm_rng_dev->base);
err_iomap:
	kzfree(msm_rng_dev->drbg_ctx);
	kzfree(msm_rng_dev);
err_exit:
	return error;
}
示例#11
0
文件: dh.c 项目: AlexShiLucky/linux
long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
			 char __user *buffer, size_t buflen,
			 struct keyctl_kdf_params *kdfcopy)
{
	long ret;
	ssize_t dlen;
	int secretlen;
	int outlen;
	struct keyctl_dh_params pcopy;
	struct dh dh_inputs;
	struct scatterlist outsg;
	struct dh_completion compl;
	struct crypto_kpp *tfm;
	struct kpp_request *req;
	uint8_t *secret;
	uint8_t *outbuf;
	struct kdf_sdesc *sdesc = NULL;

	if (!params || (!buffer && buflen)) {
		ret = -EINVAL;
		goto out1;
	}
	if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
		ret = -EFAULT;
		goto out1;
	}

	if (kdfcopy) {
		char *hashname;

		if (memchr_inv(kdfcopy->__spare, 0, sizeof(kdfcopy->__spare))) {
			ret = -EINVAL;
			goto out1;
		}

		if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
		    kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
			ret = -EMSGSIZE;
			goto out1;
		}

		/* get KDF name string */
		hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
		if (IS_ERR(hashname)) {
			ret = PTR_ERR(hashname);
			goto out1;
		}

		/* allocate KDF from the kernel crypto API */
		ret = kdf_alloc(&sdesc, hashname);
		kfree(hashname);
		if (ret)
			goto out1;
	}

	memset(&dh_inputs, 0, sizeof(dh_inputs));

	dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p);
	if (dlen < 0) {
		ret = dlen;
		goto out1;
	}
	dh_inputs.p_size = dlen;

	dlen = dh_data_from_key(pcopy.base, &dh_inputs.g);
	if (dlen < 0) {
		ret = dlen;
		goto out2;
	}
	dh_inputs.g_size = dlen;

	dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
	if (dlen < 0) {
		ret = dlen;
		goto out2;
	}
	dh_inputs.key_size = dlen;

	secretlen = crypto_dh_key_len(&dh_inputs);
	secret = kmalloc(secretlen, GFP_KERNEL);
	if (!secret) {
		ret = -ENOMEM;
		goto out2;
	}
	ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs);
	if (ret)
		goto out3;

	tfm = crypto_alloc_kpp("dh", 0, 0);
	if (IS_ERR(tfm)) {
		ret = PTR_ERR(tfm);
		goto out3;
	}

	ret = crypto_kpp_set_secret(tfm, secret, secretlen);
	if (ret)
		goto out4;

	outlen = crypto_kpp_maxsize(tfm);

	if (!kdfcopy) {
		/*
		 * When not using a KDF, buflen 0 is used to read the
		 * required buffer length
		 */
		if (buflen == 0) {
			ret = outlen;
			goto out4;
		} else if (outlen > buflen) {
			ret = -EOVERFLOW;
			goto out4;
		}
	}

	outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen,
			 GFP_KERNEL);
	if (!outbuf) {
		ret = -ENOMEM;
		goto out4;
	}

	sg_init_one(&outsg, outbuf, outlen);

	req = kpp_request_alloc(tfm, GFP_KERNEL);
	if (!req) {
		ret = -ENOMEM;
		goto out5;
	}

	kpp_request_set_input(req, NULL, 0);
	kpp_request_set_output(req, &outsg, outlen);
	init_completion(&compl.completion);
	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				 CRYPTO_TFM_REQ_MAY_SLEEP,
				 dh_crypto_done, &compl);

	/*
	 * For DH, generate_public_key and generate_shared_secret are
	 * the same calculation
	 */
	ret = crypto_kpp_generate_public_key(req);
	if (ret == -EINPROGRESS) {
		wait_for_completion(&compl.completion);
		ret = compl.err;
		if (ret)
			goto out6;
	}

	if (kdfcopy) {
		/*
		 * Concatenate SP800-56A otherinfo past DH shared secret -- the
		 * input to the KDF is (DH shared secret || otherinfo)
		 */
		if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo,
				   kdfcopy->otherinfolen) != 0) {
			ret = -EFAULT;
			goto out6;
		}

		ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf,
					    req->dst_len + kdfcopy->otherinfolen,
					    outlen - req->dst_len);
	} else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
		ret = req->dst_len;
	} else {
		ret = -EFAULT;
	}

out6:
	kpp_request_free(req);
out5:
	kzfree(outbuf);
out4:
	crypto_free_kpp(tfm);
out3:
	kzfree(secret);
out2:
	dh_free_data(&dh_inputs);
out1:
	kdf_dealloc(sdesc);
	return ret;
}
示例#12
0
/*----------------------------------------------------------------
 * p80211knetdev_hard_start_xmit
 *
 * Linux netdevice method for transmitting a frame.
 *
 * Arguments:
 *	skb	Linux sk_buff containing the frame.
 *	netdev	Linux netdevice.
 *
 * Side effects:
 *	If the lower layers report that buffers are full. netdev->tbusy
 *	will be set to prevent higher layers from sending more traffic.
 *
 *	Note: If this function returns non-zero, higher layers retain
 *	      ownership of the skb.
 *
 * Returns:
 *	zero on success, non-zero on failure.
 *----------------------------------------------------------------
 */
static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
						 struct net_device *netdev)
{
	int result = 0;
	int txresult = -1;
	struct wlandevice *wlandev = netdev->ml_priv;
	union p80211_hdr p80211_hdr;
	struct p80211_metawep p80211_wep;

	p80211_wep.data = NULL;

	if (!skb)
		return NETDEV_TX_OK;

	if (wlandev->state != WLAN_DEVICE_OPEN) {
		result = 1;
		goto failed;
	}

	memset(&p80211_hdr, 0, sizeof(p80211_hdr));
	memset(&p80211_wep, 0, sizeof(p80211_wep));

	if (netif_queue_stopped(netdev)) {
		netdev_dbg(netdev, "called when queue stopped.\n");
		result = 1;
		goto failed;
	}

	netif_stop_queue(netdev);

	/* Check to see that a valid mode is set */
	switch (wlandev->macmode) {
	case WLAN_MACMODE_IBSS_STA:
	case WLAN_MACMODE_ESS_STA:
	case WLAN_MACMODE_ESS_AP:
		break;
	default:
		/* Mode isn't set yet, just drop the frame
		 * and return success .
		 * TODO: we need a saner way to handle this
		 */
		if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) {
			netif_start_queue(wlandev->netdev);
			netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n");
			netdev->stats.tx_dropped++;
			result = 0;
			goto failed;
		}
		break;
	}

	/* Check for raw transmits */
	if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) {
		if (!capable(CAP_NET_ADMIN)) {
			result = 1;
			goto failed;
		}
		/* move the header over */
		memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr));
		skb_pull(skb, sizeof(p80211_hdr));
	} else {
		if (skb_ether_to_p80211
		    (wlandev, wlandev->ethconv, skb, &p80211_hdr,
		     &p80211_wep) != 0) {
			/* convert failed */
			netdev_dbg(netdev, "ether_to_80211(%d) failed.\n",
				   wlandev->ethconv);
			result = 1;
			goto failed;
		}
	}
	if (!wlandev->txframe) {
		result = 1;
		goto failed;
	}

	netif_trans_update(netdev);

	netdev->stats.tx_packets++;
	/* count only the packet payload */
	netdev->stats.tx_bytes += skb->len;

	txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);

	if (txresult == 0) {
		/* success and more buf */
		/* avail, re: hw_txdata */
		netif_wake_queue(wlandev->netdev);
		result = NETDEV_TX_OK;
	} else if (txresult == 1) {
		/* success, no more avail */
		netdev_dbg(netdev, "txframe success, no more bufs\n");
		/* netdev->tbusy = 1;  don't set here, irqhdlr */
		/*   may have already cleared it */
		result = NETDEV_TX_OK;
	} else if (txresult == 2) {
		/* alloc failure, drop frame */
		netdev_dbg(netdev, "txframe returned alloc_fail\n");
		result = NETDEV_TX_BUSY;
	} else {
		/* buffer full or queue busy, drop frame. */
		netdev_dbg(netdev, "txframe returned full or busy\n");
		result = NETDEV_TX_BUSY;
	}

failed:
	/* Free up the WEP buffer if it's not the same as the skb */
	if ((p80211_wep.data) && (p80211_wep.data != skb->data))
		kzfree(p80211_wep.data);

	/* we always free the skb here, never in a lower level. */
	if (!result)
		dev_kfree_skb(skb);

	return result;
}
示例#13
0
/**
 * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
 * @clk: struct clk * for a DPLL
 * @target_rate: desired DPLL clock rate
 *
 * Given a DPLL and a desired target rate, round the target rate to a
 * possible, programmable rate for this DPLL.  Attempts to select the
 * minimum possible n.  Stores the computed (m, n) in the DPLL's
 * dpll_data structure so set_rate() will not need to call this
 * (expensive) function again.  Returns ~0 if the target rate cannot
 * be rounded, or the rounded rate upon success.
 */
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
{
	int m, n, r, scaled_max_m;
	unsigned long scaled_rt_rp;
	unsigned long new_rate = 0;
	struct dpll_data *dd;
	unsigned long bestrate = 0, diff, bestdiff = ULONG_MAX;
	int bestm = 0, bestn = 0;
	struct dpll_rate_list *rs, *rate_cache;

	if (!clk || !clk->dpll_data)
		return ~0;

	dd = clk->dpll_data;

	rate_cache = dd->rate_cache;
	for (rs = rate_cache; rs; rs = rs->next)
		if (rs->target_rate == target_rate) {
			dd->last_rounded_m = rs->m;
			dd->last_rounded_n = rs->n;
			dd->last_rounded_rate = rs->actual_rate;
			return rs->actual_rate;
		}

	pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
		 clk->name, target_rate);

	scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;

	dd->last_rounded_rate = 0;

	for (n = dd->min_divider; n <= dd->max_divider; n++) {

		/* Is the (input clk, divider) pair valid for the DPLL? */
		r = _dpll_test_fint(clk, n);
		if (r == DPLL_FINT_UNDERFLOW)
			break;
		else if (r == DPLL_FINT_INVALID)
			continue;

		/* Compute the scaled DPLL multiplier, based on the divider */
		m = scaled_rt_rp * n;

		/*
		 * Since we're counting n up, a m overflow means we
		 * can bail out completely (since as n increases in
		 * the next iteration, there's no way that m can
		 * increase beyond the current m)
		 */
		if (m > scaled_max_m)
			break;

		r = _dpll_test_mult(&m, n, &new_rate, target_rate,
				    dd->clk_ref->rate);

		/* m can't be set low enough for this n - try with a larger n */
		if (r == DPLL_MULT_UNDERFLOW)
			continue;

#ifdef DEBUG
		pr_err("clock: target=%ld %s: m = %d: n = %d: new_rate = %ld\n",
			 target_rate, clk->name, m, n, new_rate);
#endif

		if (target_rate > new_rate)
			diff = target_rate - new_rate;
		else
			diff = new_rate - target_rate;
		if (diff < bestdiff) {
			bestm = m;
			bestn = n;
			bestrate = new_rate;
			bestdiff = diff;
		}
		if (new_rate == target_rate)
			break;
	}
	/*
	 * The following if verifies that the new frequency is within 0.01% of
	 * the target frequency.
	 */
	if (bestdiff < (ULONG_MAX / 10000) &&
				      ((bestdiff * 10000) / target_rate) < 1) {
		dd->last_rounded_m = bestm;
		dd->last_rounded_n = bestn;
		dd->last_rounded_rate = bestrate;
		rs = kzalloc(sizeof (struct dpll_rate_list), GFP_ATOMIC);
		if (rs) {
			rs->m = bestm;
			rs->n = bestn;
			rs->target_rate = target_rate;
			rs->actual_rate = bestrate;
			if (rate_cache == dd->rate_cache) {
				rs->next = dd->rate_cache;
				dd->rate_cache = rs;
			} else
				kzfree(rs);
		}
		return bestrate;
	} else
		return 0;
}
示例#14
0
/*
 * Sign operation is performed with the private key in the TPM.
 */
static int tpm_key_sign(struct tpm_key *tk,
			struct kernel_pkey_params *params,
			const void *in, void *out)
{
	struct tpm_buf *tb;
	uint32_t keyhandle;
	uint8_t srkauth[SHA1_DIGEST_SIZE];
	uint8_t keyauth[SHA1_DIGEST_SIZE];
	void *asn1_wrapped = NULL;
	uint32_t in_len = params->in_len;
	int r;

	pr_devel("==>%s()\n", __func__);

	if (strcmp(params->encoding, "pkcs1"))
		return -ENOPKG;

	if (params->hash_algo) {
		const struct asn1_template *asn1 =
						lookup_asn1(params->hash_algo);

		if (!asn1)
			return -ENOPKG;

		/* request enough space for the ASN.1 template + input hash */
		asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
		if (!asn1_wrapped)
			return -ENOMEM;

		/* Copy ASN.1 template, then the input */
		memcpy(asn1_wrapped, asn1->data, asn1->size);
		memcpy(asn1_wrapped + asn1->size, in, in_len);

		in = asn1_wrapped;
		in_len += asn1->size;
	}

	if (in_len > tk->key_len / 8 - 11) {
		r = -EOVERFLOW;
		goto error_free_asn1_wrapped;
	}

	r = -ENOMEM;
	tb = kzalloc(sizeof(*tb), GFP_KERNEL);
	if (!tb)
		goto error_free_asn1_wrapped;

	/* TODO: Handle a non-all zero SRK authorization */
	memset(srkauth, 0, sizeof(srkauth));

	r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
			 tk->blob, tk->blob_len, &keyhandle);
	if (r < 0) {
		pr_devel("loadkey2 failed (%d)\n", r);
		goto error_free_tb;
	}

	/* TODO: Handle a non-all zero key authorization */
	memset(keyauth, 0, sizeof(keyauth));

	r = tpm_sign(tb, keyhandle, keyauth, in, in_len, out, params->out_len);
	if (r < 0)
		pr_devel("tpm_sign failed (%d)\n", r);

	if (tpm_flushspecific(tb, keyhandle) < 0)
		pr_devel("flushspecific failed (%d)\n", r);

error_free_tb:
	kzfree(tb);
error_free_asn1_wrapped:
	kfree(asn1_wrapped);
	pr_devel("<==%s() = %d\n", __func__, r);
	return r;
}
示例#15
0
/*
 * tpm_st33_i2c_probe initialize the TPM device
 * @param: client, the i2c_client drescription (TPM I2C description).
 * @param: id, the i2c_device_id struct.
 * @return: 0 in case of success.
 *	 -1 in other case.
 */
static int
tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int err;
	u8 intmask;
	struct tpm_chip *chip;
	struct st33zp24_platform_data *platform_data;

	if (client == NULL) {
		pr_info("%s: i2c client is NULL. Device not accessible.\n",
			__func__);
		err = -ENODEV;
		goto end;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_info(&client->dev, "client not i2c capable\n");
		err = -ENODEV;
		goto end;
	}

	chip = tpm_register_hardware(&client->dev, &st_i2c_tpm);
	if (!chip) {
		dev_info(&client->dev, "fail chip\n");
		err = -ENODEV;
		goto end;
	}

	platform_data = client->dev.platform_data;

	if (!platform_data) {
		dev_info(&client->dev, "chip not available\n");
		err = -ENODEV;
		goto _tpm_clean_answer;
	}

	platform_data->tpm_i2c_buffer[0] =
	    kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
	if (platform_data->tpm_i2c_buffer[0] == NULL) {
		err = -ENOMEM;
		goto _tpm_clean_answer;
	}
	platform_data->tpm_i2c_buffer[1] =
	    kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
	if (platform_data->tpm_i2c_buffer[1] == NULL) {
		err = -ENOMEM;
		goto _tpm_clean_response1;
	}

	TPM_VPRIV(chip) = client;

	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);

	chip->vendor.locality = LOCALITY0;

	if (power_mgt) {
		err = gpio_request(platform_data->io_lpcpd, "TPM IO_LPCPD");
		if (err)
			goto _gpio_init1;
		gpio_set_value(platform_data->io_lpcpd, 1);
	}

	if (interrupts) {
		init_completion(&platform_data->irq_detection);
		if (request_locality(chip) != LOCALITY0) {
			err = -ENODEV;
			goto _tpm_clean_response2;
		}
		err = gpio_request(platform_data->io_serirq, "TPM IO_SERIRQ");
		if (err)
			goto _gpio_init2;

		clear_interruption(client);
		err = request_irq(gpio_to_irq(platform_data->io_serirq),
				&tpm_ioserirq_handler,
				IRQF_TRIGGER_HIGH,
				"TPM SERIRQ management", chip);
		if (err < 0) {
			dev_err(chip->dev , "TPM SERIRQ signals %d not available\n",
				gpio_to_irq(platform_data->io_serirq));
			goto _irq_set;
		}

		err = I2C_READ_DATA(client, TPM_INT_ENABLE, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		intmask |= TPM_INTF_CMD_READY_INT
			|  TPM_INTF_FIFO_AVALAIBLE_INT
			|  TPM_INTF_WAKE_UP_READY_INT
			|  TPM_INTF_LOCALITY_CHANGE_INT
			|  TPM_INTF_STS_VALID_INT
			|  TPM_INTF_DATA_AVAIL_INT;

		err = I2C_WRITE_DATA(client, TPM_INT_ENABLE, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		intmask = TPM_GLOBAL_INT_ENABLE;
		err = I2C_WRITE_DATA(client, (TPM_INT_ENABLE + 3), &intmask, 1);
		if (err < 0)
			goto _irq_set;

		err = I2C_READ_DATA(client, TPM_INT_STATUS, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		chip->vendor.irq = interrupts;

		tpm_gen_interrupt(chip);
	}

	tpm_get_timeouts(chip);
	tpm_do_selftest(chip);

	dev_info(chip->dev, "TPM I2C Initialized\n");
	return 0;
_irq_set:
	free_irq(gpio_to_irq(platform_data->io_serirq), (void *)chip);
_gpio_init2:
	if (interrupts)
		gpio_free(platform_data->io_serirq);
_gpio_init1:
	if (power_mgt)
		gpio_free(platform_data->io_lpcpd);
_tpm_clean_response2:
	kzfree(platform_data->tpm_i2c_buffer[1]);
	platform_data->tpm_i2c_buffer[1] = NULL;
_tpm_clean_response1:
	kzfree(platform_data->tpm_i2c_buffer[0]);
	platform_data->tpm_i2c_buffer[0] = NULL;
_tpm_clean_answer:
	tpm_remove_hardware(chip->dev);
end:
	pr_info("TPM I2C initialisation fail\n");
	return err;
}
示例#16
0
static int __init rtac_init(void)
{
	int i = 0;
	pr_debug("%s\n", __func__);

	/* Driver */
	atomic_set(&rtac_common.usage_count, 0);
	atomic_set(&rtac_common.apr_err_code, 0);

	/* ADM */
	memset(&rtac_adm_data, 0, sizeof(rtac_adm_data));
	memset(&rtac_adm_data_v2, 0, sizeof(rtac_adm_data_v2));
	rtac_adm_apr_data.apr_handle = NULL;
	atomic_set(&rtac_adm_apr_data.cmd_state, 0);
	init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
	mutex_init(&rtac_adm_mutex);
	mutex_init(&rtac_adm_apr_mutex);

	rtac_adm_buffer = kzalloc(
		rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
	if (rtac_adm_buffer == NULL) {
		pr_err("%s: Could not allocate payload of size = %d\n",
			__func__, rtac_cal[ADM_RTAC_CAL].map_data.map_size);
		goto nomem;
	}

	/* ASM */
	for (i = 0; i < SESSION_MAX+1; i++) {
		rtac_asm_apr_data[i].apr_handle = NULL;
		atomic_set(&rtac_asm_apr_data[i].cmd_state, 0);
		init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
	}
	mutex_init(&rtac_asm_apr_mutex);

	rtac_asm_buffer = kzalloc(
		rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
	if (rtac_asm_buffer == NULL) {
		pr_err("%s: Could not allocate payload of size = %d\n",
			__func__, rtac_cal[ASM_RTAC_CAL].map_data.map_size);
		kzfree(rtac_adm_buffer);
		goto nomem;
	}

	/* Voice */
	memset(&rtac_voice_data, 0, sizeof(rtac_voice_data));
	for (i = 0; i < RTAC_VOICE_MODES; i++) {
		rtac_voice_apr_data[i].apr_handle = NULL;
		atomic_set(&rtac_voice_apr_data[i].cmd_state, 0);
		init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait);
	}
	mutex_init(&rtac_voice_mutex);
	mutex_init(&rtac_voice_apr_mutex);

	rtac_voice_buffer = kzalloc(
		rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
	if (rtac_voice_buffer == NULL) {
		pr_err("%s: Could not allocate payload of size = %d\n",
			__func__, rtac_cal[VOICE_RTAC_CAL].map_data.map_size);
		kzfree(rtac_adm_buffer);
		kzfree(rtac_asm_buffer);
		goto nomem;
	}

	return misc_register(&rtac_misc);
nomem:
	return -ENOMEM;
}
示例#17
0
int fscrypt_get_encryption_info(struct inode *inode)
{
	struct fscrypt_info *crypt_info;
	struct fscrypt_context ctx;
	struct crypto_skcipher *ctfm;
	const char *cipher_str;
	int keysize;
	u8 *raw_key = NULL;
	int res;

	if (inode->i_crypt_info)
		return 0;

	res = fscrypt_initialize(inode->i_sb->s_cop->flags);
	if (res)
		return res;

	res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
	if (res < 0) {
		if (!fscrypt_dummy_context_enabled(inode) ||
		    inode->i_sb->s_cop->is_encrypted(inode))
			return res;
		/* Fake up a context for an unencrypted directory */
		memset(&ctx, 0, sizeof(ctx));
		ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
		ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
		ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
		memset(ctx.master_key_descriptor, 0x42, FS_KEY_DESCRIPTOR_SIZE);
	} else if (res != sizeof(ctx)) {
		return -EINVAL;
	}

	if (ctx.format != FS_ENCRYPTION_CONTEXT_FORMAT_V1)
		return -EINVAL;

	if (ctx.flags & ~FS_POLICY_FLAGS_VALID)
		return -EINVAL;

	crypt_info = kmem_cache_alloc(fscrypt_info_cachep, GFP_NOFS);
	if (!crypt_info)
		return -ENOMEM;

	crypt_info->ci_flags = ctx.flags;
	crypt_info->ci_data_mode = ctx.contents_encryption_mode;
	crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
	crypt_info->ci_ctfm = NULL;
	crypt_info->ci_essiv_tfm = NULL;
	memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
				sizeof(crypt_info->ci_master_key));

	res = determine_cipher_type(crypt_info, inode, &cipher_str, &keysize);
	if (res)
		goto out;

	/*
	 * This cannot be a stack buffer because it is passed to the scatterlist
	 * crypto API as part of key derivation.
	 */
	res = -ENOMEM;
	raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS);
	if (!raw_key)
		goto out;

	res = validate_user_key(crypt_info, &ctx, raw_key, FS_KEY_DESC_PREFIX,
				keysize);
	if (res && inode->i_sb->s_cop->key_prefix) {
		int res2 = validate_user_key(crypt_info, &ctx, raw_key,
					     inode->i_sb->s_cop->key_prefix,
					     keysize);
		if (res2) {
			if (res2 == -ENOKEY)
				res = -ENOKEY;
			goto out;
		}
	} else if (res) {
		goto out;
	}
	ctfm = crypto_alloc_skcipher(cipher_str, 0, 0);
	if (!ctfm || IS_ERR(ctfm)) {
		res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
		pr_debug("%s: error %d (inode %lu) allocating crypto tfm\n",
			 __func__, res, inode->i_ino);
		goto out;
	}
	crypt_info->ci_ctfm = ctfm;
	crypto_skcipher_clear_flags(ctfm, ~0);
	crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_WEAK_KEY);
	/*
	 * if the provided key is longer than keysize, we use the first
	 * keysize bytes of the derived key only
	 */
	res = crypto_skcipher_setkey(ctfm, raw_key, keysize);
	if (res)
		goto out;

	if (S_ISREG(inode->i_mode) &&
	    crypt_info->ci_data_mode == FS_ENCRYPTION_MODE_AES_128_CBC) {
		res = init_essiv_generator(crypt_info, raw_key, keysize);
		if (res) {
			pr_debug("%s: error %d (inode %lu) allocating essiv tfm\n",
				 __func__, res, inode->i_ino);
			goto out;
		}
	}
	if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL)
		crypt_info = NULL;
out:
	if (res == -ENOKEY)
		res = 0;
	put_crypt_info(crypt_info);
	kzfree(raw_key);
	return res;
}