diff options
Diffstat (limited to 'drivers/video/cg14.c')
| -rw-r--r-- | drivers/video/cg14.c | 326 |
1 files changed, 153 insertions, 173 deletions
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 63b6c79c8a0a..7f926c619b61 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* cg14.c: CGFOURTEEN frame buffer driver | 1 | /* cg14.c: CGFOURTEEN frame buffer driver |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2003 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) |
| 4 | * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) | 4 | * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) |
| 5 | * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) | 5 | * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) |
| 6 | * | 6 | * |
| @@ -18,8 +18,8 @@ | |||
| 18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
| 19 | 19 | ||
| 20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| 21 | #include <asm/sbus.h> | 21 | #include <asm/prom.h> |
| 22 | #include <asm/oplib.h> | 22 | #include <asm/of_device.h> |
| 23 | #include <asm/fbio.h> | 23 | #include <asm/fbio.h> |
| 24 | 24 | ||
| 25 | #include "sbuslib.h" | 25 | #include "sbuslib.h" |
| @@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = { | |||
| 99 | #define CG14_MCR_PIXMODE_32 3 | 99 | #define CG14_MCR_PIXMODE_32 3 |
| 100 | 100 | ||
| 101 | struct cg14_regs{ | 101 | struct cg14_regs{ |
| 102 | volatile u8 mcr; /* Master Control Reg */ | 102 | u8 mcr; /* Master Control Reg */ |
| 103 | volatile u8 ppr; /* Packed Pixel Reg */ | 103 | u8 ppr; /* Packed Pixel Reg */ |
| 104 | volatile u8 tms[2]; /* Test Mode Status Regs */ | 104 | u8 tms[2]; /* Test Mode Status Regs */ |
| 105 | volatile u8 msr; /* Master Status Reg */ | 105 | u8 msr; /* Master Status Reg */ |
| 106 | volatile u8 fsr; /* Fault Status Reg */ | 106 | u8 fsr; /* Fault Status Reg */ |
| 107 | volatile u8 rev; /* Revision & Impl */ | 107 | u8 rev; /* Revision & Impl */ |
| 108 | volatile u8 ccr; /* Clock Control Reg */ | 108 | u8 ccr; /* Clock Control Reg */ |
| 109 | volatile u32 tmr; /* Test Mode Read Back */ | 109 | u32 tmr; /* Test Mode Read Back */ |
| 110 | volatile u8 mod; /* Monitor Operation Data Reg */ | 110 | u8 mod; /* Monitor Operation Data Reg */ |
| 111 | volatile u8 acr; /* Aux Control */ | 111 | u8 acr; /* Aux Control */ |
| 112 | u8 xxx0[6]; | 112 | u8 xxx0[6]; |
| 113 | volatile u16 hct; /* Hor Counter */ | 113 | u16 hct; /* Hor Counter */ |
| 114 | volatile u16 vct; /* Vert Counter */ | 114 | u16 vct; /* Vert Counter */ |
| 115 | volatile u16 hbs; /* Hor Blank Start */ | 115 | u16 hbs; /* Hor Blank Start */ |
| 116 | volatile u16 hbc; /* Hor Blank Clear */ | 116 | u16 hbc; /* Hor Blank Clear */ |
| 117 | volatile u16 hss; /* Hor Sync Start */ | 117 | u16 hss; /* Hor Sync Start */ |
| 118 | volatile u16 hsc; /* Hor Sync Clear */ | 118 | u16 hsc; /* Hor Sync Clear */ |
| 119 | volatile u16 csc; /* Composite Sync Clear */ | 119 | u16 csc; /* Composite Sync Clear */ |
| 120 | volatile u16 vbs; /* Vert Blank Start */ | 120 | u16 vbs; /* Vert Blank Start */ |
| 121 | volatile u16 vbc; /* Vert Blank Clear */ | 121 | u16 vbc; /* Vert Blank Clear */ |
| 122 | volatile u16 vss; /* Vert Sync Start */ | 122 | u16 vss; /* Vert Sync Start */ |
| 123 | volatile u16 vsc; /* Vert Sync Clear */ | 123 | u16 vsc; /* Vert Sync Clear */ |
| 124 | volatile u16 xcs; | 124 | u16 xcs; |
| 125 | volatile u16 xcc; | 125 | u16 xcc; |
| 126 | volatile u16 fsa; /* Fault Status Address */ | 126 | u16 fsa; /* Fault Status Address */ |
| 127 | volatile u16 adr; /* Address Registers */ | 127 | u16 adr; /* Address Registers */ |
| 128 | u8 xxx1[0xce]; | 128 | u8 xxx1[0xce]; |
| 129 | volatile u8 pcg[0x100]; /* Pixel Clock Generator */ | 129 | u8 pcg[0x100]; /* Pixel Clock Generator */ |
| 130 | volatile u32 vbr; /* Frame Base Row */ | 130 | u32 vbr; /* Frame Base Row */ |
| 131 | volatile u32 vmcr; /* VBC Master Control */ | 131 | u32 vmcr; /* VBC Master Control */ |
| 132 | volatile u32 vcr; /* VBC refresh */ | 132 | u32 vcr; /* VBC refresh */ |
| 133 | volatile u32 vca; /* VBC Config */ | 133 | u32 vca; /* VBC Config */ |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | #define CG14_CCR_ENABLE 0x04 | 136 | #define CG14_CCR_ENABLE 0x04 |
| 137 | #define CG14_CCR_SELECT 0x02 /* HW/Full screen */ | 137 | #define CG14_CCR_SELECT 0x02 /* HW/Full screen */ |
| 138 | 138 | ||
| 139 | struct cg14_cursor { | 139 | struct cg14_cursor { |
| 140 | volatile u32 cpl0[32]; /* Enable plane 0 */ | 140 | u32 cpl0[32]; /* Enable plane 0 */ |
| 141 | volatile u32 cpl1[32]; /* Color selection plane */ | 141 | u32 cpl1[32]; /* Color selection plane */ |
| 142 | volatile u8 ccr; /* Cursor Control Reg */ | 142 | u8 ccr; /* Cursor Control Reg */ |
| 143 | u8 xxx0[3]; | 143 | u8 xxx0[3]; |
| 144 | volatile u16 cursx; /* Cursor x,y position */ | 144 | u16 cursx; /* Cursor x,y position */ |
| 145 | volatile u16 cursy; /* Cursor x,y position */ | 145 | u16 cursy; /* Cursor x,y position */ |
| 146 | volatile u32 color0; | 146 | u32 color0; |
| 147 | volatile u32 color1; | 147 | u32 color1; |
| 148 | u32 xxx1[0x1bc]; | 148 | u32 xxx1[0x1bc]; |
| 149 | volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */ | 149 | u32 cpl0i[32]; /* Enable plane 0 autoinc */ |
| 150 | volatile u32 cpl1i[32]; /* Color selection autoinc */ | 150 | u32 cpl1i[32]; /* Color selection autoinc */ |
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| 153 | struct cg14_dac { | 153 | struct cg14_dac { |
| 154 | volatile u8 addr; /* Address Register */ | 154 | u8 addr; /* Address Register */ |
| 155 | u8 xxx0[255]; | 155 | u8 xxx0[255]; |
| 156 | volatile u8 glut; /* Gamma table */ | 156 | u8 glut; /* Gamma table */ |
| 157 | u8 xxx1[255]; | 157 | u8 xxx1[255]; |
| 158 | volatile u8 select; /* Register Select */ | 158 | u8 select; /* Register Select */ |
| 159 | u8 xxx2[255]; | 159 | u8 xxx2[255]; |
| 160 | volatile u8 mode; /* Mode Register */ | 160 | u8 mode; /* Mode Register */ |
| 161 | }; | 161 | }; |
| 162 | 162 | ||
| 163 | struct cg14_xlut{ | 163 | struct cg14_xlut{ |
| 164 | volatile u8 x_xlut [256]; | 164 | u8 x_xlut [256]; |
| 165 | volatile u8 x_xlutd [256]; | 165 | u8 x_xlutd [256]; |
| 166 | u8 xxx0[0x600]; | 166 | u8 xxx0[0x600]; |
| 167 | volatile u8 x_xlut_inc [256]; | 167 | u8 x_xlut_inc [256]; |
| 168 | volatile u8 x_xlutd_inc [256]; | 168 | u8 x_xlutd_inc [256]; |
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | /* Color look up table (clut) */ | 171 | /* Color look up table (clut) */ |
| @@ -204,7 +204,6 @@ struct cg14_par { | |||
| 204 | 204 | ||
| 205 | int mode; | 205 | int mode; |
| 206 | int ramsize; | 206 | int ramsize; |
| 207 | struct sbus_dev *sdev; | ||
| 208 | }; | 207 | }; |
| 209 | 208 | ||
| 210 | static void __cg14_reset(struct cg14_par *par) | 209 | static void __cg14_reset(struct cg14_par *par) |
| @@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) | |||
| 355 | * Initialisation | 354 | * Initialisation |
| 356 | */ | 355 | */ |
| 357 | 356 | ||
| 358 | static void cg14_init_fix(struct fb_info *info, int linebytes) | 357 | static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) |
| 359 | { | 358 | { |
| 360 | struct cg14_par *par = (struct cg14_par *)info->par; | 359 | const char *name = dp->name; |
| 361 | const char *name; | ||
| 362 | |||
| 363 | name = "cgfourteen"; | ||
| 364 | if (par->sdev) | ||
| 365 | name = par->sdev->prom_name; | ||
| 366 | 360 | ||
| 367 | strlcpy(info->fix.id, name, sizeof(info->fix.id)); | 361 | strlcpy(info->fix.id, name, sizeof(info->fix.id)); |
| 368 | 362 | ||
| @@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = { | |||
| 456 | struct all_info { | 450 | struct all_info { |
| 457 | struct fb_info info; | 451 | struct fb_info info; |
| 458 | struct cg14_par par; | 452 | struct cg14_par par; |
| 459 | struct list_head list; | ||
| 460 | }; | 453 | }; |
| 461 | static LIST_HEAD(cg14_list); | ||
| 462 | 454 | ||
| 463 | static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) | 455 | static void cg14_unmap_regs(struct all_info *all) |
| 464 | { | 456 | { |
| 465 | struct all_info *all; | 457 | if (all->par.regs) |
| 466 | unsigned long phys, rphys; | 458 | of_iounmap(all->par.regs, sizeof(struct cg14_regs)); |
| 467 | u32 bases[6]; | 459 | if (all->par.clut) |
| 468 | int is_8mb, linebytes, i; | 460 | of_iounmap(all->par.clut, sizeof(struct cg14_clut)); |
| 469 | 461 | if (all->par.cursor) | |
| 470 | if (!sdev) { | 462 | of_iounmap(all->par.cursor, sizeof(struct cg14_cursor)); |
| 471 | if (prom_getproperty(node, "address", | 463 | if (all->info.screen_base) |
| 472 | (char *) &bases[0], sizeof(bases)) <= 0 | 464 | of_iounmap(all->info.screen_base, all->par.fbsize); |
| 473 | || !bases[0]) { | 465 | } |
| 474 | printk(KERN_ERR "cg14: Device is not mapped.\n"); | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | if (__get_iospace(bases[0]) != __get_iospace(bases[1])) { | ||
| 478 | printk(KERN_ERR "cg14: I/O spaces don't match.\n"); | ||
| 479 | return; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | 466 | ||
| 483 | all = kmalloc(sizeof(*all), GFP_KERNEL); | 467 | static int __devinit cg14_init_one(struct of_device *op) |
| 484 | if (!all) { | 468 | { |
| 485 | printk(KERN_ERR "cg14: Cannot allocate memory.\n"); | 469 | struct device_node *dp = op->node; |
| 486 | return; | 470 | struct all_info *all; |
| 487 | } | 471 | int is_8mb, linebytes, i, err; |
| 488 | memset(all, 0, sizeof(*all)); | ||
| 489 | 472 | ||
| 490 | INIT_LIST_HEAD(&all->list); | 473 | all = kzalloc(sizeof(*all), GFP_KERNEL); |
| 474 | if (!all) | ||
| 475 | return -ENOMEM; | ||
| 491 | 476 | ||
| 492 | spin_lock_init(&all->par.lock); | 477 | spin_lock_init(&all->par.lock); |
| 493 | 478 | ||
| 494 | sbusfb_fill_var(&all->info.var, node, 8); | 479 | sbusfb_fill_var(&all->info.var, dp->node, 8); |
| 495 | all->info.var.red.length = 8; | 480 | all->info.var.red.length = 8; |
| 496 | all->info.var.green.length = 8; | 481 | all->info.var.green.length = 8; |
| 497 | all->info.var.blue.length = 8; | 482 | all->info.var.blue.length = 8; |
| 498 | 483 | ||
| 499 | linebytes = prom_getintdefault(node, "linebytes", | 484 | linebytes = of_getintprop_default(dp, "linebytes", |
| 500 | all->info.var.xres); | 485 | all->info.var.xres); |
| 501 | all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); | 486 | all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); |
| 502 | 487 | ||
| 503 | all->par.sdev = sdev; | 488 | if (!strcmp(dp->parent->name, "sbus") || |
| 504 | if (sdev) { | 489 | !strcmp(dp->parent->name, "sbi")) { |
| 505 | rphys = sdev->reg_addrs[0].phys_addr; | 490 | all->par.physbase = op->resource[0].start; |
| 506 | all->par.physbase = phys = sdev->reg_addrs[1].phys_addr; | 491 | all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; |
| 507 | all->par.iospace = sdev->reg_addrs[0].which_io; | ||
| 508 | |||
| 509 | all->par.regs = sbus_ioremap(&sdev->resource[0], 0, | ||
| 510 | sizeof(struct cg14_regs), | ||
| 511 | "cg14 regs"); | ||
| 512 | all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1, | ||
| 513 | sizeof(struct cg14_clut), | ||
| 514 | "cg14 clut"); | ||
| 515 | all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS, | ||
| 516 | sizeof(struct cg14_cursor), | ||
| 517 | "cg14 cursor"); | ||
| 518 | all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0, | ||
| 519 | all->par.fbsize, "cg14 ram"); | ||
| 520 | } else { | 492 | } else { |
| 521 | rphys = __get_phys(bases[0]); | 493 | all->par.physbase = op->resource[1].start; |
| 522 | all->par.physbase = phys = __get_phys(bases[1]); | 494 | all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; |
| 523 | all->par.iospace = __get_iospace(bases[0]); | ||
| 524 | all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0]; | ||
| 525 | all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] + | ||
| 526 | CG14_CLUT1); | ||
| 527 | all->par.cursor = | ||
| 528 | (struct cg14_cursor __iomem *)((unsigned long)bases[0] + | ||
| 529 | CG14_CURSORREGS); | ||
| 530 | |||
| 531 | all->info.screen_base = (char __iomem *)(unsigned long)bases[1]; | ||
| 532 | } | 495 | } |
| 533 | 496 | ||
| 534 | prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases)); | 497 | all->par.regs = of_ioremap(&op->resource[0], 0, |
| 535 | is_8mb = (bases[5] == 0x800000); | 498 | sizeof(struct cg14_regs), "cg14 regs"); |
| 499 | all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1, | ||
| 500 | sizeof(struct cg14_clut), "cg14 clut"); | ||
| 501 | all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, | ||
| 502 | sizeof(struct cg14_cursor), "cg14 cursor"); | ||
| 536 | 503 | ||
| 537 | if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) { | 504 | all->info.screen_base = of_ioremap(&op->resource[1], 0, |
| 538 | extern void __cg14_mmap_sized_wrongly(void); | 505 | all->par.fbsize, "cg14 ram"); |
| 539 | 506 | ||
| 540 | __cg14_mmap_sized_wrongly(); | 507 | if (!all->par.regs || !all->par.clut || !all->par.cursor || |
| 541 | } | 508 | !all->info.screen_base) |
| 509 | cg14_unmap_regs(all); | ||
| 510 | |||
| 511 | is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == | ||
| 512 | (8 * 1024 * 1024)); | ||
| 513 | |||
| 514 | BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)); | ||
| 542 | 515 | ||
| 543 | memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map)); | 516 | memcpy(&all->par.mmap_map, &__cg14_mmap_map, |
| 517 | sizeof(all->par.mmap_map)); | ||
| 518 | |||
| 544 | for (i = 0; i < CG14_MMAP_ENTRIES; i++) { | 519 | for (i = 0; i < CG14_MMAP_ENTRIES; i++) { |
| 545 | struct sbus_mmap_map *map = &all->par.mmap_map[i]; | 520 | struct sbus_mmap_map *map = &all->par.mmap_map[i]; |
| 546 | 521 | ||
| 547 | if (!map->size) | 522 | if (!map->size) |
| 548 | break; | 523 | break; |
| 549 | if (map->poff & 0x80000000) | 524 | if (map->poff & 0x80000000) |
| 550 | map->poff = (map->poff & 0x7fffffff) + rphys - phys; | 525 | map->poff = (map->poff & 0x7fffffff) + |
| 526 | (op->resource[0].start - | ||
| 527 | op->resource[1].start); | ||
| 551 | if (is_8mb && | 528 | if (is_8mb && |
| 552 | map->size >= 0x100000 && | 529 | map->size >= 0x100000 && |
| 553 | map->size <= 0x400000) | 530 | map->size <= 0x400000) |
| @@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) | |||
| 564 | __cg14_reset(&all->par); | 541 | __cg14_reset(&all->par); |
| 565 | 542 | ||
| 566 | if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { | 543 | if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { |
| 567 | printk(KERN_ERR "cg14: Could not allocate color map.\n"); | 544 | cg14_unmap_regs(all); |
| 568 | kfree(all); | 545 | kfree(all); |
| 569 | return; | 546 | return -ENOMEM; |
| 570 | } | 547 | } |
| 571 | fb_set_cmap(&all->info.cmap, &all->info); | 548 | fb_set_cmap(&all->info.cmap, &all->info); |
| 572 | 549 | ||
| 573 | cg14_init_fix(&all->info, linebytes); | 550 | cg14_init_fix(&all->info, linebytes, dp); |
| 574 | 551 | ||
| 575 | if (register_framebuffer(&all->info) < 0) { | 552 | err = register_framebuffer(&all->info); |
| 576 | printk(KERN_ERR "cg14: Could not register framebuffer.\n"); | 553 | if (err < 0) { |
| 577 | fb_dealloc_cmap(&all->info.cmap); | 554 | fb_dealloc_cmap(&all->info.cmap); |
| 555 | cg14_unmap_regs(all); | ||
| 578 | kfree(all); | 556 | kfree(all); |
| 579 | return; | 557 | return err; |
| 580 | } | 558 | } |
| 581 | 559 | ||
| 582 | list_add(&all->list, &cg14_list); | 560 | dev_set_drvdata(&op->dev, all); |
| 583 | 561 | ||
| 584 | printk("cg14: cgfourteen at %lx:%lx, %dMB\n", | 562 | printk("%s: cgfourteen at %lx:%lx, %dMB\n", |
| 585 | all->par.iospace, all->par.physbase, all->par.ramsize >> 20); | 563 | dp->full_name, |
| 564 | all->par.iospace, all->par.physbase, | ||
| 565 | all->par.ramsize >> 20); | ||
| 586 | 566 | ||
| 567 | return 0; | ||
| 587 | } | 568 | } |
| 588 | 569 | ||
| 589 | int __init cg14_init(void) | 570 | static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match) |
| 590 | { | 571 | { |
| 591 | struct sbus_bus *sbus; | 572 | struct of_device *op = to_of_device(&dev->dev); |
| 592 | struct sbus_dev *sdev; | ||
| 593 | 573 | ||
| 594 | if (fb_get_options("cg14fb", NULL)) | 574 | return cg14_init_one(op); |
| 595 | return -ENODEV; | 575 | } |
| 596 | 576 | ||
| 597 | #ifdef CONFIG_SPARC32 | 577 | static int __devexit cg14_remove(struct of_device *dev) |
| 598 | { | 578 | { |
| 599 | int root, node; | 579 | struct all_info *all = dev_get_drvdata(&dev->dev); |
| 600 | 580 | ||
| 601 | root = prom_getchild(prom_root_node); | 581 | unregister_framebuffer(&all->info); |
| 602 | root = prom_searchsiblings(root, "obio"); | 582 | fb_dealloc_cmap(&all->info.cmap); |
| 603 | if (root) { | 583 | |
| 604 | node = prom_searchsiblings(prom_getchild(root), | 584 | cg14_unmap_regs(all); |
| 605 | "cgfourteen"); | 585 | |
| 606 | if (node) | 586 | kfree(all); |
| 607 | cg14_init_one(NULL, node, root); | 587 | |
| 608 | } | 588 | dev_set_drvdata(&dev->dev, NULL); |
| 609 | } | ||
| 610 | #endif | ||
| 611 | for_all_sbusdev(sdev, sbus) { | ||
| 612 | if (!strcmp(sdev->prom_name, "cgfourteen")) | ||
| 613 | cg14_init_one(sdev, sdev->prom_node, sbus->prom_node); | ||
| 614 | } | ||
| 615 | 589 | ||
| 616 | return 0; | 590 | return 0; |
| 617 | } | 591 | } |
| 618 | 592 | ||
| 619 | void __exit cg14_exit(void) | 593 | static struct of_device_id cg14_match[] = { |
| 620 | { | 594 | { |
| 621 | struct list_head *pos, *tmp; | 595 | .name = "cgfourteen", |
| 596 | }, | ||
| 597 | {}, | ||
| 598 | }; | ||
| 599 | MODULE_DEVICE_TABLE(of, cg14_match); | ||
| 622 | 600 | ||
| 623 | list_for_each_safe(pos, tmp, &cg14_list) { | 601 | static struct of_platform_driver cg14_driver = { |
| 624 | struct all_info *all = list_entry(pos, typeof(*all), list); | 602 | .name = "cg14", |
| 603 | .match_table = cg14_match, | ||
| 604 | .probe = cg14_probe, | ||
| 605 | .remove = __devexit_p(cg14_remove), | ||
| 606 | }; | ||
| 625 | 607 | ||
| 626 | unregister_framebuffer(&all->info); | 608 | int __init cg14_init(void) |
| 627 | fb_dealloc_cmap(&all->info.cmap); | 609 | { |
| 628 | kfree(all); | 610 | if (fb_get_options("cg14fb", NULL)) |
| 629 | } | 611 | return -ENODEV; |
| 612 | |||
| 613 | return of_register_driver(&cg14_driver, &of_bus_type); | ||
| 630 | } | 614 | } |
| 631 | 615 | ||
| 632 | int __init | 616 | void __exit cg14_exit(void) |
| 633 | cg14_setup(char *arg) | ||
| 634 | { | 617 | { |
| 635 | /* No cmdline options yet... */ | 618 | of_unregister_driver(&cg14_driver); |
| 636 | return 0; | ||
| 637 | } | 619 | } |
| 638 | 620 | ||
| 639 | module_init(cg14_init); | 621 | module_init(cg14_init); |
| 640 | |||
| 641 | #ifdef MODULE | ||
| 642 | module_exit(cg14_exit); | 622 | module_exit(cg14_exit); |
| 643 | #endif | ||
| 644 | 623 | ||
| 645 | MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); | 624 | MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); |
| 646 | MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); | 625 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); |
| 626 | MODULE_VERSION("2.0"); | ||
| 647 | MODULE_LICENSE("GPL"); | 627 | MODULE_LICENSE("GPL"); |
