diff options
author | Jon Medhurst <tixy@linaro.org> | 2015-09-08 13:11:58 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2015-11-27 15:22:12 +0000 |
commit | 26721135a237521ae486cdee346c61083ca44a90 (patch) | |
tree | e4627a3d35038ef01d8d93f1d018b22c95869abd | |
parent | 9a59baf8224c21c8fabd371e2f79ed7dca0b0e57 (diff) |
drm: hdlcd: Fork drm_fb_cma_helper -> hdlcd_fb_helper
Because we need to modify it to get Android and Mali working
Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r-- | drivers/gpu/drm/arm/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_fb_helper.c | 451 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_fb_helper.h | 31 |
6 files changed, 492 insertions, 10 deletions
diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile index 3bf3ede31ee0..9a96f9b6340d 100644 --- a/drivers/gpu/drm/arm/Makefile +++ b/drivers/gpu/drm/arm/Makefile @@ -1,4 +1,4 @@ -hdlcd-y := hdlcd_drv.o hdlcd_crtc.o hdlcd_vexpress_encoder.o +hdlcd-y := hdlcd_drv.o hdlcd_crtc.o hdlcd_vexpress_encoder.o hdlcd_fb_helper.o hdlcd-$(CONFIG_DRM_VIRTUAL_HDLCD) += hdlcd_virt_encoder.o obj-$(CONFIG_DRM_HDLCD) += hdlcd.o diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index aa640455f18d..aa435cb06a21 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -13,7 +13,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> -#include <drm/drm_fb_cma_helper.h> +#include "hdlcd_fb_helper.h" #include <drm/drm_gem_cma_helper.h> #include <drm/drm_of.h> #include <drm/drm_plane_helper.h> @@ -46,7 +46,7 @@ void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd, bool wait) dma_addr_t scanout_start; drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); - gem = drm_fb_cma_get_gem_obj(fb, 0); + gem = hdlcd_fb_get_gem_obj(fb, 0); scanout_start = gem->paddr + fb->offsets[0] + (hdlcd->crtc.y * fb->pitches[0]) + (hdlcd->crtc.x * bpp/8); diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index e3faa02842d9..e9d8a63666ad 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -19,7 +19,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> -#include <drm/drm_fb_cma_helper.h> +#include "hdlcd_fb_helper.h" #include <drm/drm_gem_cma_helper.h> #include <drm/drm_of.h> @@ -61,7 +61,7 @@ static int hdlcd_unload(struct drm_device *dev) drm_kms_helper_poll_fini(dev); if (hdlcd->fbdev) - drm_fbdev_cma_fini(hdlcd->fbdev); + hdlcd_drm_fbdev_fini(hdlcd->fbdev); drm_vblank_cleanup(dev); drm_mode_config_cleanup(dev); @@ -177,7 +177,7 @@ static int hdlcd_load(struct drm_device *dev, unsigned long flags) init_completion(&hdlcd->frame_completion); - hdlcd->fbdev = drm_fbdev_cma_init(dev, preferred_bpp, + hdlcd->fbdev = hdlcd_drm_fbdev_init(dev, preferred_bpp, dev->mode_config.num_crtc, dev->mode_config.num_connector); @@ -200,12 +200,12 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *dev) { struct hdlcd_drm_private *hdlcd = dev->dev_private; if (hdlcd->fbdev) { - drm_fbdev_cma_hotplug_event(hdlcd->fbdev); + hdlcd_drm_fbdev_hotplug_event(hdlcd->fbdev); } } static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { - .fb_create = drm_fb_cma_create, + .fb_create = hdlcd_fb_create, .output_poll_changed = hdlcd_fb_output_poll_changed, }; @@ -226,7 +226,7 @@ static void hdlcd_preclose(struct drm_device *dev, struct drm_file *file) static void hdlcd_lastclose(struct drm_device *dev) { struct hdlcd_drm_private *hdlcd = dev->dev_private; - drm_fbdev_cma_restore_mode(hdlcd->fbdev); + hdlcd_drm_fbdev_restore_mode(hdlcd->fbdev); } static irqreturn_t hdlcd_irq(int irq, void *arg) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h index 78c8eb3d1ae3..3980276d77bc 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.h +++ b/drivers/gpu/drm/arm/hdlcd_drv.h @@ -8,7 +8,7 @@ struct hdlcd_drm_private { void __iomem *mmio; struct clk *clk; - struct drm_fbdev_cma *fbdev; + struct hdlcd_drm_fbdev *fbdev; struct drm_framebuffer *fb; struct drm_pending_vblank_event *event; struct drm_crtc crtc; diff --git a/drivers/gpu/drm/arm/hdlcd_fb_helper.c b/drivers/gpu/drm/arm/hdlcd_fb_helper.c new file mode 100644 index 000000000000..585393ca2136 --- /dev/null +++ b/drivers/gpu/drm/arm/hdlcd_fb_helper.c @@ -0,0 +1,451 @@ +/* + * Copied from drivers/gpu/drm/drm_fb_cma_helper.c which has the following + * copyright and notices... + * + * Copyright (C) 2012 Analog Device Inc. + * Author: Lars-Peter Clausen <lars@metafoo.de> + * + * Based on udl_fbdev.c + * Copyright (C) 2012 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include "hdlcd_fb_helper.h" +#include <linux/module.h> + +struct hdlcd_fb { + struct drm_framebuffer fb; + struct drm_gem_cma_object *obj[4]; +}; + +struct hdlcd_drm_fbdev { + struct drm_fb_helper fb_helper; + struct hdlcd_fb *fb; +}; + +static inline struct hdlcd_drm_fbdev *to_hdlcd_fbdev(struct drm_fb_helper *helper) +{ + return container_of(helper, struct hdlcd_drm_fbdev, fb_helper); +} + +static inline struct hdlcd_fb *to_hdlcd_fb(struct drm_framebuffer *fb) +{ + return container_of(fb, struct hdlcd_fb, fb); +} + +static void hdlcd_fb_destroy(struct drm_framebuffer *fb) +{ + struct hdlcd_fb *hdlcd_fb = to_hdlcd_fb(fb); + int i; + + for (i = 0; i < 4; i++) { + if (hdlcd_fb->obj[i]) + drm_gem_object_unreference_unlocked(&hdlcd_fb->obj[i]->base); + } + + drm_framebuffer_cleanup(fb); + kfree(hdlcd_fb); +} + +static int hdlcd_fb_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, unsigned int *handle) +{ + struct hdlcd_fb *hdlcd_fb = to_hdlcd_fb(fb); + + return drm_gem_handle_create(file_priv, + &hdlcd_fb->obj[0]->base, handle); +} + +static struct drm_framebuffer_funcs hdlcd_fb_funcs = { + .destroy = hdlcd_fb_destroy, + .create_handle = hdlcd_fb_create_handle, +}; + +static struct hdlcd_fb *hdlcd_fb_alloc(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, + unsigned int num_planes) +{ + struct hdlcd_fb *hdlcd_fb; + int ret; + int i; + + hdlcd_fb = kzalloc(sizeof(*hdlcd_fb), GFP_KERNEL); + if (!hdlcd_fb) + return ERR_PTR(-ENOMEM); + + drm_helper_mode_fill_fb_struct(&hdlcd_fb->fb, mode_cmd); + + for (i = 0; i < num_planes; i++) + hdlcd_fb->obj[i] = obj[i]; + + ret = drm_framebuffer_init(dev, &hdlcd_fb->fb, &hdlcd_fb_funcs); + if (ret) { + dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret); + kfree(hdlcd_fb); + return ERR_PTR(ret); + } + + return hdlcd_fb; +} + +/** + * hdlcd_fb_create() - (struct drm_mode_config_funcs *)->fb_create callback function + * + * If your hardware has special alignment or pitch requirements these should be + * checked before calling this function. + */ +struct drm_framebuffer *hdlcd_fb_create(struct drm_device *dev, + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct hdlcd_fb *hdlcd_fb; + struct drm_gem_cma_object *objs[4]; + struct drm_gem_object *obj; + unsigned int hsub; + unsigned int vsub; + int ret; + int i; + + hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format); + vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format); + + for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) { + unsigned int width = mode_cmd->width / (i ? hsub : 1); + unsigned int height = mode_cmd->height / (i ? vsub : 1); + unsigned int min_size; + + obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[i]); + if (!obj) { + dev_err(dev->dev, "Failed to lookup GEM object\n"); + ret = -ENXIO; + goto err_gem_object_unreference; + } + + min_size = (height - 1) * mode_cmd->pitches[i] + + width * drm_format_plane_cpp(mode_cmd->pixel_format, i) + + mode_cmd->offsets[i]; + + if (obj->size < min_size) { + drm_gem_object_unreference_unlocked(obj); + ret = -EINVAL; + goto err_gem_object_unreference; + } + objs[i] = to_drm_gem_cma_obj(obj); + } + + hdlcd_fb = hdlcd_fb_alloc(dev, mode_cmd, objs, i); + if (IS_ERR(hdlcd_fb)) { + ret = PTR_ERR(hdlcd_fb); + goto err_gem_object_unreference; + } + + return &hdlcd_fb->fb; + +err_gem_object_unreference: + for (i--; i >= 0; i--) + drm_gem_object_unreference_unlocked(&objs[i]->base); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(hdlcd_fb_create); + +/** + * hdlcd_fb_get_gem_obj() - Get CMA GEM object for framebuffer + * @fb: The framebuffer + * @plane: Which plane + * + * Return the CMA GEM object for given framebuffer. + * + * This function will usually be called from the CRTC callback functions. + */ +struct drm_gem_cma_object *hdlcd_fb_get_gem_obj(struct drm_framebuffer *fb, + unsigned int plane) +{ + struct hdlcd_fb *hdlcd_fb = to_hdlcd_fb(fb); + + if (plane >= 4) + return NULL; + + return hdlcd_fb->obj[plane]; +} +EXPORT_SYMBOL_GPL(hdlcd_fb_get_gem_obj); + +#ifdef CONFIG_DEBUG_FS +/* + * hdlcd_fb_describe() - Helper to dump information about a single + * CMA framebuffer object + */ +static void hdlcd_fb_describe(struct drm_framebuffer *fb, struct seq_file *m) +{ + struct hdlcd_fb *hdlcd_fb = to_hdlcd_fb(fb); + int i, n = drm_format_num_planes(fb->pixel_format); + + seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height, + (char *)&fb->pixel_format); + + for (i = 0; i < n; i++) { + seq_printf(m, " %d: offset=%d pitch=%d, obj: ", + i, fb->offsets[i], fb->pitches[i]); + drm_gem_cma_describe(hdlcd_fb->obj[i], m); + } +} + +/** + * hdlcd_fb_debugfs_show() - Helper to list CMA framebuffer objects + * in debugfs. + */ +int hdlcd_fb_debugfs_show(struct seq_file *m, void *arg) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_framebuffer *fb; + int ret; + + ret = mutex_lock_interruptible(&dev->mode_config.mutex); + if (ret) + return ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) { + mutex_unlock(&dev->mode_config.mutex); + return ret; + } + + list_for_each_entry(fb, &dev->mode_config.fb_list, head) + hdlcd_fb_describe(fb, m); + + mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->mode_config.mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(hdlcd_fb_debugfs_show); +#endif + +static struct fb_ops hdlcd_drm_fbdev_ops = { + .owner = THIS_MODULE, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_blank = drm_fb_helper_blank, + .fb_pan_display = drm_fb_helper_pan_display, + .fb_setcmap = drm_fb_helper_setcmap, +}; + +static int hdlcd_drm_fbdev_create(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct hdlcd_drm_fbdev *hdlcd_fbdev = to_hdlcd_fbdev(helper); + struct drm_mode_fb_cmd2 mode_cmd = { 0 }; + struct drm_device *dev = helper->dev; + struct drm_gem_cma_object *obj; + struct drm_framebuffer *fb; + unsigned int bytes_per_pixel; + unsigned long offset; + struct fb_info *fbi; + size_t size; + int ret; + + DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); + + mode_cmd.width = sizes->surface_width; + mode_cmd.height = sizes->surface_height; + mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel; + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, + sizes->surface_depth); + + size = mode_cmd.pitches[0] * mode_cmd.height; + obj = drm_gem_cma_create(dev, size); + if (IS_ERR(obj)) + return -ENOMEM; + + fbi = framebuffer_alloc(0, dev->dev); + if (!fbi) { + dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); + ret = -ENOMEM; + goto err_drm_gem_cma_free_object; + } + + hdlcd_fbdev->fb = hdlcd_fb_alloc(dev, &mode_cmd, &obj, 1); + if (IS_ERR(hdlcd_fbdev->fb)) { + dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); + ret = PTR_ERR(hdlcd_fbdev->fb); + goto err_framebuffer_release; + } + + fb = &hdlcd_fbdev->fb->fb; + helper->fb = fb; + helper->fbdev = fbi; + + fbi->par = helper; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->fbops = &hdlcd_drm_fbdev_ops; + + ret = fb_alloc_cmap(&fbi->cmap, 256, 0); + if (ret) { + dev_err(dev->dev, "Failed to allocate color map.\n"); + goto err_hdlcd_fb_destroy; + } + + drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); + drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); + + offset = fbi->var.xoffset * bytes_per_pixel; + offset += fbi->var.yoffset * fb->pitches[0]; + + dev->mode_config.fb_base = (resource_size_t)obj->paddr; + fbi->screen_base = obj->vaddr + offset; + fbi->fix.smem_start = (unsigned long)(obj->paddr + offset); + fbi->screen_size = size; + fbi->fix.smem_len = size; + + return 0; + +err_hdlcd_fb_destroy: + drm_framebuffer_unregister_private(fb); + hdlcd_fb_destroy(fb); +err_framebuffer_release: + framebuffer_release(fbi); +err_drm_gem_cma_free_object: + drm_gem_cma_free_object(&obj->base); + return ret; +} + +static const struct drm_fb_helper_funcs hdlcd_fb_helper_funcs = { + .fb_probe = hdlcd_drm_fbdev_create, +}; + +/** + * hdlcd_drm_fbdev_init() - Allocate and initializes a hdlcd_drm_fbdev struct + * @dev: DRM device + * @preferred_bpp: Preferred bits per pixel for the device + * @num_crtc: Number of CRTCs + * @max_conn_count: Maximum number of connectors + * + * Returns a newly allocated hdlcd_drm_fbdev struct or a ERR_PTR. + */ +struct hdlcd_drm_fbdev *hdlcd_drm_fbdev_init(struct drm_device *dev, + unsigned int preferred_bpp, unsigned int num_crtc, + unsigned int max_conn_count) +{ + struct hdlcd_drm_fbdev *hdlcd_fbdev; + struct drm_fb_helper *helper; + int ret; + + hdlcd_fbdev = kzalloc(sizeof(*hdlcd_fbdev), GFP_KERNEL); + if (!hdlcd_fbdev) { + dev_err(dev->dev, "Failed to allocate drm fbdev.\n"); + return ERR_PTR(-ENOMEM); + } + + helper = &hdlcd_fbdev->fb_helper; + + drm_fb_helper_prepare(dev, helper, &hdlcd_fb_helper_funcs); + + ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); + if (ret < 0) { + dev_err(dev->dev, "Failed to initialize drm fb helper.\n"); + goto err_free; + } + + ret = drm_fb_helper_single_add_all_connectors(helper); + if (ret < 0) { + dev_err(dev->dev, "Failed to add connectors.\n"); + goto err_drm_fb_helper_fini; + + } + + /* disable all the possible outputs/crtcs before entering KMS mode */ + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(helper, preferred_bpp); + if (ret < 0) { + dev_err(dev->dev, "Failed to set initial hw configuration.\n"); + goto err_drm_fb_helper_fini; + } + + return hdlcd_fbdev; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(helper); +err_free: + kfree(hdlcd_fbdev); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(hdlcd_drm_fbdev_init); + +/** + * hdlcd_drm_fbdev_fini() - Free hdlcd_drm_fbdev struct + * @hdlcd_fbdev: The hdlcd_drm_fbdev struct + */ +void hdlcd_drm_fbdev_fini(struct hdlcd_drm_fbdev *hdlcd_fbdev) +{ + if (hdlcd_fbdev->fb_helper.fbdev) { + struct fb_info *info; + int ret; + + info = hdlcd_fbdev->fb_helper.fbdev; + ret = unregister_framebuffer(info); + if (ret < 0) + DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); + + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + + framebuffer_release(info); + } + + if (hdlcd_fbdev->fb) { + drm_framebuffer_unregister_private(&hdlcd_fbdev->fb->fb); + hdlcd_fb_destroy(&hdlcd_fbdev->fb->fb); + } + + drm_fb_helper_fini(&hdlcd_fbdev->fb_helper); + kfree(hdlcd_fbdev); +} +EXPORT_SYMBOL_GPL(hdlcd_drm_fbdev_fini); + +/** + * hdlcd_drm_fbdev_restore_mode() - Restores initial framebuffer mode + * @hdlcd_fbdev: The hdlcd_drm_fbdev struct, may be NULL + * + * This function is usually called from the DRM drivers lastclose callback. + */ +void hdlcd_drm_fbdev_restore_mode(struct hdlcd_drm_fbdev *hdlcd_fbdev) +{ + if (hdlcd_fbdev) + drm_fb_helper_restore_fbdev_mode_unlocked(&hdlcd_fbdev->fb_helper); +} +EXPORT_SYMBOL_GPL(hdlcd_drm_fbdev_restore_mode); + +/** + * hdlcd_drm_fbdev_hotplug_event() - Poll for hotpulug events + * @hdlcd_fbdev: The hdlcd_drm_fbdev struct, may be NULL + * + * This function is usually called from the DRM drivers output_poll_changed + * callback. + */ +void hdlcd_drm_fbdev_hotplug_event(struct hdlcd_drm_fbdev *hdlcd_fbdev) +{ + if (hdlcd_fbdev) + drm_fb_helper_hotplug_event(&hdlcd_fbdev->fb_helper); +} +EXPORT_SYMBOL_GPL(hdlcd_drm_fbdev_hotplug_event); diff --git a/drivers/gpu/drm/arm/hdlcd_fb_helper.h b/drivers/gpu/drm/arm/hdlcd_fb_helper.h new file mode 100644 index 000000000000..23e268db972f --- /dev/null +++ b/drivers/gpu/drm/arm/hdlcd_fb_helper.h @@ -0,0 +1,31 @@ +#ifndef __DRM_FB_CMA_HELPER_H__ +#define __DRM_FB_CMA_HELPER_H__ + +struct hdlcd_drm_fbdev; +struct drm_gem_cma_object; + +struct drm_framebuffer; +struct drm_device; +struct drm_file; +struct drm_mode_fb_cmd2; + +struct hdlcd_drm_fbdev *hdlcd_drm_fbdev_init(struct drm_device *dev, + unsigned int preferred_bpp, unsigned int num_crtc, + unsigned int max_conn_count); +void hdlcd_drm_fbdev_fini(struct hdlcd_drm_fbdev *hdlcd_fbdev); + +void hdlcd_drm_fbdev_restore_mode(struct hdlcd_drm_fbdev *hdlcd_fbdev); +void hdlcd_drm_fbdev_hotplug_event(struct hdlcd_drm_fbdev *hdlcd_fbdev); + +struct drm_framebuffer *hdlcd_fb_create(struct drm_device *dev, + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd); + +struct drm_gem_cma_object *hdlcd_fb_get_gem_obj(struct drm_framebuffer *fb, + unsigned int plane); + +#ifdef CONFIG_DEBUG_FS +int hdlcd_fb_debugfs_show(struct seq_file *m, void *arg); +#endif + +#endif + |