Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

radeonfb: Deinline large functions

With this .config: http://busybox.net/~vda/kernel_config,
after uninlining these functions have sizes and callsite counts
as follows:

__OUTPLLP: 61 bytes, 12 callsites
__INPLL: 79 bytes, 150 callsites
__OUTPLL: 82 bytes, 138 callsites
_OUTREGP: 101 bytes, 8 callsites
_radeon_msleep: 66 bytes, 18 callsites
_radeon_fifo_wait: 83 bytes, 24 callsites
_radeon_engine_idle: 92 bytes, 10 callsites
radeon_engine_flush: 105 bytes, 2 callsites
radeon_pll_errata_after_index_slow: 31 bytes, 11 callsites
radeon_pll_errata_after_data_slow: 91 bytes, 9 callsites

radeon_pll_errata_after_FOO functions are split into two parts:
the inlined part which checks corresponding rinfo->errata bit,
and out-of-line part which performs workaround magic per se.

Reduction in code size is about 49,500 bytes:

text data bss dec hex filename
85789648 22294616 20627456 128711720 7abfc28 vmlinux.before
85740176 22294680 20627456 128662312 7ab3b28 vmlinux

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: David Airlie <airlied@linux.ie>
Cc: Alex Deucher <alexdeucher@gmail.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Dave Airlie <airlied@redhat.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Denys Vlasenko and committed by
Tomi Valkeinen
08bfb453 2035608e

+146 -131
+131 -2
drivers/video/fbdev/aty/radeon_base.c
··· 276 276 static int backlight = 0; 277 277 #endif 278 278 279 - /* 280 - * prototypes 279 + /* Note about this function: we have some rare cases where we must not schedule, 280 + * this typically happen with our special "wake up early" hook which allows us to 281 + * wake up the graphic chip (and thus get the console back) before everything else 282 + * on some machines that support that mechanism. At this point, interrupts are off 283 + * and scheduling is not permitted 281 284 */ 285 + void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) 286 + { 287 + if (rinfo->no_schedule || oops_in_progress) 288 + mdelay(ms); 289 + else 290 + msleep(ms); 291 + } 292 + 293 + void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo) 294 + { 295 + /* Called if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS) is set */ 296 + (void)INREG(CLOCK_CNTL_DATA); 297 + (void)INREG(CRTC_GEN_CNTL); 298 + } 299 + 300 + void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo) 301 + { 302 + if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) { 303 + /* we can't deal with posted writes here ... */ 304 + _radeon_msleep(rinfo, 5); 305 + } 306 + if (rinfo->errata & CHIP_ERRATA_R300_CG) { 307 + u32 save, tmp; 308 + save = INREG(CLOCK_CNTL_INDEX); 309 + tmp = save & ~(0x3f | PLL_WR_EN); 310 + OUTREG(CLOCK_CNTL_INDEX, tmp); 311 + tmp = INREG(CLOCK_CNTL_DATA); 312 + OUTREG(CLOCK_CNTL_INDEX, save); 313 + } 314 + } 315 + 316 + void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask) 317 + { 318 + unsigned long flags; 319 + unsigned int tmp; 320 + 321 + spin_lock_irqsave(&rinfo->reg_lock, flags); 322 + tmp = INREG(addr); 323 + tmp &= (mask); 324 + tmp |= (val); 325 + OUTREG(addr, tmp); 326 + spin_unlock_irqrestore(&rinfo->reg_lock, flags); 327 + } 328 + 329 + u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) 330 + { 331 + u32 data; 332 + 333 + OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); 334 + radeon_pll_errata_after_index(rinfo); 335 + data = INREG(CLOCK_CNTL_DATA); 336 + radeon_pll_errata_after_data(rinfo); 337 + return data; 338 + } 339 + 340 + void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val) 341 + { 342 + OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); 343 + radeon_pll_errata_after_index(rinfo); 344 + OUTREG(CLOCK_CNTL_DATA, val); 345 + radeon_pll_errata_after_data(rinfo); 346 + } 347 + 348 + void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, 349 + u32 val, u32 mask) 350 + { 351 + unsigned int tmp; 352 + 353 + tmp = __INPLL(rinfo, index); 354 + tmp &= (mask); 355 + tmp |= (val); 356 + __OUTPLL(rinfo, index, tmp); 357 + } 358 + 359 + void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) 360 + { 361 + int i; 362 + 363 + for (i=0; i<2000000; i++) { 364 + if ((INREG(RBBM_STATUS) & 0x7f) >= entries) 365 + return; 366 + udelay(1); 367 + } 368 + printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); 369 + } 370 + 371 + void radeon_engine_flush(struct radeonfb_info *rinfo) 372 + { 373 + int i; 374 + 375 + /* Initiate flush */ 376 + OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, 377 + ~RB2D_DC_FLUSH_ALL); 378 + 379 + /* Ensure FIFO is empty, ie, make sure the flush commands 380 + * has reached the cache 381 + */ 382 + _radeon_fifo_wait(rinfo, 64); 383 + 384 + /* Wait for the flush to complete */ 385 + for (i=0; i < 2000000; i++) { 386 + if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) 387 + return; 388 + udelay(1); 389 + } 390 + printk(KERN_ERR "radeonfb: Flush Timeout !\n"); 391 + } 392 + 393 + void _radeon_engine_idle(struct radeonfb_info *rinfo) 394 + { 395 + int i; 396 + 397 + /* ensure FIFO is empty before waiting for idle */ 398 + _radeon_fifo_wait(rinfo, 64); 399 + 400 + for (i=0; i<2000000; i++) { 401 + if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { 402 + radeon_engine_flush(rinfo); 403 + return; 404 + } 405 + udelay(1); 406 + } 407 + printk(KERN_ERR "radeonfb: Idle Timeout !\n"); 408 + } 409 + 410 + 282 411 283 412 static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) 284 413 {
+15 -129
drivers/video/fbdev/aty/radeonfb.h
··· 370 370 * IO macros 371 371 */ 372 372 373 - /* Note about this function: we have some rare cases where we must not schedule, 374 - * this typically happen with our special "wake up early" hook which allows us to 375 - * wake up the graphic chip (and thus get the console back) before everything else 376 - * on some machines that support that mechanism. At this point, interrupts are off 377 - * and scheduling is not permitted 378 - */ 379 - static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) 380 - { 381 - if (rinfo->no_schedule || oops_in_progress) 382 - mdelay(ms); 383 - else 384 - msleep(ms); 385 - } 386 - 373 + void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms); 387 374 388 375 #define INREG8(addr) readb((rinfo->mmio_base)+addr) 389 376 #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) ··· 379 392 #define INREG(addr) readl((rinfo->mmio_base)+addr) 380 393 #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) 381 394 382 - static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, 383 - u32 val, u32 mask) 384 - { 385 - unsigned long flags; 386 - unsigned int tmp; 387 - 388 - spin_lock_irqsave(&rinfo->reg_lock, flags); 389 - tmp = INREG(addr); 390 - tmp &= (mask); 391 - tmp |= (val); 392 - OUTREG(addr, tmp); 393 - spin_unlock_irqrestore(&rinfo->reg_lock, flags); 394 - } 395 + void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask); 395 396 396 397 #define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask) 397 398 ··· 400 425 * possible exception to this rule is the call to unblank(), which may 401 426 * be done at irq time if an oops is in progress. 402 427 */ 428 + void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo); 403 429 static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo) 404 430 { 405 - if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)) 406 - return; 407 - 408 - (void)INREG(CLOCK_CNTL_DATA); 409 - (void)INREG(CRTC_GEN_CNTL); 431 + if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS) 432 + radeon_pll_errata_after_index_slow(rinfo); 410 433 } 411 434 435 + void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo); 412 436 static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo) 413 437 { 414 - if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) { 415 - /* we can't deal with posted writes here ... */ 416 - _radeon_msleep(rinfo, 5); 417 - } 418 - if (rinfo->errata & CHIP_ERRATA_R300_CG) { 419 - u32 save, tmp; 420 - save = INREG(CLOCK_CNTL_INDEX); 421 - tmp = save & ~(0x3f | PLL_WR_EN); 422 - OUTREG(CLOCK_CNTL_INDEX, tmp); 423 - tmp = INREG(CLOCK_CNTL_DATA); 424 - OUTREG(CLOCK_CNTL_INDEX, save); 425 - } 438 + if (rinfo->errata & (CHIP_ERRATA_PLL_DELAY|CHIP_ERRATA_R300_CG)) 439 + radeon_pll_errata_after_data_slow(rinfo); 426 440 } 427 441 428 - static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) 429 - { 430 - u32 data; 431 - 432 - OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); 433 - radeon_pll_errata_after_index(rinfo); 434 - data = INREG(CLOCK_CNTL_DATA); 435 - radeon_pll_errata_after_data(rinfo); 436 - return data; 437 - } 438 - 439 - static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, 440 - u32 val) 441 - { 442 - 443 - OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); 444 - radeon_pll_errata_after_index(rinfo); 445 - OUTREG(CLOCK_CNTL_DATA, val); 446 - radeon_pll_errata_after_data(rinfo); 447 - } 448 - 449 - 450 - static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, 451 - u32 val, u32 mask) 452 - { 453 - unsigned int tmp; 454 - 455 - tmp = __INPLL(rinfo, index); 456 - tmp &= (mask); 457 - tmp |= (val); 458 - __OUTPLL(rinfo, index, tmp); 459 - } 460 - 442 + u32 __INPLL(struct radeonfb_info *rinfo, u32 addr); 443 + void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val); 444 + void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, 445 + u32 val, u32 mask); 461 446 462 447 #define INPLL(addr) __INPLL(rinfo, addr) 463 448 #define OUTPLL(index, val) __OUTPLL(rinfo, index, val) ··· 467 532 * 2D Engine helper routines 468 533 */ 469 534 470 - static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) 471 - { 472 - int i; 473 - 474 - for (i=0; i<2000000; i++) { 475 - if ((INREG(RBBM_STATUS) & 0x7f) >= entries) 476 - return; 477 - udelay(1); 478 - } 479 - printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); 480 - } 481 - 482 - static inline void radeon_engine_flush (struct radeonfb_info *rinfo) 483 - { 484 - int i; 485 - 486 - /* Initiate flush */ 487 - OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, 488 - ~RB2D_DC_FLUSH_ALL); 489 - 490 - /* Ensure FIFO is empty, ie, make sure the flush commands 491 - * has reached the cache 492 - */ 493 - _radeon_fifo_wait (rinfo, 64); 494 - 495 - /* Wait for the flush to complete */ 496 - for (i=0; i < 2000000; i++) { 497 - if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) 498 - return; 499 - udelay(1); 500 - } 501 - printk(KERN_ERR "radeonfb: Flush Timeout !\n"); 502 - } 503 - 504 - 505 - static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) 506 - { 507 - int i; 508 - 509 - /* ensure FIFO is empty before waiting for idle */ 510 - _radeon_fifo_wait (rinfo, 64); 511 - 512 - for (i=0; i<2000000; i++) { 513 - if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { 514 - radeon_engine_flush (rinfo); 515 - return; 516 - } 517 - udelay(1); 518 - } 519 - printk(KERN_ERR "radeonfb: Idle Timeout !\n"); 520 - } 521 - 535 + void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries); 536 + void radeon_engine_flush(struct radeonfb_info *rinfo); 537 + void _radeon_engine_idle(struct radeonfb_info *rinfo); 522 538 523 539 #define radeon_engine_idle() _radeon_engine_idle(rinfo) 524 540 #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)