int armsoc_bo_cpu_prep(struct armsoc_bo *bo, enum armsoc_gem_op op)
{
	int ret = 0;

	assert(bo->refcnt > 0);
	if (armsoc_bo_has_dmabuf(bo)) {
		fd_set fds;
		/* 10s before printing a msg */
		const struct timeval timeout = {10, 0};
		struct timeval t;

		FD_ZERO(&fds);
		FD_SET(bo->dmabuf, &fds);

		do {
			t = timeout;
			ret = select(bo->dmabuf+1, &fds, NULL, NULL, &t);
			if (ret == 0)
				xf86DrvMsg(-1, X_ERROR,
					"select() on dma_buf fd has timed-out\n");
		} while ((ret == -1 && errno == EINTR) || ret == 0);

		if (ret > 0)
			ret = 0;
	}
	return ret;
}
void armsoc_bo_clear_dmabuf(struct armsoc_bo *bo)
{
	assert(bo->refcnt > 0);
	assert(armsoc_bo_has_dmabuf(bo));

	close(bo->dmabuf);
	bo->dmabuf = -1;
}
/* used by DRI2 code to play buffer switcharoo */
void
ARMSOCPixmapExchange(PixmapPtr a, PixmapPtr b)
{
	struct ARMSOCPixmapPrivRec *apriv = exaGetPixmapDriverPrivate(a);
	struct ARMSOCPixmapPrivRec *bpriv = exaGetPixmapDriverPrivate(b);
	exchange(apriv->priv, bpriv->priv);
	exchange(apriv->bo, bpriv->bo);

	/* Ensure neither pixmap has a dmabuf fd attached to the bo if the
	 * ext_access_cnt refcount is 0, as it will never be cleared. */
	if (armsoc_bo_has_dmabuf(apriv->bo) && !apriv->ext_access_cnt) {
		armsoc_bo_clear_dmabuf(apriv->bo);

		/* Should only have to clear one dmabuf fd, otherwise the
		 * refcount is wrong */
		assert(!armsoc_bo_has_dmabuf(bpriv->bo));
	} else if (armsoc_bo_has_dmabuf(bpriv->bo) && !bpriv->ext_access_cnt) {
		armsoc_bo_clear_dmabuf(bpriv->bo);

		assert(!armsoc_bo_has_dmabuf(apriv->bo));
	}
}
int armsoc_bo_set_dmabuf(struct armsoc_bo *bo)
{
	int res;
	struct drm_prime_handle prime_handle;

	assert(bo->refcnt > 0);
	assert(!armsoc_bo_has_dmabuf(bo));

	/* Try to get dma_buf fd */
	prime_handle.handle = bo->handle;
	prime_handle.flags  = 0;
	res  = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD,
						&prime_handle);
	if (res)
		res = errno;
	else
		bo->dmabuf = prime_handle.fd;

	return res;
}