aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2010-04-22 15:48:09 -0400
committerJonathan Corbet <corbet@lwn.net>2010-05-07 19:16:02 -0400
commit24b4d82e4715841848a499534ed5cb7db3d6bca3 (patch)
tree957c3664ac41da616e2aec7e8adb07247ee1a551 /drivers/video
parentf045f77bc0bf238a871b10bea9e425329a8e4abc (diff)
viafb: Separate global and fb-specific data
This patch moves data of interest into a new viafb_dev structure which describes the device as a whole; the idea here is to create a separation between what all devices may need and what the framebuffer device in particular needs. I've also made some small steps toward thinning out the global.h mess. Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Cc: Harald Welte <laforge@gnumonks.org> Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/via/accel.c14
-rw-r--r--drivers/video/via/dvi.c2
-rw-r--r--drivers/video/via/global.h2
-rw-r--r--drivers/video/via/hw.c131
-rw-r--r--drivers/video/via/hw.h4
-rw-r--r--drivers/video/via/lcd.c3
-rw-r--r--drivers/video/via/via-core.c185
-rw-r--r--drivers/video/via/via-core.h38
-rw-r--r--drivers/video/via/via_i2c.c2
-rw-r--r--drivers/video/via/viafbdev.c54
-rw-r--r--drivers/video/via/viafbdev.h13
-rw-r--r--drivers/video/via/vt1636.c2
12 files changed, 265 insertions, 185 deletions
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 0d90c859cc1..e77746857c8 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -18,6 +18,7 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21#include "via-core.h"
21#include "global.h" 22#include "global.h"
22 23
23/* 24/*
@@ -321,8 +322,7 @@ int viafb_init_engine(struct fb_info *info)
321 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, 322 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
322 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; 323 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
323 324
324 engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 325 engine = viapar->shared->vdev->engine_mmio;
325 viapar->shared->engine_mmio = engine;
326 if (!engine) { 326 if (!engine) {
327 printk(KERN_WARNING "viafb_init_accel: ioremap failed, " 327 printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
328 "hardware acceleration disabled\n"); 328 "hardware acceleration disabled\n");
@@ -465,7 +465,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
465 struct viafb_par *viapar = info->par; 465 struct viafb_par *viapar = info->par;
466 u32 temp, iga_path = viapar->iga_path; 466 u32 temp, iga_path = viapar->iga_path;
467 467
468 temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); 468 temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
469 switch (Status) { 469 switch (Status) {
470 case HW_Cursor_ON: 470 case HW_Cursor_ON:
471 temp |= 0x1; 471 temp |= 0x1;
@@ -482,7 +482,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
482 default: 482 default:
483 temp &= 0x7FFFFFFF; 483 temp &= 0x7FFFFFFF;
484 } 484 }
485 writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); 485 writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
486} 486}
487 487
488void viafb_wait_engine_idle(struct fb_info *info) 488void viafb_wait_engine_idle(struct fb_info *info)
@@ -490,6 +490,7 @@ void viafb_wait_engine_idle(struct fb_info *info)
490 struct viafb_par *viapar = info->par; 490 struct viafb_par *viapar = info->par;
491 int loop = 0; 491 int loop = 0;
492 u32 mask; 492 u32 mask;
493 void __iomem *engine = viapar->shared->vdev->engine_mmio;
493 494
494 switch (viapar->shared->chip_info.twod_engine) { 495 switch (viapar->shared->chip_info.twod_engine) {
495 case VIA_2D_ENG_H5: 496 case VIA_2D_ENG_H5:
@@ -498,7 +499,7 @@ void viafb_wait_engine_idle(struct fb_info *info)
498 VIA_3D_ENG_BUSY_M1; 499 VIA_3D_ENG_BUSY_M1;
499 break; 500 break;
500 default: 501 default:
501 while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & 502 while (!(readl(engine + VIA_REG_STATUS) &
502 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { 503 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
503 loop++; 504 loop++;
504 cpu_relax(); 505 cpu_relax();
@@ -507,8 +508,7 @@ void viafb_wait_engine_idle(struct fb_info *info)
507 break; 508 break;
508 } 509 }
509 510
510 while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & mask) && 511 while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) {
511 (loop < MAXLOOP)) {
512 loop++; 512 loop++;
513 cpu_relax(); 513 cpu_relax();
514 } 514 }
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index e357c4d1cd0..6271b769632 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -18,6 +18,8 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21#include "via-core.h"
22#include "via_i2c.h"
21#include "global.h" 23#include "global.h"
22 24
23static void tmds_register_write(int index, u8 data); 25static void tmds_register_write(int index, u8 data);
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index be48e73da04..28221a062dd 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -35,14 +35,12 @@
35 35
36#include "debug.h" 36#include "debug.h"
37 37
38#include "via-core.h"
39#include "viafbdev.h" 38#include "viafbdev.h"
40#include "chip.h" 39#include "chip.h"
41#include "accel.h" 40#include "accel.h"
42#include "share.h" 41#include "share.h"
43#include "dvi.h" 42#include "dvi.h"
44#include "viamode.h" 43#include "viamode.h"
45#include "via_i2c.h"
46#include "hw.h" 44#include "hw.h"
47 45
48#include "lcd.h" 46#include "lcd.h"
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 2322612fbb9..f2425ae228a 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -18,7 +18,7 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21#include "via-core.h"
22#include "global.h" 22#include "global.h"
23 23
24static struct pll_map pll_value[] = { 24static struct pll_map pll_value[] = {
@@ -526,8 +526,7 @@ static void dvi_patch_skew_dvp_low(void);
526static void set_dvi_output_path(int set_iga, int output_interface); 526static void set_dvi_output_path(int set_iga, int output_interface);
527static void set_lcd_output_path(int set_iga, int output_interface); 527static void set_lcd_output_path(int set_iga, int output_interface);
528static void load_fix_bit_crtc_reg(void); 528static void load_fix_bit_crtc_reg(void);
529static void init_gfx_chip_info(struct pci_dev *pdev, 529static void init_gfx_chip_info(int chip_type);
530 const struct pci_device_id *pdi);
531static void init_tmds_chip_info(void); 530static void init_tmds_chip_info(void);
532static void init_lvds_chip_info(void); 531static void init_lvds_chip_info(void);
533static void device_screen_off(void); 532static void device_screen_off(void);
@@ -1911,10 +1910,9 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1911 1910
1912} 1911}
1913 1912
1914void viafb_init_chip_info(struct pci_dev *pdev, 1913void viafb_init_chip_info(int chip_type)
1915 const struct pci_device_id *pdi)
1916{ 1914{
1917 init_gfx_chip_info(pdev, pdi); 1915 init_gfx_chip_info(chip_type);
1918 init_tmds_chip_info(); 1916 init_tmds_chip_info();
1919 init_lvds_chip_info(); 1917 init_lvds_chip_info();
1920 1918
@@ -1981,12 +1979,11 @@ void viafb_update_device_setting(int hres, int vres,
1981 } 1979 }
1982} 1980}
1983 1981
1984static void init_gfx_chip_info(struct pci_dev *pdev, 1982static void init_gfx_chip_info(int chip_type)
1985 const struct pci_device_id *pdi)
1986{ 1983{
1987 u8 tmp; 1984 u8 tmp;
1988 1985
1989 viaparinfo->chip_info->gfx_chip_name = pdi->driver_data; 1986 viaparinfo->chip_info->gfx_chip_name = chip_type;
1990 1987
1991 /* Check revision of CLE266 Chip */ 1988 /* Check revision of CLE266 Chip */
1992 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 1989 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
@@ -2489,122 +2486,6 @@ static void disable_second_display_channel(void)
2489 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); 2486 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2490} 2487}
2491 2488
2492static u_int16_t via_function3[] = {
2493 CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
2494 CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
2495 P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
2496};
2497
2498/* Get the BIOS-configured framebuffer size from PCI configuration space
2499 * of function 3 in the respective chipset */
2500int viafb_get_fb_size_from_pci(void)
2501{
2502 int i;
2503 u_int8_t offset = 0;
2504 u_int32_t FBSize;
2505 u_int32_t VideoMemSize;
2506
2507 /* search for the "FUNCTION3" device in this chipset */
2508 for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
2509 struct pci_dev *pdev;
2510
2511 pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
2512 NULL);
2513 if (!pdev)
2514 continue;
2515
2516 DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
2517
2518 switch (pdev->device) {
2519 case CLE266_FUNCTION3:
2520 case KM400_FUNCTION3:
2521 offset = 0xE0;
2522 break;
2523 case CN400_FUNCTION3:
2524 case CN700_FUNCTION3:
2525 case CX700_FUNCTION3:
2526 case KM800_FUNCTION3:
2527 case KM890_FUNCTION3:
2528 case P4M890_FUNCTION3:
2529 case P4M900_FUNCTION3:
2530 case VX800_FUNCTION3:
2531 case VX855_FUNCTION3:
2532 /*case CN750_FUNCTION3: */
2533 offset = 0xA0;
2534 break;
2535 }
2536
2537 if (!offset)
2538 break;
2539
2540 pci_read_config_dword(pdev, offset, &FBSize);
2541 pci_dev_put(pdev);
2542 }
2543
2544 if (!offset) {
2545 printk(KERN_ERR "cannot determine framebuffer size\n");
2546 return -EIO;
2547 }
2548
2549 FBSize = FBSize & 0x00007000;
2550 DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
2551
2552 if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
2553 switch (FBSize) {
2554 case 0x00004000:
2555 VideoMemSize = (16 << 20); /*16M */
2556 break;
2557
2558 case 0x00005000:
2559 VideoMemSize = (32 << 20); /*32M */
2560 break;
2561
2562 case 0x00006000:
2563 VideoMemSize = (64 << 20); /*64M */
2564 break;
2565
2566 default:
2567 VideoMemSize = (32 << 20); /*32M */
2568 break;
2569 }
2570 } else {
2571 switch (FBSize) {
2572 case 0x00001000:
2573 VideoMemSize = (8 << 20); /*8M */
2574 break;
2575
2576 case 0x00002000:
2577 VideoMemSize = (16 << 20); /*16M */
2578 break;
2579
2580 case 0x00003000:
2581 VideoMemSize = (32 << 20); /*32M */
2582 break;
2583
2584 case 0x00004000:
2585 VideoMemSize = (64 << 20); /*64M */
2586 break;
2587
2588 case 0x00005000:
2589 VideoMemSize = (128 << 20); /*128M */
2590 break;
2591
2592 case 0x00006000:
2593 VideoMemSize = (256 << 20); /*256M */
2594 break;
2595
2596 case 0x00007000: /* Only on VX855/875 */
2597 VideoMemSize = (512 << 20); /*512M */
2598 break;
2599
2600 default:
2601 VideoMemSize = (32 << 20); /*32M */
2602 break;
2603 }
2604 }
2605
2606 return VideoMemSize;
2607}
2608 2489
2609void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 2490void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2610 *p_gfx_dpa_setting) 2491 *p_gfx_dpa_setting)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index d6b25acd4a9..d248f4dc12e 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -900,15 +900,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
900 struct VideoModeTable *vmode_tbl1, int video_bpp1); 900 struct VideoModeTable *vmode_tbl1, int video_bpp1);
901void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 901void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
902 struct VideoModeTable *vmode_tbl); 902 struct VideoModeTable *vmode_tbl);
903void viafb_init_chip_info(struct pci_dev *pdev, 903void viafb_init_chip_info(int chip_type);
904 const struct pci_device_id *pdi);
905void viafb_init_dac(int set_iga); 904void viafb_init_dac(int set_iga);
906int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 905int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
907int viafb_get_refresh(int hres, int vres, u32 float_refresh); 906int viafb_get_refresh(int hres, int vres, u32 float_refresh);
908void viafb_update_device_setting(int hres, int vres, int bpp, 907void viafb_update_device_setting(int hres, int vres, int bpp,
909 int vmode_refresh, int flag); 908 int vmode_refresh, int flag);
910 909
911int viafb_get_fb_size_from_pci(void);
912void viafb_set_iga_path(void); 910void viafb_set_iga_path(void);
913void viafb_set_primary_address(u32 addr); 911void viafb_set_primary_address(u32 addr);
914void viafb_set_secondary_address(u32 addr); 912void viafb_set_secondary_address(u32 addr);
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 8ef60c035fa..04eec31aa9a 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -18,7 +18,8 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21#include "via-core.h"
22#include "via_i2c.h"
22#include "global.h" 23#include "global.h"
23#include "lcdtbl.h" 24#include "lcdtbl.h"
24 25
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index e7201470cf3..b77cd5c2fc9 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -7,9 +7,12 @@
7/* 7/*
8 * Core code for the Via multifunction framebuffer device. 8 * Core code for the Via multifunction framebuffer device.
9 */ 9 */
10#include "via-core.h"
11#include "via_i2c.h"
12#include "global.h"
13
10#include <linux/module.h> 14#include <linux/module.h>
11#include <linux/platform_device.h> 15#include <linux/platform_device.h>
12#include "global.h" /* Includes everything under the sun */
13 16
14/* 17/*
15 * The default port config. 18 * The default port config.
@@ -23,6 +26,169 @@ static struct via_port_cfg adap_configs[] = {
23 { 0, 0, 0, 0 } 26 { 0, 0, 0, 0 }
24}; 27};
25 28
29/*
30 * We currently only support one viafb device (will there ever be
31 * more than one?), so just declare it globally here.
32 */
33static struct viafb_dev global_dev;
34
35
36/*
37 * Figure out how big our framebuffer memory is. Kind of ugly,
38 * but evidently we can't trust the information found in the
39 * fbdev configuration area.
40 */
41static u16 via_function3[] = {
42 CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
43 CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
44 P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
45};
46
47/* Get the BIOS-configured framebuffer size from PCI configuration space
48 * of function 3 in the respective chipset */
49static int viafb_get_fb_size_from_pci(int chip_type)
50{
51 int i;
52 u8 offset = 0;
53 u32 FBSize;
54 u32 VideoMemSize;
55
56 /* search for the "FUNCTION3" device in this chipset */
57 for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
58 struct pci_dev *pdev;
59
60 pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
61 NULL);
62 if (!pdev)
63 continue;
64
65 DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
66
67 switch (pdev->device) {
68 case CLE266_FUNCTION3:
69 case KM400_FUNCTION3:
70 offset = 0xE0;
71 break;
72 case CN400_FUNCTION3:
73 case CN700_FUNCTION3:
74 case CX700_FUNCTION3:
75 case KM800_FUNCTION3:
76 case KM890_FUNCTION3:
77 case P4M890_FUNCTION3:
78 case P4M900_FUNCTION3:
79 case VX800_FUNCTION3:
80 case VX855_FUNCTION3:
81 /*case CN750_FUNCTION3: */
82 offset = 0xA0;
83 break;
84 }
85
86 if (!offset)
87 break;
88
89 pci_read_config_dword(pdev, offset, &FBSize);
90 pci_dev_put(pdev);
91 }
92
93 if (!offset) {
94 printk(KERN_ERR "cannot determine framebuffer size\n");
95 return -EIO;
96 }
97
98 FBSize = FBSize & 0x00007000;
99 DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
100
101 if (chip_type < UNICHROME_CX700) {
102 switch (FBSize) {
103 case 0x00004000:
104 VideoMemSize = (16 << 20); /*16M */
105 break;
106
107 case 0x00005000:
108 VideoMemSize = (32 << 20); /*32M */
109 break;
110
111 case 0x00006000:
112 VideoMemSize = (64 << 20); /*64M */
113 break;
114
115 default:
116 VideoMemSize = (32 << 20); /*32M */
117 break;
118 }
119 } else {
120 switch (FBSize) {
121 case 0x00001000:
122 VideoMemSize = (8 << 20); /*8M */
123 break;
124
125 case 0x00002000:
126 VideoMemSize = (16 << 20); /*16M */
127 break;
128
129 case 0x00003000:
130 VideoMemSize = (32 << 20); /*32M */
131 break;
132
133 case 0x00004000:
134 VideoMemSize = (64 << 20); /*64M */
135 break;
136
137 case 0x00005000:
138 VideoMemSize = (128 << 20); /*128M */
139 break;
140
141 case 0x00006000:
142 VideoMemSize = (256 << 20); /*256M */
143 break;
144
145 case 0x00007000: /* Only on VX855/875 */
146 VideoMemSize = (512 << 20); /*512M */
147 break;
148
149 default:
150 VideoMemSize = (32 << 20); /*32M */
151 break;
152 }
153 }
154
155 return VideoMemSize;
156}
157
158
159/*
160 * Figure out and map our MMIO regions.
161 */
162static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
163{
164 /*
165 * Hook up to the device registers.
166 */
167 vdev->engine_start = pci_resource_start(vdev->pdev, 1);
168 vdev->engine_len = pci_resource_len(vdev->pdev, 1);
169 /* If this fails, others will notice later */
170 vdev->engine_mmio = ioremap_nocache(vdev->engine_start,
171 vdev->engine_len);
172
173 /*
174 * Likewise with I/O memory.
175 */
176 vdev->fbmem_start = pci_resource_start(vdev->pdev, 0);
177 vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
178 if (vdev->fbmem_len < 0)
179 return vdev->fbmem_len;
180 vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len);
181 if (vdev->fbmem == NULL)
182 return -ENOMEM;
183 return 0;
184}
185
186static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev)
187{
188 iounmap(vdev->fbmem);
189 iounmap(vdev->engine_mmio);
190}
191
26 192
27static int __devinit via_pci_probe(struct pci_dev *pdev, 193static int __devinit via_pci_probe(struct pci_dev *pdev,
28 const struct pci_device_id *ent) 194 const struct pci_device_id *ent)
@@ -33,22 +199,34 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
33 if (ret) 199 if (ret)
34 return ret; 200 return ret;
35 /* 201 /*
202 * Global device initialization.
203 */
204 memset(&global_dev, 0, sizeof(global_dev));
205 global_dev.pdev = pdev;
206 global_dev.chip_type = ent->driver_data;
207 spin_lock_init(&global_dev.reg_lock);
208 ret = via_pci_setup_mmio(&global_dev);
209 if (ret)
210 goto out_disable;
211 /*
36 * Create the I2C busses. Bailing out on failure seems extreme, 212 * Create the I2C busses. Bailing out on failure seems extreme,
37 * but that's what the code did before. 213 * but that's what the code did before.
38 */ 214 */
39 ret = viafb_create_i2c_busses(adap_configs); 215 ret = viafb_create_i2c_busses(adap_configs);
40 if (ret) 216 if (ret)
41 goto out_disable; 217 goto out_teardown;
42 /* 218 /*
43 * Set up the framebuffer. 219 * Set up the framebuffer.
44 */ 220 */
45 ret = via_fb_pci_probe(pdev, ent); 221 ret = via_fb_pci_probe(&global_dev);
46 if (ret) 222 if (ret)
47 goto out_i2c; 223 goto out_i2c;
48 return 0; 224 return 0;
49 225
50out_i2c: 226out_i2c:
51 viafb_delete_i2c_busses(); 227 viafb_delete_i2c_busses();
228out_teardown:
229 via_pci_teardown_mmio(&global_dev);
52out_disable: 230out_disable:
53 pci_disable_device(pdev); 231 pci_disable_device(pdev);
54 return ret; 232 return ret;
@@ -58,6 +236,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
58{ 236{
59 viafb_delete_i2c_busses(); 237 viafb_delete_i2c_busses();
60 via_fb_pci_remove(pdev); 238 via_fb_pci_remove(pdev);
239 via_pci_teardown_mmio(&global_dev);
61 pci_disable_device(pdev); 240 pci_disable_device(pdev);
62} 241}
63 242
diff --git a/drivers/video/via/via-core.h b/drivers/video/via/via-core.h
index 1c2fb06b77a..d004290dc8f 100644
--- a/drivers/video/via/via-core.h
+++ b/drivers/video/via/via-core.h
@@ -22,6 +22,9 @@
22 22
23#ifndef __VIA_CORE_H__ 23#ifndef __VIA_CORE_H__
24#define __VIA_CORE_H__ 24#define __VIA_CORE_H__
25#include <linux/spinlock.h>
26#include <linux/pci.h>
27
25/* 28/*
26 * A description of each known serial I2C/GPIO port. 29 * A description of each known serial I2C/GPIO port.
27 */ 30 */
@@ -49,7 +52,38 @@ enum viafb_i2c_adap {
49struct via_port_cfg { 52struct via_port_cfg {
50 enum via_port_type type; 53 enum via_port_type type;
51 enum via_port_mode mode; 54 enum via_port_mode mode;
52 u_int16_t io_port; 55 u16 io_port;
53 u_int8_t ioport_index; 56 u8 ioport_index;
54}; 57};
58
59/*
60 * This is the global viafb "device" containing stuff needed by
61 * all subdevs.
62 */
63struct viafb_dev {
64 struct pci_dev *pdev;
65 int chip_type;
66 /*
67 * Spinlock for access to device registers. Not yet
68 * globally used.
69 */
70 spinlock_t reg_lock;
71 /*
72 * The framebuffer MMIO region. Little, if anything, touches
73 * this memory directly, and certainly nothing outside of the
74 * framebuffer device itself. We *do* have to be able to allocate
75 * chunks of this memory for other devices, though.
76 */
77 unsigned long fbmem_start;
78 long fbmem_len;
79 void __iomem *fbmem;
80 /*
81 * The MMIO region for device registers.
82 */
83 unsigned long engine_start;
84 unsigned long engine_len;
85 void __iomem *engine_mmio;
86
87};
88
55#endif /* __VIA_CORE_H__ */ 89#endif /* __VIA_CORE_H__ */
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 47882928156..bcf2fe61a6e 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -19,6 +19,8 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include "via-core.h"
23#include "via_i2c.h"
22#include "global.h" 24#include "global.h"
23 25
24/* 26/*
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 17a874f6ea1..70ed71facd8 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -24,6 +24,7 @@
24#include <linux/stat.h> 24#include <linux/stat.h>
25#define _MASTER_FILE 25#define _MASTER_FILE
26 26
27#include "via-core.h"
27#include "global.h" 28#include "global.h"
28 29
29static char *viafb_name = "Via"; 30static char *viafb_name = "Via";
@@ -220,7 +221,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
220 /* Adjust var according to our driver's own table */ 221 /* Adjust var according to our driver's own table */
221 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 222 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
222 if (info->var.accel_flags & FB_ACCELF_TEXT && 223 if (info->var.accel_flags & FB_ACCELF_TEXT &&
223 !ppar->shared->engine_mmio) 224 !ppar->shared->vdev->engine_mmio)
224 info->var.accel_flags = 0; 225 info->var.accel_flags = 0;
225 226
226 return 0; 227 return 0;
@@ -695,7 +696,7 @@ static void viafb_fillrect(struct fb_info *info,
695 rop = 0xF0; 696 rop = 0xF0;
696 697
697 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); 698 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
698 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL, 699 if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_FILL,
699 rect->width, rect->height, info->var.bits_per_pixel, 700 rect->width, rect->height, info->var.bits_per_pixel,
700 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, 701 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
701 NULL, 0, 0, 0, 0, fg_color, 0, rop)) 702 NULL, 0, 0, 0, 0, fg_color, 0, rop))
@@ -717,7 +718,7 @@ static void viafb_copyarea(struct fb_info *info,
717 return; 718 return;
718 719
719 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); 720 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n");
720 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR, 721 if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_COLOR,
721 area->width, area->height, info->var.bits_per_pixel, 722 area->width, area->height, info->var.bits_per_pixel,
722 viapar->vram_addr, info->fix.line_length, area->dx, area->dy, 723 viapar->vram_addr, info->fix.line_length, area->dx, area->dy,
723 NULL, viapar->vram_addr, info->fix.line_length, 724 NULL, viapar->vram_addr, info->fix.line_length,
@@ -754,7 +755,7 @@ static void viafb_imageblit(struct fb_info *info,
754 op = VIA_BITBLT_COLOR; 755 op = VIA_BITBLT_COLOR;
755 756
756 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); 757 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n");
757 if (shared->hw_bitblt(shared->engine_mmio, op, 758 if (shared->hw_bitblt(shared->vdev->engine_mmio, op,
758 image->width, image->height, info->var.bits_per_pixel, 759 image->width, image->height, info->var.bits_per_pixel,
759 viapar->vram_addr, info->fix.line_length, image->dx, image->dy, 760 viapar->vram_addr, info->fix.line_length, image->dx, image->dy,
760 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) 761 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0))
@@ -764,7 +765,7 @@ static void viafb_imageblit(struct fb_info *info,
764static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 765static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
765{ 766{
766 struct viafb_par *viapar = info->par; 767 struct viafb_par *viapar = info->par;
767 void __iomem *engine = viapar->shared->engine_mmio; 768 void __iomem *engine = viapar->shared->vdev->engine_mmio;
768 u32 temp, xx, yy, bg_color = 0, fg_color = 0, 769 u32 temp, xx, yy, bg_color = 0, fg_color = 0,
769 chip_name = viapar->shared->chip_info.gfx_chip_name; 770 chip_name = viapar->shared->chip_info.gfx_chip_name;
770 int i, j = 0, cur_size = 64; 771 int i, j = 0, cur_size = 64;
@@ -1732,8 +1733,7 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
1732} 1733}
1733 1734
1734 1735
1735int __devinit via_fb_pci_probe(struct pci_dev *pdev, 1736int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1736 const struct pci_device_id *ent)
1737{ 1737{
1738 u32 default_xres, default_yres; 1738 u32 default_xres, default_yres;
1739 struct VideoModeTable *vmode_entry; 1739 struct VideoModeTable *vmode_entry;
@@ -1750,7 +1750,7 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1750 */ 1750 */
1751 viafbinfo = framebuffer_alloc(viafb_par_length + 1751 viafbinfo = framebuffer_alloc(viafb_par_length +
1752 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), 1752 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),
1753 &pdev->dev); 1753 &vdev->pdev->dev);
1754 if (!viafbinfo) { 1754 if (!viafbinfo) {
1755 printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); 1755 printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
1756 return -ENOMEM; 1756 return -ENOMEM;
@@ -1758,6 +1758,7 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1758 1758
1759 viaparinfo = (struct viafb_par *)viafbinfo->par; 1759 viaparinfo = (struct viafb_par *)viafbinfo->par;
1760 viaparinfo->shared = viafbinfo->par + viafb_par_length; 1760 viaparinfo->shared = viafbinfo->par + viafb_par_length;
1761 viaparinfo->shared->vdev = vdev;
1761 viaparinfo->vram_addr = 0; 1762 viaparinfo->vram_addr = 0;
1762 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; 1763 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info;
1763 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; 1764 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;
@@ -1765,7 +1766,6 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1765 &viaparinfo->shared->lvds_setting_info2; 1766 &viaparinfo->shared->lvds_setting_info2;
1766 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; 1767 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info;
1767 viaparinfo->chip_info = &viaparinfo->shared->chip_info; 1768 viaparinfo->chip_info = &viaparinfo->shared->chip_info;
1768 spin_lock_init(&viaparinfo->reg_lock);
1769 1769
1770 if (viafb_dual_fb) 1770 if (viafb_dual_fb)
1771 viafb_SAMM_ON = 1; 1771 viafb_SAMM_ON = 1;
@@ -1776,25 +1776,20 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1776 if (!viafb_SAMM_ON) 1776 if (!viafb_SAMM_ON)
1777 viafb_dual_fb = 0; 1777 viafb_dual_fb = 0;
1778 1778
1779 viafb_init_chip_info(pdev, ent); 1779 viafb_init_chip_info(vdev->chip_type);
1780 viaparinfo->fbmem = pci_resource_start(pdev, 0); 1780 /*
1781 viaparinfo->memsize = viafb_get_fb_size_from_pci(); 1781 * The framebuffer will have been successfully mapped by
1782 if (viaparinfo->memsize < 0) { 1782 * the core (or we'd not be here), but we still need to
1783 rc = viaparinfo->memsize; 1783 * set up our own accounting.
1784 goto out_fb_release; 1784 */
1785 } 1785 viaparinfo->fbmem = vdev->fbmem_start;
1786 viaparinfo->memsize = vdev->fbmem_len;
1786 viaparinfo->fbmem_free = viaparinfo->memsize; 1787 viaparinfo->fbmem_free = viaparinfo->memsize;
1787 viaparinfo->fbmem_used = 0; 1788 viaparinfo->fbmem_used = 0;
1788 viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, 1789 viafbinfo->screen_base = vdev->fbmem;
1789 viaparinfo->memsize);
1790 if (!viafbinfo->screen_base) {
1791 printk(KERN_ERR "ioremap of fbmem failed\n");
1792 rc = -ENOMEM;
1793 goto out_fb_release;
1794 }
1795 1790
1796 viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); 1791 viafbinfo->fix.mmio_start = vdev->engine_start;
1797 viafbinfo->fix.mmio_len = pci_resource_len(pdev, 1); 1792 viafbinfo->fix.mmio_len = vdev->engine_len;
1798 viafbinfo->node = 0; 1793 viafbinfo->node = 0;
1799 viafbinfo->fbops = &viafb_ops; 1794 viafbinfo->fbops = &viafb_ops;
1800 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1795 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
@@ -1862,12 +1857,13 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1862 viafbinfo->var = default_var; 1857 viafbinfo->var = default_var;
1863 1858
1864 if (viafb_dual_fb) { 1859 if (viafb_dual_fb) {
1865 viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); 1860 viafbinfo1 = framebuffer_alloc(viafb_par_length,
1861 &vdev->pdev->dev);
1866 if (!viafbinfo1) { 1862 if (!viafbinfo1) {
1867 printk(KERN_ERR 1863 printk(KERN_ERR
1868 "allocate the second framebuffer struct error\n"); 1864 "allocate the second framebuffer struct error\n");
1869 rc = -ENOMEM; 1865 rc = -ENOMEM;
1870 goto out_unmap_screen; 1866 goto out_fb_release;
1871 } 1867 }
1872 viaparinfo1 = viafbinfo1->par; 1868 viaparinfo1 = viafbinfo1->par;
1873 memcpy(viaparinfo1, viaparinfo, viafb_par_length); 1869 memcpy(viaparinfo1, viaparinfo, viafb_par_length);
@@ -1958,8 +1954,6 @@ out_dealloc_cmap:
1958out_fb1_release: 1954out_fb1_release:
1959 if (viafbinfo1) 1955 if (viafbinfo1)
1960 framebuffer_release(viafbinfo1); 1956 framebuffer_release(viafbinfo1);
1961out_unmap_screen:
1962 iounmap(viafbinfo->screen_base);
1963out_fb_release: 1957out_fb_release:
1964 framebuffer_release(viafbinfo); 1958 framebuffer_release(viafbinfo);
1965 return rc; 1959 return rc;
@@ -1972,8 +1966,6 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
1972 unregister_framebuffer(viafbinfo); 1966 unregister_framebuffer(viafbinfo);
1973 if (viafb_dual_fb) 1967 if (viafb_dual_fb)
1974 unregister_framebuffer(viafbinfo1); 1968 unregister_framebuffer(viafbinfo1);
1975 iounmap((void *)viafbinfo->screen_base);
1976 iounmap(viaparinfo->shared->engine_mmio);
1977 1969
1978 framebuffer_release(viafbinfo); 1970 framebuffer_release(viafbinfo);
1979 if (viafb_dual_fb) 1971 if (viafb_dual_fb)
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 5604f27eb74..52a35fabba9 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -30,7 +30,6 @@
30#include "share.h" 30#include "share.h"
31#include "chip.h" 31#include "chip.h"
32#include "hw.h" 32#include "hw.h"
33#include "via_i2c.h"
34 33
35#define VERSION_MAJOR 2 34#define VERSION_MAJOR 2
36#define VERSION_KERNEL 6 /* For kernel 2.6 */ 35#define VERSION_KERNEL 6 /* For kernel 2.6 */
@@ -42,6 +41,7 @@
42 41
43struct viafb_shared { 42struct viafb_shared {
44 struct proc_dir_entry *proc_entry; /*viafb proc entry */ 43 struct proc_dir_entry *proc_entry; /*viafb proc entry */
44 struct viafb_dev *vdev; /* Global dev info */
45 45
46 /* All the information will be needed to set engine */ 46 /* All the information will be needed to set engine */
47 struct tmds_setting_information tmds_setting_info; 47 struct tmds_setting_information tmds_setting_info;
@@ -51,7 +51,6 @@ struct viafb_shared {
51 struct chip_information chip_info; 51 struct chip_information chip_info;
52 52
53 /* hardware acceleration stuff */ 53 /* hardware acceleration stuff */
54 void __iomem *engine_mmio;
55 u32 cursor_vram_addr; 54 u32 cursor_vram_addr;
56 u32 vq_vram_addr; /* virtual queue address in video ram */ 55 u32 vq_vram_addr; /* virtual queue address in video ram */
57 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, 56 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
@@ -72,14 +71,6 @@ struct viafb_par {
72 71
73 struct viafb_shared *shared; 72 struct viafb_shared *shared;
74 73
75 /*
76 * (jc) I believe one should use locking to protect against
77 * concurrent access to the device ports and registers. Thus,
78 * this lock. Use of it is *far* from universal, though...
79 * someday...
80 */
81 spinlock_t reg_lock;
82
83 /* All the information will be needed to set engine */ 74 /* All the information will be needed to set engine */
84 /* depreciated, use the ones in shared directly */ 75 /* depreciated, use the ones in shared directly */
85 struct tmds_setting_information *tmds_setting_info; 76 struct tmds_setting_information *tmds_setting_info;
@@ -107,7 +98,7 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
107void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information 98void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
108 *plvds_setting_info, struct lvds_chip_information 99 *plvds_setting_info, struct lvds_chip_information
109 *plvds_chip_info, struct IODATA io_data); 100 *plvds_chip_info, struct IODATA io_data);
110int via_fb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 101int via_fb_pci_probe(struct viafb_dev *vdev);
111void via_fb_pci_remove(struct pci_dev *pdev); 102void via_fb_pci_remove(struct pci_dev *pdev);
112/* Temporary */ 103/* Temporary */
113int viafb_init(void); 104int viafb_init(void);
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
index 4589c6e73c5..e9f3661d6b3 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/via/vt1636.c
@@ -19,6 +19,8 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include "via-core.h"
23#include "via_i2c.h"
22#include "global.h" 24#include "global.h"
23 25
24u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 26u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information