aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/amifb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/amifb.c')
-rw-r--r--drivers/video/amifb.c286
1 files changed, 146 insertions, 140 deletions
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 2bfaf1b86d46..f23cae094f1b 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -710,7 +710,7 @@ static u_short *lofsprite, *shfsprite, *dummysprite;
710 * Current Video Mode 710 * Current Video Mode
711 */ 711 */
712 712
713static struct amifb_par { 713struct amifb_par {
714 714
715 /* General Values */ 715 /* General Values */
716 716
@@ -773,15 +773,6 @@ static struct amifb_par {
773 /* Additional AGA Hardware Registers */ 773 /* Additional AGA Hardware Registers */
774 774
775 u_short fmode; /* vmode */ 775 u_short fmode; /* vmode */
776} currentpar;
777
778
779static struct fb_info fb_info = {
780 .fix = {
781 .id = "Amiga ",
782 .visual = FB_VISUAL_PSEUDOCOLOR,
783 .accel = FB_ACCEL_AMIGABLITT
784 }
785}; 776};
786 777
787 778
@@ -1130,8 +1121,8 @@ static u_short sprfetchmode[3] = {
1130 * it up, if it's too big, return -EINVAL. 1121 * it up, if it's too big, return -EINVAL.
1131 */ 1122 */
1132 1123
1133static int ami_decode_var(struct fb_var_screeninfo *var, 1124static int ami_decode_var(struct fb_var_screeninfo *var, struct amifb_par *par,
1134 struct amifb_par *par) 1125 const struct fb_info *info)
1135{ 1126{
1136 u_short clk_shift, line_shift; 1127 u_short clk_shift, line_shift;
1137 u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n; 1128 u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
@@ -1449,14 +1440,14 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
1449 if (amifb_ilbm) { 1440 if (amifb_ilbm) {
1450 par->next_plane = div8(upx(16 << maxfmode, par->vxres)); 1441 par->next_plane = div8(upx(16 << maxfmode, par->vxres));
1451 par->next_line = par->bpp * par->next_plane; 1442 par->next_line = par->bpp * par->next_plane;
1452 if (par->next_line * par->vyres > fb_info.fix.smem_len) { 1443 if (par->next_line * par->vyres > info->fix.smem_len) {
1453 DPRINTK("too few video mem\n"); 1444 DPRINTK("too few video mem\n");
1454 return -EINVAL; 1445 return -EINVAL;
1455 } 1446 }
1456 } else { 1447 } else {
1457 par->next_line = div8(upx(16 << maxfmode, par->vxres)); 1448 par->next_line = div8(upx(16 << maxfmode, par->vxres));
1458 par->next_plane = par->vyres * par->next_line; 1449 par->next_plane = par->vyres * par->next_line;
1459 if (par->next_plane * par->bpp > fb_info.fix.smem_len) { 1450 if (par->next_plane * par->bpp > info->fix.smem_len) {
1460 DPRINTK("too few video mem\n"); 1451 DPRINTK("too few video mem\n");
1461 return -EINVAL; 1452 return -EINVAL;
1462 } 1453 }
@@ -1519,8 +1510,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
1519 * other values read out of the hardware. 1510 * other values read out of the hardware.
1520 */ 1511 */
1521 1512
1522static int ami_encode_var(struct fb_var_screeninfo *var, 1513static void ami_encode_var(struct fb_var_screeninfo *var,
1523 struct amifb_par *par) 1514 struct amifb_par *par)
1524{ 1515{
1525 u_short clk_shift, line_shift; 1516 u_short clk_shift, line_shift;
1526 1517
@@ -1596,8 +1587,6 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
1596 var->sync |= FB_SYNC_EXT; 1587 var->sync |= FB_SYNC_EXT;
1597 if (par->vmode & FB_VMODE_YWRAP) 1588 if (par->vmode & FB_VMODE_YWRAP)
1598 var->vmode |= FB_VMODE_YWRAP; 1589 var->vmode |= FB_VMODE_YWRAP;
1599
1600 return 0;
1601} 1590}
1602 1591
1603 1592
@@ -1605,9 +1594,9 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
1605 * Update hardware 1594 * Update hardware
1606 */ 1595 */
1607 1596
1608static int ami_update_par(void) 1597static void ami_update_par(struct fb_info *info)
1609{ 1598{
1610 struct amifb_par *par = &currentpar; 1599 struct amifb_par *par = info->par;
1611 short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod; 1600 short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
1612 1601
1613 clk_shift = par->clk_shift; 1602 clk_shift = par->clk_shift;
@@ -1649,11 +1638,11 @@ static int ami_update_par(void)
1649 par->bpl1mod = par->bpl2mod; 1638 par->bpl1mod = par->bpl2mod;
1650 1639
1651 if (par->yoffset) { 1640 if (par->yoffset) {
1652 par->bplpt0 = fb_info.fix.smem_start + 1641 par->bplpt0 = info->fix.smem_start +
1653 par->next_line * par->yoffset + move; 1642 par->next_line * par->yoffset + move;
1654 if (par->vmode & FB_VMODE_YWRAP) { 1643 if (par->vmode & FB_VMODE_YWRAP) {
1655 if (par->yoffset > par->vyres - par->yres) { 1644 if (par->yoffset > par->vyres - par->yres) {
1656 par->bplpt0wrap = fb_info.fix.smem_start + move; 1645 par->bplpt0wrap = info->fix.smem_start + move;
1657 if (par->bplcon0 & BPC0_LACE && 1646 if (par->bplcon0 & BPC0_LACE &&
1658 mod2(par->diwstrt_v + par->vyres - 1647 mod2(par->diwstrt_v + par->vyres -
1659 par->yoffset)) 1648 par->yoffset))
@@ -1661,12 +1650,10 @@ static int ami_update_par(void)
1661 } 1650 }
1662 } 1651 }
1663 } else 1652 } else
1664 par->bplpt0 = fb_info.fix.smem_start + move; 1653 par->bplpt0 = info->fix.smem_start + move;
1665 1654
1666 if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v)) 1655 if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
1667 par->bplpt0 += par->next_line; 1656 par->bplpt0 += par->next_line;
1668
1669 return 0;
1670} 1657}
1671 1658
1672 1659
@@ -1677,9 +1664,9 @@ static int ami_update_par(void)
1677 * in `var'. 1664 * in `var'.
1678 */ 1665 */
1679 1666
1680static void ami_pan_var(struct fb_var_screeninfo *var) 1667static void ami_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1681{ 1668{
1682 struct amifb_par *par = &currentpar; 1669 struct amifb_par *par = info->par;
1683 1670
1684 par->xoffset = var->xoffset; 1671 par->xoffset = var->xoffset;
1685 par->yoffset = var->yoffset; 1672 par->yoffset = var->yoffset;
@@ -1689,15 +1676,13 @@ static void ami_pan_var(struct fb_var_screeninfo *var)
1689 par->vmode &= ~FB_VMODE_YWRAP; 1676 par->vmode &= ~FB_VMODE_YWRAP;
1690 1677
1691 do_vmode_pan = 0; 1678 do_vmode_pan = 0;
1692 ami_update_par(); 1679 ami_update_par(info);
1693 do_vmode_pan = 1; 1680 do_vmode_pan = 1;
1694} 1681}
1695 1682
1696 1683
1697static void ami_update_display(void) 1684static void ami_update_display(const struct amifb_par *par)
1698{ 1685{
1699 struct amifb_par *par = &currentpar;
1700
1701 custom.bplcon1 = par->bplcon1; 1686 custom.bplcon1 = par->bplcon1;
1702 custom.bpl1mod = par->bpl1mod; 1687 custom.bpl1mod = par->bpl1mod;
1703 custom.bpl2mod = par->bpl2mod; 1688 custom.bpl2mod = par->bpl2mod;
@@ -1709,9 +1694,8 @@ static void ami_update_display(void)
1709 * Change the video mode (called by VBlank interrupt) 1694 * Change the video mode (called by VBlank interrupt)
1710 */ 1695 */
1711 1696
1712static void ami_init_display(void) 1697static void ami_init_display(const struct amifb_par *par)
1713{ 1698{
1714 struct amifb_par *par = &currentpar;
1715 int i; 1699 int i;
1716 1700
1717 custom.bplcon0 = par->bplcon0 & ~BPC0_LACE; 1701 custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
@@ -1764,9 +1748,8 @@ static void ami_init_display(void)
1764 * (Un)Blank the screen (called by VBlank interrupt) 1748 * (Un)Blank the screen (called by VBlank interrupt)
1765 */ 1749 */
1766 1750
1767static void ami_do_blank(void) 1751static void ami_do_blank(const struct amifb_par *par)
1768{ 1752{
1769 struct amifb_par *par = &currentpar;
1770#if defined(CONFIG_FB_AMIGA_AGA) 1753#if defined(CONFIG_FB_AMIGA_AGA)
1771 u_short bplcon3 = par->bplcon3; 1754 u_short bplcon3 = par->bplcon3;
1772#endif 1755#endif
@@ -1843,10 +1826,9 @@ static void ami_do_blank(void)
1843 is_blanked = do_blank > 0 ? do_blank : 0; 1826 is_blanked = do_blank > 0 ? do_blank : 0;
1844} 1827}
1845 1828
1846static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix) 1829static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix,
1830 const struct amifb_par *par)
1847{ 1831{
1848 struct amifb_par *par = &currentpar;
1849
1850 fix->crsr_width = fix->crsr_xsize = par->crsr.width; 1832 fix->crsr_width = fix->crsr_xsize = par->crsr.width;
1851 fix->crsr_height = fix->crsr_ysize = par->crsr.height; 1833 fix->crsr_height = fix->crsr_ysize = par->crsr.height;
1852 fix->crsr_color1 = 17; 1834 fix->crsr_color1 = 17;
@@ -1854,9 +1836,10 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
1854 return 0; 1836 return 0;
1855} 1837}
1856 1838
1857static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) 1839static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var,
1840 u_char __user *data,
1841 const struct amifb_par *par)
1858{ 1842{
1859 struct amifb_par *par = &currentpar;
1860 register u_short *lspr, *sspr; 1843 register u_short *lspr, *sspr;
1861#ifdef __mc68000__ 1844#ifdef __mc68000__
1862 register u_long datawords asm ("d2"); 1845 register u_long datawords asm ("d2");
@@ -1929,9 +1912,9 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
1929 return 0; 1912 return 0;
1930} 1913}
1931 1914
1932static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) 1915static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var,
1916 u_char __user *data, struct amifb_par *par)
1933{ 1917{
1934 struct amifb_par *par = &currentpar;
1935 register u_short *lspr, *sspr; 1918 register u_short *lspr, *sspr;
1936#ifdef __mc68000__ 1919#ifdef __mc68000__
1937 register u_long datawords asm ("d2"); 1920 register u_long datawords asm ("d2");
@@ -2047,20 +2030,18 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
2047 return 0; 2030 return 0;
2048} 2031}
2049 2032
2050static int ami_get_cursorstate(struct fb_cursorstate *state) 2033static int ami_get_cursorstate(struct fb_cursorstate *state,
2034 const struct amifb_par *par)
2051{ 2035{
2052 struct amifb_par *par = &currentpar;
2053
2054 state->xoffset = par->crsr.crsr_x; 2036 state->xoffset = par->crsr.crsr_x;
2055 state->yoffset = par->crsr.crsr_y; 2037 state->yoffset = par->crsr.crsr_y;
2056 state->mode = cursormode; 2038 state->mode = cursormode;
2057 return 0; 2039 return 0;
2058} 2040}
2059 2041
2060static int ami_set_cursorstate(struct fb_cursorstate *state) 2042static int ami_set_cursorstate(struct fb_cursorstate *state,
2043 struct amifb_par *par)
2061{ 2044{
2062 struct amifb_par *par = &currentpar;
2063
2064 par->crsr.crsr_x = state->xoffset; 2045 par->crsr.crsr_x = state->xoffset;
2065 par->crsr.crsr_y = state->yoffset; 2046 par->crsr.crsr_y = state->yoffset;
2066 if ((cursormode = state->mode) == FB_CURSOR_OFF) 2047 if ((cursormode = state->mode) == FB_CURSOR_OFF)
@@ -2069,9 +2050,8 @@ static int ami_set_cursorstate(struct fb_cursorstate *state)
2069 return 0; 2050 return 0;
2070} 2051}
2071 2052
2072static void ami_set_sprite(void) 2053static void ami_set_sprite(const struct amifb_par *par)
2073{ 2054{
2074 struct amifb_par *par = &currentpar;
2075 copins *copl, *cops; 2055 copins *copl, *cops;
2076 u_short hs, vs, ve; 2056 u_short hs, vs, ve;
2077 u_long pl, ps, pt; 2057 u_long pl, ps, pt;
@@ -2153,10 +2133,8 @@ static void __init ami_init_copper(void)
2153 custom.copjmp1 = 0; 2133 custom.copjmp1 = 0;
2154} 2134}
2155 2135
2156static void ami_reinit_copper(void) 2136static void ami_reinit_copper(const struct amifb_par *par)
2157{ 2137{
2158 struct amifb_par *par = &currentpar;
2159
2160 copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0; 2138 copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0;
2161 copdisplay.wait->l = CWAIT(32, par->diwstrt_v - 4); 2139 copdisplay.wait->l = CWAIT(32, par->diwstrt_v - 4);
2162} 2140}
@@ -2168,9 +2146,8 @@ static void ami_reinit_copper(void)
2168 * We only change the things that are not static 2146 * We only change the things that are not static
2169 */ 2147 */
2170 2148
2171static void ami_rebuild_copper(void) 2149static void ami_rebuild_copper(const struct amifb_par *par)
2172{ 2150{
2173 struct amifb_par *par = &currentpar;
2174 copins *copl, *cops; 2151 copins *copl, *cops;
2175 u_short line, h_end1, h_end2; 2152 u_short line, h_end1, h_end2;
2176 short i; 2153 short i;
@@ -2182,7 +2159,7 @@ static void ami_rebuild_copper(void)
2182 h_end1 = par->htotal - 32; 2159 h_end1 = par->htotal - 32;
2183 h_end2 = par->ddfstop + 64; 2160 h_end2 = par->ddfstop + 64;
2184 2161
2185 ami_set_sprite(); 2162 ami_set_sprite(par);
2186 2163
2187 copl = copdisplay.rebuild[1]; 2164 copl = copdisplay.rebuild[1];
2188 p = par->bplpt0; 2165 p = par->bplpt0;
@@ -2259,9 +2236,9 @@ static void ami_rebuild_copper(void)
2259 * Build the Copper List 2236 * Build the Copper List
2260 */ 2237 */
2261 2238
2262static void ami_build_copper(void) 2239static void ami_build_copper(struct fb_info *info)
2263{ 2240{
2264 struct amifb_par *par = &currentpar; 2241 struct amifb_par *par = info->par;
2265 copins *copl, *cops; 2242 copins *copl, *cops;
2266 u_long p; 2243 u_long p;
2267 2244
@@ -2326,8 +2303,8 @@ static void ami_build_copper(void)
2326 } 2303 }
2327 copdisplay.rebuild[1] = copl; 2304 copdisplay.rebuild[1] = copl;
2328 2305
2329 ami_update_par(); 2306 ami_update_par(info);
2330 ami_rebuild_copper(); 2307 ami_rebuild_copper(info->par);
2331} 2308}
2332 2309
2333 2310
@@ -2405,7 +2382,8 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
2405 struct amifb_par par; 2382 struct amifb_par par;
2406 2383
2407 /* Validate wanted screen parameters */ 2384 /* Validate wanted screen parameters */
2408 if ((err = ami_decode_var(var, &par))) 2385 err = ami_decode_var(var, &par, info);
2386 if (err)
2409 return err; 2387 return err;
2410 2388
2411 /* Encode (possibly rounded) screen parameters */ 2389 /* Encode (possibly rounded) screen parameters */
@@ -2417,15 +2395,18 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
2417static int amifb_set_par(struct fb_info *info) 2395static int amifb_set_par(struct fb_info *info)
2418{ 2396{
2419 struct amifb_par *par = info->par; 2397 struct amifb_par *par = info->par;
2398 int error;
2420 2399
2421 do_vmode_pan = 0; 2400 do_vmode_pan = 0;
2422 do_vmode_full = 0; 2401 do_vmode_full = 0;
2423 2402
2424 /* Decode wanted screen parameters */ 2403 /* Decode wanted screen parameters */
2425 ami_decode_var(&info->var, par); 2404 error = ami_decode_var(&info->var, par, info);
2405 if (error)
2406 return error;
2426 2407
2427 /* Set new videomode */ 2408 /* Set new videomode */
2428 ami_build_copper(); 2409 ami_build_copper(info);
2429 2410
2430 /* Set VBlank trigger */ 2411 /* Set VBlank trigger */
2431 do_vmode_full = 1; 2412 do_vmode_full = 1;
@@ -2471,10 +2452,12 @@ static int amifb_set_par(struct fb_info *info)
2471static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 2452static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2472 u_int transp, struct fb_info *info) 2453 u_int transp, struct fb_info *info)
2473{ 2454{
2455 const struct amifb_par *par = info->par;
2456
2474 if (IS_AGA) { 2457 if (IS_AGA) {
2475 if (regno > 255) 2458 if (regno > 255)
2476 return 1; 2459 return 1;
2477 } else if (currentpar.bplcon0 & BPC0_SHRES) { 2460 } else if (par->bplcon0 & BPC0_SHRES) {
2478 if (regno > 3) 2461 if (regno > 3)
2479 return 1; 2462 return 1;
2480 } else { 2463 } else {
@@ -2501,7 +2484,7 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2501 if (regno || !is_blanked) { 2484 if (regno || !is_blanked) {
2502#if defined(CONFIG_FB_AMIGA_AGA) 2485#if defined(CONFIG_FB_AMIGA_AGA)
2503 if (IS_AGA) { 2486 if (IS_AGA) {
2504 u_short bplcon3 = currentpar.bplcon3; 2487 u_short bplcon3 = par->bplcon3;
2505 VBlankOff(); 2488 VBlankOff();
2506 custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000); 2489 custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
2507 custom.color[regno & 31] = rgb2hw8_high(red, green, 2490 custom.color[regno & 31] = rgb2hw8_high(red, green,
@@ -2515,7 +2498,7 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2515 } else 2498 } else
2516#endif 2499#endif
2517#if defined(CONFIG_FB_AMIGA_ECS) 2500#if defined(CONFIG_FB_AMIGA_ECS)
2518 if (currentpar.bplcon0 & BPC0_SHRES) { 2501 if (par->bplcon0 & BPC0_SHRES) {
2519 u_short color, mask; 2502 u_short color, mask;
2520 int i; 2503 int i;
2521 2504
@@ -2572,7 +2555,7 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
2572 var->yoffset + info->var.yres > info->var.yres_virtual) 2555 var->yoffset + info->var.yres > info->var.yres_virtual)
2573 return -EINVAL; 2556 return -EINVAL;
2574 } 2557 }
2575 ami_pan_var(var); 2558 ami_pan_var(var, info);
2576 info->var.xoffset = var->xoffset; 2559 info->var.xoffset = var->xoffset;
2577 info->var.yoffset = var->yoffset; 2560 info->var.yoffset = var->yoffset;
2578 if (var->vmode & FB_VMODE_YWRAP) 2561 if (var->vmode & FB_VMODE_YWRAP)
@@ -3418,7 +3401,7 @@ static int amifb_ioctl(struct fb_info *info,
3418 3401
3419 switch (cmd) { 3402 switch (cmd) {
3420 case FBIOGET_FCURSORINFO: 3403 case FBIOGET_FCURSORINFO:
3421 i = ami_get_fix_cursorinfo(&crsr.fix); 3404 i = ami_get_fix_cursorinfo(&crsr.fix, info->par);
3422 if (i) 3405 if (i)
3423 return i; 3406 return i;
3424 return copy_to_user(argp, &crsr.fix, 3407 return copy_to_user(argp, &crsr.fix,
@@ -3426,7 +3409,8 @@ static int amifb_ioctl(struct fb_info *info,
3426 3409
3427 case FBIOGET_VCURSORINFO: 3410 case FBIOGET_VCURSORINFO:
3428 i = ami_get_var_cursorinfo(&crsr.var, 3411 i = ami_get_var_cursorinfo(&crsr.var,
3429 ((struct fb_var_cursorinfo __user *)arg)->data); 3412 ((struct fb_var_cursorinfo __user *)arg)->data,
3413 info->par);
3430 if (i) 3414 if (i)
3431 return i; 3415 return i;
3432 return copy_to_user(argp, &crsr.var, 3416 return copy_to_user(argp, &crsr.var,
@@ -3436,10 +3420,11 @@ static int amifb_ioctl(struct fb_info *info,
3436 if (copy_from_user(&crsr.var, argp, sizeof(crsr.var))) 3420 if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
3437 return -EFAULT; 3421 return -EFAULT;
3438 return ami_set_var_cursorinfo(&crsr.var, 3422 return ami_set_var_cursorinfo(&crsr.var,
3439 ((struct fb_var_cursorinfo __user *)arg)->data); 3423 ((struct fb_var_cursorinfo __user *)arg)->data,
3424 info->par);
3440 3425
3441 case FBIOGET_CURSORSTATE: 3426 case FBIOGET_CURSORSTATE:
3442 i = ami_get_cursorstate(&crsr.state); 3427 i = ami_get_cursorstate(&crsr.state, info->par);
3443 if (i) 3428 if (i)
3444 return i; 3429 return i;
3445 return copy_to_user(argp, &crsr.state, 3430 return copy_to_user(argp, &crsr.state,
@@ -3448,7 +3433,7 @@ static int amifb_ioctl(struct fb_info *info,
3448 case FBIOPUT_CURSORSTATE: 3433 case FBIOPUT_CURSORSTATE:
3449 if (copy_from_user(&crsr.state, argp, sizeof(crsr.state))) 3434 if (copy_from_user(&crsr.state, argp, sizeof(crsr.state)))
3450 return -EFAULT; 3435 return -EFAULT;
3451 return ami_set_cursorstate(&crsr.state); 3436 return ami_set_cursorstate(&crsr.state, info->par);
3452 } 3437 }
3453 return -EINVAL; 3438 return -EINVAL;
3454} 3439}
@@ -3479,32 +3464,34 @@ static int flash_cursor(void)
3479 3464
3480static irqreturn_t amifb_interrupt(int irq, void *dev_id) 3465static irqreturn_t amifb_interrupt(int irq, void *dev_id)
3481{ 3466{
3467 struct amifb_par *par = dev_id;
3468
3482 if (do_vmode_pan || do_vmode_full) 3469 if (do_vmode_pan || do_vmode_full)
3483 ami_update_display(); 3470 ami_update_display(par);
3484 3471
3485 if (do_vmode_full) 3472 if (do_vmode_full)
3486 ami_init_display(); 3473 ami_init_display(par);
3487 3474
3488 if (do_vmode_pan) { 3475 if (do_vmode_pan) {
3489 flash_cursor(); 3476 flash_cursor();
3490 ami_rebuild_copper(); 3477 ami_rebuild_copper(par);
3491 do_cursor = do_vmode_pan = 0; 3478 do_cursor = do_vmode_pan = 0;
3492 } else if (do_cursor) { 3479 } else if (do_cursor) {
3493 flash_cursor(); 3480 flash_cursor();
3494 ami_set_sprite(); 3481 ami_set_sprite(par);
3495 do_cursor = 0; 3482 do_cursor = 0;
3496 } else { 3483 } else {
3497 if (flash_cursor()) 3484 if (flash_cursor())
3498 ami_set_sprite(); 3485 ami_set_sprite(par);
3499 } 3486 }
3500 3487
3501 if (do_blank) { 3488 if (do_blank) {
3502 ami_do_blank(); 3489 ami_do_blank(par);
3503 do_blank = 0; 3490 do_blank = 0;
3504 } 3491 }
3505 3492
3506 if (do_vmode_full) { 3493 if (do_vmode_full) {
3507 ami_reinit_copper(); 3494 ami_reinit_copper(par);
3508 do_vmode_full = 0; 3495 do_vmode_full = 0;
3509 } 3496 }
3510 return IRQ_HANDLED; 3497 return IRQ_HANDLED;
@@ -3549,23 +3536,13 @@ static inline void chipfree(void)
3549} 3536}
3550 3537
3551 3538
3552static void amifb_deinit(struct platform_device *pdev)
3553{
3554 if (fb_info.cmap.len)
3555 fb_dealloc_cmap(&fb_info.cmap);
3556 chipfree();
3557 if (videomemory)
3558 iounmap((void *)videomemory);
3559 custom.dmacon = DMAF_ALL | DMAF_MASTER;
3560}
3561
3562
3563 /* 3539 /*
3564 * Initialisation 3540 * Initialisation
3565 */ 3541 */
3566 3542
3567static int __init amifb_probe(struct platform_device *pdev) 3543static int __init amifb_probe(struct platform_device *pdev)
3568{ 3544{
3545 struct fb_info *info;
3569 int tag, i, err = 0; 3546 int tag, i, err = 0;
3570 u_long chipptr; 3547 u_long chipptr;
3571 u_int defmode; 3548 u_int defmode;
@@ -3581,10 +3558,20 @@ static int __init amifb_probe(struct platform_device *pdev)
3581#endif 3558#endif
3582 custom.dmacon = DMAF_ALL | DMAF_MASTER; 3559 custom.dmacon = DMAF_ALL | DMAF_MASTER;
3583 3560
3561 info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);
3562 if (!info) {
3563 dev_err(&pdev->dev, "framebuffer_alloc failed\n");
3564 return -ENOMEM;
3565 }
3566
3567 strcpy(info->fix.id, "Amiga ");
3568 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
3569 info->fix.accel = FB_ACCEL_AMIGABLITT;
3570
3584 switch (amiga_chipset) { 3571 switch (amiga_chipset) {
3585#ifdef CONFIG_FB_AMIGA_OCS 3572#ifdef CONFIG_FB_AMIGA_OCS
3586 case CS_OCS: 3573 case CS_OCS:
3587 strcat(fb_info.fix.id, "OCS"); 3574 strcat(info->fix.id, "OCS");
3588default_chipset: 3575default_chipset:
3589 chipset = TAG_OCS; 3576 chipset = TAG_OCS;
3590 maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */ 3577 maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
@@ -3592,13 +3579,13 @@ default_chipset:
3592 maxdepth[TAG_LORES] = 6; 3579 maxdepth[TAG_LORES] = 6;
3593 maxfmode = TAG_FMODE_1; 3580 maxfmode = TAG_FMODE_1;
3594 defmode = amiga_vblank == 50 ? DEFMODE_PAL : DEFMODE_NTSC; 3581 defmode = amiga_vblank == 50 ? DEFMODE_PAL : DEFMODE_NTSC;
3595 fb_info.fix.smem_len = VIDEOMEMSIZE_OCS; 3582 info->fix.smem_len = VIDEOMEMSIZE_OCS;
3596 break; 3583 break;
3597#endif /* CONFIG_FB_AMIGA_OCS */ 3584#endif /* CONFIG_FB_AMIGA_OCS */
3598 3585
3599#ifdef CONFIG_FB_AMIGA_ECS 3586#ifdef CONFIG_FB_AMIGA_ECS
3600 case CS_ECS: 3587 case CS_ECS:
3601 strcat(fb_info.fix.id, "ECS"); 3588 strcat(info->fix.id, "ECS");
3602 chipset = TAG_ECS; 3589 chipset = TAG_ECS;
3603 maxdepth[TAG_SHRES] = 2; 3590 maxdepth[TAG_SHRES] = 2;
3604 maxdepth[TAG_HIRES] = 4; 3591 maxdepth[TAG_HIRES] = 4;
@@ -3612,15 +3599,15 @@ default_chipset:
3612 : DEFMODE_NTSC; 3599 : DEFMODE_NTSC;
3613 if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT > 3600 if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
3614 VIDEOMEMSIZE_ECS_2M) 3601 VIDEOMEMSIZE_ECS_2M)
3615 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M; 3602 info->fix.smem_len = VIDEOMEMSIZE_ECS_2M;
3616 else 3603 else
3617 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M; 3604 info->fix.smem_len = VIDEOMEMSIZE_ECS_1M;
3618 break; 3605 break;
3619#endif /* CONFIG_FB_AMIGA_ECS */ 3606#endif /* CONFIG_FB_AMIGA_ECS */
3620 3607
3621#ifdef CONFIG_FB_AMIGA_AGA 3608#ifdef CONFIG_FB_AMIGA_AGA
3622 case CS_AGA: 3609 case CS_AGA:
3623 strcat(fb_info.fix.id, "AGA"); 3610 strcat(info->fix.id, "AGA");
3624 chipset = TAG_AGA; 3611 chipset = TAG_AGA;
3625 maxdepth[TAG_SHRES] = 8; 3612 maxdepth[TAG_SHRES] = 8;
3626 maxdepth[TAG_HIRES] = 8; 3613 maxdepth[TAG_HIRES] = 8;
@@ -3629,20 +3616,20 @@ default_chipset:
3629 defmode = DEFMODE_AGA; 3616 defmode = DEFMODE_AGA;
3630 if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT > 3617 if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
3631 VIDEOMEMSIZE_AGA_2M) 3618 VIDEOMEMSIZE_AGA_2M)
3632 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M; 3619 info->fix.smem_len = VIDEOMEMSIZE_AGA_2M;
3633 else 3620 else
3634 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M; 3621 info->fix.smem_len = VIDEOMEMSIZE_AGA_1M;
3635 break; 3622 break;
3636#endif /* CONFIG_FB_AMIGA_AGA */ 3623#endif /* CONFIG_FB_AMIGA_AGA */
3637 3624
3638 default: 3625 default:
3639#ifdef CONFIG_FB_AMIGA_OCS 3626#ifdef CONFIG_FB_AMIGA_OCS
3640 printk("Unknown graphics chipset, defaulting to OCS\n"); 3627 printk("Unknown graphics chipset, defaulting to OCS\n");
3641 strcat(fb_info.fix.id, "Unknown"); 3628 strcat(info->fix.id, "Unknown");
3642 goto default_chipset; 3629 goto default_chipset;
3643#else /* CONFIG_FB_AMIGA_OCS */ 3630#else /* CONFIG_FB_AMIGA_OCS */
3644 err = -ENODEV; 3631 err = -ENODEV;
3645 goto amifb_error; 3632 goto release;
3646#endif /* CONFIG_FB_AMIGA_OCS */ 3633#endif /* CONFIG_FB_AMIGA_OCS */
3647 break; 3634 break;
3648 } 3635 }
@@ -3672,44 +3659,43 @@ default_chipset:
3672 } 3659 }
3673 3660
3674 if (amifb_hfmin) { 3661 if (amifb_hfmin) {
3675 fb_info.monspecs.hfmin = amifb_hfmin; 3662 info->monspecs.hfmin = amifb_hfmin;
3676 fb_info.monspecs.hfmax = amifb_hfmax; 3663 info->monspecs.hfmax = amifb_hfmax;
3677 fb_info.monspecs.vfmin = amifb_vfmin; 3664 info->monspecs.vfmin = amifb_vfmin;
3678 fb_info.monspecs.vfmax = amifb_vfmax; 3665 info->monspecs.vfmax = amifb_vfmax;
3679 } else { 3666 } else {
3680 /* 3667 /*
3681 * These are for a typical Amiga monitor (e.g. A1960) 3668 * These are for a typical Amiga monitor (e.g. A1960)
3682 */ 3669 */
3683 fb_info.monspecs.hfmin = 15000; 3670 info->monspecs.hfmin = 15000;
3684 fb_info.monspecs.hfmax = 38000; 3671 info->monspecs.hfmax = 38000;
3685 fb_info.monspecs.vfmin = 49; 3672 info->monspecs.vfmin = 49;
3686 fb_info.monspecs.vfmax = 90; 3673 info->monspecs.vfmax = 90;
3687 } 3674 }
3688 3675
3689 fb_info.fbops = &amifb_ops; 3676 info->fbops = &amifb_ops;
3690 fb_info.par = &currentpar; 3677 info->flags = FBINFO_DEFAULT;
3691 fb_info.flags = FBINFO_DEFAULT; 3678 info->device = &pdev->dev;
3692 fb_info.device = &pdev->dev;
3693 3679
3694 if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb, 3680 if (!fb_find_mode(&info->var, info, mode_option, ami_modedb,
3695 NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) { 3681 NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
3696 err = -EINVAL; 3682 err = -EINVAL;
3697 goto amifb_error; 3683 goto release;
3698 } 3684 }
3699 3685
3700 fb_videomode_to_modelist(ami_modedb, NUM_TOTAL_MODES, 3686 fb_videomode_to_modelist(ami_modedb, NUM_TOTAL_MODES,
3701 &fb_info.modelist); 3687 &info->modelist);
3702 3688
3703 round_down_bpp = 0; 3689 round_down_bpp = 0;
3704 chipptr = chipalloc(fb_info.fix.smem_len + SPRITEMEMSIZE + 3690 chipptr = chipalloc(info->fix.smem_len + SPRITEMEMSIZE +
3705 DUMMYSPRITEMEMSIZE + COPINITSIZE + 3691 DUMMYSPRITEMEMSIZE + COPINITSIZE +
3706 4 * COPLISTSIZE); 3692 4 * COPLISTSIZE);
3707 if (!chipptr) { 3693 if (!chipptr) {
3708 err = -ENOMEM; 3694 err = -ENOMEM;
3709 goto amifb_error; 3695 goto release;
3710 } 3696 }
3711 3697
3712 assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len); 3698 assignchunk(videomemory, u_long, chipptr, info->fix.smem_len);
3713 assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE); 3699 assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE);
3714 assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE); 3700 assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE);
3715 assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE); 3701 assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE);
@@ -3721,14 +3707,15 @@ default_chipset:
3721 /* 3707 /*
3722 * access the videomem with writethrough cache 3708 * access the videomem with writethrough cache
3723 */ 3709 */
3724 fb_info.fix.smem_start = (u_long)ZTWO_PADDR(videomemory); 3710 info->fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
3725 videomemory = (u_long)ioremap_writethrough(fb_info.fix.smem_start, 3711 videomemory = (u_long)ioremap_writethrough(info->fix.smem_start,
3726 fb_info.fix.smem_len); 3712 info->fix.smem_len);
3727 if (!videomemory) { 3713 if (!videomemory) {
3728 printk("amifb: WARNING! unable to map videomem cached writethrough\n"); 3714 dev_warn(&pdev->dev,
3729 fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start); 3715 "Unable to map videomem cached writethrough\n");
3716 info->screen_base = (char *)ZTWO_VADDR(info->fix.smem_start);
3730 } else 3717 } else
3731 fb_info.screen_base = (char *)videomemory; 3718 info->screen_base = (char *)videomemory;
3732 3719
3733 memset(dummysprite, 0, DUMMYSPRITEMEMSIZE); 3720 memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
3734 3721
@@ -3743,36 +3730,55 @@ default_chipset:
3743 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | 3730 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
3744 DMAF_BLITTER | DMAF_SPRITE; 3731 DMAF_BLITTER | DMAF_SPRITE;
3745 3732
3746 if (request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0, 3733 err = request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
3747 "fb vertb handler", &currentpar)) { 3734 "fb vertb handler", info->par);
3748 err = -EBUSY; 3735 if (err)
3749 goto amifb_error; 3736 goto disable_dma;
3750 }
3751 3737
3752 err = fb_alloc_cmap(&fb_info.cmap, 1 << fb_info.var.bits_per_pixel, 0); 3738 err = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
3753 if (err) 3739 if (err)
3754 goto amifb_error; 3740 goto free_irq;
3755 3741
3756 if (register_framebuffer(&fb_info) < 0) { 3742 dev_set_drvdata(&pdev->dev, info);
3757 err = -EINVAL; 3743
3758 goto amifb_error; 3744 err = register_framebuffer(info);
3759 } 3745 if (err)
3746 goto unset_drvdata;
3760 3747
3761 printk("fb%d: %s frame buffer device, using %dK of video memory\n", 3748 printk("fb%d: %s frame buffer device, using %dK of video memory\n",
3762 fb_info.node, fb_info.fix.id, fb_info.fix.smem_len>>10); 3749 info->node, info->fix.id, info->fix.smem_len>>10);
3763 3750
3764 return 0; 3751 return 0;
3765 3752
3766amifb_error: 3753unset_drvdata:
3767 amifb_deinit(pdev); 3754 dev_set_drvdata(&pdev->dev, NULL);
3755 fb_dealloc_cmap(&info->cmap);
3756free_irq:
3757 free_irq(IRQ_AMIGA_COPPER, info->par);
3758disable_dma:
3759 custom.dmacon = DMAF_ALL | DMAF_MASTER;
3760 if (videomemory)
3761 iounmap((void *)videomemory);
3762 chipfree();
3763release:
3764 framebuffer_release(info);
3768 return err; 3765 return err;
3769} 3766}
3770 3767
3771 3768
3772static int __exit amifb_remove(struct platform_device *pdev) 3769static int __exit amifb_remove(struct platform_device *pdev)
3773{ 3770{
3774 unregister_framebuffer(&fb_info); 3771 struct fb_info *info = dev_get_drvdata(&pdev->dev);
3775 amifb_deinit(pdev); 3772
3773 unregister_framebuffer(info);
3774 dev_set_drvdata(&pdev->dev, NULL);
3775 fb_dealloc_cmap(&info->cmap);
3776 free_irq(IRQ_AMIGA_COPPER, info->par);
3777 custom.dmacon = DMAF_ALL | DMAF_MASTER;
3778 if (videomemory)
3779 iounmap((void *)videomemory);
3780 chipfree();
3781 framebuffer_release(info);
3776 amifb_video_off(); 3782 amifb_video_off();
3777 return 0; 3783 return 0;
3778} 3784}