diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-25 17:26:13 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-25 17:26:13 -0800 |
| commit | e78df3d0a4a20b04bbbf81c29be0c9519da43380 (patch) | |
| tree | 26dfe5b57e9cc2d3b3bd823fb869507dab8b70ac | |
| parent | bc0b0607c7d024d6c4b75d69b3c948344a51065f (diff) | |
| parent | 49744e17ed83e7e92d04839cb89370d5a8d1c246 (diff) | |
Merge bk://bk.arm.linux.org.uk/linux-2.5-rmk
into home.transmeta.com:/home/torvalds/v2.5/linux
| -rw-r--r-- | arch/arm/kernel/apm.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/armksyms.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 8 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-common.S | 1 | ||||
| -rw-r--r-- | arch/arm/lib/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/lib/div64.S | 42 | ||||
| -rw-r--r-- | arch/arm/mach-footbridge/dc21285.c | 96 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/assabet.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/cpu-sa1110.c | 2 | ||||
| -rw-r--r-- | arch/arm/tools/mach-types | 10 | ||||
| -rw-r--r-- | drivers/mtd/maps/epxa10db-flash.c | 7 | ||||
| -rw-r--r-- | drivers/serial/21285.c | 3 | ||||
| -rw-r--r-- | drivers/video/Makefile | 2 | ||||
| -rw-r--r-- | drivers/video/cyber2000fb.c | 542 | ||||
| -rw-r--r-- | drivers/video/fbmem.c | 4 | ||||
| -rw-r--r-- | include/asm-arm/div64.h | 10 | ||||
| -rw-r--r-- | include/asm-arm/proc-armv/pgtable.h | 7 | ||||
| -rw-r--r-- | include/asm-arm/system.h | 11 |
18 files changed, 320 insertions, 433 deletions
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 732676de268f..6a25174546a4 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -552,8 +552,6 @@ MODULE_AUTHOR("Stephen Rothwell"); MODULE_DESCRIPTION("Advanced Power Management"); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; - #ifndef MODULE static int __init apm_setup(char *str) { diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index d2f8e4ad8bae..95433bb565f6 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -69,6 +69,7 @@ extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void abort(void); +extern void do_div64(void); extern void ret_from_exception(void); extern void fpundefinstr(void); @@ -234,6 +235,7 @@ EXPORT_SYMBOL_NOVERS(__umoddi3); EXPORT_SYMBOL_NOVERS(__udivmoddi4); EXPORT_SYMBOL_NOVERS(__udivsi3); EXPORT_SYMBOL_NOVERS(__umodsi3); +EXPORT_SYMBOL_NOVERS(do_div64); /* bitops */ EXPORT_SYMBOL(_set_bit_le); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 0268780931bd..ec13c1d9110a 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -997,11 +997,11 @@ ENTRY(fp_enter) * previous and next are guaranteed not to be the same. */ ENTRY(__switch_to) - add ip, r0, #TI_CPU_SAVE - ldr r2, [r1, #TI_CPU_DOMAIN]! + add ip, r1, #TI_CPU_SAVE + ldr r3, [r2, #TI_CPU_DOMAIN]! stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack - mcr p15, 0, r2, c3, c0 @ Set domain register - ldmib r1, {r4 - sl, fp, sp, pc} @ Load all regs saved previously + mcr p15, 0, r3, c3, c0, 0 @ Set domain register + ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously __INIT /* diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 6124e11adb3e..11cc623c3726 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -75,7 +75,6 @@ no_work_pending: * This is how we return from a fork. */ ENTRY(ret_from_fork) - ldr r0, [r0, #TI_TASK] bl schedule_tail get_thread_info tsk ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 04ee1aba722a..8250528e86fe 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -13,7 +13,7 @@ obj-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o + ucmpdi2.o udivdi3.o lib1funcs.o div64.o obj-m := obj-n := diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S new file mode 100644 index 000000000000..8abb07d45c62 --- /dev/null +++ b/arch/arm/lib/div64.S @@ -0,0 +1,42 @@ +#include <linux/linkage.h> + +ql .req r0 @ quotient low +qh .req r1 @ quotient high +dl .req r3 @ divisor low +dh .req r2 @ divisor high +nl .req r4 @ dividend low +nh .req r5 @ dividend high + +ENTRY(do_div64) + stmfd sp!, {r4, r5, lr} + mov nl, r0 + movs nh, r1 @ if high bits are zero + movne lr, #33 + moveq lr, #1 @ only divide low bits + moveq nh, r0 + +1: cmp nh, dh + bls 2f + add lr, lr, #1 + movs dh, dh, lsl #1 @ left justify divisor + bpl 1b + +2: movs nh, r1 + moveq dl, dh + moveq dh, #0 + movne dl, #0 + mov ql, #0 + mov qh, #0 +3: subs ip, nl, dl @ trial subtraction + sbcs ip, nh, dh + movcs nh, ip @ only update if successful + subcs nl, nl, dl @ (repeat the subtraction) + adcs ql, ql, ql @ C=1 if successful, shift into + adc qh, qh, qh @ quotient + movs dh, dh, lsr #1 @ shift base high part right + mov dl, dl, rrx @ shift base low part right + subs lr, lr, #1 + bne 3b + + mov r2, nl + ldmfd sp!, {r4, r5, pc} diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index fb0ac649543f..717e9fbb1fb6 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -25,10 +25,13 @@ #define MAX_SLOTS 21 -#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \ - PCI_STATUS_REC_MASTER_ABORT | \ - PCI_STATUS_REC_TARGET_ABORT | \ - PCI_STATUS_PARITY) << 16) +#define PCICMD_ABORT ((PCI_STATUS_REC_MASTER_ABORT| \ + PCI_STATUS_REC_TARGET_ABORT)<<16) + +#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \ + PCI_STATUS_REC_MASTER_ABORT | \ + PCI_STATUS_REC_TARGET_ABORT | \ + PCI_STATUS_PARITY) << 16) extern int setup_arm_irq(int, struct irqaction *); extern void pcibios_report_status(u_int status_mask, int warn); @@ -84,6 +87,12 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, *value = v; + v = *CSR_PCICMD; + if (v & PCICMD_ABORT) { + *CSR_PCICMD = v & (0xffff|PCICMD_ABORT); + return -1; + } + return PCIBIOS_SUCCESSFUL; } @@ -92,6 +101,7 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { unsigned long addr = dc21285_base_address(bus, devfn); + u32 v; if (addr) switch (size) { @@ -109,6 +119,12 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, break; } + v = *CSR_PCICMD; + if (v & PCICMD_ABORT) { + *CSR_PCICMD = v & (0xffff|PCICMD_ABORT); + return -1; + } + return PCIBIOS_SUCCESSFUL; } @@ -148,16 +164,16 @@ static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) cmd = cmd & 0xffff; if (status & PCI_STATUS_REC_MASTER_ABORT) { - printk(KERN_DEBUG "PCI: master abort: "); - pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT, 1); - printk("\n"); - + printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", + instruction_pointer(regs)); cmd |= PCI_STATUS_REC_MASTER_ABORT << 16; } if (status & PCI_STATUS_REC_TARGET_ABORT) { printk(KERN_DEBUG "PCI: target abort: "); - pcibios_report_status(PCI_STATUS_SIG_TARGET_ABORT, 1); + pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT, 1); printk("\n"); cmd |= PCI_STATUS_REC_TARGET_ABORT << 16; @@ -289,6 +305,38 @@ void __init dc21285_preinit(void) "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ? "central function" : "addin"); + if (footbridge_cfn_mode()) { + /* + * Clear any existing errors - we aren't + * interested in historical data... + */ + *CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) | + SA110_CNTL_RXSERR; + *CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS; + } + + init_timer(&serr_timer); + init_timer(&perr_timer); + + serr_timer.data = IRQ_PCI_SERR; + serr_timer.function = dc21285_enable_error; + perr_timer.data = IRQ_PCI_PERR; + perr_timer.function = dc21285_enable_error; + + /* + * We don't care if these fail. + */ + request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT, + "PCI system error", &serr_timer); + request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT, + "PCI parity error", &perr_timer); + request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, + "PCI abort", NULL); + request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, + "Discard timer", NULL); + request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, + "PCI data parity", NULL); + if (cfn_mode) { static struct resource csrio; @@ -324,35 +372,5 @@ void __init dc21285_preinit(void) void __init dc21285_postinit(void) { - if (footbridge_cfn_mode()) { - /* - * Clear any existing errors - we aren't - * interested in historical data... - */ - *CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) | - SA110_CNTL_RXSERR; - *CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS; - } - - /* - * Initialise PCI error IRQ after we've finished probing - */ - request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, "PCI abort", NULL); - request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, "Discard timer", NULL); - request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, "PCI data parity", NULL); - - init_timer(&serr_timer); - init_timer(&perr_timer); - - serr_timer.data = IRQ_PCI_SERR; - serr_timer.function = dc21285_enable_error; - perr_timer.data = IRQ_PCI_PERR; - perr_timer.function = dc21285_enable_error; - - request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT, - "PCI system error", &serr_timer); - request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT, - "PCI parity error", &perr_timer); - register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0); } diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 6d775017ab7b..e57c2ccc10cd 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -117,6 +117,8 @@ static int __init assabet_init(void) PGSR = 0; PCFR = 0; PSDR = 0; + PPDR |= PPC_TXD3 | PPC_TXD1; + PPSR |= PPC_TXD3 | PPC_TXD1; sa1100fb_lcd_power = assabet_lcd_power; sa1100fb_backlight_power = assabet_backlight_power; diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index d0e64dae380d..cf7686ddd90e 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -234,6 +234,8 @@ static int sa1110_target(struct cpufreq_policy *policy, (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min)) ppcr--; break; + default: + return -EINVAL; } freqs.old = sa11x0_getspeed(); diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index ff845a01f596..99ce70b534c9 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Wed Mar 5 22:11:59 2003 +# Last update: Tue Mar 25 16:34:29 2003 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -305,3 +305,11 @@ meg03 ARCH_MEG03 MEG03 293 pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294 nwsc ARCH_NWSC NWSC 295 nwlarm ARCH_NWLARM NWLARM 296 +ixp425_mguard ARCH_IXP425_MGUARD IXP425_MGUARD 297 +pxa_netdcu4 ARCH_PXA_NETDCU4 PXA_NETDCU4 298 +ixdp2401 ARCH_IXDP2401 IXDP2401 299 +ixdp2801 ARCH_IXDP2801 IXDP2801 300 +zodiac ARCH_ZODIAC ZODIAC 301 +armmodul ARCH_ARMMODUL ARMMODUL 302 +ketop SA1100_KETOP KETOP 303 +av7200 ARCH_AV7200 AV7200 304 diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c index fc4f0e92a06c..c3f9580c5b2f 100644 --- a/drivers/mtd/maps/epxa10db-flash.c +++ b/drivers/mtd/maps/epxa10db-flash.c @@ -199,12 +199,12 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa printk("Using default partitions for %s\n",BOARD_NAME); npartitions=1; - parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL); - memzero(parts,npartitions*sizeof(*parts)+strlen(name)); + parts = kmalloc(npartitions*sizeof(*parts)+strlen(name)+1, GFP_KERNEL); if (!parts) { ret = -ENOMEM; goto out; } + memzero(parts,npartitions*sizeof(*parts)+strlen(name)); i=0; names = (char *)&parts[npartitions]; parts[i].name = names; @@ -218,10 +218,11 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa parts[i].size = FLASH_SIZE-0x00180000; parts[i].offset = 0x00180000; #endif + ret = npartitions; out: *pparts = parts; - return npartitions; + return ret; } diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 119e9a816e8a..81f9814e113c 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -501,10 +501,11 @@ static struct console serial21285_console = .index = -1, }; -static void __init rs285_console_init(void) +static int __init rs285_console_init(void) { serial21285_setup_ports(); register_console(&serial21285_console); + return 0; } console_initcall(rs285_console_init); diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 8f86a41c8c9e..c99f54958274 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -31,7 +31,7 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbim obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CYBER) += cyberfb.o -obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o +obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o cfbimgblt.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 0d88606bb6d0..9f9b037cc66d 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -55,12 +55,6 @@ #include <asm/system.h> #include <asm/uaccess.h> -#include <video/fbcon.h> -#include <video/fbcon-cfb8.h> -#include <video/fbcon-cfb16.h> -#include <video/fbcon-cfb24.h> -#include <video/fbcon-cfb32.h> - #include "cyber2000fb.h" struct cfb_info { @@ -147,167 +141,114 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb) /* * Hardware Cyber2000 Acceleration */ -static void cyber2000_accel_wait(struct cfb_info *cfb) -{ - int count = 100000; - - while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) { - if (!count--) { - debug_printf("accel_wait timed out\n"); - cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); - return; - } - udelay(1); - } -} - -static void cyber2000_accel_setup(struct display *display) -{ - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; - - cfb->dispsw->setup(display); -} - static void -cyber2000_accel_bmove(struct display *display, int sy, int sx, int dy, int dx, - int height, int width) +cyber2000fb_fillrect(struct fb_info *info, struct fb_fillrect *rect) { - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; - struct fb_var_screeninfo *var = &display->var; - u_long src, dst; - u_int fh, fw, cmd = CO_CMD_L_PATTERN_FGCOL; - - fw = fontwidth(display); - sx *= fw; - dx *= fw; - width *= fw; - width -= 1; - - if (sx < dx) { - sx += width; - dx += width; - cmd |= CO_CMD_L_INC_LEFT; - } - - fh = fontheight(display); - sy *= fh; - dy *= fh; - height *= fh; - height -= 1; + struct cfb_info *cfb = (struct cfb_info *)info; + unsigned long dst, col; - if (sy < dy) { - sy += height; - dy += height; - cmd |= CO_CMD_L_INC_UP; + if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { + cfb_fillrect(info, rect); + return; } - src = sx + sy * var->xres_virtual; - dst = dx + dy * var->xres_virtual; + cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); + cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb); + cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb); - cyber2000_accel_wait(cfb); - cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); - cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); - cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb); + col = rect->color; + if (cfb->fb.var.bits_per_pixel > 8) + col = ((u32 *)cfb->fb.pseudo_palette)[col]; + cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb); - if (var->bits_per_pixel == 24) { + dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual; + if (cfb->fb.var.bits_per_pixel == 24) { cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); dst *= 3; - src *= 3; } - cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); - cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb); - cyber2000fb_writew(CO_CMD_H_FGSRCMAP|CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); + cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb); + cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); } static void -cyber2000_accel_clear(struct vc_data *conp, struct display *display, int sy, - int sx, int height, int width) +cyber2000fb_copyarea(struct fb_info *info, struct fb_copyarea *region) { - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; - struct fb_var_screeninfo *var = &display->var; - u_long dst; - u_int fw, fh; - u32 bgx = attr_bgcol_ec(display, conp); + struct cfb_info *cfb = (struct cfb_info *)info; + unsigned int cmd = CO_CMD_L_PATTERN_FGCOL; + unsigned long src, dst; + + if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { + cfb_copyarea(info, region); + return; + } - fw = fontwidth(display); - fh = fontheight(display); + if (region->sx < region->dx) { + region->sx += region->width - 1; + region->dx += region->width - 1; + cmd |= CO_CMD_L_INC_LEFT; + } - dst = sx * fw + sy * var->xres_virtual * fh; - width = width * fw - 1; - height = height * fh - 1; + if (region->sy < region->dy) { + region->sy += region->height - 1; + region->dy += region->height - 1; + cmd |= CO_CMD_L_INC_UP; + } - cyber2000_accel_wait(cfb); - cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); - cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); - cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb); + cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); + cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb); + cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb); - if (var->bits_per_pixel == 24) { + src = region->sx + region->sy * cfb->fb.var.xres_virtual; + dst = region->dx + region->dy * cfb->fb.var.xres_virtual; + if (cfb->fb.var.bits_per_pixel == 24) { cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); + src *= 3; dst *= 3; } - - if (var->bits_per_pixel == 16) - bgx = ((u16 *)display->dispsw_data)[bgx]; - else if (var->bits_per_pixel >= 24) - bgx = ((u32 *)display->dispsw_data)[bgx]; - - cyber2000fb_writel(bgx, CO_REG_FGCOLOUR, cfb); + cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); - cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); - cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb); - cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); -} - -static void -cyber2000_accel_putc(struct vc_data *conp, struct display *display, int c, - int yy, int xx) -{ - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; - - cyber2000_accel_wait(cfb); - cfb->dispsw->putc(conp, display, c, yy, xx); + cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); + cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb); + cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER, + CO_REG_CMD_H, cfb); } static void -cyber2000_accel_putcs(struct vc_data *conp, struct display *display, - const unsigned short *s, int count, int yy, int xx) +cyber2000fb_imageblit(struct fb_info *info, struct fb_image *image) { - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; + struct cfb_info *cfb = (struct cfb_info *)info; - cyber2000_accel_wait(cfb); - cfb->dispsw->putcs(conp, display, s, count, yy, xx); +// if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { + cfb_imageblit(info, image); + return; +// } } -static void cyber2000_accel_revc(struct display *display, int xx, int yy) +static int cyber2000fb_sync(struct fb_info *info) { - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; - - cyber2000_accel_wait(cfb); - cfb->dispsw->revc(display, xx, yy); -} + struct cfb_info *cfb = (struct cfb_info *)info; + int count = 100000; -static void -cyber2000_accel_clear_margins(struct vc_data *conp, struct display *display, - int bottom_only) -{ - struct cfb_info *cfb = (struct cfb_info *)display->fb_info; + if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) + return 0; - cfb->dispsw->clear_margins(conp, display, bottom_only); + while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) { + if (!count--) { + debug_printf("accel_wait timed out\n"); + cyber2000fb_writeb(0, CO_REG_CONTROL, cfb); + break; + } + udelay(1); + } + return 0; } -static struct display_switch fbcon_cyber_accel = { - .setup = cyber2000_accel_setup, - .bmove = cyber2000_accel_bmove, - .clear = cyber2000_accel_clear, - .putc = cyber2000_accel_putc, - .putcs = cyber2000_accel_putcs, - .revc = cyber2000_accel_revc, - .clear_margins = cyber2000_accel_clear_margins, - .fontwidthmask = FONTWIDTH(8)|FONTWIDTH(16) -}; +/* + * =========================================================================== + */ static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf) { @@ -324,7 +265,7 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { struct cfb_info *cfb = (struct cfb_info *)info; - struct fb_var_screeninfo *var = &cfb->display->var; + struct fb_var_screeninfo *var = &cfb->fb.var; u32 pseudo_val; int ret = 1; @@ -332,7 +273,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, default: return 1; -#ifdef FBCON_HAS_CFB8 /* * Pseudocolour: * 8 8 @@ -359,7 +299,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, cyber2000fb_writeb(green, 0x3c9, cfb); cyber2000fb_writeb(blue, 0x3c9, cfb); return 0; -#endif /* * Direct colour: @@ -455,13 +394,8 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, /* * Now set our pseudo palette for the CFB16/24/32 drivers. */ - if (regno < 16) { - if (var->bits_per_pixel == 16) - ((u16 *)cfb->fb.pseudo_palette)[regno] = pseudo_val; - else - ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val; - ret = 0; - } + if (regno < 16) + ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val; return ret; } @@ -800,20 +734,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, } /* - * Decode the info required for the hardware. - * This involves the PLL parameters for the dot clock, - * CRTC registers, and accelerator settings. + * Set the User Defined Part of the Display */ static int -cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, - struct par_info *hw) +cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { + struct cfb_info *cfb = (struct cfb_info *)info; + struct par_info hw; unsigned int mem; int err; - hw->width = var->xres_virtual; - hw->ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT; - var->transp.msb_right = 0; var->red.msb_right = 0; var->green.msb_right = 0; @@ -822,10 +752,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, switch (var->bits_per_pixel) { #ifdef FBCON_HAS_CFB8 case 8: /* PSEUDOCOLOUR, 256 */ - hw->co_pixfmt = CO_PIXFMT_8BPP; - hw->pitch = hw->width >> 3; - hw->extseqmisc = EXT_SEQ_MISC_8; - var->transp.offset = 0; var->transp.length = 0; var->red.offset = 0; @@ -838,13 +764,8 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, #endif #ifdef FBCON_HAS_CFB16 case 16:/* DIRECTCOLOUR, 64k or 32k */ - hw->co_pixfmt = CO_PIXFMT_16BPP; - hw->pitch = hw->width >> 2; - switch (var->green.length) { case 6: /* RGB565, 64k */ - hw->extseqmisc = EXT_SEQ_MISC_16_RGB565; - var->transp.offset = 0; var->transp.length = 0; var->red.offset = 11; @@ -857,8 +778,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, default: case 5: /* RGB555, 32k */ - hw->extseqmisc = EXT_SEQ_MISC_16_RGB555; - var->transp.offset = 0; var->transp.length = 0; var->red.offset = 10; @@ -870,8 +789,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, break; case 4: /* RGB444, 4k + transparency? */ - hw->extseqmisc = EXT_SEQ_MISC_16_RGB444; - var->transp.offset = 12; var->transp.length = 4; var->red.offset = 8; @@ -886,12 +803,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, #endif #ifdef FBCON_HAS_CFB24 case 24:/* TRUECOLOUR, 16m */ - hw->co_pixfmt = CO_PIXFMT_24BPP; - hw->width *= 3; - hw->pitch = hw->width >> 3; - hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); - hw->extseqmisc = EXT_SEQ_MISC_24_RGB888; - var->transp.offset = 0; var->transp.length = 0; var->red.offset = 16; @@ -904,11 +815,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, #endif #ifdef FBCON_HAS_CFB32 case 32:/* TRUECOLOUR, 16m */ - hw->co_pixfmt = CO_PIXFMT_32BPP; - hw->pitch = hw->width >> 1; - hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); - hw->extseqmisc = EXT_SEQ_MISC_32; - var->transp.offset = 24; var->transp.length = 8; var->red.offset = 16; @@ -933,127 +839,107 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, if (var->xres > var->xres_virtual) var->xres = var->xres_virtual; - err = cyber2000fb_decode_clock(hw, cfb, var); + err = cyber2000fb_decode_clock(&hw, cfb, var); if (err) return err; - err = cyber2000fb_decode_crtc(hw, cfb, var); + err = cyber2000fb_decode_crtc(&hw, cfb, var); if (err) return err; - hw->width -= 1; - hw->fetch = hw->pitch; - if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT)) - hw->fetch <<= 1; - hw->fetch += 1; - return 0; } -/* - * Set the User Defined Part of the Display - */ -static int -cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) +static int cyber2000fb_set_par(struct fb_info *info) { struct cfb_info *cfb = (struct cfb_info *)info; - struct display *display; + struct fb_var_screeninfo *var = &cfb->fb.var; struct par_info hw; - int err, chgvar; - - /* - * CONUPDATE and SMOOTH_XPAN are equal. However, - * SMOOTH_XPAN is only used internally by fbcon. - */ - if (var->vmode & FB_VMODE_CONUPDATE) { - var->vmode |= FB_VMODE_YWRAP; - var->xoffset = cfb->display->var.xoffset; - var->yoffset = cfb->display->var.yoffset; - } - - err = cyber2000fb_decode_var(var, cfb, &hw); - if (err) - return err; - - if (var->activate & FB_ACTIVATE_TEST) - return 0; + unsigned int mem; - if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) - return -EINVAL; + hw.width = var->xres_virtual; + hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT; - if (con < 0) { - display = cfb->fb.disp; - } else { - display = fb_display + con; - } + switch (var->bits_per_pixel) { + case 8: + hw.co_pixfmt = CO_PIXFMT_8BPP; + hw.pitch = hw.width >> 3; + hw.extseqmisc = EXT_SEQ_MISC_8; + break; - chgvar = cfb->fb.var.xres != var->xres || - cfb->fb.var.yres != var->yres || - cfb->fb.var.xres_virtual != var->xres_virtual || - cfb->fb.var.yres_virtual != var->yres_virtual || - cfb->fb.var.bits_per_pixel != var->bits_per_pixel; + case 16: + hw.co_pixfmt = CO_PIXFMT_16BPP; + hw.pitch = hw.width >> 2; - if (memcmp(&cfb->fb.var.red, &var->red, sizeof(var->red)) || - memcmp(&cfb->fb.var.green, &var->green, sizeof(var->green)) || - memcmp(&cfb->fb.var.blue, &var->blue, sizeof(var->blue))) - chgvar = 1; + switch (var->green.length) { + case 6: /* RGB565, 64k */ + hw.extseqmisc = EXT_SEQ_MISC_16_RGB565; + break; + case 5: /* RGB555, 32k */ + hw.extseqmisc = EXT_SEQ_MISC_16_RGB555; + break; + case 4: /* RGB444, 4k + transparency? */ + hw.extseqmisc = EXT_SEQ_MISC_16_RGB444; + break; + default: + BUG(); + } + case 24:/* TRUECOLOUR, 16m */ + hw.co_pixfmt = CO_PIXFMT_24BPP; + hw.width *= 3; + hw.pitch = hw.width >> 3; + hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); + hw.extseqmisc = EXT_SEQ_MISC_24_RGB888; + break; - if (con >= 0 && chgvar == 0) - return 0; + case 32:/* TRUECOLOUR, 16m */ + hw.co_pixfmt = CO_PIXFMT_32BPP; + hw.pitch = hw.width >> 1; + hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN); + hw.extseqmisc = EXT_SEQ_MISC_32; + break; - if (con < 0) - chgvar = 0; + default: + BUG(); + } /* - * If we are setting all the virtual consoles, also set the - * defaults used to create new consoles. + * Sigh, this is absolutely disgusting, but caused by + * the way the fbcon developers want to separate out + * the "checking" and the "setting" of the video mode. + * + * If the mode is not suitable for the hardware here, + * we can't prevent it being set by returning an error. + * + * In theory, since NetWinders contain just one VGA card, + * we should never end up hitting this problem. */ - err = var->activate; - var->activate = FB_ACTIVATE_NOW; - if (err & FB_ACTIVATE_ALL) - cfb->fb.disp->var = *var; + BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0); + BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0); + + hw.width -= 1; + hw.fetch = hw.pitch; + if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT)) + hw.fetch <<= 1; + hw.fetch += 1; - cfb->fb.var = *var; cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; - switch (var->bits_per_pixel) { -#ifdef FBCON_HAS_CFB8 - case 8: /* PSEUDOCOLOUR, 256 */ - cfb->dispsw = &fbcon_cfb8; - display->dispsw_data = NULL; - break; -#endif -#ifdef FBCON_HAS_CFB16 - case 16:/* DIRECTCOLOUR */ - cfb->dispsw = &fbcon_cfb16; - display->dispsw_data = cfb->fb.pseudo_palette; - break; -#endif -#ifdef FBCON_HAS_CFB24 - case 24:/* TRUECOLOUR, 16m */ - cfb->dispsw = &fbcon_cfb24; - display->dispsw_data = cfb->fb.pseudo_palette; - break; -#endif -#ifdef FBCON_HAS_CFB32 - case 32:/* TRUECOLOUR, 16m */ - cfb->dispsw = &fbcon_cfb32; - display->dispsw_data = cfb->fb.pseudo_palette; - break; -#endif - default:/* in theory this should never happen */ - printk(KERN_WARNING "%s: no support for %dbpp\n", - cfb->fb.fix.id, var->bits_per_pixel); - cfb->dispsw = &fbcon_dummy; - break; - } + /* + * Same here - if the size of the video mode exceeds the + * available RAM, we can't prevent this mode being set. + * + * In theory, since NetWinders contain just one VGA card, + * we should never end up hitting this problem. + */ + mem = cfb->fb.fix.line_length * var->yres_virtual; + BUG_ON(mem > cfb->fb.fix.smem_len); /* - * 8bpp displays are always pseudo colour. - * 16bpp and above are direct colour or true colour, depending - * on whether the RAMDAC palettes are bypassed. (Direct colour - * has palettes, true colour does not.) + * 8bpp displays are always pseudo colour. 16bpp and above + * are direct colour or true colour, depending on whether + * the RAMDAC palettes are bypassed. (Direct colour has + * palettes, true colour does not.) */ if (var->bits_per_pixel == 8) cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -1062,20 +948,8 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, else cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR; - if (var->accel_flags & FB_ACCELF_TEXT && cfb->dispsw != &fbcon_dummy) - display->dispsw = &fbcon_cyber_accel; - else - display->dispsw = cfb->dispsw; - - display->can_soft_blank = 1; - display->inverse = 0; - cyber2000fb_set_timing(cfb, &hw); cyber2000fb_update_start(cfb, var); - fb_set_cmap(&cfb->fb.cmap, 1, &cfb->fb); - - if (chgvar && cfb->fb.changevar) - cfb->fb.changevar(con); return 0; } @@ -1085,85 +959,22 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, * Pan or Wrap the Display */ static int -cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con, - struct fb_info *info) +cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { struct cfb_info *cfb = (struct cfb_info *)info; - u_int y_bottom; - - y_bottom = var->yoffset; - - if (!(var->vmode & FB_VMODE_YWRAP)) - y_bottom += var->yres; - - if (var->xoffset > (var->xres_virtual - var->xres)) - return -EINVAL; - if (y_bottom > cfb->display->var.yres_virtual) - return -EINVAL; if (cyber2000fb_update_start(cfb, var)) return -EINVAL; - cfb->display->var.xoffset = var->xoffset; - cfb->display->var.yoffset = var->yoffset; + cfb->fb.var.xoffset = var->xoffset; + cfb->fb.var.yoffset = var->yoffset; + if (var->vmode & FB_VMODE_YWRAP) { - cfb->display->var.vmode |= FB_VMODE_YWRAP; + cfb->fb.var.vmode |= FB_VMODE_YWRAP; } else { - cfb->display->var.vmode &= ~FB_VMODE_YWRAP; - } - - return 0; -} - - -/* - * Update the `var' structure (called by fbcon.c) - * - * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. - * Since it's called by a kernel driver, no range checking is done. - */ -static int cyber2000fb_updatevar(int con, struct fb_info *info) -{ - struct cfb_info *cfb = (struct cfb_info *)info; - - return cyber2000fb_update_start(cfb, &fb_display[con].var); -} - -static int cyber2000fb_switch(int con, struct fb_info *info) -{ - struct cfb_info *cfb = (struct cfb_info *)info; - struct display *display = cfb->display; - struct fb_cmap *cmap; - - if (display) { - /* - * Save the old colormap and video mode. - */ - if (display->cmap.len) - fb_copy_cmap(&cfb->fb.cmap, &display->cmap, 0); + cfb->fb.var.vmode &= ~FB_VMODE_YWRAP; } - cfb->display = display = fb_display + con; - - /* - * Install the new colormap and change the video mode. By default, - * fbcon sets all the colormaps and video modes to the default - * values at bootup. - * - * Really, we want to set the colourmap size depending on the - * depth of the new video mode. For now, we leave it at its - * default 256 entry. - */ - if (display->cmap.len) - cmap = &display->cmap; - else - cmap = fb_default_cmap(1 << display->var.bits_per_pixel); - - fb_copy_cmap(cmap, &cfb->fb.cmap, 0); - - display->var.activate = FB_ACTIVATE_NOW; - cyber2000fb_set_var(&display->var, con, &cfb->fb); - return 0; } @@ -1243,12 +1054,16 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) static struct fb_ops cyber2000fb_ops = { .owner = THIS_MODULE, - .fb_set_var = cyber2000fb_set_var, - .fb_get_cmap = gen_get_cmap, - .fb_set_cmap = gen_set_cmap, + .fb_check_var = cyber2000fb_check_var, + .fb_set_par = cyber2000fb_set_par, .fb_setcolreg = cyber2000fb_setcolreg, - .fb_pan_display = cyber2000fb_pan_display, .fb_blank = cyber2000fb_blank, + .fb_pan_display = cyber2000fb_pan_display, + .fb_fillrect = cyber2000fb_fillrect, + .fb_copyarea = cyber2000fb_copyarea, + .fb_imageblit = cyber2000fb_imageblit, + .fb_cursor = soft_cursor, + .fb_sync = cyber2000fb_sync, }; /* @@ -1295,7 +1110,7 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb) void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) { - memcpy(var, &cfb->display->var, sizeof(struct fb_var_screeninfo)); + memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo)); } /* @@ -1313,8 +1128,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) info->info = int_cfb_info; strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name)); - - MOD_INC_USE_COUNT; } return int_cfb_info != NULL; @@ -1325,7 +1138,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) */ void cyber2000fb_detach(int idx) { - MOD_DEC_USE_COUNT; } EXPORT_SYMBOL(cyber2000fb_attach); @@ -1411,13 +1223,13 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) { struct cfb_info *cfb; - cfb = kmalloc(sizeof(struct cfb_info) + sizeof(struct display) + + cfb = kmalloc(sizeof(struct cfb_info) + sizeof(u32) * 16, GFP_KERNEL); if (!cfb) return NULL; - memset(cfb, 0, sizeof(struct cfb_info) + sizeof(struct display)); + memset(cfb, 0, sizeof(struct cfb_info)); cfb->id = id; @@ -1467,17 +1279,10 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) cfb->fb.var.width = -1; cfb->fb.var.accel_flags = FB_ACCELF_TEXT; - strcpy(cfb->fb.modename, cfb->fb.fix.id); - strcpy(cfb->fb.fontname, default_font); - cfb->fb.fbops = &cyber2000fb_ops; - cfb->fb.changevar = NULL; - cfb->fb.switch_con = cyber2000fb_switch; - cfb->fb.updatevar = cyber2000fb_updatevar; cfb->fb.flags = FBINFO_FLAG_DEFAULT; cfb->fb.node = NODEV; - cfb->fb.disp = (struct display *)(cfb + 1); - cfb->fb.pseudo_palette = (void *)(cfb->fb.disp + 1); + cfb->fb.pseudo_palette = (void *)(cfb + 1); fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); @@ -1575,7 +1380,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) if (cfb->fb.var.yres_virtual < cfb->fb.var.yres) cfb->fb.var.yres_virtual = cfb->fb.var.yres; - cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb); +// fb_set_var(&cfb->fb.var, -1, &cfb->fb); /* * Calculate the hsync and vsync frequencies. Note that @@ -1614,8 +1419,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb) * Restore the old video mode and the palette. * We also need to tell fbcon to redraw the console. */ - cfb->fb.var.activate = FB_ACTIVATE_NOW; - cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb); + cyber2000fb_set_par(&cfb->fb); } #ifdef CONFIG_ARCH_SHARK diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 36542e2968e0..7fdbb284d303 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1111,13 +1111,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) #elif defined(__mips__) pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; -#elif defined(__arm__) - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #elif defined(__sh__) pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE; #elif defined(__hppa__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; -#elif defined(__ia64__) +#elif defined(__ia64__) || defined(__arm__) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); #else #warning What do we have to do here?? diff --git a/include/asm-arm/div64.h b/include/asm-arm/div64.h index 27fec4ee6aed..3e3bdb7e7b79 100644 --- a/include/asm-arm/div64.h +++ b/include/asm-arm/div64.h @@ -4,9 +4,13 @@ /* We're not 64-bit, but... */ #define do_div(n,base) \ ({ \ - int __res; \ - __res = ((unsigned long)n) % (unsigned int)base; \ - n = ((unsigned long)n) / (unsigned int)base; \ + register int __res asm("r2") = base; \ + register unsigned long long __n asm("r0") = n; \ + asm("bl do_div64" \ + : "=r" (__n), "=r" (__res) \ + : "0" (__n), "1" (__res) \ + : "r3", "ip", "lr", "cc"); \ + n = __n; \ __res; \ }) diff --git a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h index 7d53a3443c5a..53f2b3da4d16 100644 --- a/include/asm-arm/proc-armv/pgtable.h +++ b/include/asm-arm/proc-armv/pgtable.h @@ -103,6 +103,7 @@ * entries are stored 1024 bytes below. */ #define L_PTE_PRESENT (1 << 0) +#define L_PTE_FILE (1 << 1) /* only when !PRESENT */ #define L_PTE_YOUNG (1 << 1) #define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */ #define L_PTE_CACHEABLE (1 << 3) /* matches PTE */ @@ -173,6 +174,7 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd) #define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) +#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) #define PTE_BIT_FUNC(fn,op) \ static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } @@ -196,6 +198,11 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); #define pgtable_cache_init() do { } while (0) +#define pte_to_pgoff(x) (pte_val(x) >> 2) +#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) + +#define PTE_FILE_MAX_BITS 30 + #endif /* __ASSEMBLY__ */ #endif /* __ASM_PROC_PGTABLE_H */ diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 6c57031c5f27..0acb296754d0 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -65,12 +65,13 @@ extern int cpu_architecture(void); * The `mb' is to tell GCC not to cache `current' across this call. */ struct thread_info; -extern struct thread_info *__switch_to(struct thread_info *, struct thread_info *); +struct task_struct; +extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); -#define switch_to(prev,next,last) \ - do { \ - __switch_to(prev->thread_info,next->thread_info); \ - mb(); \ +#define switch_to(prev,next,last) \ + do { \ + last = __switch_to(prev,prev->thread_info,next->thread_info); \ + mb(); \ } while (0) #ifdef CONFIG_SMP |
