Commit 9084b0058e11378abb43d01e669bac8ac7b593ff
Committed by
Ralf Baechle
1 parent
4df4db5c6c
Exists in
master
and in
39 other branches
[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 |