Blame view

drivers/video/bw2.c 9.22 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /* bw2.c: BWTWO 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
  #include <asm/fbio.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
29
  #include "sbuslib.h"
  
  /*
   * Local functions.
   */
  
  static int bw2_blank(int, struct fb_info *);
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
30
  static int bw2_mmap(struct fb_info *, struct vm_area_struct *);
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
31
  static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
38
39
40
41
42
43
44
  
  /*
   *  Frame buffer operations
   */
  
  static struct fb_ops bw2_ops = {
  	.owner			= THIS_MODULE,
  	.fb_blank		= bw2_blank,
  	.fb_fillrect		= cfb_fillrect,
  	.fb_copyarea		= cfb_copyarea,
  	.fb_imageblit		= cfb_imageblit,
  	.fb_mmap		= bw2_mmap,
  	.fb_ioctl		= bw2_ioctl,
9ffb83bcc   Christoph Hellwig   [SBUSFB]: impleme...
45
46
47
  #ifdef CONFIG_COMPAT
  	.fb_compat_ioctl	= sbusfb_compat_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
51
52
53
  };
  
  /* OBio addresses for the bwtwo registers */
  #define BWTWO_REGISTER_OFFSET 0x400000
  
  struct bt_regs {
50312ce9d   David S. Miller   [SPARC]: Convert ...
54
55
56
57
  	u32 addr;
  	u32 color_map;
  	u32 control;
  	u32 cursor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
  };
  
  struct bw2_regs {
  	struct bt_regs	cmap;
50312ce9d   David S. Miller   [SPARC]: Convert ...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  	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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  };
  
  /* Status Register Constants */
  #define BWTWO_SR_RES_MASK	0x70
  #define BWTWO_SR_1600_1280	0x50
  #define BWTWO_SR_1152_900_76_A	0x40
  #define BWTWO_SR_1152_900_76_B	0x60
  #define BWTWO_SR_ID_MASK	0x0f
  #define BWTWO_SR_ID_MONO	0x02
  #define BWTWO_SR_ID_MONO_ECL	0x03
  #define BWTWO_SR_ID_MSYNC	0x04
  #define BWTWO_SR_ID_NOCONN	0x0a
  
  /* Control Register Constants */
  #define BWTWO_CTL_ENABLE_INTS   0x80
  #define BWTWO_CTL_ENABLE_VIDEO  0x40
  #define BWTWO_CTL_ENABLE_TIMING 0x20
  #define BWTWO_CTL_ENABLE_CURCMP 0x10
  #define BWTWO_CTL_XTAL_MASK     0x0C
  #define BWTWO_CTL_DIVISOR_MASK  0x03
  
  /* Status Register Constants */
  #define BWTWO_STAT_PENDING_INT  0x80
  #define BWTWO_STAT_MSENSE_MASK  0x70
  #define BWTWO_STAT_ID_MASK      0x0f
  
  struct bw2_par {
  	spinlock_t		lock;
  	struct bw2_regs		__iomem *regs;
  
  	u32			flags;
  #define BW2_FLAG_BLANKED	0x00000001
50312ce9d   David S. Miller   [SPARC]: Convert ...
110
  	unsigned long		which_io;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
115
116
117
118
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
  };
  
  /**
   *      bw2_blank - Optional function.  Blanks the display.
   *      @blank_mode: the blank mode we want.
   *      @info: frame buffer structure that represents a single frame buffer
   */
  static int
  bw2_blank(int blank, struct fb_info *info)
  {
  	struct bw2_par *par = (struct bw2_par *) info->par;
  	struct bw2_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 |= BWTWO_CTL_ENABLE_VIDEO;
  		sbus_writeb(val, &regs->control);
  		par->flags &= ~BW2_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 &= ~BWTWO_CTL_ENABLE_VIDEO;
  		sbus_writeb(val, &regs->control);
  		par->flags |= BW2_FLAG_BLANKED;
  		break;
  	}
  
  	spin_unlock_irqrestore(&par->lock, flags);
  
  	return 0;
  }
  
  static struct sbus_mmap_map bw2_mmap_map[] = {
  	{
  		.size = SBUS_MMAP_FBSIZE(1)
  	},
  	{ .size = 0 }
  };
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
158
  static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
162
  {
  	struct bw2_par *par = (struct bw2_par *)info->par;
  
  	return sbusfb_mmap_helper(bw2_mmap_map,
3f06cd293   Krzysztof Helt   bw2: use standard...
163
  				  info->fix.smem_start, info->fix.smem_len,
50312ce9d   David S. Miller   [SPARC]: Convert ...
164
  				  par->which_io,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
  				  vma);
  }
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
167
  static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  	return sbusfb_ioctl_helper(cmd, arg, info,
3f06cd293   Krzysztof Helt   bw2: use standard...
170
  				   FBTYPE_SUN2BW, 1, info->fix.smem_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
172
173
174
175
  }
  
  /*
   *  Initialisation
   */
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
176
  static void __devinit bw2_init_fix(struct fb_info *info, int linebytes)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
181
182
183
184
185
186
  {
  	strlcpy(info->fix.id, "bwtwo", sizeof(info->fix.id));
  
  	info->fix.type = FB_TYPE_PACKED_PIXELS;
  	info->fix.visual = FB_VISUAL_MONO01;
  
  	info->fix.line_length = linebytes;
  
  	info->fix.accel = FB_ACCEL_SUN_BWTWO;
  }
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
187
  static u8 bw2regs_1600[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
191
192
  	0x14, 0x8b,	0x15, 0x28,	0x16, 0x03,	0x17, 0x13,
  	0x18, 0x7b,	0x19, 0x05,	0x1a, 0x34,	0x1b, 0x2e,
  	0x1c, 0x00,	0x1d, 0x0a,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x21,	0
  };
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
193
  static u8 bw2regs_ecl[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
197
198
  	0x14, 0x65,	0x15, 0x1e,	0x16, 0x04,	0x17, 0x0c,
  	0x18, 0x5e,	0x19, 0x03,	0x1a, 0xa7,	0x1b, 0x23,
  	0x1c, 0x00,	0x1d, 0x08,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x20,	0
  };
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
199
  static u8 bw2regs_analog[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
  	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x03,	0x17, 0x13,
  	0x18, 0xb0,	0x19, 0x03,	0x1a, 0xa6,	0x1b, 0x22,
  	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
  	0x10, 0x20,	0
  };
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
205
  static u8 bw2regs_76hz[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
208
209
210
  	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
  };
63abdcdc0   Robert Reif   [BW2]: Fix sectio...
211
  static u8 bw2regs_66hz[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
215
216
  	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
  };
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
217
218
219
  static int __devinit bw2_do_default_mode(struct bw2_par *par,
  					 struct fb_info *info,
  					 int *linebytes)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  {
  	u8 status, mon;
  	u8 *p;
  
  	status = sbus_readb(&par->regs->status);
  	mon = status & BWTWO_SR_RES_MASK;
  	switch (status & BWTWO_SR_ID_MASK) {
  	case BWTWO_SR_ID_MONO_ECL:
  		if (mon == BWTWO_SR_1600_1280) {
  			p = bw2regs_1600;
  			info->var.xres = info->var.xres_virtual = 1600;
  			info->var.yres = info->var.yres_virtual = 1280;
  			*linebytes = 1600 / 8;
  		} else
  			p = bw2regs_ecl;
  		break;
  
  	case BWTWO_SR_ID_MONO:
  		p = bw2regs_analog;
  		break;
  
  	case BWTWO_SR_ID_MSYNC:
  		if (mon == BWTWO_SR_1152_900_76_A ||
  		    mon == BWTWO_SR_1152_900_76_B)
  			p = bw2regs_76hz;
  		else
  			p = bw2regs_66hz;
  		break;
  
  	case BWTWO_SR_ID_NOCONN:
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
250
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
  
  	default:
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
253
254
255
256
  		printk(KERN_ERR "bw2: can't handle SR %02x
  ",
  		       status);
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
260
261
  	}
  	for ( ; *p; p += 2) {
  		u8 __iomem *regp = &((u8 __iomem *)par->regs)[p[0]];
  		sbus_writeb(p[1], regp);
  	}
6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
262
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  }
28541d0f1   Grant Likely   dt/video: Elimina...
264
  static int __devinit bw2_probe(struct platform_device *op)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  {
d4b8b2c2c   Anatolij Gustschin   of/video: fix bui...
266
  	struct device_node *dp = op->dev.of_node;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
267
268
  	struct fb_info *info;
  	struct bw2_par *par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
269
  	int linebytes, err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270

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

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
273
274
275
276
  	err = -ENOMEM;
  	if (!info)
  		goto out_err;
  	par = info->par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
277

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
278
  	spin_lock_init(&par->lock);
50312ce9d   David S. Miller   [SPARC]: Convert ...
279

3f06cd293   Krzysztof Helt   bw2: use standard...
280
  	info->fix.smem_start = op->resource[0].start;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
281
  	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
6cd5a86b5   Robert Reif   sparc video: remo...
282
  	sbusfb_fill_var(&info->var, dp, 1);
50312ce9d   David S. Miller   [SPARC]: Convert ...
283
  	linebytes = of_getintprop_default(dp, "linebytes",
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
284
  					  info->var.xres);
50312ce9d   David S. Miller   [SPARC]: Convert ...
285

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
286
287
288
289
  	info->var.red.length = info->var.green.length =
  		info->var.blue.length = info->var.bits_per_pixel;
  	info->var.red.offset = info->var.green.offset =
  		info->var.blue.offset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
291
292
293
294
  	par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
  			       sizeof(struct bw2_regs), "bw2 regs");
  	if (!par->regs)
  		goto out_release_fb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295

6c8f5b90b   David S. Miller   [VIDEO]: Do not p...
296
297
298
299
300
  	if (!of_find_property(dp, "width", NULL)) {
  		err = bw2_do_default_mode(par, info, &linebytes);
  		if (err)
  			goto out_unmap_regs;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301

3f06cd293   Krzysztof Helt   bw2: use standard...
302
  	info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
304
305
  	info->flags = FBINFO_DEFAULT;
  	info->fbops = &bw2_ops;
50312ce9d   David S. Miller   [SPARC]: Convert ...
306

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
307
  	info->screen_base = of_ioremap(&op->resource[0], 0,
3f06cd293   Krzysztof Helt   bw2: use standard...
308
  				       info->fix.smem_len, "bw2 ram");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
309
310
  	if (!info->screen_base)
  		goto out_unmap_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311

59f7137a1   Robert Reif   sparc video: make...
312
  	bw2_blank(FB_BLANK_UNBLANK, info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
314
  	bw2_init_fix(info, linebytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
316
317
318
  	err = register_framebuffer(info);
  	if (err < 0)
  		goto out_unmap_screen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
320
  	dev_set_drvdata(&op->dev, info);
50312ce9d   David S. Miller   [SPARC]: Convert ...
321

194f1a68b   Robert Reif   sparc: video driv...
322
323
  	printk(KERN_INFO "%s: bwtwo at %lx:%lx
  ",
3f06cd293   Krzysztof Helt   bw2: use standard...
324
  	       dp->full_name, par->which_io, info->fix.smem_start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325

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

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
328
  out_unmap_screen:
3f06cd293   Krzysztof Helt   bw2: use standard...
329
  	of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
330
331
332
333
334
335
  
  out_unmap_regs:
  	of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
  
  out_release_fb:
  	framebuffer_release(info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
337
338
  out_err:
  	return err;
50312ce9d   David S. Miller   [SPARC]: Convert ...
339
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340

2dc115813   Grant Likely   of/device: Replac...
341
  static int __devexit bw2_remove(struct platform_device *op)
50312ce9d   David S. Miller   [SPARC]: Convert ...
342
  {
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
343
344
  	struct fb_info *info = dev_get_drvdata(&op->dev);
  	struct bw2_par *par = info->par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
345

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
346
  	unregister_framebuffer(info);
50312ce9d   David S. Miller   [SPARC]: Convert ...
347

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
348
  	of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
3f06cd293   Krzysztof Helt   bw2: use standard...
349
  	of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
50312ce9d   David S. Miller   [SPARC]: Convert ...
350

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

e3a411a3d   David S. Miller   [SPARC64]: Fix of...
353
  	dev_set_drvdata(&op->dev, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
  
  	return 0;
  }
fd098316e   David S. Miller   sparc: Annotate o...
357
  static const struct of_device_id bw2_match[] = {
50312ce9d   David S. Miller   [SPARC]: Convert ...
358
359
360
361
362
363
  	{
  		.name = "bwtwo",
  	},
  	{},
  };
  MODULE_DEVICE_TABLE(of, bw2_match);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

28541d0f1   Grant Likely   dt/video: Elimina...
365
  static struct platform_driver bw2_driver = {
4018294b5   Grant Likely   of: Remove duplic...
366
367
368
369
370
  	.driver = {
  		.name = "bw2",
  		.owner = THIS_MODULE,
  		.of_match_table = bw2_match,
  	},
50312ce9d   David S. Miller   [SPARC]: Convert ...
371
372
373
  	.probe		= bw2_probe,
  	.remove		= __devexit_p(bw2_remove),
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374

50312ce9d   David S. Miller   [SPARC]: Convert ...
375
376
377
378
  static int __init bw2_init(void)
  {
  	if (fb_get_options("bw2fb", NULL))
  		return -ENODEV;
28541d0f1   Grant Likely   dt/video: Elimina...
379
  	return platform_driver_register(&bw2_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  }
50312ce9d   David S. Miller   [SPARC]: Convert ...
381
  static void __exit bw2_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
  {
28541d0f1   Grant Likely   dt/video: Elimina...
383
  	platform_driver_unregister(&bw2_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
  }
50312ce9d   David S. Miller   [SPARC]: Convert ...
385
  module_init(bw2_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
  module_exit(bw2_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
  
  MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets");
50312ce9d   David S. Miller   [SPARC]: Convert ...
389
390
  MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
  MODULE_VERSION("2.0");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  MODULE_LICENSE("GPL");