Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 105553
b: refs/heads/master
c: 9b599fb
h: refs/heads/master
i:
  105551: f8b98a6
v: v3
  • Loading branch information
Ben Dooks authored and Linus Torvalds committed Jul 24, 2008
1 parent 4c1ff18 commit f09d355
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 116 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 206c5d69d0540024faffd423fc703f1e457332d7
refs/heads/master: 9b599fb2fc23386dfd2965bf7d10b2b0f628b208
264 changes: 149 additions & 115 deletions trunk/drivers/video/sm501fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
unsigned int why, size_t size)
{
unsigned int ptr = 0;
unsigned int end;
struct fb_info *fbi;

switch (why) {
case SM501_MEMF_CURSOR:
Expand All @@ -152,7 +154,9 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,

case SM501_MEMF_PANEL:
ptr = inf->fbmem_len - size;
if (ptr < inf->fb[0]->fix.smem_len)
fbi = inf->fb[0];

if (fbi && ptr < fbi->fix.smem_len)
return -ENOMEM;

break;
Expand All @@ -162,11 +166,18 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
break;

case SM501_MEMF_ACCEL:
ptr = inf->fb[0]->fix.smem_len;
fbi = inf->fb[0];
ptr = fbi ? fbi->fix.smem_len : 0;

fbi = inf->fb[1];
if (fbi)
end = (fbi->fix.smem_start - inf->fbmem_res->start);
else
end = inf->fbmem_len;

if ((ptr + size) >
(inf->fb[1]->fix.smem_start - inf->fbmem_res->start))
if ((ptr + size) > end)
return -ENOMEM;

break;

default:
Expand Down Expand Up @@ -1228,50 +1239,23 @@ static struct fb_ops sm501fb_ops_pnl = {
.fb_imageblit = cfb_imageblit,
};

/* sm501fb_info_alloc
*
* creates and initialises an sm501fb_info structure
*/

static struct sm501fb_info *sm501fb_info_alloc(struct fb_info *fbinfo_crt,
struct fb_info *fbinfo_pnl)
{
struct sm501fb_info *info;
struct sm501fb_par *par;

info = kzalloc(sizeof(struct sm501fb_info), GFP_KERNEL);
if (info) {
/* set the references back */

par = fbinfo_crt->par;
par->info = info;
par->head = HEAD_CRT;
fbinfo_crt->pseudo_palette = &par->pseudo_palette;

par = fbinfo_pnl->par;
par->info = info;
par->head = HEAD_PANEL;
fbinfo_pnl->pseudo_palette = &par->pseudo_palette;

/* store the two fbs into our info */
info->fb[HEAD_CRT] = fbinfo_crt;
info->fb[HEAD_PANEL] = fbinfo_pnl;
}

return info;
}

/* sm501_init_cursor
*
* initialise hw cursor parameters
*/

static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
{
struct sm501fb_par *par = fbi->par;
struct sm501fb_info *info = par->info;
struct sm501fb_par *par;
struct sm501fb_info *info;
int ret;

if (fbi == NULL)
return 0;

par = fbi->par;
info = par->info;

par->cursor_regs = info->regs + reg_base;

ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024);
Expand Down Expand Up @@ -1299,13 +1283,10 @@ static int sm501fb_start(struct sm501fb_info *info,
struct platform_device *pdev)
{
struct resource *res;
struct device *dev;
struct device *dev = &pdev->dev;
int k;
int ret;

info->dev = dev = &pdev->dev;
platform_set_drvdata(pdev, info);

info->irq = ret = platform_get_irq(pdev, 0);
if (ret < 0) {
/* we currently do not use the IRQ */
Expand Down Expand Up @@ -1408,11 +1389,6 @@ static void sm501fb_stop(struct sm501fb_info *info)
kfree(info->regs_res);
}

static void sm501fb_info_release(struct sm501fb_info *info)
{
kfree(info);
}

static int sm501fb_init_fb(struct fb_info *fb,
enum sm501_controller head,
const char *fbname)
Expand Down Expand Up @@ -1557,36 +1533,93 @@ static struct sm501_platdata_fb sm501fb_def_pdata = {
static char driver_name_crt[] = "sm501fb-crt";
static char driver_name_pnl[] = "sm501fb-panel";

static int __init sm501fb_probe(struct platform_device *pdev)
static int __devinit sm501fb_probe_one(struct sm501fb_info *info,
enum sm501_controller head)
{
struct sm501fb_info *info;
struct device *dev = &pdev->dev;
struct fb_info *fbinfo_crt;
struct fb_info *fbinfo_pnl;
int ret;
unsigned char *name = (head == HEAD_CRT) ? "crt" : "panel";
struct sm501_platdata_fbsub *pd;
struct sm501fb_par *par;
struct fb_info *fbi;

/* allocate our framebuffers */
pd = (head == HEAD_CRT) ? info->pdata->fb_crt : info->pdata->fb_pnl;

fbinfo_crt = framebuffer_alloc(sizeof(struct sm501fb_par), dev);
if (fbinfo_crt == NULL) {
dev_err(dev, "cannot allocate crt framebuffer\n");
/* Do not initialise if we've not been given any platform data */
if (pd == NULL) {
dev_info(info->dev, "no data for fb %s (disabled)\n", name);
return 0;
}

fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);
if (fbi == NULL) {
dev_err(info->dev, "cannot allocate %s framebuffer\n", name);
return -ENOMEM;
}

fbinfo_pnl = framebuffer_alloc(sizeof(struct sm501fb_par), dev);
if (fbinfo_pnl == NULL) {
dev_err(dev, "cannot allocate panel framebuffer\n");
ret = -ENOMEM;
goto fbinfo_crt_alloc_fail;
par = fbi->par;
par->info = info;
par->head = head;
fbi->pseudo_palette = &par->pseudo_palette;

info->fb[head] = fbi;

return 0;
}

/* Free up anything allocated by sm501fb_init_fb */

static void sm501_free_init_fb(struct sm501fb_info *info,
enum sm501_controller head)
{
struct fb_info *fbi = info->fb[head];

fb_dealloc_cmap(&fbi->cmap);
}

static int __devinit sm501fb_start_one(struct sm501fb_info *info,
enum sm501_controller head,
const char *drvname)
{
struct fb_info *fbi = info->fb[head];
int ret;

if (!fbi)
return 0;

ret = sm501fb_init_fb(info->fb[head], head, drvname);
if (ret) {
dev_err(info->dev, "cannot initialise fb %s\n", drvname);
return ret;
}

ret = register_framebuffer(info->fb[head]);
if (ret) {
dev_err(info->dev, "failed to register fb %s\n", drvname);
sm501_free_init_fb(info, head);
return ret;
}

info = sm501fb_info_alloc(fbinfo_crt, fbinfo_pnl);
if (info == NULL) {
dev_err(dev, "cannot allocate par\n");
ret = -ENOMEM;
goto sm501fb_alloc_fail;
dev_info(info->dev, "fb%d: %s frame buffer\n", fbi->node, fbi->fix.id);

return 0;
}

static int __devinit sm501fb_probe(struct platform_device *pdev)
{
struct sm501fb_info *info;
struct device *dev = &pdev->dev;
int ret;

/* allocate our framebuffers */

info = kzalloc(sizeof(struct sm501fb_info), GFP_KERNEL);
if (!info) {
dev_err(dev, "failed to allocate state\n");
return -ENOMEM;
}

info->dev = dev = &pdev->dev;
platform_set_drvdata(pdev, info);

if (dev->parent->platform_data) {
struct sm501_platdata *pd = dev->parent->platform_data;
info->pdata = pd->fb;
Expand All @@ -1597,90 +1630,88 @@ static int __init sm501fb_probe(struct platform_device *pdev)
info->pdata = &sm501fb_def_pdata;
}

/* start the framebuffers */
/* probe for the presence of each panel */

ret = sm501fb_start(info, pdev);
if (ret) {
dev_err(dev, "cannot initialise SM501\n");
goto sm501fb_start_fail;
ret = sm501fb_probe_one(info, HEAD_CRT);
if (ret < 0) {
dev_err(dev, "failed to probe CRT\n");
goto err_alloc;
}

/* CRT framebuffer setup */
ret = sm501fb_probe_one(info, HEAD_PANEL);
if (ret < 0) {
dev_err(dev, "failed to probe PANEL\n");
goto err_probed_crt;
}

ret = sm501fb_init_fb(fbinfo_crt, HEAD_CRT, driver_name_crt);
if (ret) {
dev_err(dev, "cannot initialise CRT fb\n");
goto sm501fb_start_fail;
if (info->fb[HEAD_PANEL] == NULL &&
info->fb[HEAD_CRT] == NULL) {
dev_err(dev, "no framebuffers found\n");
goto err_alloc;
}

/* Panel framebuffer setup */
/* get the resources for both of the framebuffers */

ret = sm501fb_init_fb(fbinfo_pnl, HEAD_PANEL, driver_name_pnl);
ret = sm501fb_start(info, pdev);
if (ret) {
dev_err(dev, "cannot initialise Panel fb\n");
goto sm501fb_start_fail;
dev_err(dev, "cannot initialise SM501\n");
goto err_probed_panel;
}

/* register framebuffers */

ret = register_framebuffer(fbinfo_crt);
if (ret < 0) {
dev_err(dev, "failed to register CRT fb (%d)\n", ret);
goto register_crt_fail;
ret = sm501fb_start_one(info, HEAD_CRT, driver_name_crt);
if (ret) {
dev_err(dev, "failed to start CRT\n");
goto err_started;
}

ret = register_framebuffer(fbinfo_pnl);
if (ret < 0) {
dev_err(dev, "failed to register panel fb (%d)\n", ret);
goto register_pnl_fail;
ret = sm501fb_start_one(info, HEAD_PANEL, driver_name_pnl);
if (ret) {
dev_err(dev, "failed to start Panel\n");
goto err_started_crt;
}

dev_info(dev, "fb%d: %s frame buffer device\n",
fbinfo_crt->node, fbinfo_crt->fix.id);

dev_info(dev, "fb%d: %s frame buffer device\n",
fbinfo_pnl->node, fbinfo_pnl->fix.id);

/* create device files */

ret = device_create_file(dev, &dev_attr_crt_src);
if (ret)
goto crtsrc_fail;
goto err_started_panel;

ret = device_create_file(dev, &dev_attr_fbregs_pnl);
if (ret)
goto fbregs_pnl_fail;
goto err_attached_crtsrc_file;

ret = device_create_file(dev, &dev_attr_fbregs_crt);
if (ret)
goto fbregs_crt_fail;
goto err_attached_pnlregs_file;

/* we registered, return ok */
return 0;

fbregs_crt_fail:
err_attached_pnlregs_file:
device_remove_file(dev, &dev_attr_fbregs_pnl);

fbregs_pnl_fail:
err_attached_crtsrc_file:
device_remove_file(dev, &dev_attr_crt_src);

crtsrc_fail:
unregister_framebuffer(fbinfo_pnl);
err_started_panel:
unregister_framebuffer(info->fb[HEAD_PANEL]);
sm501_free_init_fb(info, HEAD_PANEL);

register_pnl_fail:
unregister_framebuffer(fbinfo_crt);
err_started_crt:
unregister_framebuffer(info->fb[HEAD_CRT]);
sm501_free_init_fb(info, HEAD_CRT);

register_crt_fail:
err_started:
sm501fb_stop(info);

sm501fb_start_fail:
sm501fb_info_release(info);
err_probed_panel:
framebuffer_release(info->fb[HEAD_PANEL]);

sm501fb_alloc_fail:
framebuffer_release(fbinfo_pnl);
err_probed_crt:
framebuffer_release(info->fb[HEAD_CRT]);

fbinfo_crt_alloc_fail:
framebuffer_release(fbinfo_crt);
err_alloc:
kfree(info);

return ret;
}
Expand All @@ -1699,11 +1730,14 @@ static int sm501fb_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_fbregs_pnl);
device_remove_file(&pdev->dev, &dev_attr_crt_src);

sm501_free_init_fb(info, HEAD_CRT);
sm501_free_init_fb(info, HEAD_PANEL);

unregister_framebuffer(fbinfo_crt);
unregister_framebuffer(fbinfo_pnl);

sm501fb_stop(info);
sm501fb_info_release(info);
kfree(info);

framebuffer_release(fbinfo_pnl);
framebuffer_release(fbinfo_crt);
Expand Down

0 comments on commit f09d355

Please sign in to comment.