diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-02-13 15:31:38 +0200 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-04-17 08:10:19 +0300 |
commit | f7018c21350204c4cf628462f229d44d03545254 (patch) | |
tree | 408787177164cf51cc06f7aabdb04fcff8d2b6aa /drivers/video/fbdev/sbuslib.c | |
parent | c26ef3eb3c11274bad1b64498d0a134f85755250 (diff) |
video: move fbdev to drivers/video/fbdev
The drivers/video directory is a mess. It contains generic video related
files, directories for backlight, console, linux logo, lots of fbdev
device drivers, fbdev framework files.
Make some order into the chaos by creating drivers/video/fbdev
directory, and move all fbdev related files there.
No functionality is changed, although I guess it is possible that some
subtle Makefile build order related issue could be created by this
patch.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/video/fbdev/sbuslib.c')
-rw-r--r-- | drivers/video/fbdev/sbuslib.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/drivers/video/fbdev/sbuslib.c b/drivers/video/fbdev/sbuslib.c new file mode 100644 index 00000000000..a350209ffbd --- /dev/null +++ b/drivers/video/fbdev/sbuslib.c @@ -0,0 +1,267 @@ +/* sbuslib.c: Helper library for SBUS framebuffer drivers. + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + */ + +#include <linux/compat.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/of_device.h> + +#include <asm/fbio.h> + +#include "sbuslib.h" + +void sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp, + int bpp) +{ + memset(var, 0, sizeof(*var)); + + var->xres = of_getintprop_default(dp, "width", 1152); + var->yres = of_getintprop_default(dp, "height", 900); + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + var->bits_per_pixel = bpp; +} + +EXPORT_SYMBOL(sbusfb_fill_var); + +static unsigned long sbusfb_mmapsize(long size, unsigned long fbsize) +{ + if (size == SBUS_MMAP_EMPTY) return 0; + if (size >= 0) return size; + return fbsize * (-size); +} + +int sbusfb_mmap_helper(struct sbus_mmap_map *map, + unsigned long physbase, + unsigned long fbsize, + unsigned long iospace, + struct vm_area_struct *vma) +{ + unsigned int size, page, r, map_size; + unsigned long map_offset = 0; + unsigned long off; + int i; + + if (!(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) + return -EINVAL; + + size = vma->vm_end - vma->vm_start; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + + off = vma->vm_pgoff << PAGE_SHIFT; + + /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* Each page, see which map applies */ + for (page = 0; page < size; ){ + map_size = 0; + for (i = 0; map[i].size; i++) + if (map[i].voff == off+page) { + map_size = sbusfb_mmapsize(map[i].size, fbsize); +#ifdef __sparc_v9__ +#define POFF_MASK (PAGE_MASK|0x1UL) +#else +#define POFF_MASK (PAGE_MASK) +#endif + map_offset = (physbase + map[i].poff) & POFF_MASK; + break; + } + if (!map_size) { + page += PAGE_SIZE; + continue; + } + if (page + map_size > size) + map_size = size - page; + r = io_remap_pfn_range(vma, + vma->vm_start + page, + MK_IOSPACE_PFN(iospace, + map_offset >> PAGE_SHIFT), + map_size, + vma->vm_page_prot); + if (r) + return -EAGAIN; + page += map_size; + } + + return 0; +} +EXPORT_SYMBOL(sbusfb_mmap_helper); + +int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, + struct fb_info *info, + int type, int fb_depth, unsigned long fb_size) +{ + switch(cmd) { + case FBIOGTYPE: { + struct fbtype __user *f = (struct fbtype __user *) arg; + + if (put_user(type, &f->fb_type) || + __put_user(info->var.yres, &f->fb_height) || + __put_user(info->var.xres, &f->fb_width) || + __put_user(fb_depth, &f->fb_depth) || + __put_user(0, &f->fb_cmsize) || + __put_user(fb_size, &f->fb_cmsize)) + return -EFAULT; + return 0; + } + case FBIOPUTCMAP_SPARC: { + struct fbcmap __user *c = (struct fbcmap __user *) arg; + struct fb_cmap cmap; + u16 red, green, blue; + u8 red8, green8, blue8; + unsigned char __user *ured; + unsigned char __user *ugreen; + unsigned char __user *ublue; + int index, count, i; + + if (get_user(index, &c->index) || + __get_user(count, &c->count) || + __get_user(ured, &c->red) || + __get_user(ugreen, &c->green) || + __get_user(ublue, &c->blue)) + return -EFAULT; + + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + cmap.transp = NULL; + for (i = 0; i < count; i++) { + int err; + + if (get_user(red8, &ured[i]) || + get_user(green8, &ugreen[i]) || + get_user(blue8, &ublue[i])) + return -EFAULT; + + red = red8 << 8; + green = green8 << 8; + blue = blue8 << 8; + + cmap.start = index + i; + err = fb_set_cmap(&cmap, info); + if (err) + return err; + } + return 0; + } + case FBIOGETCMAP_SPARC: { + struct fbcmap __user *c = (struct fbcmap __user *) arg; + unsigned char __user *ured; + unsigned char __user *ugreen; + unsigned char __user *ublue; + struct fb_cmap *cmap = &info->cmap; + int index, count, i; + u8 red, green, blue; + + if (get_user(index, &c->index) || + __get_user(count, &c->count) || + __get_user(ured, &c->red) || + __get_user(ugreen, &c->green) || + __get_user(ublue, &c->blue)) + return -EFAULT; + + if (index + count > cmap->len) + return -EINVAL; + + for (i = 0; i < count; i++) { + red = cmap->red[index + i] >> 8; + green = cmap->green[index + i] >> 8; + blue = cmap->blue[index + i] >> 8; + if (put_user(red, &ured[i]) || + put_user(green, &ugreen[i]) || + put_user(blue, &ublue[i])) + return -EFAULT; + } + return 0; + } + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(sbusfb_ioctl_helper); + +#ifdef CONFIG_COMPAT +static int fbiogetputcmap(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ + struct fbcmap32 __user *argp = (void __user *)arg; + struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p)); + u32 addr; + int ret; + + ret = copy_in_user(p, argp, 2 * sizeof(int)); + ret |= get_user(addr, &argp->red); + ret |= put_user(compat_ptr(addr), &p->red); + ret |= get_user(addr, &argp->green); + ret |= put_user(compat_ptr(addr), &p->green); + ret |= get_user(addr, &argp->blue); + ret |= put_user(compat_ptr(addr), &p->blue); + if (ret) + return -EFAULT; + return info->fbops->fb_ioctl(info, + (cmd == FBIOPUTCMAP32) ? + FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, + (unsigned long)p); +} + +static int fbiogscursor(struct fb_info *info, unsigned long arg) +{ + struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p)); + struct fbcursor32 __user *argp = (void __user *)arg; + compat_uptr_t addr; + int ret; + + ret = copy_in_user(p, argp, + 2 * sizeof (short) + 2 * sizeof(struct fbcurpos)); + ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos)); + ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int)); + ret |= get_user(addr, &argp->cmap.red); + ret |= put_user(compat_ptr(addr), &p->cmap.red); + ret |= get_user(addr, &argp->cmap.green); + ret |= put_user(compat_ptr(addr), &p->cmap.green); + ret |= get_user(addr, &argp->cmap.blue); + ret |= put_user(compat_ptr(addr), &p->cmap.blue); + ret |= get_user(addr, &argp->mask); + ret |= put_user(compat_ptr(addr), &p->mask); + ret |= get_user(addr, &argp->image); + ret |= put_user(compat_ptr(addr), &p->image); + if (ret) + return -EFAULT; + return info->fbops->fb_ioctl(info, FBIOSCURSOR, (unsigned long)p); +} + +int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case FBIOGTYPE: + case FBIOSATTR: + case FBIOGATTR: + case FBIOSVIDEO: + case FBIOGVIDEO: + case FBIOGCURSOR32: /* This is not implemented yet. + Later it should be converted... */ + case FBIOSCURPOS: + case FBIOGCURPOS: + case FBIOGCURMAX: + return info->fbops->fb_ioctl(info, cmd, arg); + case FBIOPUTCMAP32: + return fbiogetputcmap(info, cmd, arg); + case FBIOGETCMAP32: + return fbiogetputcmap(info, cmd, arg); + case FBIOSCURSOR32: + return fbiogscursor(info, arg); + default: + return -ENOIOCTLCMD; + } +} +EXPORT_SYMBOL(sbusfb_compat_ioctl); +#endif |