aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/leo.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-06-29 17:35:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-29 19:37:18 -0400
commit50312ce9dd794eef3df9e64194ba95ca730d82c8 (patch)
tree15703fd98b8b757197d43e11f8de791bbc3b8f00 /drivers/video/leo.c
parent3ca9fab410fbef6fc3a13284f5c26faccade21d1 (diff)
[SPARC]: Convert all FB SBUS drivers to of_driver framework.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/video/leo.c')
-rw-r--r--drivers/video/leo.c294
1 files changed, 160 insertions, 134 deletions
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index a23cfdb9d826..f3a24338d9ac 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -1,6 +1,6 @@
1/* leo.c: LEO frame buffer driver 1/* leo.c: LEO 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-1999 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) 5 * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
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"
@@ -80,10 +80,10 @@ static struct fb_ops leo_ops = {
80 80
81struct leo_cursor { 81struct leo_cursor {
82 u8 xxx0[16]; 82 u8 xxx0[16];
83 volatile u32 cur_type; 83 u32 cur_type;
84 volatile u32 cur_misc; 84 u32 cur_misc;
85 volatile u32 cur_cursxy; 85 u32 cur_cursxy;
86 volatile u32 cur_data; 86 u32 cur_data;
87}; 87};
88 88
89#define LEO_KRN_TYPE_CLUT0 0x00001000 89#define LEO_KRN_TYPE_CLUT0 0x00001000
@@ -99,27 +99,27 @@ struct leo_cursor {
99#define LEO_KRN_CSR_UNK2 0x00000001 99#define LEO_KRN_CSR_UNK2 0x00000001
100 100
101struct leo_lx_krn { 101struct leo_lx_krn {
102 volatile u32 krn_type; 102 u32 krn_type;
103 volatile u32 krn_csr; 103 u32 krn_csr;
104 volatile u32 krn_value; 104 u32 krn_value;
105}; 105};
106 106
107struct leo_lc_ss0_krn { 107struct leo_lc_ss0_krn {
108 volatile u32 misc; 108 u32 misc;
109 u8 xxx0[0x800-4]; 109 u8 xxx0[0x800-4];
110 volatile u32 rev; 110 u32 rev;
111}; 111};
112 112
113struct leo_lc_ss0_usr { 113struct leo_lc_ss0_usr {
114 volatile u32 csr; 114 u32 csr;
115 volatile u32 addrspace; 115 u32 addrspace;
116 volatile u32 fontmsk; 116 u32 fontmsk;
117 volatile u32 fontt; 117 u32 fontt;
118 volatile u32 extent; 118 u32 extent;
119 volatile u32 src; 119 u32 src;
120 u32 dst; 120 u32 dst;
121 volatile u32 copy; 121 u32 copy;
122 volatile u32 fill; 122 u32 fill;
123}; 123};
124 124
125struct leo_lc_ss1_krn { 125struct leo_lc_ss1_krn {
@@ -132,47 +132,47 @@ struct leo_lc_ss1_usr {
132 132
133struct leo_ld { 133struct leo_ld {
134 u8 xxx0[0xe00]; 134 u8 xxx0[0xe00];
135 volatile u32 csr; 135 u32 csr;
136 volatile u32 wid; 136 u32 wid;
137 volatile u32 wmask; 137 u32 wmask;
138 volatile u32 widclip; 138 u32 widclip;
139 volatile u32 vclipmin; 139 u32 vclipmin;
140 volatile u32 vclipmax; 140 u32 vclipmax;
141 volatile u32 pickmin; /* SS1 only */ 141 u32 pickmin; /* SS1 only */
142 volatile u32 pickmax; /* SS1 only */ 142 u32 pickmax; /* SS1 only */
143 volatile u32 fg; 143 u32 fg;
144 volatile u32 bg; 144 u32 bg;
145 volatile u32 src; /* Copy/Scroll (SS0 only) */ 145 u32 src; /* Copy/Scroll (SS0 only) */
146 volatile u32 dst; /* Copy/Scroll/Fill (SS0 only) */ 146 u32 dst; /* Copy/Scroll/Fill (SS0 only) */
147 volatile u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ 147 u32 extent; /* Copy/Scroll/Fill size (SS0 only) */
148 u32 xxx1[3]; 148 u32 xxx1[3];
149 volatile u32 setsem; /* SS1 only */ 149 u32 setsem; /* SS1 only */
150 volatile u32 clrsem; /* SS1 only */ 150 u32 clrsem; /* SS1 only */
151 volatile u32 clrpick; /* SS1 only */ 151 u32 clrpick; /* SS1 only */
152 volatile u32 clrdat; /* SS1 only */ 152 u32 clrdat; /* SS1 only */
153 volatile u32 alpha; /* SS1 only */ 153 u32 alpha; /* SS1 only */
154 u8 xxx2[0x2c]; 154 u8 xxx2[0x2c];
155 volatile u32 winbg; 155 u32 winbg;
156 volatile u32 planemask; 156 u32 planemask;
157 volatile u32 rop; 157 u32 rop;
158 volatile u32 z; 158 u32 z;
159 volatile u32 dczf; /* SS1 only */ 159 u32 dczf; /* SS1 only */
160 volatile u32 dczb; /* SS1 only */ 160 u32 dczb; /* SS1 only */
161 volatile u32 dcs; /* SS1 only */ 161 u32 dcs; /* SS1 only */
162 volatile u32 dczs; /* SS1 only */ 162 u32 dczs; /* SS1 only */
163 volatile u32 pickfb; /* SS1 only */ 163 u32 pickfb; /* SS1 only */
164 volatile u32 pickbb; /* SS1 only */ 164 u32 pickbb; /* SS1 only */
165 volatile u32 dcfc; /* SS1 only */ 165 u32 dcfc; /* SS1 only */
166 volatile u32 forcecol; /* SS1 only */ 166 u32 forcecol; /* SS1 only */
167 volatile u32 door[8]; /* SS1 only */ 167 u32 door[8]; /* SS1 only */
168 volatile u32 pick[5]; /* SS1 only */ 168 u32 pick[5]; /* SS1 only */
169}; 169};
170 170
171#define LEO_SS1_MISC_ENABLE 0x00000001 171#define LEO_SS1_MISC_ENABLE 0x00000001
172#define LEO_SS1_MISC_STEREO 0x00000002 172#define LEO_SS1_MISC_STEREO 0x00000002
173struct leo_ld_ss1 { 173struct leo_ld_ss1 {
174 u8 xxx0[0xef4]; 174 u8 xxx0[0xef4];
175 volatile u32 ss1_misc; 175 u32 ss1_misc;
176}; 176};
177 177
178struct leo_ld_gbl { 178struct leo_ld_gbl {
@@ -193,9 +193,8 @@ struct leo_par {
193#define LEO_FLAG_BLANKED 0x00000001 193#define LEO_FLAG_BLANKED 0x00000001
194 194
195 unsigned long physbase; 195 unsigned long physbase;
196 unsigned long which_io;
196 unsigned long fbsize; 197 unsigned long fbsize;
197
198 struct sbus_dev *sdev;
199}; 198};
200 199
201static void leo_wait(struct leo_lx_krn __iomem *lx_krn) 200static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
@@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
368 367
369 return sbusfb_mmap_helper(leo_mmap_map, 368 return sbusfb_mmap_helper(leo_mmap_map,
370 par->physbase, par->fbsize, 369 par->physbase, par->fbsize,
371 par->sdev->reg_addrs[0].which_io, 370 par->which_io, vma);
372 vma);
373} 371}
374 372
375static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 373static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
385 */ 383 */
386 384
387static void 385static void
388leo_init_fix(struct fb_info *info) 386leo_init_fix(struct fb_info *info, struct device_node *dp)
389{ 387{
390 struct leo_par *par = (struct leo_par *)info->par; 388 strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
391
392 strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
393 389
394 info->fix.type = FB_TYPE_PACKED_PIXELS; 390 info->fix.type = FB_TYPE_PACKED_PIXELS;
395 info->fix.visual = FB_VISUAL_TRUECOLOR; 391 info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
532struct all_info { 528struct all_info {
533 struct fb_info info; 529 struct fb_info info;
534 struct leo_par par; 530 struct leo_par par;
535 struct list_head list;
536}; 531};
537static LIST_HEAD(leo_list);
538 532
539static void leo_init_one(struct sbus_dev *sdev) 533static void leo_unmap_regs(struct all_info *all)
540{ 534{
541 struct all_info *all; 535 if (all->par.lc_ss0_usr)
542 int linebytes; 536 of_iounmap(all->par.lc_ss0_usr, 0x1000);
537 if (all->par.ld_ss0)
538 of_iounmap(all->par.ld_ss0, 0x1000);
539 if (all->par.ld_ss1)
540 of_iounmap(all->par.ld_ss1, 0x1000);
541 if (all->par.lx_krn)
542 of_iounmap(all->par.lx_krn, 0x1000);
543 if (all->par.cursor)
544 of_iounmap(all->par.cursor, sizeof(struct leo_cursor));
545 if (all->info.screen_base)
546 of_iounmap(all->info.screen_base, 0x800000);
547}
543 548
544 all = kmalloc(sizeof(*all), GFP_KERNEL); 549static int __devinit leo_init_one(struct of_device *op)
545 if (!all) { 550{
546 printk(KERN_ERR "leo: Cannot allocate memory.\n"); 551 struct device_node *dp = op->node;
547 return; 552 struct all_info *all;
548 } 553 int linebytes, err;
549 memset(all, 0, sizeof(*all));
550 554
551 INIT_LIST_HEAD(&all->list); 555 all = kzalloc(sizeof(*all), GFP_KERNEL);
556 if (!all)
557 return -ENOMEM;
552 558
553 spin_lock_init(&all->par.lock); 559 spin_lock_init(&all->par.lock);
554 all->par.sdev = sdev;
555 560
556 all->par.physbase = sdev->reg_addrs[0].phys_addr; 561 all->par.physbase = op->resource[0].start;
562 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
557 563
558 sbusfb_fill_var(&all->info.var, sdev->prom_node, 32); 564 sbusfb_fill_var(&all->info.var, dp->node, 32);
559 leo_fixup_var_rgb(&all->info.var); 565 leo_fixup_var_rgb(&all->info.var);
560 566
561 linebytes = prom_getintdefault(sdev->prom_node, "linebytes", 567 linebytes = of_getintprop_default(dp, "linebytes",
562 all->info.var.xres); 568 all->info.var.xres);
563 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 569 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
564 570
565#ifdef CONFIG_SPARC32
566 all->info.screen_base = (char __iomem *)
567 prom_getintdefault(sdev->prom_node, "address", 0);
568#endif
569 if (!all->info.screen_base)
570 all->info.screen_base =
571 sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
572 0x800000, "leo ram");
573
574 all->par.lc_ss0_usr = 571 all->par.lc_ss0_usr =
575 sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR, 572 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
576 0x1000, "leolc ss0usr"); 573 0x1000, "leolc ss0usr");
577 all->par.ld_ss0 = 574 all->par.ld_ss0 =
578 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0, 575 of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
579 0x1000, "leold ss0"); 576 0x1000, "leold ss0");
580 all->par.ld_ss1 = 577 all->par.ld_ss1 =
581 sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1, 578 of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
582 0x1000, "leold ss1"); 579 0x1000, "leold ss1");
583 all->par.lx_krn = 580 all->par.lx_krn =
584 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN, 581 of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
585 0x1000, "leolx krn"); 582 0x1000, "leolx krn");
586 all->par.cursor = 583 all->par.cursor =
587 sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR, 584 of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
588 sizeof(struct leo_cursor), "leolx cursor"); 585 sizeof(struct leo_cursor), "leolx cursor");
586 all->info.screen_base =
587 of_ioremap(&op->resource[0], LEO_OFF_SS0,
588 0x800000, "leo ram");
589 if (!all->par.lc_ss0_usr ||
590 !all->par.ld_ss0 ||
591 !all->par.ld_ss1 ||
592 !all->par.lx_krn ||
593 !all->par.cursor ||
594 !all->info.screen_base) {
595 leo_unmap_regs(all);
596 kfree(all);
597 return -ENOMEM;
598 }
589 599
590 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 600 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
591 all->info.fbops = &leo_ops; 601 all->info.fbops = &leo_ops;
@@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev)
597 leo_blank(0, &all->info); 607 leo_blank(0, &all->info);
598 608
599 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 609 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
600 printk(KERN_ERR "leo: Could not allocate color map.\n"); 610 leo_unmap_regs(all);
601 kfree(all); 611 kfree(all);
602 return; 612 return -ENOMEM;;
603 } 613 }
604 614
605 leo_init_fix(&all->info); 615 leo_init_fix(&all->info, dp);
606 616
607 if (register_framebuffer(&all->info) < 0) { 617 err = register_framebuffer(&all->info);
608 printk(KERN_ERR "leo: Could not register framebuffer.\n"); 618 if (err < 0) {
609 fb_dealloc_cmap(&all->info.cmap); 619 fb_dealloc_cmap(&all->info.cmap);
620 leo_unmap_regs(all);
610 kfree(all); 621 kfree(all);
611 return; 622 return err;
612 } 623 }
613 624
614 list_add(&all->list, &leo_list); 625 dev_set_drvdata(&op->dev, all);
626
627 printk("%s: leo at %lx:%lx\n",
628 dp->full_name,
629 all->par.which_io, all->par.physbase);
615 630
616 printk("leo: %s at %lx:%lx\n", 631 return 0;
617 sdev->prom_name,
618 (long) sdev->reg_addrs[0].which_io,
619 (long) sdev->reg_addrs[0].phys_addr);
620} 632}
621 633
622int __init leo_init(void) 634static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match)
623{ 635{
624 struct sbus_bus *sbus; 636 struct of_device *op = to_of_device(&dev->dev);
625 struct sbus_dev *sdev;
626 637
627 if (fb_get_options("leofb", NULL)) 638 return leo_init_one(op);
628 return -ENODEV; 639}
629 640
630 for_all_sbusdev(sdev, sbus) { 641static int __devexit leo_remove(struct of_device *dev)
631 if (!strcmp(sdev->prom_name, "leo")) 642{
632 leo_init_one(sdev); 643 struct all_info *all = dev_get_drvdata(&dev->dev);
633 } 644
645 unregister_framebuffer(&all->info);
646 fb_dealloc_cmap(&all->info.cmap);
647
648 leo_unmap_regs(all);
649
650 kfree(all);
651
652 dev_set_drvdata(&dev->dev, NULL);
634 653
635 return 0; 654 return 0;
636} 655}
637 656
638void __exit leo_exit(void) 657static struct of_device_id leo_match[] = {
639{ 658 {
640 struct list_head *pos, *tmp; 659 .name = "leo",
660 },
661 {},
662};
663MODULE_DEVICE_TABLE(of, leo_match);
664
665static struct of_platform_driver leo_driver = {
666 .name = "leo",
667 .match_table = leo_match,
668 .probe = leo_probe,
669 .remove = __devexit_p(leo_remove),
670};
641 671
642 list_for_each_safe(pos, tmp, &leo_list) { 672static int __init leo_init(void)
643 struct all_info *all = list_entry(pos, typeof(*all), list); 673{
674 if (fb_get_options("leofb", NULL))
675 return -ENODEV;
644 676
645 unregister_framebuffer(&all->info); 677 return of_register_driver(&leo_driver, &of_bus_type);
646 fb_dealloc_cmap(&all->info.cmap);
647 kfree(all);
648 }
649} 678}
650 679
651int __init 680static void __exit leo_exit(void)
652leo_setup(char *arg)
653{ 681{
654 /* No cmdline options yet... */ 682 of_unregister_driver(&leo_driver);
655 return 0;
656} 683}
657 684
658module_init(leo_init); 685module_init(leo_init);
659#ifdef MODULE
660module_exit(leo_exit); 686module_exit(leo_exit);
661#endif
662 687
663MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); 688MODULE_DESCRIPTION("framebuffer driver for LEO chipsets");
664MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 689MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
690MODULE_VERSION("2.0");
665MODULE_LICENSE("GPL"); 691MODULE_LICENSE("GPL");