Commit 9084b0058e11378abb43d01e669bac8ac7b593ff

Authored by Maciej W. Rozycki
Committed by Ralf Baechle
1 parent 4df4db5c6c

[TC] pmagb-b-fb: Convert to the driver model

This is a set of changes to convert the driver to the driver model.  As a
side-effect the driver now supports building as a module.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 2 changed files with 58 additions and 44 deletions Side-by-side Diff

drivers/video/Kconfig
... ... @@ -1454,8 +1454,8 @@
1454 1454 used mainly in the MIPS-based DECstation series.
1455 1455  
1456 1456 config FB_PMAGB_B
1457   - bool "PMAGB-B TURBOchannel framebuffer support"
1458   - depends on (FB = y) && TC
  1457 + tristate "PMAGB-B TURBOchannel framebuffer support"
  1458 + depends on TC
1459 1459 select FB_CFB_FILLRECT
1460 1460 select FB_CFB_COPYAREA
1461 1461 select FB_CFB_IMAGEBLIT
drivers/video/pmagb-b-fb.c
... ... @@ -11,7 +11,7 @@
11 11 * Michael Engel <engel@unix-ag.org>,
12 12 * Karsten Merker <merker@linuxtag.org> and
13 13 * Harald Koerfgen.
14   - * Copyright (c) 2005 Maciej W. Rozycki
  14 + * Copyright (c) 2005, 2006 Maciej W. Rozycki
15 15 *
16 16 * This file is subject to the terms and conditions of the GNU General
17 17 * Public License. See the file COPYING in the main directory of this
18 18  
19 19  
... ... @@ -25,18 +25,16 @@
25 25 #include <linux/init.h>
26 26 #include <linux/kernel.h>
27 27 #include <linux/module.h>
  28 +#include <linux/tc.h>
28 29 #include <linux/types.h>
29 30  
30 31 #include <asm/io.h>
31 32 #include <asm/system.h>
32 33  
33   -#include <asm/dec/tc.h>
34   -
35 34 #include <video/pmagb-b-fb.h>
36 35  
37 36  
38 37 struct pmagbbfb_par {
39   - struct fb_info *next;
40 38 volatile void __iomem *mmio;
41 39 volatile void __iomem *smem;
42 40 volatile u32 __iomem *sfb;
... ... @@ -47,8 +45,6 @@
47 45 };
48 46  
49 47  
50   -static struct fb_info *root_pmagbbfb_dev;
51   -
52 48 static struct fb_var_screeninfo pmagbbfb_defined __initdata = {
53 49 .bits_per_pixel = 8,
54 50 .red.length = 8,
55 51  
... ... @@ -190,8 +186,9 @@
190 186 69197, 66000, 65000, 50350, 36000, 32000, 25175
191 187 };
192 188 struct pmagbbfb_par *par = info->par;
  189 + struct tc_bus *tbus = to_tc_dev(info->device)->bus;
193 190 u32 count0 = 8, count1 = 8, counttc = 16 * 256 + 8;
194   - u32 freq0, freq1, freqtc = get_tc_speed() / 250;
  191 + u32 freq0, freq1, freqtc = tc_get_speed(tbus) / 250;
195 192 int i, j;
196 193  
197 194 gp0_write(par, 0); /* select Osc0 */
198 195  
199 196  
200 197  
201 198  
202 199  
... ... @@ -249,27 +246,22 @@
249 246 };
250 247  
251 248  
252   -static int __init pmagbbfb_init_one(int slot)
  249 +static int __init pmagbbfb_probe(struct device *dev)
253 250 {
254   - char freq0[12], freq1[12];
  251 + struct tc_dev *tdev = to_tc_dev(dev);
  252 + resource_size_t start, len;
255 253 struct fb_info *info;
256 254 struct pmagbbfb_par *par;
257   - unsigned long base_addr;
  255 + char freq0[12], freq1[12];
258 256 u32 vid_base;
259 257  
260   - info = framebuffer_alloc(sizeof(struct pmagbbfb_par), NULL);
  258 + info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
261 259 if (!info)
262 260 return -ENOMEM;
263 261  
264 262 par = info->par;
265   - par->slot = slot;
266   - claim_tc_card(par->slot);
  263 + dev_set_drvdata(dev, info);
267 264  
268   - base_addr = get_tc_base_addr(par->slot);
269   -
270   - par->next = root_pmagbbfb_dev;
271   - root_pmagbbfb_dev = info;
272   -
273 265 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
274 266 goto err_alloc;
275 267  
276 268  
277 269  
278 270  
... ... @@ -278,16 +270,22 @@
278 270 info->var = pmagbbfb_defined;
279 271 info->flags = FBINFO_DEFAULT;
280 272  
  273 + /* Request the I/O MEM resource. */
  274 + start = tdev->resource.start;
  275 + len = tdev->resource.end - start + 1;
  276 + if (!request_mem_region(start, len, dev->bus_id))
  277 + goto err_cmap;
  278 +
281 279 /* MMIO mapping setup. */
282   - info->fix.mmio_start = base_addr;
  280 + info->fix.mmio_start = start;
283 281 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
284 282 if (!par->mmio)
285   - goto err_cmap;
  283 + goto err_resource;
286 284 par->sfb = par->mmio + PMAGB_B_SFB;
287 285 par->dac = par->mmio + PMAGB_B_BT459;
288 286  
289 287 /* Frame buffer mapping setup. */
290   - info->fix.smem_start = base_addr + PMAGB_B_FBMEM;
  288 + info->fix.smem_start = start + PMAGB_B_FBMEM;
291 289 par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
292 290 if (!par->smem)
293 291 goto err_mmio_map;
294 292  
... ... @@ -302,13 +300,15 @@
302 300 if (register_framebuffer(info) < 0)
303 301 goto err_smem_map;
304 302  
  303 + get_device(dev);
  304 +
305 305 snprintf(freq0, sizeof(freq0), "%u.%03uMHz",
306 306 par->osc0 / 1000, par->osc0 % 1000);
307 307 snprintf(freq1, sizeof(freq1), "%u.%03uMHz",
308 308 par->osc1 / 1000, par->osc1 % 1000);
309 309  
310   - pr_info("fb%d: %s frame buffer device in slot %d\n",
311   - info->node, info->fix.id, par->slot);
  310 + pr_info("fb%d: %s frame buffer device at %s\n",
  311 + info->node, info->fix.id, dev->bus_id);
312 312 pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n",
313 313 info->node, freq0, par->osc1 ? freq1 : "disabled",
314 314 par->osc1 != 0);
315 315  
316 316  
317 317  
318 318  
319 319  
320 320  
321 321  
322 322  
323 323  
324 324  
325 325  
326 326  
327 327  
... ... @@ -322,54 +322,68 @@
322 322 err_mmio_map:
323 323 iounmap(par->mmio);
324 324  
  325 +err_resource:
  326 + release_mem_region(start, len);
  327 +
325 328 err_cmap:
326 329 fb_dealloc_cmap(&info->cmap);
327 330  
328 331 err_alloc:
329   - root_pmagbbfb_dev = par->next;
330   - release_tc_card(par->slot);
331 332 framebuffer_release(info);
332 333 return -ENXIO;
333 334 }
334 335  
335   -static void __exit pmagbbfb_exit_one(void)
  336 +static int __exit pmagbbfb_remove(struct device *dev)
336 337 {
337   - struct fb_info *info = root_pmagbbfb_dev;
  338 + struct tc_dev *tdev = to_tc_dev(dev);
  339 + struct fb_info *info = dev_get_drvdata(dev);
338 340 struct pmagbbfb_par *par = info->par;
  341 + resource_size_t start, len;
339 342  
  343 + put_device(dev);
340 344 unregister_framebuffer(info);
341 345 iounmap(par->smem);
342 346 iounmap(par->mmio);
  347 + start = tdev->resource.start;
  348 + len = tdev->resource.end - start + 1;
  349 + release_mem_region(start, len);
343 350 fb_dealloc_cmap(&info->cmap);
344   - root_pmagbbfb_dev = par->next;
345   - release_tc_card(par->slot);
346 351 framebuffer_release(info);
  352 + return 0;
347 353 }
348 354  
349 355  
350 356 /*
351   - * Initialise the framebuffer.
  357 + * Initialize the framebuffer.
352 358 */
  359 +static const struct tc_device_id pmagbbfb_tc_table[] = {
  360 + { "DEC ", "PMAGB-BA" },
  361 + { }
  362 +};
  363 +MODULE_DEVICE_TABLE(tc, pmagbbfb_tc_table);
  364 +
  365 +static struct tc_driver pmagbbfb_driver = {
  366 + .id_table = pmagbbfb_tc_table,
  367 + .driver = {
  368 + .name = "pmagbbfb",
  369 + .bus = &tc_bus_type,
  370 + .probe = pmagbbfb_probe,
  371 + .remove = __exit_p(pmagbbfb_remove),
  372 + },
  373 +};
  374 +
353 375 static int __init pmagbbfb_init(void)
354 376 {
355   - int count = 0;
356   - int slot;
357   -
  377 +#ifndef MODULE
358 378 if (fb_get_options("pmagbbfb", NULL))
359 379 return -ENXIO;
360   -
361   - while ((slot = search_tc_card("PMAGB-BA")) >= 0) {
362   - if (pmagbbfb_init_one(slot) < 0)
363   - break;
364   - count++;
365   - }
366   - return (count > 0) ? 0 : -ENXIO;
  380 +#endif
  381 + return tc_register_driver(&pmagbbfb_driver);
367 382 }
368 383  
369 384 static void __exit pmagbbfb_exit(void)
370 385 {
371   - while (root_pmagbbfb_dev)
372   - pmagbbfb_exit_one();
  386 + tc_unregister_driver(&pmagbbfb_driver);
373 387 }
374 388  
375 389