コード例 #1
0
ファイル: file.c プロジェクト: cilynx/dd-wrt
/**
 * sysfs_chmod_file - update the modified mode value on an object attribute.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @mode: file permissions.
 *
 */
int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
{
	struct sysfs_dirent *victim_sd = NULL;
	struct dentry *victim = NULL;
	struct inode * inode;
	struct iattr newattrs;
	int rc;

	rc = -ENOENT;
	victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
	if (!victim_sd)
		goto out;

	victim = sysfs_get_dentry(victim_sd);
	if (IS_ERR(victim)) {
		rc = PTR_ERR(victim);
		victim = NULL;
		goto out;
	}

	inode = victim->d_inode;
	mutex_lock(&inode->i_mutex);
	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
	rc = notify_change(victim, &newattrs);
	mutex_unlock(&inode->i_mutex);
 out:
	dput(victim);
	sysfs_put(victim_sd);
	return rc;
}
コード例 #2
0
ファイル: file.c プロジェクト: cilynx/dd-wrt
/**
 * sysfs_update_file - update the modified timestamp on an object attribute.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 */
int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
{
	struct sysfs_dirent *victim_sd = NULL;
	struct dentry *victim = NULL;
	int rc;

	rc = -ENOENT;
	victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
	if (!victim_sd)
		goto out;

	victim = sysfs_get_dentry(victim_sd);
	if (IS_ERR(victim)) {
		rc = PTR_ERR(victim);
		victim = NULL;
		goto out;
	}

	mutex_lock(&victim->d_inode->i_mutex);
	victim->d_inode->i_mtime = CURRENT_TIME;
	fsnotify_modify(victim);
	mutex_unlock(&victim->d_inode->i_mutex);
	rc = 0;
 out:
	dput(victim);
	sysfs_put(victim_sd);
	return rc;
}
コード例 #3
0
ファイル: group.c プロジェクト: Cool-Joe/imx23-audio
/**
 * sysfs_remove_link_from_group - remove a symlink from an attribute group.
 * @kobj:	The kobject containing the group.
 * @group_name:	The name of the group.
 * @link_name:	The name of the symlink to remove.
 */
void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
				  const char *link_name)
{
	struct sysfs_dirent *dir_sd;

	dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
	if (dir_sd) {
		sysfs_hash_and_remove(dir_sd, NULL, link_name);
		sysfs_put(dir_sd);
	}
}
コード例 #4
0
ファイル: file.c プロジェクト: cilynx/dd-wrt
/**
 * sysfs_remove_file_from_group - remove an attribute file from a group.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @group: group name.
 */
void sysfs_remove_file_from_group(struct kobject *kobj,
		const struct attribute *attr, const char *group)
{
	struct sysfs_dirent *dir_sd;

	dir_sd = sysfs_get_dirent(kobj->sd, group);
	if (dir_sd) {
		sysfs_hash_and_remove(dir_sd, attr->name);
		sysfs_put(dir_sd);
	}
}
コード例 #5
0
ファイル: group.c プロジェクト: Cool-Joe/imx23-audio
/**
 * sysfs_unmerge_group - remove files from a pre-existing attribute group.
 * @kobj:	The kobject containing the group.
 * @grp:	The files to remove and the attribute group they belong to.
 */
void sysfs_unmerge_group(struct kobject *kobj,
		       const struct attribute_group *grp)
{
	struct sysfs_dirent *dir_sd;
	struct attribute *const *attr;

	dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
	if (dir_sd) {
		for (attr = grp->attrs; *attr; ++attr)
			sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
		sysfs_put(dir_sd);
	}
}
コード例 #6
0
ファイル: group.c プロジェクト: Cool-Joe/imx23-audio
/**
 * sysfs_add_link_to_group - add a symlink to an attribute group.
 * @kobj:	The kobject containing the group.
 * @group_name:	The name of the group.
 * @target:	The target kobject of the symlink to create.
 * @link_name:	The name of the symlink to create.
 */
int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
			    struct kobject *target, const char *link_name)
{
	struct sysfs_dirent *dir_sd;
	int error = 0;

	dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
	if (!dir_sd)
		return -ENOENT;

	error = sysfs_create_link_sd(dir_sd, target, link_name);
	sysfs_put(dir_sd);

	return error;
}
コード例 #7
0
ファイル: file.c プロジェクト: cilynx/dd-wrt
/**
 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @group: group name.
 */
int sysfs_add_file_to_group(struct kobject *kobj,
		const struct attribute *attr, const char *group)
{
	struct sysfs_dirent *dir_sd;
	int error;

	dir_sd = sysfs_get_dirent(kobj->sd, group);
	if (!dir_sd)
		return -ENOENT;

	error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
	sysfs_put(dir_sd);

	return error;
}
コード例 #8
0
ファイル: group.c プロジェクト: PennPanda/linux-repo
void sysfs_remove_group(struct kobject * kobj, 
			const struct attribute_group * grp)
{
	struct sysfs_dirent *dir_sd = kobj->sd;
	struct sysfs_dirent *sd;

	if (grp->name) {
		sd = sysfs_get_dirent(dir_sd, grp->name);
		BUG_ON(!sd);
	} else
		sd = sysfs_get(dir_sd);

	remove_files(sd, grp);
	if (grp->name)
		sysfs_remove_subdir(sd);

	sysfs_put(sd);
}
コード例 #9
0
ファイル: vedev.c プロジェクト: cloudlinuxadmin/cl7-kernel
static struct kobject *ve_kobj_path_create(char *path)
{
	char *e, *p = path;
	struct sysfs_dirent *sd, *parent_sd = get_exec_env()->_sysfs_root;
	struct kobject *k, *pk = NULL;

	if (*p == '/')
		p++;

	while (1) {
		e = strchr(p, '/');
		if (e)
			*e = '\0';
		sd = sysfs_get_dirent(parent_sd, p);
		if (sd == NULL) {
new:			k = kobject_create_and_add(p, pk);
			kobject_put(pk);
			if (!k)
				return ERR_PTR(-ENOMEM);
		} else {
			if (!(sd->s_flags & SYSFS_DIR)) {
コード例 #10
0
ファイル: group.c プロジェクト: Cool-Joe/imx23-audio
/**
 * sysfs_merge_group - merge files into a pre-existing attribute group.
 * @kobj:	The kobject containing the group.
 * @grp:	The files to create and the attribute group they belong to.
 *
 * This function returns an error if the group doesn't exist or any of the
 * files already exist in that group, in which case none of the new files
 * are created.
 */
int sysfs_merge_group(struct kobject *kobj,
		       const struct attribute_group *grp)
{
	struct sysfs_dirent *dir_sd;
	int error = 0;
	struct attribute *const *attr;
	int i;

	dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
	if (!dir_sd)
		return -ENOENT;

	for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
		error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
	if (error) {
		while (--i >= 0)
			sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name);
	}
	sysfs_put(dir_sd);

	return error;
}
コード例 #11
0
ファイル: group.c プロジェクト: Cool-Joe/imx23-audio
void sysfs_remove_group(struct kobject * kobj, 
			const struct attribute_group * grp)
{
	struct sysfs_dirent *dir_sd = kobj->sd;
	struct sysfs_dirent *sd;

	if (grp->name) {
		sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
		if (!sd) {
			WARN(!sd, KERN_WARNING "sysfs group %p not found for "
				"kobject '%s'\n", grp, kobject_name(kobj));
			return;
		}
	} else
		sd = sysfs_get(dir_sd);

	remove_files(sd, kobj, grp);
	if (grp->name)
		sysfs_remove_subdir(sd);

	sysfs_put(sd);
}
コード例 #12
0
ファイル: mdp3_ctrl.c プロジェクト: kaleidicforks/sturgeon
int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
	struct msm_mdp_interface *mdp3_interface = &mfd->mdp;
	struct mdp3_session_data *mdp3_session = NULL;
	u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
	int rc;
	int splash_mismatch = 0;

	pr_info("mdp3_ctrl_init\n");
	rc = mdp3_parse_dt_splash(mfd);
	if (rc)
		splash_mismatch = 1;

	mdp3_interface->on_fnc = mdp3_ctrl_on;
	mdp3_interface->off_fnc = mdp3_ctrl_off;
	mdp3_interface->do_histogram = NULL;
	mdp3_interface->cursor_update = NULL;
	mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->lut_update = mdp3_ctrl_lut_update;
	mdp3_interface->configure_panel = mdp3_update_panel_info;

	mdp3_session = kzalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
	if (!mdp3_session) {
		pr_err("fail to allocate mdp3 private data structure");
		return -ENOMEM;
	}
	mutex_init(&mdp3_session->lock);
	INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
	INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
	atomic_set(&mdp3_session->vsync_countdown, 0);
	mutex_init(&mdp3_session->histo_lock);
	mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
	if (!mdp3_session->dma) {
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_dma_init(mdp3_session->dma);
	if (rc) {
		pr_err("fail to init dma\n");
		goto init_done;
	}

	intf_type = mdp3_ctrl_get_intf_type(mfd);
	mdp3_session->intf = mdp3_get_display_intf(intf_type);
	if (!mdp3_session->intf) {
		rc = -ENODEV;
		goto init_done;
	}
	rc = mdp3_intf_init(mdp3_session->intf);
	if (rc) {
		pr_err("fail to init interface\n");
		goto init_done;
	}

	mdp3_session->dma->output_config.out_sel = intf_type;
	mdp3_session->mfd = mfd;
	mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
	mdp3_session->status = mdp3_session->intf->active;
	mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
	mdp3_bufq_init(&mdp3_session->bufq_in);
	mdp3_bufq_init(&mdp3_session->bufq_out);
	mdp3_session->histo_status = 0;
	mdp3_session->lut_sel = 0;
	BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head);

	init_timer(&mdp3_session->vsync_timer);
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate;
	mfd->mdp.private1 = mdp3_session;
	init_completion(&mdp3_session->dma_completion);
	if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
		mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done;

	rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
	if (rc) {
		pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
		goto init_done;
	}

	mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL,
							"vsync_event");
	if (!mdp3_session->vsync_event_sd) {
		pr_err("vsync_event sysfs lookup failed\n");
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_create_sysfs_link(dev);
	if (rc)
		pr_warn("problem creating link to mdp sysfs\n");

	kobject_uevent(&dev->kobj, KOBJ_ADD);
	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");

	if (mdp3_get_cont_spash_en()) {
		mdp3_session->clk_on = 1;
		mdp3_session->in_splash_screen = 1;
		mdp3_ctrl_notifier_register(mdp3_session,
			&mdp3_session->mfd->mdp_sync_pt_data.notifier);
	}

	if (splash_mismatch) {
		pr_err("splash memory mismatch, stop splash\n");
		mdp3_ctrl_off(mfd);
	}

	mdp3_session->vsync_before_commit = true;
init_done:
	if (IS_ERR_VALUE(rc))
		kfree(mdp3_session);

	return rc;
}
コード例 #13
0
static int
mic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	int brdnum = mic_data.dd_numdevs;
	int err = 0;
	bd_info_t *bd_info;
	mic_ctx_t *mic_ctx;
#ifdef CONFIG_PCI_MSI
	int i=0;
#endif
	if ((bd_info = (bd_info_t *)kzalloc(sizeof(bd_info_t), GFP_KERNEL)) == NULL) {
		printk("MIC: probe failed allocating memory for bd_info\n");
		return -ENOSPC;
	}

	mic_ctx = &bd_info->bi_ctx;
	mic_ctx->bd_info = bd_info;
	mic_ctx->bi_id = brdnum;
	mic_ctx->bi_pdev = pdev;
	mic_ctx->msie = 0;
	mic_data.dd_bi[brdnum] = bd_info;

	if ((err = pci_enable_device(pdev))) {
		printk("pci_enable failed board #%d\n", brdnum);
		goto probe_freebd;
	}

	pci_set_master(pdev);
	err = pci_reenable_device(pdev);
	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
	if (err) {
		printk("mic %d: ERROR DMA not available\n", brdnum);
		goto probe_freebd;
	}
	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
	if (err) {
		printk("mic %d: ERROR pci_set_consistent_dma_mask(64) %d\n", brdnum, err);
		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
		if (err) {
			printk("mic %d: ERROR pci_set_consistent_dma_mask(32) %d\n", brdnum, err);
			goto probe_freebd;
		}
	}

	// Allocate bar 4 for MMIO and GTT
	bd_info->bi_ctx.mmio.pa = pci_resource_start(pdev, DLDR_MMIO_BAR);
	bd_info->bi_ctx.mmio.len = pci_resource_len(pdev, DLDR_MMIO_BAR);
	if (request_mem_region(bd_info->bi_ctx.mmio.pa,
	    bd_info->bi_ctx.mmio.len, "mic") == NULL) {
		printk("mic %d: failed to reserve mmio space\n", brdnum);
		goto probe_freebd;
	}

	// Allocate bar 0 for access Aperture
	bd_info->bi_ctx.aper.pa = pci_resource_start(pdev, DLDR_APT_BAR);
	bd_info->bi_ctx.aper.len = pci_resource_len(pdev, DLDR_APT_BAR);
	if (request_mem_region(bd_info->bi_ctx.aper.pa,
	    bd_info->bi_ctx.aper.len, "mic") == NULL) {
		printk("mic %d: failed to reserve aperture space\n", brdnum);
		goto probe_relmmio;
	}

#ifdef CONFIG_PCI_MSI
	if (mic_msi_enable){
		for (i = 0; i < MIC_NUM_MSIX_ENTRIES; i ++)
			bd_info->bi_msix_entries[i].entry = i;
		err = pci_enable_msix(mic_ctx->bi_pdev, bd_info->bi_msix_entries,
				      MIC_NUM_MSIX_ENTRIES);
		if (err == 0 ) {
			// Only support 1 MSIx for now
			err = request_irq(bd_info->bi_msix_entries[0].vector,
					  mic_irq_isr, 0, "mic", mic_ctx);
			if (err != 0) {
				printk("MIC: Error in request_irq %d\n", err);
				goto probe_relaper;
			}
			mic_ctx->msie = 1;
		}
	}
#endif

	// TODO: this needs to be hardened and actually return errors
	if ((err = adapter_init_device(mic_ctx)) != 0) {
		printk("MIC: Adapter init device failed %d\n", err);
		goto probe_relaper;
	}

	// Adding sysfs entries
	set_sysfs_entries(mic_ctx);

	bd_info->bi_sysfsdev = device_create(mic_lindata.dd_class, &pdev->dev,
			mic_lindata.dd_dev + 2 + mic_ctx->bd_info->bi_ctx.bi_id,
			NULL, "mic%d", mic_ctx->bd_info->bi_ctx.bi_id);
	err = sysfs_create_group(&mic_ctx->bd_info->bi_sysfsdev->kobj, &bd_attr_group);
	mic_ctx->sysfs_state = sysfs_get_dirent(mic_ctx->bd_info->bi_sysfsdev->kobj.sd,
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
				//NULL,
#endif
				"state");

	dev_set_drvdata(mic_ctx->bd_info->bi_sysfsdev, mic_ctx);

	if (!mic_ctx->msie)
		if ((err = request_irq(mic_ctx->bi_pdev->irq, mic_irq_isr,
				       IRQF_SHARED, "mic", mic_ctx)) != 0) {
			printk("MIC: Error in request_irq %d\n", err);
			goto probe_unmapaper;
		}

	adapter_probe(&bd_info->bi_ctx);

	if (mic_ctx->bi_psmi.enabled) {
		err = sysfs_create_group(&mic_ctx->bd_info->bi_sysfsdev->kobj,
						&psmi_attr_group);
		err = device_create_bin_file(mic_ctx->bd_info->bi_sysfsdev,
						&mic_psmi_ptes_attr);
	}

	adapter_wait_reset(mic_ctx);

	// Adding a board instance so increment the total number of MICs in the system.
	list_add_tail(&bd_info->bi_list, &mic_data.dd_bdlist);
	mic_data.dd_numdevs++;
	printk("mic_probe %d:%d:%d as board #%d\n", pdev->bus->number,
	       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), brdnum);
	return 0;

probe_unmapaper:
	wait_event(mic_ctx->ioremapwq, mic_ctx->aper.va || mic_ctx->state == MIC_RESETFAIL);
	if (mic_ctx->aper.va)
		iounmap((void *)bd_info->bi_ctx.aper.va);
	iounmap((void *)bd_info->bi_ctx.mmio.va);

probe_relaper:
	release_mem_region(bd_info->bi_ctx.aper.pa, bd_info->bi_ctx.aper.len);

probe_relmmio:
	release_mem_region(bd_info->bi_ctx.mmio.pa, bd_info->bi_ctx.mmio.len);

probe_freebd:
	kfree(bd_info);
	return err;
}
コード例 #14
0
int vsp_init(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct ttm_bo_device *bdev = &dev_priv->bdev;
	struct vsp_private *vsp_priv;
	bool is_iomem;
	int ret;
	unsigned int context_size;

	VSP_DEBUG("init vsp private data structure\n");
	vsp_priv = kmalloc(sizeof(struct vsp_private), GFP_KERNEL);
	if (vsp_priv == NULL)
		return -1;

	memset(vsp_priv, 0, sizeof(*vsp_priv));

	/* get device --> drm_device --> drm_psb_private --> vsp_priv
	 * for psb_vsp_pmstate_show: vsp_pmpolicy
	 * if not pci_set_drvdata, can't get drm_device from device
	 */
	/* pci_set_drvdata(dev->pdev, dev); */
	if (device_create_file(&dev->pdev->dev,
			       &dev_attr_vsp_pmstate))
		DRM_ERROR("TOPAZ: could not create sysfs file\n");

	vsp_priv->sysfs_pmstate = sysfs_get_dirent(
		dev->pdev->dev.kobj.sd, NULL,
		"vsp_pmstate");

	vsp_priv->vsp_cmd_num = 0;
	vsp_priv->fw_loaded = VSP_FW_NONE;
	vsp_priv->current_sequence = 0;
	vsp_priv->vsp_state = VSP_STATE_DOWN;
	vsp_priv->dev = dev;
	vsp_priv->coded_buf = NULL;

	vsp_priv->context_num = 0;
	atomic_set(&dev_priv->vsp_mmu_invaldc, 0);

	dev_priv->vsp_private = vsp_priv;

	vsp_priv->cmd_queue_sz = VSP_CMD_QUEUE_SIZE *
		sizeof(struct vss_command_t);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	ret = ttm_buffer_object_create(bdev,
				       vsp_priv->cmd_queue_sz,
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, 0, NULL, &vsp_priv->cmd_queue_bo);
#else
	ret = ttm_buffer_object_create(bdev,
				       vsp_priv->cmd_queue_sz,
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, NULL, &vsp_priv->cmd_queue_bo);
#endif
	if (ret != 0) {
		DRM_ERROR("VSP: failed to allocate VSP cmd queue\n");
		goto out_clean;
	}

	vsp_priv->ack_queue_sz = VSP_ACK_QUEUE_SIZE *
		sizeof(struct vss_response_t);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	ret = ttm_buffer_object_create(bdev,
				       vsp_priv->ack_queue_sz,
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, 0, NULL, &vsp_priv->ack_queue_bo);
#else
	ret = ttm_buffer_object_create(bdev,
				       vsp_priv->ack_queue_sz,
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, NULL, &vsp_priv->ack_queue_bo);
#endif
	if (ret != 0) {
		DRM_ERROR("VSP: failed to allocate VSP cmd ack queue\n");
		goto out_clean;
	}

	/* Create setting buffer */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
	ret =  ttm_buffer_object_create(bdev,
				       sizeof(struct vsp_settings_t),
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, 0, NULL, &vsp_priv->setting_bo);
#else
	ret =  ttm_buffer_object_create(bdev,
				       sizeof(struct vsp_settings_t),
				       ttm_bo_type_kernel,
				       DRM_PSB_FLAG_MEM_MMU |
				       TTM_PL_FLAG_NO_EVICT,
				       0, 0, NULL, &vsp_priv->setting_bo);
#endif
	if (ret != 0) {
		DRM_ERROR("VSP: failed to allocate VSP setting buffer\n");
		goto out_clean;
	}

	/* map cmd queue */
	ret = ttm_bo_kmap(vsp_priv->cmd_queue_bo, 0,
			  vsp_priv->cmd_queue_bo->num_pages,
			  &vsp_priv->cmd_kmap);
	if (ret) {
		DRM_ERROR("drm_bo_kmap failed: %d\n", ret);
		ttm_bo_unref(&vsp_priv->cmd_queue_bo);
		ttm_bo_kunmap(&vsp_priv->cmd_kmap);
		goto out_clean;
	}

	vsp_priv->cmd_queue = ttm_kmap_obj_virtual(&vsp_priv->cmd_kmap,
						   &is_iomem);


	/* map ack queue */
	ret = ttm_bo_kmap(vsp_priv->ack_queue_bo, 0,
			  vsp_priv->ack_queue_bo->num_pages,
			  &vsp_priv->ack_kmap);
	if (ret) {
		DRM_ERROR("drm_bo_kmap failed: %d\n", ret);
		ttm_bo_unref(&vsp_priv->ack_queue_bo);
		ttm_bo_kunmap(&vsp_priv->ack_kmap);
		goto out_clean;
	}

	vsp_priv->ack_queue = ttm_kmap_obj_virtual(&vsp_priv->ack_kmap,
						   &is_iomem);

	/* map vsp setting */
	ret = ttm_bo_kmap(vsp_priv->setting_bo, 0,
			  vsp_priv->setting_bo->num_pages,
			  &vsp_priv->setting_kmap);
	if (ret) {
		DRM_ERROR("drm_bo_kmap setting_bo failed: %d\n", ret);
		ttm_bo_unref(&vsp_priv->setting_bo);
		ttm_bo_kunmap(&vsp_priv->setting_kmap);
		goto out_clean;
	}
	vsp_priv->setting = ttm_kmap_obj_virtual(&vsp_priv->setting_kmap,
						 &is_iomem);

	vsp_priv->vp8_filp[0] = NULL;
	vsp_priv->vp8_filp[1] = NULL;
	vsp_priv->context_vp8_num = 0;

	vsp_priv->vp8_cmd_num = 0;

	spin_lock_init(&vsp_priv->lock);
	mutex_init(&vsp_priv->vsp_mutex);

	INIT_DELAYED_WORK(&vsp_priv->vsp_suspend_wq,
			&psb_powerdown_vsp);
	INIT_DELAYED_WORK(&vsp_priv->vsp_irq_wq,
			&vsp_irq_task);

	return 0;
out_clean:
	vsp_deinit(dev);
	return -1;
}
コード例 #15
0
int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
	struct msm_mdp_interface *mdp3_interface = &mfd->mdp;
	struct mdp3_session_data *mdp3_session = NULL;
	u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
	int rc;

	pr_debug("mdp3_ctrl_init\n");
	mdp3_interface->on_fnc = mdp3_ctrl_on;
	mdp3_interface->off_fnc = mdp3_ctrl_off;
	mdp3_interface->do_histogram = NULL;
	mdp3_interface->cursor_update = NULL;
	mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->lut_update = mdp3_ctrl_lut_update;

	mdp3_session = kmalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
	if (!mdp3_session) {
		pr_err("fail to allocate mdp3 private data structure");
		return -ENOMEM;
	}
	memset(mdp3_session, 0, sizeof(struct mdp3_session_data));
	mutex_init(&mdp3_session->lock);
	mutex_init(&mdp3_session->histo_lock);
	mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
	if (!mdp3_session->dma) {
		rc = -ENODEV;
		goto init_done;
	}

	intf_type = mdp3_ctrl_get_intf_type(mfd);
	mdp3_session->intf = mdp3_get_display_intf(intf_type);
	if (!mdp3_session->intf) {
		rc = -ENODEV;
		goto init_done;
	}

	mdp3_session->mfd = mfd;
	mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
	mdp3_session->status = 0;
	mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
	mdp3_bufq_init(&mdp3_session->bufq_in);
	mdp3_bufq_init(&mdp3_session->bufq_out);
	mdp3_session->histo_status = 0;
	mdp3_session->lut_sel = 0;

	init_timer(&mdp3_session->vsync_timer);
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate;
	mfd->mdp.private1 = mdp3_session;

	rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
	if (rc) {
		pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
		goto init_done;
	}

	mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL,
							"vsync_event");
	if (!mdp3_session->vsync_event_sd) {
		pr_err("vsync_event sysfs lookup failed\n");
		rc = -ENODEV;
		goto init_done;
	}

	kobject_uevent(&dev->kobj, KOBJ_ADD);
	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");

init_done:
	if (IS_ERR_VALUE(rc))
		kfree(mdp3_session);

	return rc;
}