struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags)
{
	struct smem_client *client;
	int rc = 0;
	struct msm_smem *mem;

	client = clt;
	if (!client) {
		pr_err("Invalid  client passed\n");
		return NULL;
	}
	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
	if (!mem) {
		pr_err("Failed to allocate shared mem\n");
		return NULL;
	}
	switch (client->mem_type) {
	case SMEM_ION:
		rc = alloc_ion_mem(client, size, align, flags, mem);
		break;
	default:
		pr_err("Mem type not supported\n");
		rc = -EINVAL;
		break;
	}
	if (rc) {
		pr_err("Failed to allocate shared memory\n");
		kfree(mem);
		mem = NULL;
	}
	return mem;
}
int gr_init(void)
{
    gglInit(&gr_context);
    GGLContext *gl = gr_context;

    gr_init_font();
    gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
    if (gr_vt_fd < 0) {
        // This is non-fatal; post-Cupcake kernels don't have tty0.
        perror("can't open /dev/tty0");
    } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
        // However, if we do open tty0, we expect the ioctl to work.
        perror("failed KDSETMODE to KD_GRAPHICS on tty0");
        gr_exit();
        return -1;
    }

    gr_fb_fd = get_framebuffer(gr_framebuffer);
    if (gr_fb_fd < 0) {
        gr_exit();
        return -1;
    }

    get_memory_surface(&gr_mem_surface);

    fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
            gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);

    /* start with 0 as front (displayed) and 1 as back (drawing) */
    gr_active_fb = 0;
    if (!has_overlay)
        set_active_framebuffer(0);
    gl->colorBuffer(gl, &gr_mem_surface);

    gl->activeTexture(gl, 0);
    gl->enable(gl, GGL_BLEND);
    gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);

    gr_fb_blank(true);
    gr_fb_blank(false);

    if (has_overlay) {
        if (alloc_ion_mem(fi.line_length * vi.yres) ||
            allocate_overlay(gr_fb_fd, gr_framebuffer)) {
                free_ion_mem();
        }
    }

    return 0;
}
static int impl_open(struct framebuffer *fb)
{
    struct fb_qcom_overlay_data *data = mzalloc(sizeof(struct fb_qcom_overlay_data));
    data->overlay_id = MSMFB_NEW_REQUEST;

    if (alloc_ion_mem(data, fb->fi.line_length * fb->vi.yres) < 0)
        goto fail;

    if(allocate_overlay(data, fb->fd, fb->vi.xres, fb->vi.yres) < 0)
    {
        free_ion_mem(data);
        goto fail;
    }

    fb->impl_data = data;
    return 0;

fail:
    free(data);
    return -1;
}
struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
		enum hal_buffer buffer_type, int map_kernel)
{
	struct smem_client *client;
	int rc = 0;
	struct msm_smem *mem;
	client = clt;
	if (!client) {
		dprintk(VIDC_ERR, "Invalid  client passed\n");
		return NULL;
	}
	if (!size) {
		dprintk(VIDC_ERR, "No need to allocate memory of size: %d\n",
			size);
		return NULL;
	}
	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
	if (!mem) {
		dprintk(VIDC_ERR, "Failed to allocate shared mem\n");
		return NULL;
	}
	switch (client->mem_type) {
	case SMEM_ION:
		rc = alloc_ion_mem(client, size, align, flags, buffer_type,
					mem, map_kernel);
		break;
	default:
		dprintk(VIDC_ERR, "Mem type not supported\n");
		rc = -EINVAL;
		break;
	}
	if (rc) {
		dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
		kfree(mem);
		mem = NULL;
	}
	return mem;
}