Blame view

drivers/video/cg3.c 11.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /* cg3.c: CGTHREE frame buffer driver
   *
50312ce9d   David S. Miller   [SPARC]: Convert ...
3
   * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
   * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
   * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
   * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
   *
   * Driver layout based loosely on tgafb.c, see that file for credits.
   */
  
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/errno.h>
  #include <linux/string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
18
  #include <linux/delay.h>
  #include <linux/init.h>
  #include <linux/fb.h>
  #include <linux/mm.h>
6cd5a86b5   Robert Reif   sparc video: remo...
19
  #include <linux/of_device.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
  
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
26
27
28
29
30
31
32
  #include <asm/fbio.h>
  
  #include "sbuslib.h"
  
  /*
   * Local functions.
   */
  
  static int cg3_setcolreg(unsigned, unsigned, unsigned, unsigned,
  			 unsigned, struct fb_info *);
  static int cg3_blank(int, struct fb_info *);
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
33
  static int cg3_mmap(struct fb_info *, struct vm_area_struct *);
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
34
  static int cg3_ioctl(struct fb_info *, unsigned int, unsigned long);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  
  /*
   *  Frame buffer operations
   */
  
  static struct fb_ops cg3_ops = {
  	.owner			= THIS_MODULE,
  	.fb_setcolreg		= cg3_setcolreg,
  	.fb_blank		= cg3_blank,
  	.fb_fillrect		= cfb_fillrect,
  	.fb_copyarea		= cfb_copyarea,
  	.fb_imageblit		= cfb_imageblit,
  	.fb_mmap		= cg3_mmap,
  	.fb_ioctl		= cg3_ioctl,
9ffb83bcc   Christoph Hellwig   [SBUSFB]: impleme...
49
50
51
  #ifdef CONFIG_COMPAT
  	.fb_compat_ioctl	= sbusfb_compat_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  };
  
  
  /* Control Register Constants */
  #define CG3_CR_ENABLE_INTS      0x80
  #define CG3_CR_ENABLE_VIDEO     0x40
  #define CG3_CR_ENABLE_TIMING    0x20
  #define CG3_CR_ENABLE_CURCMP    0x10
  #define CG3_CR_XTAL_MASK        0x0c
  #define CG3_CR_DIVISOR_MASK     0x03
  
  /* Status Register Constants */
  #define CG3_SR_PENDING_INT      0x80
  #define CG3_SR_RES_MASK         0x70
  #define CG3_SR_1152_900_76_A    0x40
  #define CG3_SR_1152_900_76_B    0x60
  #define CG3_SR_ID_MASK          0x0f
  #define CG3_SR_ID_COLOR         0x01
  #define CG3_SR_ID_MONO          0x02
  #define CG3_SR_ID_MONO_ECL      0x03
  
  enum cg3_type {
  	CG3_AT_66HZ = 0,
  	CG3_AT_76HZ,
  	CG3_RDI
  };
  
  struct bt_regs {
50312ce9d   David S. Miller   [SPARC]: Convert ...
80
81
82
83
  	u32 addr;
  	u32 color_map;
  	u32 control;
  	u32 cursor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
  };
  
  struct cg3_regs {
  	struct bt_regs	cmap;
50312ce9d   David S. Miller   [SPARC]: Convert ...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  	u8	control;
  	u8	status;
  	u8	cursor_start;
  	u8	cursor_end;
  	u8	h_blank_start;
  	u8	h_blank_end;
  	u8	h_sync_start;
  	u8	h_sync_end;
  	u8	comp_sync_end;
  	u8	v_blank_start_high;
  	u8	v_blank_start_low;
  	u8	v_blank_end;
  	u8	v_sync_start;
  	u8	v_sync_end;
  	u8	xfer_holdoff_start;
  	u8	xfer_holdoff_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  };
  
  /* Offset of interesting structures in the OBIO space */
  #define CG3_REGS_OFFSET	     0x400000UL
  #define CG3_RAM_OFFSET	     0x800000UL
  
  struct cg3_par {
  	spinlock_t		lock;
  	struct cg3_regs		__iomem *regs;
  	u32			sw_cmap[((256 * 3) + 3) / 4];
  
  	u32			flags;
  #define CG3_FLAG_BLANKED	0x00000001
  #define CG3_FLAG_RDI		0x00000002
50312ce9d   David S. Miller   [SPARC]: Convert ...
118
  	unsigned long		which_io;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  };
  
  /**
   *      cg3_setcolreg - Optional function. Sets a color register.
   *      @regno: boolean, 0 copy local, 1 get_user() function
   *      @red: frame buffer colormap structure
   *      @green: The green value which can be up to 16 bits wide
   *      @blue:  The blue value which can be up to 16 bits wide.
   *      @transp: If supported the alpha value which can be up to 16 bits wide.
   *      @info: frame buffer info structure
   *
   * The cg3 palette is loaded with 4 color values at each time
   * so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on.
   * We keep a sw copy of the hw cmap to assist us in this esoteric
   * loading procedure.
   */
  static int cg3_setcolreg(unsigned regno,
  			 unsigned red, unsigned green, unsigned blue,
  			 unsigned transp, struct fb_info *info)
  {
  	struct cg3_par *par = (struct cg3_par *) info->par;
  	struct bt_regs __iomem *bt = &par->regs->cmap;
  	unsigned long flags;
  	u32 *p32;
  	u8 *p8;
  	int count;
  
  	if (regno >= 256)
  		return 1;
  
  	red >>= 8;
  	green >>= 8;
  	blue >>= 8;
  
  	spin_lock_irqsave(&par->lock, flags);
  
  	p8 = (u8 *)par->sw_cmap + (regno * 3);
  	p8[0] = red;
  	p8[1] = green;
  	p8[2] = blue;
  
  #define D4M3(x) ((((x)>>2)<<1) + ((x)>>2))      /* (x/4)*3 */
  #define D4M4(x) ((x)&~0x3)                      /* (x/4)*4 */
  
  	count = 3;
  	p32 = &par->sw_cmap[D4M3(regno)];
  	sbus_writel(D4M4(regno), &bt->addr);
  	while (count--)
  		sbus_writel(*p32++, &bt->color_map);
  
  #undef D4M3
  #undef D4M4
  
  	spin_unlock_irqrestore(&par->lock, flags);
  
  	return 0;
  }
  
  /**
   *      cg3_blank - Optional function.  Blanks the display.
   *      @blank_mode: the blank mode we want.
   *      @info: frame buffer structure that represents a single frame buffer
   */
a71775147   Robert Reif   [VIDEO]: Fix sect...
182
  static int cg3_blank(int blank, struct fb_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  {
  	struct cg3_par *par = (struct cg3_par *) info->par;
  	struct cg3_regs __iomem *regs = par->regs;
  	unsigned long flags;
  	u8 val;
  
  	spin_lock_irqsave(&par->lock, flags);
  
  	switch (blank) {
  	case FB_BLANK_UNBLANK: /* Unblanking */
  		val = sbus_readb(&regs->control);
  		val |= CG3_CR_ENABLE_VIDEO;
  		sbus_writeb(val, &regs->control);
  		par->flags &= ~CG3_FLAG_BLANKED;
  		break;
  
  	case FB_BLANK_NORMAL: /* Normal blanking */
  	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
  	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
  	case FB_BLANK_POWERDOWN: /* Poweroff */
  		val = sbus_readb(&regs->control);
  		val &= ~CG3_CR_ENABLE_VIDEO;
  		sbus_writeb(val, &regs->control);
  		par->flags |= CG3_FLAG_BLANKED;
  		break;
  	}
  
  	spin_unlock_irqrestore(&par->lock, flags);
  
  	return 0;
  }
  
  static struct sbus_mmap_map cg3_mmap_map[] = {
  	{
  		.voff	= CG3_MMAP_OFFSET,
  		.poff	= CG3_RAM_OFFSET,
  		.size	= SBUS_MMAP_FBSIZE(1)
  	},
  	{ .size = 0 }
  };
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
223
  static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
227
  {
  	struct cg3_par *par = (struct cg3_par *)info->par;
  
  	return sbusfb_mmap_helper(cg3_mmap_map,
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
228
  				  info->fix.smem_start, info->fix.smem_len,
50312ce9d   David S. Miller   [SPARC]: Convert ...
229
  				  par->which_io,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
  				  vma);
  }
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
232
  static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  	return sbusfb_ioctl_helper(cmd, arg, info,
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
235
  				   FBTYPE_SUN3COLOR, 8, info->fix.smem_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
240
  }
  
  /*
   *  Initialisation
   */
a71775147   Robert Reif   [VIDEO]: Fix sect...
241
242
  static void __devinit cg3_init_fix(struct fb_info *info, int linebytes,
  				   struct device_node *dp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  {
50312ce9d   David S. Miller   [SPARC]: Convert ...
244
  	strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
251
252
  
  	info->fix.type = FB_TYPE_PACKED_PIXELS;
  	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
  
  	info->fix.line_length = linebytes;
  
  	info->fix.accel = FB_ACCEL_SUN_CGTHREE;
  }
a71775147   Robert Reif   [VIDEO]: Fix sect...
253
254
  static void __devinit cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
  					      struct device_node *dp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  {
ccf0dec6f   Stephen Rothwell   [SPARC/64] consti...
256
  	const char *params;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
  	char *p;
  	int ww, hh;
50312ce9d   David S. Miller   [SPARC]: Convert ...
259
260
261
  	params = of_get_property(dp, "params", NULL);
  	if (params) {
  		ww = simple_strtoul(params, &p, 10);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
268
269
270
271
272
273
  		if (ww && *p == 'x') {
  			hh = simple_strtoul(p + 1, &p, 10);
  			if (hh && *p == '-') {
  				if (var->xres != ww ||
  				    var->yres != hh) {
  					var->xres = var->xres_virtual = ww;
  					var->yres = var->yres_virtual = hh;
  				}
  			}
  		}
  	}
  }
a71775147   Robert Reif   [VIDEO]: Fix sect...
274
  static u8 cg3regvals_66hz[] __devinitdata = {	/* 1152 x 900, 66 Hz */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
  	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
  	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
  	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x20,	0
  };
a71775147   Robert Reif   [VIDEO]: Fix sect...
280
  static u8 cg3regvals_76hz[] __devinitdata = {	/* 1152 x 900, 76 Hz */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
283
284
285
  	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
  	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
  	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x24,	0
  };
a71775147   Robert Reif   [VIDEO]: Fix sect...
286
  static u8 cg3regvals_rdi[] __devinitdata = {	/* 640 x 480, cgRDI */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
290
291
  	0x14, 0x70,	0x15, 0x20,	0x16, 0x08,	0x17, 0x10,
  	0x18, 0x06,	0x19, 0x02,	0x1a, 0x31,	0x1b, 0x51,
  	0x1c, 0x06,	0x1d, 0x0c,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x22,	0
  };
a71775147   Robert Reif   [VIDEO]: Fix sect...
292
  static u8 *cg3_regvals[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
  	cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
  };
a71775147   Robert Reif   [VIDEO]: Fix sect...
295
  static u_char cg3_dacvals[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
  	4, 0xff,	5, 0x00,	6, 0x70,	7, 0x00,	0
  };
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
298
  static int __devinit cg3_do_default_mode(struct cg3_par *par)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  {
  	enum cg3_type type;
  	u8 *p;
  
  	if (par->flags & CG3_FLAG_RDI)
  		type = CG3_RDI;
  	else {
  		u8 status = sbus_readb(&par->regs->status), mon;
  		if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
  			mon = status & CG3_SR_RES_MASK;
  			if (mon == CG3_SR_1152_900_76_A ||
  			    mon == CG3_SR_1152_900_76_B)
  				type = CG3_AT_76HZ;
  			else
  				type = CG3_AT_66HZ;
  		} else {
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
315
316
317
318
  			printk(KERN_ERR "cgthree: can't handle SR %02x
  ",
  			       status);
  			return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319
320
321
322
323
324
325
326
  		}
  	}
  
  	for (p = cg3_regvals[type]; *p; p += 2) {
  		u8 __iomem *regp = &((u8 __iomem *)par->regs)[p[0]];
  		sbus_writeb(p[1], regp);
  	}
  	for (p = cg3_dacvals; *p; p += 2) {
50312ce9d   David S. Miller   [SPARC]: Convert ...
327
  		u8 __iomem *regp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328

50312ce9d   David S. Miller   [SPARC]: Convert ...
329
  		regp = (u8 __iomem *)&par->regs->cmap.addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
  		sbus_writeb(p[0], regp);
50312ce9d   David S. Miller   [SPARC]: Convert ...
331
  		regp = (u8 __iomem *)&par->regs->cmap.control;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
  		sbus_writeb(p[1], regp);
  	}
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
334
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  }
28541d0f1   Grant Likely   dt/video: Elimina...
336
  static int __devinit cg3_probe(struct platform_device *op)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  {
d4b8b2c2c   Anatolij Gustschin   of/video: fix bui...
338
  	struct device_node *dp = op->dev.of_node;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
339
340
  	struct fb_info *info;
  	struct cg3_par *par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
341
  	int linebytes, err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
343
  	info = framebuffer_alloc(sizeof(struct cg3_par), &op->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
345
346
347
348
  	err = -ENOMEM;
  	if (!info)
  		goto out_err;
  	par = info->par;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
350
  	spin_lock_init(&par->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351

9fbfd4b8a   Krzysztof Helt   cg3: use standard...
352
  	info->fix.smem_start = op->resource[0].start;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
353
  	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
6cd5a86b5   Robert Reif   sparc video: remo...
354
  	sbusfb_fill_var(&info->var, dp, 8);
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
355
356
357
  	info->var.red.length = 8;
  	info->var.green.length = 8;
  	info->var.blue.length = 8;
50312ce9d   David S. Miller   [SPARC]: Convert ...
358
  	if (!strcmp(dp->name, "cgRDI"))
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
359
360
361
  		par->flags |= CG3_FLAG_RDI;
  	if (par->flags & CG3_FLAG_RDI)
  		cg3_rdi_maybe_fixup_var(&info->var, dp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362

50312ce9d   David S. Miller   [SPARC]: Convert ...
363
  	linebytes = of_getintprop_default(dp, "linebytes",
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
364
  					  info->var.xres);
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
365
  	info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
367
368
369
370
  	par->regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
  			       sizeof(struct cg3_regs), "cg3 regs");
  	if (!par->regs)
  		goto out_release_fb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
372
373
374
  	info->flags = FBINFO_DEFAULT;
  	info->fbops = &cg3_ops;
  	info->screen_base = of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
375
  				       info->fix.smem_len, "cg3 ram");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
376
377
  	if (!info->screen_base)
  		goto out_unmap_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378

59f7137a1   Robert Reif   sparc video: make...
379
  	cg3_blank(FB_BLANK_UNBLANK, info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380

6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
381
382
383
384
385
  	if (!of_find_property(dp, "width", NULL)) {
  		err = cg3_do_default_mode(par);
  		if (err)
  			goto out_unmap_screen;
  	}
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
386
387
388
389
390
  
  	if (fb_alloc_cmap(&info->cmap, 256, 0))
  		goto out_unmap_screen;
  
  	fb_set_cmap(&info->cmap, info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
392
393
394
395
396
397
398
  	cg3_init_fix(info, linebytes, dp);
  
  	err = register_framebuffer(info);
  	if (err < 0)
  		goto out_dealloc_cmap;
  
  	dev_set_drvdata(&op->dev, info);
50312ce9d   David S. Miller   [SPARC]: Convert ...
399

194f1a68b   Robert Reif   sparc: video driv...
400
401
  	printk(KERN_INFO "%s: cg3 at %lx:%lx
  ",
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
402
  	       dp->full_name, par->which_io, info->fix.smem_start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403

50312ce9d   David S. Miller   [SPARC]: Convert ...
404
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
406
407
408
409
  out_dealloc_cmap:
  	fb_dealloc_cmap(&info->cmap);
  
  out_unmap_screen:
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
410
  	of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
411
412
413
414
415
416
  
  out_unmap_regs:
  	of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
  
  out_release_fb:
  	framebuffer_release(info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
418
419
  out_err:
  	return err;
50312ce9d   David S. Miller   [SPARC]: Convert ...
420
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421

2dc115813   Grant Likely   of/device: Replac...
422
  static int __devexit cg3_remove(struct platform_device *op)
50312ce9d   David S. Miller   [SPARC]: Convert ...
423
  {
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
424
425
  	struct fb_info *info = dev_get_drvdata(&op->dev);
  	struct cg3_par *par = info->par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
426

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
427
428
  	unregister_framebuffer(info);
  	fb_dealloc_cmap(&info->cmap);
50312ce9d   David S. Miller   [SPARC]: Convert ...
429

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
430
  	of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
9fbfd4b8a   Krzysztof Helt   cg3: use standard...
431
  	of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
50312ce9d   David S. Miller   [SPARC]: Convert ...
432

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
433
  	framebuffer_release(info);
50312ce9d   David S. Miller   [SPARC]: Convert ...
434

e3a411a3d   David S. Miller   [SPARC64]: Fix of...
435
  	dev_set_drvdata(&op->dev, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
  
  	return 0;
  }
fd098316e   David S. Miller   sparc: Annotate o...
439
  static const struct of_device_id cg3_match[] = {
50312ce9d   David S. Miller   [SPARC]: Convert ...
440
441
442
443
444
445
446
447
448
  	{
  		.name = "cgthree",
  	},
  	{
  		.name = "cgRDI",
  	},
  	{},
  };
  MODULE_DEVICE_TABLE(of, cg3_match);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449

28541d0f1   Grant Likely   dt/video: Elimina...
450
  static struct platform_driver cg3_driver = {
4018294b5   Grant Likely   of: Remove duplic...
451
452
453
454
455
  	.driver = {
  		.name = "cg3",
  		.owner = THIS_MODULE,
  		.of_match_table = cg3_match,
  	},
50312ce9d   David S. Miller   [SPARC]: Convert ...
456
457
458
  	.probe		= cg3_probe,
  	.remove		= __devexit_p(cg3_remove),
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459

50312ce9d   David S. Miller   [SPARC]: Convert ...
460
461
462
463
  static int __init cg3_init(void)
  {
  	if (fb_get_options("cg3fb", NULL))
  		return -ENODEV;
28541d0f1   Grant Likely   dt/video: Elimina...
464
  	return platform_driver_register(&cg3_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
  }
50312ce9d   David S. Miller   [SPARC]: Convert ...
466
  static void __exit cg3_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
  {
28541d0f1   Grant Likely   dt/video: Elimina...
468
  	platform_driver_unregister(&cg3_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
471
  }
  
  module_init(cg3_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
  module_exit(cg3_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
474
  
  MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets");
50312ce9d   David S. Miller   [SPARC]: Convert ...
475
476
  MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
  MODULE_VERSION("2.0");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
  MODULE_LICENSE("GPL");