コード例 #1
0
ファイル: rtlx.c プロジェクト: Herysutrisno/mpc5200
static ssize_t file_write(struct file *file, const char __user * buffer,
                          size_t count, loff_t * ppos)
{
    int minor;
    struct rtlx_channel *rt;

    minor = iminor(file->f_path.dentry->d_inode);
    rt = &rtlx->channel[minor];

    /* any space left... */
    if (!rtlx_write_poll(minor)) {
        int ret = 0;

        if (file->f_flags & O_NONBLOCK)
            return -EAGAIN;

        __wait_event_interruptible(channel_wqs[minor].rt_queue,
                                   rtlx_write_poll(minor),
                                   ret);
        if (ret)
            return ret;
    }

    return rtlx_write(minor, buffer, count);
}
コード例 #2
0
ファイル: rtlx.c プロジェクト: Herysutrisno/mpc5200
unsigned int rtlx_read_poll(int index, int can_sleep)
{
    struct rtlx_channel *chan;

    if (rtlx == NULL)
        return 0;

    chan = &rtlx->channel[index];

    /* data available to read? */
    if (chan->lx_read == chan->lx_write) {
        if (can_sleep) {
            int ret = 0;

            __wait_event_interruptible(channel_wqs[index].lx_queue,
                                       (chan->lx_read != chan->lx_write) ||
                                       sp_stopping, ret);
            if (ret)
                return ret;

            if (sp_stopping)
                return 0;
        } else
            return 0;
    }

    return (chan->lx_write + chan->buffer_size - chan->lx_read)
           % chan->buffer_size;
}
コード例 #3
0
ファイル: adreno_drawctxt.c プロジェクト: Skin1980/bass-MM
/**
 * adreno_drawctxt_wait() - sleep until a timestamp expires
 * @adreno_dev: pointer to the adreno_device struct
 * @drawctxt: Pointer to the draw context to sleep for
 * @timetamp: Timestamp to wait on
 * @timeout: Number of jiffies to wait (0 for infinite)
 *
 * Register an event to wait for a timestamp on a context and sleep until it
 * has past.  Returns < 0 on error, -ETIMEDOUT if the timeout expires or 0
 * on success
 */
int adreno_drawctxt_wait(struct adreno_device *adreno_dev,
		struct kgsl_context *context,
		uint32_t timestamp, unsigned int timeout)
{
	struct kgsl_device *device = &adreno_dev->dev;
	struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
	int ret;
	long ret_temp;

	if (kgsl_context_detached(context))
		return -EINVAL;

	if (kgsl_context_invalid(context))
		return -EDEADLK;

	/* Needs to hold the device mutex */
	BUG_ON(!mutex_is_locked(&device->mutex));

	trace_adreno_drawctxt_wait_start(context->id, timestamp);

	ret = kgsl_add_event(device, &context->events, timestamp,
		wait_callback, (void *) drawctxt);
	if (ret)
		goto done;

	mutex_unlock(&device->mutex);

	if (timeout) {
		ret_temp = msecs_to_jiffies(timeout);
		__wait_event_interruptible_timeout(
			drawctxt->waiting,
			_check_context_timestamp(device, drawctxt, timestamp),
			ret_temp);

		if (ret_temp == 0)
			ret = -ETIMEDOUT;
		else if (ret_temp > 0)
			ret = 0;
		else
			ret = (int) ret_temp;
	} else {
		__wait_event_interruptible(drawctxt->waiting,
			_check_context_timestamp(device, drawctxt, timestamp),
				ret_temp);
		ret = (int)ret_temp;
	}

	mutex_lock(&device->mutex);

	/* -EDEADLK if the context was invalidated while we were waiting */
	if (kgsl_context_invalid(context))
		ret = -EDEADLK;


	/* Return -EINVAL if the context was detached while we were waiting */
	if (kgsl_context_detached(context))
		ret = -EINVAL;

done:
	trace_adreno_drawctxt_wait_done(context->id, timestamp, ret);
	return ret;
}
コード例 #4
0
ファイル: rtlx.c プロジェクト: Herysutrisno/mpc5200
int rtlx_open(int index, int can_sleep)
{
    struct rtlx_info **p;
    struct rtlx_channel *chan;
    enum rtlx_state state;
    int ret = 0;

    if (index >= RTLX_CHANNELS) {
        printk(KERN_DEBUG "rtlx_open index out of range\n");
        return -ENOSYS;
    }

    if (atomic_inc_return(&channel_wqs[index].in_open) > 1) {
        printk(KERN_DEBUG "rtlx_open channel %d already opened\n",
               index);
        ret = -EBUSY;
        goto out_fail;
    }

    if (rtlx == NULL) {
        if( (p = vpe_get_shared(tclimit)) == NULL) {
            if (can_sleep) {
                __wait_event_interruptible(channel_wqs[index].lx_queue,
                                           (p = vpe_get_shared(tclimit)), ret);
                if (ret)
                    goto out_fail;
            } else {
                printk(KERN_DEBUG "No SP program loaded, and device "
                       "opened with O_NONBLOCK\n");
                ret = -ENOSYS;
                goto out_fail;
            }
        }

        smp_rmb();
        if (*p == NULL) {
            if (can_sleep) {
                DEFINE_WAIT(wait);

                for (;;) {
                    prepare_to_wait(
                        &channel_wqs[index].lx_queue,
                        &wait, TASK_INTERRUPTIBLE);
                    smp_rmb();
                    if (*p != NULL)
                        break;
                    if (!signal_pending(current)) {
                        schedule();
                        continue;
                    }
                    ret = -ERESTARTSYS;
                    goto out_fail;
                }
                finish_wait(&channel_wqs[index].lx_queue, &wait);
            } else {
                pr_err(" *vpe_get_shared is NULL. "
                       "Has an SP program been loaded?\n");
                ret = -ENOSYS;
                goto out_fail;
            }
        }

        if ((unsigned int)*p < KSEG0) {
            printk(KERN_WARNING "vpe_get_shared returned an "
                   "invalid pointer maybe an error code %d\n",
                   (int)*p);
            ret = -ENOSYS;
            goto out_fail;
        }

        if ((ret = rtlx_init(*p)) < 0)
            goto out_ret;
    }

    chan = &rtlx->channel[index];

    state = xchg(&chan->lx_state, RTLX_STATE_OPENED);
    if (state == RTLX_STATE_OPENED) {
        ret = -EBUSY;
        goto out_fail;
    }

out_fail:
    smp_mb();
    atomic_dec(&channel_wqs[index].in_open);
    smp_mb();

out_ret:
    return ret;
}
コード例 #5
0
ファイル: rtlx.c プロジェクト: Broadcom/stblinux-2.6.18
int rtlx_open(int index, int can_sleep)
{
	volatile struct rtlx_info **p;
	struct rtlx_channel *chan;
	enum rtlx_state state;
	int ret = 0;

	if (index >= RTLX_CHANNELS) {
		printk(KERN_DEBUG "rtlx_open index out of range\n");
		return -ENOSYS;
	}

	if (atomic_inc_return(&channel_wqs[index].in_open) > 1) {
		printk(KERN_DEBUG "rtlx_open channel %d already opened\n",
		       index);
		ret = -EBUSY;
		goto out_fail;
	}

	if (rtlx == NULL) {
		if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
			if (can_sleep) {
				__wait_event_interruptible(channel_wqs[index].lx_queue,
				                           (p = vpe_get_shared(RTLX_TARG_VPE)),
				                           ret);
				if (ret)
					goto out_fail;
			} else {
				printk(KERN_DEBUG "No SP program loaded, and device "
					"opened with O_NONBLOCK\n");
				ret = -ENOSYS;
				goto out_fail;
			}
		}

		if (*p == NULL) {
			if (can_sleep) {
				__wait_event_interruptible(channel_wqs[index].lx_queue,
				                           *p != NULL,
				                           ret);
				if (ret)
					goto out_fail;
			} else {
				printk(" *vpe_get_shared is NULL. "
				       "Has an SP program been loaded?\n");
				ret = -ENOSYS;
				goto out_fail;
			}
		}

		if ((unsigned int)*p < KSEG0) {
			printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
			       "maybe an error code %d\n", (int)*p);
			ret = -ENOSYS;
			goto out_fail;
		}

		if ((ret = rtlx_init(*p)) < 0)
  			goto out_ret;
	}

	chan = &rtlx->channel[index];

	state = xchg(&chan->lx_state, RTLX_STATE_OPENED);
 	if (state == RTLX_STATE_OPENED) {
  		ret = -EBUSY;
		goto out_fail;
 	}

out_fail:
	smp_mb();
	atomic_dec(&channel_wqs[index].in_open);
	smp_mb();

out_ret:
	return ret;
}