From 9dc5bc83b84bd66a6a5331537da86799ea5814fc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 31 Mar 2009 19:13:13 +0200 Subject: [PATCH] --- yaml --- r: 139300 b: refs/heads/master c: 5886cea45d1b230f86fd24de708b0d9f14ff88db h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/fb/00-INDEX | 2 + trunk/Documentation/fb/cyblafb/bugs | 13 + trunk/Documentation/fb/cyblafb/credits | 7 + trunk/Documentation/fb/cyblafb/documentation | 17 + trunk/Documentation/fb/cyblafb/fb.modes | 154 ++ trunk/Documentation/fb/cyblafb/performance | 79 + trunk/Documentation/fb/cyblafb/todo | 31 + trunk/Documentation/fb/cyblafb/usage | 217 +++ trunk/Documentation/fb/cyblafb/whatsnew | 29 + trunk/Documentation/fb/cyblafb/whycyblafb | 85 + .../feature-removal-schedule.txt | 12 - trunk/Documentation/filesystems/Locking | 2 +- trunk/Documentation/hwmon/lis3lv02d | 20 +- trunk/Documentation/hwmon/ltc4215 | 50 - trunk/Documentation/misc-devices/isl29003 | 62 - .../powerpc/dts-bindings/mmc-spi-slot.txt | 23 - trunk/Documentation/sysrq.txt | 5 - trunk/MAINTAINERS | 1 - trunk/arch/alpha/include/asm/machvec.h | 2 +- trunk/arch/alpha/include/asm/system.h | 547 +++++- trunk/arch/alpha/include/asm/types.h | 5 - trunk/arch/alpha/include/asm/uaccess.h | 12 +- trunk/arch/alpha/include/asm/xchg.h | 258 --- trunk/arch/alpha/kernel/err_ev6.c | 4 +- trunk/arch/alpha/kernel/err_ev7.c | 6 +- trunk/arch/alpha/kernel/err_marvel.c | 40 +- trunk/arch/alpha/kernel/err_titan.c | 28 +- trunk/arch/alpha/kernel/pci.c | 2 +- trunk/arch/alpha/kernel/pci_iommu.c | 34 +- trunk/arch/alpha/kernel/proto.h | 16 +- trunk/arch/alpha/kernel/setup.c | 2 +- trunk/arch/alpha/kernel/smc37c669.c | 4 +- trunk/arch/alpha/kernel/sys_jensen.c | 3 +- trunk/arch/alpha/kernel/sys_sable.c | 4 +- trunk/arch/alpha/kernel/traps.c | 2 +- trunk/arch/avr32/mm/fault.c | 18 + trunk/arch/ia64/hp/sim/simserial.c | 49 +- trunk/arch/ia64/kernel/time.c | 16 - .../arch/mips/include/asm/mach-bcm47xx/gpio.h | 20 +- trunk/arch/mips/mm/highmem.c | 2 - trunk/arch/parisc/kernel/time.c | 7 +- trunk/arch/powerpc/Kconfig | 3 - trunk/arch/powerpc/Kconfig.debug | 1 - trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts | 24 - trunk/arch/powerpc/include/asm/highmem.h | 2 - trunk/arch/powerpc/include/asm/suspend.h | 3 + .../arch/powerpc/platforms/83xx/mpc832x_rdb.c | 123 +- trunk/arch/powerpc/sysdev/fsl_soc.c | 109 ++ trunk/arch/powerpc/sysdev/fsl_soc.h | 7 +- trunk/arch/s390/Kconfig | 3 - trunk/arch/s390/Kconfig.debug | 1 - trunk/arch/sparc/Kconfig | 3 - trunk/arch/sparc/Kconfig.debug | 3 +- trunk/arch/sparc/mm/highmem.c | 1 - trunk/arch/um/drivers/pcap_user.h | 10 + trunk/arch/um/drivers/port.h | 10 + trunk/arch/um/drivers/ssl.h | 10 + trunk/arch/um/drivers/stdio_console.h | 10 + trunk/arch/um/drivers/ubd_kern.c | 17 +- trunk/arch/um/drivers/xterm.h | 10 + trunk/arch/um/include/asm/irq_vectors.h | 10 + trunk/arch/um/include/asm/mmu.h | 10 + trunk/arch/um/include/asm/pda.h | 10 + trunk/arch/um/include/asm/pgalloc.h | 10 + trunk/arch/um/include/asm/pgtable-3level.h | 10 + trunk/arch/um/include/shared/frame_kern.h | 10 + trunk/arch/um/include/shared/initrd.h | 10 + trunk/arch/um/include/shared/irq_kern.h | 10 + trunk/arch/um/include/shared/mem_kern.h | 10 + trunk/arch/um/include/shared/ubd_user.h | 10 + trunk/arch/um/kernel/Makefile | 6 +- trunk/arch/um/kernel/config.c.in | 18 +- trunk/arch/um/os-Linux/start_up.c | 8 +- trunk/arch/um/sys-i386/asm/archparam.h | 10 + .../arch/um/sys-i386/shared/sysdep/checksum.h | 10 + trunk/arch/um/sys-ia64/sysdep/ptrace.h | 10 + trunk/arch/um/sys-ia64/sysdep/sigcontext.h | 10 + trunk/arch/um/sys-ia64/sysdep/syscalls.h | 10 + trunk/arch/um/sys-ppc/miscthings.c | 11 + trunk/arch/um/sys-ppc/ptrace.c | 10 + trunk/arch/um/sys-ppc/ptrace_user.c | 10 + trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h | 10 + .../um/sys-ppc/shared/sysdep/sigcontext.h | 10 + .../arch/um/sys-ppc/shared/sysdep/syscalls.h | 10 + trunk/arch/um/sys-ppc/sigcontext.c | 10 + trunk/arch/um/sys-x86_64/asm/archparam.h | 10 + trunk/arch/um/sys-x86_64/asm/module.h | 10 + trunk/arch/um/sys-x86_64/mem.c | 9 + trunk/arch/x86/Kconfig | 3 - trunk/arch/x86/Kconfig.debug | 1 - trunk/arch/x86/include/asm/suspend_32.h | 24 + trunk/arch/x86/kernel/asm-offsets_32.c | 1 - trunk/arch/x86/kernel/asm-offsets_64.c | 1 - trunk/arch/x86/mm/highmem_32.c | 46 +- trunk/arch/x86/mm/iomap_32.c | 2 - trunk/arch/x86/power/cpu_32.c | 1 - trunk/arch/x86/power/cpu_64.c | 1 - trunk/arch/x86/power/hibernate_64.c | 1 - trunk/arch/xtensa/platforms/iss/console.c | 29 +- trunk/drivers/auxdisplay/Kconfig | 3 +- trunk/drivers/block/loop.c | 30 - trunk/drivers/char/amiserial.c | 62 +- trunk/drivers/char/cyclades.c | 54 +- trunk/drivers/char/ip2/ip2main.c | 74 +- trunk/drivers/char/istallion.c | 121 +- trunk/drivers/char/pcmcia/synclink_cs.c | 73 +- trunk/drivers/char/stallion.c | 126 +- trunk/drivers/char/synclink.c | 98 +- trunk/drivers/char/synclink_gt.c | 74 +- trunk/drivers/char/synclinkmp.c | 74 +- trunk/drivers/char/sysrq.c | 21 +- trunk/drivers/char/tty_io.c | 20 +- trunk/drivers/hwmon/Kconfig | 36 - trunk/drivers/hwmon/Makefile | 3 - trunk/drivers/hwmon/hp_accel.c | 124 +- trunk/drivers/hwmon/lis3lv02d.c | 288 ++- trunk/drivers/hwmon/lis3lv02d.h | 20 +- trunk/drivers/hwmon/lis3lv02d_spi.c | 114 -- trunk/drivers/hwmon/lm95241.c | 527 ------ trunk/drivers/hwmon/ltc4215.c | 364 ---- trunk/drivers/isdn/capi/capi.c | 7 + trunk/drivers/misc/Kconfig | 10 - trunk/drivers/misc/Makefile | 1 - trunk/drivers/misc/hpilo.c | 6 +- trunk/drivers/misc/hpilo.h | 6 +- trunk/drivers/misc/isl29003.c | 470 ----- trunk/drivers/mmc/card/sdio_uart.c | 62 +- trunk/drivers/of/base.c | 1 - trunk/drivers/rtc/Kconfig | 17 +- trunk/drivers/rtc/Makefile | 1 - trunk/drivers/rtc/rtc-ds1307.c | 189 +- trunk/drivers/rtc/rtc-ds1374.c | 6 +- trunk/drivers/rtc/rtc-efi.c | 235 --- trunk/drivers/rtc/rtc-lib.c | 7 +- trunk/drivers/rtc/rtc-parisc.c | 56 +- trunk/drivers/rtc/rtc-v3020.c | 40 +- trunk/drivers/rtc/rtc-wm8350.c | 43 +- trunk/drivers/serial/serial_core.c | 76 +- trunk/drivers/spi/spi_mpc83xx.c | 366 +--- trunk/drivers/usb/serial/usb-serial.c | 58 +- trunk/drivers/video/68328fb.c | 5 +- trunk/drivers/video/Kconfig | 61 +- trunk/drivers/video/Makefile | 2 - trunk/drivers/video/amba-clcd.c | 8 +- trunk/drivers/video/amifb.c | 7 +- trunk/drivers/video/arkfb.c | 4 +- trunk/drivers/video/asiliantfb.c | 26 +- trunk/drivers/video/aty/mach64_accel.c | 3 +- trunk/drivers/video/aty/mach64_cursor.c | 15 +- trunk/drivers/video/aty/radeon_pm.c | 3 - trunk/drivers/video/backlight/backlight.c | 3 - trunk/drivers/video/backlight/lcd.c | 3 - trunk/drivers/video/cirrusfb.c | 1529 ++++++++------- trunk/drivers/video/console/fbcon.c | 73 +- trunk/drivers/video/cyblafb.c | 1683 +++++++++++++++++ trunk/drivers/video/efifb.c | 5 +- trunk/drivers/video/fb_defio.c | 3 +- trunk/drivers/video/fbmem.c | 22 +- trunk/drivers/video/nvidia/nv_type.h | 2 + trunk/drivers/video/nvidia/nvidia.c | 7 + trunk/drivers/video/omap/hwa742.c | 4 +- trunk/drivers/video/omap/omapfb_main.c | 8 +- trunk/drivers/video/s1d13xxxfb.c | 48 +- trunk/drivers/video/s3c-fb.c | 1036 ---------- trunk/drivers/video/sgivwfb.c | 2 - trunk/drivers/video/skeletonfb.c | 9 +- trunk/drivers/video/sm501fb.c | 5 +- trunk/drivers/video/sstfb.c | 10 +- trunk/drivers/video/stifb.c | 18 +- trunk/drivers/video/sunxvr500.c | 6 +- trunk/drivers/video/tdfxfb.c | 1 - trunk/drivers/video/tgafb.c | 4 +- trunk/drivers/video/tridentfb.c | 19 +- trunk/drivers/video/uvesafb.c | 17 +- trunk/drivers/video/valkyriefb.c | 15 +- trunk/drivers/video/vesafb.c | 2 +- trunk/drivers/video/vfb.c | 1 - trunk/drivers/video/via/accel.c | 8 +- trunk/fs/autofs4/autofs_i.h | 2 - trunk/fs/autofs4/dev-ioctl.c | 29 +- trunk/fs/autofs4/expire.c | 27 +- trunk/fs/autofs4/root.c | 41 +- trunk/fs/btrfs/ctree.h | 2 +- trunk/fs/btrfs/inode.c | 12 +- trunk/fs/buffer.c | 56 +- trunk/fs/ecryptfs/keystore.c | 3 +- trunk/fs/ecryptfs/messaging.c | 3 +- trunk/fs/eventfd.c | 26 +- trunk/fs/eventpoll.c | 614 +++--- trunk/fs/ext4/ext4.h | 2 +- trunk/fs/ext4/inode.c | 5 +- trunk/fs/fuse/file.c | 3 +- trunk/fs/gfs2/ops_file.c | 5 +- trunk/fs/hugetlbfs/inode.c | 21 +- trunk/fs/nfs/file.c | 5 +- trunk/fs/ntfs/dir.c | 4 +- trunk/fs/ntfs/inode.c | 3 +- trunk/fs/ntfs/layout.h | 329 ++-- trunk/fs/ntfs/logfile.h | 6 +- trunk/fs/ntfs/mft.c | 2 +- trunk/fs/ntfs/super.c | 50 +- trunk/fs/ntfs/usnjrnl.h | 48 +- trunk/fs/ocfs2/mmap.c | 6 +- trunk/fs/proc/proc_tty.c | 12 +- trunk/fs/ramfs/file-nommu.c | 15 +- trunk/fs/ramfs/inode.c | 94 +- trunk/fs/sysfs/bin.c | 8 +- trunk/fs/ubifs/file.c | 9 +- trunk/fs/xfs/linux-2.6/xfs_file.c | 4 +- trunk/include/asm-frv/highmem.h | 2 - trunk/include/asm-generic/dma-mapping.h | 308 +++ trunk/include/asm-mn10300/highmem.h | 2 - trunk/include/linux/auto_dev-ioctl.h | 7 +- trunk/include/linux/auto_fs.h | 6 +- trunk/include/linux/bootmem.h | 6 +- trunk/include/linux/buffer_head.h | 2 +- trunk/include/linux/eventfd.h | 12 +- trunk/include/linux/fb.h | 11 +- trunk/include/linux/fs.h | 1 - trunk/include/linux/fsl_devices.h | 7 +- trunk/include/linux/highmem.h | 12 - trunk/include/linux/kernel.h | 2 - trunk/include/linux/loop.h | 1 - trunk/include/linux/mm.h | 4 +- trunk/include/linux/mm_types.h | 4 - trunk/include/linux/mmzone.h | 8 - trunk/include/linux/page-debug-flags.h | 30 - trunk/include/linux/page-flags.h | 20 +- trunk/include/linux/pagevec.h | 1 + trunk/include/linux/poison.h | 3 - trunk/include/linux/rtc.h | 6 - trunk/include/linux/sched.h | 11 +- trunk/include/linux/string.h | 1 - trunk/include/linux/suspend.h | 3 + trunk/include/linux/swap.h | 7 +- trunk/include/linux/tty_driver.h | 3 +- trunk/include/linux/wait.h | 29 +- trunk/include/linux/writeback.h | 4 +- trunk/include/video/aty128.h | 2 +- trunk/include/video/cirrus.h | 2 +- trunk/include/video/newport.h | 4 +- trunk/include/video/radeon.h | 564 +++--- trunk/include/video/s1d13xxxfb.h | 16 +- trunk/init/main.c | 1 - trunk/kernel/power/disk.c | 1 - trunk/kernel/power/snapshot.c | 9 +- trunk/kernel/power/swsusp.c | 18 +- trunk/kernel/sched.c | 23 +- trunk/kernel/sysctl.c | 2 +- trunk/lib/Kconfig.debug | 1 - trunk/lib/rbtree.c | 14 +- trunk/mm/Kconfig | 9 +- trunk/mm/Kconfig.debug | 17 - trunk/mm/Makefile | 1 - trunk/mm/debug-pagealloc.c | 129 -- trunk/mm/highmem.c | 45 - trunk/mm/hugetlb.c | 6 +- trunk/mm/internal.h | 8 +- trunk/mm/memory.c | 33 +- trunk/mm/oom_kill.c | 12 +- trunk/mm/page-writeback.c | 42 +- trunk/mm/page_alloc.c | 29 +- trunk/mm/shmem.c | 3 +- trunk/mm/sparse.c | 4 +- trunk/mm/swap.c | 23 + trunk/mm/util.c | 30 - trunk/mm/vmalloc.c | 19 +- trunk/mm/vmscan.c | 101 +- trunk/mm/vmstat.c | 11 +- trunk/net/bluetooth/rfcomm/tty.c | 6 + trunk/net/core/sock.c | 8 +- trunk/net/irda/ircomm/ircomm_tty.c | 256 ++- 273 files changed, 7043 insertions(+), 7639 deletions(-) create mode 100644 trunk/Documentation/fb/cyblafb/bugs create mode 100644 trunk/Documentation/fb/cyblafb/credits create mode 100644 trunk/Documentation/fb/cyblafb/documentation create mode 100644 trunk/Documentation/fb/cyblafb/fb.modes create mode 100644 trunk/Documentation/fb/cyblafb/performance create mode 100644 trunk/Documentation/fb/cyblafb/todo create mode 100644 trunk/Documentation/fb/cyblafb/usage create mode 100644 trunk/Documentation/fb/cyblafb/whatsnew create mode 100644 trunk/Documentation/fb/cyblafb/whycyblafb delete mode 100644 trunk/Documentation/hwmon/ltc4215 delete mode 100644 trunk/Documentation/misc-devices/isl29003 delete mode 100644 trunk/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt delete mode 100644 trunk/arch/alpha/include/asm/xchg.h delete mode 100644 trunk/drivers/hwmon/lis3lv02d_spi.c delete mode 100644 trunk/drivers/hwmon/lm95241.c delete mode 100644 trunk/drivers/hwmon/ltc4215.c delete mode 100644 trunk/drivers/misc/isl29003.c delete mode 100644 trunk/drivers/rtc/rtc-efi.c create mode 100644 trunk/drivers/video/cyblafb.c delete mode 100644 trunk/drivers/video/s3c-fb.c create mode 100644 trunk/include/asm-generic/dma-mapping.h delete mode 100644 trunk/include/linux/page-debug-flags.h delete mode 100644 trunk/mm/Kconfig.debug delete mode 100644 trunk/mm/debug-pagealloc.c diff --git a/[refs] b/[refs] index 6ae40ffc89a2..a46fe92ac460 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e14a685dfabf3ceeb366f1db1a22471b8f98a08b +refs/heads/master: 5886cea45d1b230f86fd24de708b0d9f14ff88db diff --git a/trunk/Documentation/fb/00-INDEX b/trunk/Documentation/fb/00-INDEX index a618fd99c9f0..caabbd395e61 100644 --- a/trunk/Documentation/fb/00-INDEX +++ b/trunk/Documentation/fb/00-INDEX @@ -11,6 +11,8 @@ aty128fb.txt - info on the ATI Rage128 frame buffer driver. cirrusfb.txt - info on the driver for Cirrus Logic chipsets. +cyblafb/ + - directory with documentation files related to the cyblafb driver. deferred_io.txt - an introduction to deferred IO. fbcon.txt diff --git a/trunk/Documentation/fb/cyblafb/bugs b/trunk/Documentation/fb/cyblafb/bugs new file mode 100644 index 000000000000..9443a6d72cdd --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/bugs @@ -0,0 +1,13 @@ +Bugs +==== + +I currently don't know of any bug. Please do send reports to: + - linux-fbdev-devel@lists.sourceforge.net + - Knut_Petersen@t-online.de. + + +Untested features +================= + +All LCD stuff is untested. If it worked in tridentfb, it should work in +cyblafb. Please test and report the results to Knut_Petersen@t-online.de. diff --git a/trunk/Documentation/fb/cyblafb/credits b/trunk/Documentation/fb/cyblafb/credits new file mode 100644 index 000000000000..0eb3b443dc2b --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/credits @@ -0,0 +1,7 @@ +Thanks to +========= + * Alan Hourihane, for writing the X trident driver + * Jani Monoses, for writing the tridentfb driver + * Antonino A. Daplas, for review of the first published + version of cyblafb and some code + * Jochen Hein, for testing and a helpfull bug report diff --git a/trunk/Documentation/fb/cyblafb/documentation b/trunk/Documentation/fb/cyblafb/documentation new file mode 100644 index 000000000000..bb1aac048425 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/documentation @@ -0,0 +1,17 @@ +Available Documentation +======================= + +Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22, +2001, available from VIA: + + http://www.viavpsd.com/product/6/15/DS8601A182.pdf + +The datasheet is incomplete, some registers that need to be programmed are not +explained at all and important bits are listed as "reserved". But you really +need the datasheet to understand the code. "p. xxx" comments refer to page +numbers of this document. + +XFree/XOrg drivers are available and of good quality, looking at the code +there is a good idea if the datasheet does not provide enough information +or if the datasheet seems to be wrong. + diff --git a/trunk/Documentation/fb/cyblafb/fb.modes b/trunk/Documentation/fb/cyblafb/fb.modes new file mode 100644 index 000000000000..fe0e5223ba86 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/fb.modes @@ -0,0 +1,154 @@ +# +# Sample fb.modes file +# +# Provides an incomplete list of working modes for +# the cyberblade/i1 graphics core. +# +# The value 4294967256 is used instead of -40. Of course, -40 is not +# a really reasonable value, but chip design does not always follow +# logic. Believe me, it's ok, and it's the way the BIOS does it. +# +# fbset requires 4294967256 in fb.modes and -40 as an argument to +# the -t parameter. That's also not too reasonable, and it might change +# in the future or might even be differt for your current version. +# + +mode "640x480-50" + geometry 640 480 2048 4096 8 + timings 47619 4294967256 24 17 0 216 3 +endmode + +mode "640x480-60" + geometry 640 480 2048 4096 8 + timings 39682 4294967256 24 17 0 216 3 +endmode + +mode "640x480-70" + geometry 640 480 2048 4096 8 + timings 34013 4294967256 24 17 0 216 3 +endmode + +mode "640x480-72" + geometry 640 480 2048 4096 8 + timings 33068 4294967256 24 17 0 216 3 +endmode + +mode "640x480-75" + geometry 640 480 2048 4096 8 + timings 31746 4294967256 24 17 0 216 3 +endmode + +mode "640x480-80" + geometry 640 480 2048 4096 8 + timings 29761 4294967256 24 17 0 216 3 +endmode + +mode "640x480-85" + geometry 640 480 2048 4096 8 + timings 28011 4294967256 24 17 0 216 3 +endmode + +mode "800x600-50" + geometry 800 600 2048 4096 8 + timings 30303 96 24 14 0 136 11 +endmode + +mode "800x600-60" + geometry 800 600 2048 4096 8 + timings 25252 96 24 14 0 136 11 +endmode + +mode "800x600-70" + geometry 800 600 2048 4096 8 + timings 21645 96 24 14 0 136 11 +endmode + +mode "800x600-72" + geometry 800 600 2048 4096 8 + timings 21043 96 24 14 0 136 11 +endmode + +mode "800x600-75" + geometry 800 600 2048 4096 8 + timings 20202 96 24 14 0 136 11 +endmode + +mode "800x600-80" + geometry 800 600 2048 4096 8 + timings 18939 96 24 14 0 136 11 +endmode + +mode "800x600-85" + geometry 800 600 2048 4096 8 + timings 17825 96 24 14 0 136 11 +endmode + +mode "1024x768-50" + geometry 1024 768 2048 4096 8 + timings 19054 144 24 29 0 120 3 +endmode + +mode "1024x768-60" + geometry 1024 768 2048 4096 8 + timings 15880 144 24 29 0 120 3 +endmode + +mode "1024x768-70" + geometry 1024 768 2048 4096 8 + timings 13610 144 24 29 0 120 3 +endmode + +mode "1024x768-72" + geometry 1024 768 2048 4096 8 + timings 13232 144 24 29 0 120 3 +endmode + +mode "1024x768-75" + geometry 1024 768 2048 4096 8 + timings 12703 144 24 29 0 120 3 +endmode + +mode "1024x768-80" + geometry 1024 768 2048 4096 8 + timings 11910 144 24 29 0 120 3 +endmode + +mode "1024x768-85" + geometry 1024 768 2048 4096 8 + timings 11209 144 24 29 0 120 3 +endmode + +mode "1280x1024-50" + geometry 1280 1024 2048 4096 8 + timings 11114 232 16 39 0 160 3 +endmode + +mode "1280x1024-60" + geometry 1280 1024 2048 4096 8 + timings 9262 232 16 39 0 160 3 +endmode + +mode "1280x1024-70" + geometry 1280 1024 2048 4096 8 + timings 7939 232 16 39 0 160 3 +endmode + +mode "1280x1024-72" + geometry 1280 1024 2048 4096 8 + timings 7719 232 16 39 0 160 3 +endmode + +mode "1280x1024-75" + geometry 1280 1024 2048 4096 8 + timings 7410 232 16 39 0 160 3 +endmode + +mode "1280x1024-80" + geometry 1280 1024 2048 4096 8 + timings 6946 232 16 39 0 160 3 +endmode + +mode "1280x1024-85" + geometry 1280 1024 2048 4096 8 + timings 6538 232 16 39 0 160 3 +endmode diff --git a/trunk/Documentation/fb/cyblafb/performance b/trunk/Documentation/fb/cyblafb/performance new file mode 100644 index 000000000000..8d15d5dfc6b3 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/performance @@ -0,0 +1,79 @@ +Speed +===== + +CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data +for mode 1280x1024-[8,16,32]@61 Hz. + +Test 1: Cat a file with 2000 lines of 0 characters. +Test 2: Cat a file with 2000 lines of 80 characters. +Test 3: Cat a file with 2000 lines of 160 characters. + +All values show system time use in seconds, kernel 2.6.12 was used for +the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a +patch that speeds up kernel bitblitting a lot ( > 20%). + ++-----------+-----------------------------------------------------+ +| | not accelerated | +| TRIDENTFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- | +| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- | +| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | | | completely bro- | +| | | | ken, monitor | +| | | | switches off | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | accelerated | +| TRIDENTFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- | +| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- | +| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | broken, writing | broken, ok only | completely bro- | +| | to wrong places | if bgcolor is | ken, monitor | +| | on screen + bug | black, bug in | switches off | +| | in fillrect() | fillrect() | | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | not accelerated | +| VESAFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- | +| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- | +| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | vga=0x307 | vga=0x31a | vga=0x31b not | +| | fh=80kHz | fh=80kHz | supported by | +| | fv=75kHz | fv=75kHz | video BIOS and | +| | | | hardware | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | accelerated | +| CYBLAFB +-----------------+-----------------+-----------------+ +| | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 | +| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 | +| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | | | | +| | | | | +| | | | | +| | | | | ++-----------+-----------------+-----------------+-----------------+ diff --git a/trunk/Documentation/fb/cyblafb/todo b/trunk/Documentation/fb/cyblafb/todo new file mode 100644 index 000000000000..c5f6d0eae545 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/todo @@ -0,0 +1,31 @@ +TODO / Missing features +======================= + +Verify LCD stuff "stretch" and "center" options are + completely untested ... this code needs to be + verified. As I don't have access to such + hardware, please contact me if you are + willing run some tests. + +Interlaced video modes The reason that interleaved + modes are disabled is that I do not know + the meaning of the vertical interlace + parameter. Also the datasheet mentions a + bit d8 of a horizontal interlace parameter, + but nowhere the lower 8 bits. Please help + if you can. + +low-res double scan modes Who needs it? + +accelerated color blitting Who needs it? The console driver does use color + blitting for nothing but drawing the penguine, + everything else is done using color expanding + blitting of 1bpp character bitmaps. + +ioctls Who needs it? + +TV-out Will be done later. Use "vga= " at boot time + to set a suitable video mode. + +??? Feel free to contact me if you have any + feature requests diff --git a/trunk/Documentation/fb/cyblafb/usage b/trunk/Documentation/fb/cyblafb/usage new file mode 100644 index 000000000000..a39bb3d402a2 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/usage @@ -0,0 +1,217 @@ +CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated +into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and +tested using a VIA EPIA 5000 board. + +Cyblafb - compiled into the kernel or as a module? +================================================== + +You might compile cyblafb either as a module or compile it permanently into the +kernel. + +Unless you have a real reason to do so you should not compile both vesafb and +cyblafb permanently into the kernel. It's possible and it helps during the +developement cycle, but it's useless and will at least block some otherwise +usefull memory for ordinary users. + +Selecting Modes +=============== + + Startup Mode + ============ + + First of all, you might use the "vga=???" boot parameter as it is + documented in vesafb.txt and svga.txt. Cyblafb will detect the video + mode selected and will use the geometry and timings found by + inspecting the hardware registers. + + video=cyblafb vga=0x317 + + Alternatively you might use a combination of the mode, ref and bpp + parameters. If you compiled the driver into the kernel, add something + like this to the kernel command line: + + video=cyblafb:1280x1024,bpp=16,ref=50 ... + + If you compiled the driver as a module, the same mode would be + selected by the following command: + + modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ... + + None of the modes possible to select as startup modes are affected by + the problems described at the end of the next subsection. + + For all startup modes cyblafb chooses a virtual x resolution of 2048, + the only exception is mode 1280x1024 in combination with 32 bpp. This + allows ywrap scrolling for all those modes if rotation is 0 or 2, and + also fast scrolling if rotation is 1 or 3. The default virtual y reso- + lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32, + again with the only exception of 1280x1024 at 32 bpp. + + Please do set your video memory size to 8 Mb in the Bios setup. Other + values will work, but performace is decreased for a lot of modes. + + Mode changes using fbset + ======================== + + You might use fbset to change the video mode, see "man fbset". Cyblafb + generally does assume that you know what you are doing. But it does + some checks, especially those that are needed to prevent you from + damaging your hardware. + + - only 8, 16, 24 and 32 bpp video modes are accepted + - interlaced video modes are not accepted + - double scan video modes are not accepted + - if a flat panel is found, cyblafb does not allow you + to program a resolution higher than the physical + resolution of the flat panel monitor + - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp + and (currently) 24 bit modes use a doubled vclk internally, + the dotclock limit as seen by fbset is 115 MHz for those + modes and 230 MHz for 8 and 16 bpp modes. + - cyblafb will allow you to select very high resolutions as + long as the hardware can be programmed to these modes. The + documented limit 1600x1200 is not enforced, but don't expect + perfect signal quality. + + Any request that violates the rules given above will be either changed + to something the hardware supports or an error value will be returned. + + If you program a virtual y resolution higher than the hardware limit, + cyblafb will silently decrease that value to the highest possible + value. The same is true for a virtual x resolution that is not + supported by the hardware. Cyblafb tries to adapt vyres first because + vxres decides if ywrap scrolling is possible or not. + + Attempts to disable acceleration are ignored, I believe that this is + safe. + + Some video modes that should work do not work as expected. If you use + the standard fb.modes, fbset 640x480-60 will program that mode, but + you will see a vertical area, about two characters wide, with only + much darker characters than the other characters on the screen. + Cyblafb does allow that mode to be set, as it does not violate the + official specifications. It would need a lot of code to reliably sort + out all invalid modes, playing around with the margin values will + give a valid mode quickly. And if cyblafb would detect such an invalid + mode, should it silently alter the requested values or should it + report an error? Both options have some pros and cons. As stated + above, none of the startup modes are affected, and if you set + verbosity to 1 or higher, cyblafb will print the fbset command that + would be needed to program that mode using fbset. + + +Other Parameters +================ + + +crt don't autodetect, assume monitor connected to + standard VGA connector + +fp don't autodetect, assume flat panel display + connected to flat panel monitor interface + +nativex inform driver about native x resolution of + flat panel monitor connected to special + interface (should be autodetected) + +stretch stretch image to adapt low resolution modes to + higer resolutions of flat panel monitors + connected to special interface + +center center image to adapt low resolution modes to + higer resolutions of flat panel monitors + connected to special interface + +memsize use if autodetected memsize is wrong ... + should never be necessary + +nopcirr disable PCI read retry +nopciwr disable PCI write retry +nopcirb disable PCI read bursts +nopciwb disable PCI write bursts + +bpp bpp for specified modes + valid values: 8 || 16 || 24 || 32 + +ref refresh rate for specified mode + valid values: 50 <= ref <= 85 + +mode 640x480 or 800x600 or 1024x768 or 1280x1024 + if not specified, the startup mode will be detected + and used, so you might also use the vga=??? parameter + described in vesafb.txt. If you do not specify a mode, + bpp and ref parameters are ignored. + +verbosity 0 is the default, increase to at least 2 for every + bug report! + +Development hints +================= + +It's much faster do compile a module and to load the new version after +unloading the old module than to compile a new kernel and to reboot. So if you +try to work on cyblafb, it might be a good idea to use cyblafb as a module. +In real life, fast often means dangerous, and that's also the case here. If +you introduce a serious bug when cyblafb is compiled into the kernel, the +kernel will lock or oops with a high probability before the file system is +mounted, and the danger for your data is low. If you load a broken own version +of cyblafb on a running system, the danger for the integrity of the file +system is much higher as you might need a hard reset afterwards. Decide +yourself. + +Module unloading, the vfb method +================================ + +If you want to unload/reload cyblafb using the virtual framebuffer, you need +to enable vfb support in the kernel first. After that, load the modules as +shown below: + + modprobe vfb vfb_enable=1 + modprobe fbcon + modprobe cyblafb + fbset -fb /dev/fb1 1280x1024-60 -vyres 2662 + con2fb /dev/fb1 /dev/tty1 + ... + +If you now made some changes to cyblafb and want to reload it, you might do it +as show below: + + con2fb /dev/fb0 /dev/tty1 + ... + rmmod cyblafb + modprobe cyblafb + con2fb /dev/fb1 /dev/tty1 + ... + +Of course, you might choose another mode, and most certainly you also want to +map some other /dev/tty* to the real framebuffer device. You might also choose +to compile fbcon as a kernel module or place it permanently in the kernel. + +I do not know of any way to unload fbcon, and fbcon will prevent the +framebuffer device loaded first from unloading. [If there is a way, then +please add a description here!] + +Module unloading, the vesafb method +=================================== + +Configure the kernel: + + <*> Support for frame buffer devices + [*] VESA VGA graphics support + Cyberblade/i1 support + +Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan +parameter is important, choose any vga parameter you like as long as it is +a graphics mode. + +After booting, load cyblafb without any mode and bpp parameter and assign +cyblafb to individual ttys using con2fb, e.g.: + + modprobe cyblafb + con2fb /dev/fb1 /dev/tty1 + +Unloading cyblafb works without problems after you assign vesafb to all +ttys again, e.g.: + + con2fb /dev/fb0 /dev/tty1 + rmmod cyblafb diff --git a/trunk/Documentation/fb/cyblafb/whatsnew b/trunk/Documentation/fb/cyblafb/whatsnew new file mode 100644 index 000000000000..76c07a26e044 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/whatsnew @@ -0,0 +1,29 @@ +0.62 +==== + + - the vesafb parameter has been removed as I decided to allow the + feature without any special parameter. + + - Cyblafb does not use the vga style of panning any longer, now the + "right view" register in the graphics engine IO space is used. Without + that change it was impossible to use all available memory, and without + access to all available memory it is impossible to ywrap. + + - The imageblit function now uses hardware acceleration for all font + widths. Hardware blitting across pixel column 2048 is broken in the + cyberblade/i1 graphics core, but we work around that hardware bug. + + - modes with vxres != xres are supported now. + + - ywrap scrolling is supported now and the default. This is a big + performance gain. + + - default video modes use vyres > yres and vxres > xres to allow + almost optimal scrolling speed for normal and rotated screens + + - some features mainly usefull for debugging the upper layers of the + framebuffer system have been added, have a look at the code + + - fixed: Oops after unloading cyblafb when reading /proc/io* + + - we work around some bugs of the higher framebuffer layers. diff --git a/trunk/Documentation/fb/cyblafb/whycyblafb b/trunk/Documentation/fb/cyblafb/whycyblafb new file mode 100644 index 000000000000..a123bc11e698 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/whycyblafb @@ -0,0 +1,85 @@ +I tried the following framebuffer drivers: + + - TRIDENTFB is full of bugs. Acceleration is broken for Blade3D + graphics cores like the cyberblade/i1. It claims to support a great + number of devices, but documentation for most of these devices is + unfortunately not available. There is _no_ reason to use tridentfb + for cyberblade/i1 + CRT users. VESAFB is faster, and the one + advantage, mode switching, is broken in tridentfb. + + - VESAFB is used by many distributions as a standard. Vesafb does + not support mode switching. VESAFB is a bit faster than the working + configurations of TRIDENTFB, but it is still too slow, even if you + use ypan. + + - EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1 + graphics core, but it still has serious bugs and developement seems + to have stopped. This is the one driver with TV-out support. If you + do need this feature, try epiafb. + +None of these drivers was a real option for me. + +I believe that is unreasonable to change code that announces to support 20 +devices if I only have more or less sufficient documentation for exactly one +of these. The risk of breaking device foo while fixing device bar is too high. + +So I decided to start CyBlaFB as a stripped down tridentfb. + +All code specific to other Trident chips has been removed. After that there +were a lot of cosmetic changes to increase the readability of the code. All +register names were changed to those mnemonics used in the datasheet. Function +and macro names were changed if they hindered easy understanding of the code. + +After that I debugged the code and implemented some new features. I'll try to +give a little summary of the main changes: + + - calculation of vertical and horizontal timings was fixed + + - video signal quality has been improved dramatically + + - acceleration: + + - fillrect and copyarea were fixed and reenabled + + - color expanding imageblit was newly implemented, color + imageblit (only used to draw the penguine) still uses the + generic code. + + - init of the acceleration engine was improved and moved to a + place where it really works ... + + - sync function has a timeout now and tries to reset and + reinit the accel engine if necessary + + - fewer slow copyarea calls when doing ypan scrolling by using + undocumented bit d21 of screen start address stored in + CR2B[5]. BIOS does use it also, so this should be safe. + + - cyblafb rejects any attempt to set modes that would cause vclk + values above reasonable 230 MHz. 32bit modes use a clock + multiplicator of 2, so fbset does show the correct values for + pixclock but not for vclk in this case. The fbset limit is 115 MHz + for 32 bpp modes. + + - cyblafb rejects modes known to be broken or unimplemented (all + interlaced modes, all doublescan modes for now) + + - cyblafb now works independant of the video mode in effect at startup + time (tridentfb does not init all needed registers to reasonable + values) + + - switching between video modes does work reliably now + + - the first video mode now is the one selected on startup using the + vga=???? mechanism or any of + - 640x480, 800x600, 1024x768, 1280x1024 + - 8, 16, 24 or 32 bpp + - refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32 + is limited to 63Hz) + + - pci retry and pci burst mode are settable (try to disable if you + experience latency problems) + + - built as a module cyblafb might be unloaded and reloaded using + the vfb module and con2vt or might be used together with vesafb + diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index ea7d1bdad34d..5e02b83ac12b 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -311,18 +311,6 @@ Who: Vlad Yasevich --------------------------- -What: Ability for non root users to shm_get hugetlb pages based on mlock - resource limits -When: 2.6.31 -Why: Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or - have CAP_IPC_LOCK to be able to allocate shm segments backed by - huge pages. The mlock based rlimit check to allow shm hugetlb is - inconsistent with mmap based allocations. Hence it is being - deprecated. -Who: Ravikiran Thirumalai - ---------------------------- - What: CONFIG_THERMAL_HWMON When: January 2009 Why: This option was introduced just to allow older lm-sensors userspace diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 76efe5b71d7d..4e78ce677843 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -505,7 +505,7 @@ prototypes: void (*open)(struct vm_area_struct*); void (*close)(struct vm_area_struct*); int (*fault)(struct vm_area_struct*, struct vm_fault *); - int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *); + int (*page_mkwrite)(struct vm_area_struct *, struct page *); int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); locking rules: diff --git a/trunk/Documentation/hwmon/lis3lv02d b/trunk/Documentation/hwmon/lis3lv02d index effe949a7282..287f8c902656 100644 --- a/trunk/Documentation/hwmon/lis3lv02d +++ b/trunk/Documentation/hwmon/lis3lv02d @@ -1,11 +1,11 @@ Kernel driver lis3lv02d -======================= +================== Supported chips: * STMicroelectronics LIS3LV02DL and LIS3LV02DQ -Authors: +Author: Yan Burman Eric Piel @@ -15,7 +15,7 @@ Description This driver provides support for the accelerometer found in various HP laptops sporting the feature officially called "HP Mobile Data -Protection System 3D" or "HP 3D DriveGuard". It detects automatically +Protection System 3D" or "HP 3D DriveGuard". It detect automatically laptops with this sensor. Known models (for now the HP 2133, nc6420, nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis automatically oriented on standard way (eg: you can directly play @@ -27,7 +27,7 @@ position - 3D position that the accelerometer reports. Format: "(x,y,z)" calibrate - read: values (x, y, z) that are used as the base for input class device operation. write: forces the base to be recalibrated with the current - position. + position. rate - reports the sampling rate of the accelerometer device in HZ This driver also provides an absolute input class device, allowing @@ -48,7 +48,7 @@ For better compatibility between the various laptops. The values reported by the accelerometer are converted into a "standard" organisation of the axes (aka "can play neverball out of the box"): * When the laptop is horizontal the position reported is about 0 for X and Y - and a positive value for Z +and a positive value for Z * If the left side is elevated, X increases (becomes positive) * If the front side (where the touchpad is) is elevated, Y decreases (becomes negative) @@ -59,13 +59,3 @@ email to the authors to add it to the database. When reporting a new laptop, please include the output of "dmidecode" plus the value of /sys/devices/platform/lis3lv02d/position in these four cases. -Q&A ---- - -Q: How do I safely simulate freefall? I have an HP "portable -workstation" which has about 3.5kg and a plastic case, so letting it -fall to the ground is out of question... - -A: The sensor is pretty sensitive, so your hands can do it. Lift it -into free space, follow the fall with your hands for like 10 -centimeters. That should be enough to trigger the detection. diff --git a/trunk/Documentation/hwmon/ltc4215 b/trunk/Documentation/hwmon/ltc4215 deleted file mode 100644 index 2e6a21eb656c..000000000000 --- a/trunk/Documentation/hwmon/ltc4215 +++ /dev/null @@ -1,50 +0,0 @@ -Kernel driver ltc4215 -===================== - -Supported chips: - * Linear Technology LTC4215 - Prefix: 'ltc4215' - Addresses scanned: 0x44 - Datasheet: - http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697 - -Author: Ira W. Snyder - - -Description ------------ - -The LTC4215 controller allows a board to be safely inserted and removed -from a live backplane. - - -Usage Notes ------------ - -This driver does not probe for LTC4215 devices, due to the fact that some -of the possible addresses are unfriendly to probing. You will need to use -the "force" parameter to tell the driver where to find the device. - -Example: the following will load the driver for an LTC4215 at address 0x44 -on I2C bus #0: -$ modprobe ltc4215 force=0,0x44 - - -Sysfs entries -------------- - -The LTC4215 has built-in limits for overvoltage, undervoltage, and -undercurrent warnings. This makes it very likely that the reference -circuit will be used. - -in1_input input voltage -in2_input output voltage - -in1_min_alarm input undervoltage alarm -in1_max_alarm input overvoltage alarm - -curr1_input current -curr1_max_alarm overcurrent alarm - -power1_input power usage -power1_alarm power bad alarm diff --git a/trunk/Documentation/misc-devices/isl29003 b/trunk/Documentation/misc-devices/isl29003 deleted file mode 100644 index c4ff5f38e010..000000000000 --- a/trunk/Documentation/misc-devices/isl29003 +++ /dev/null @@ -1,62 +0,0 @@ -Kernel driver isl29003 -===================== - -Supported chips: -* Intersil ISL29003 -Prefix: 'isl29003' -Addresses scanned: none -Datasheet: -http://www.intersil.com/data/fn/fn7464.pdf - -Author: Daniel Mack - - -Description ------------ -The ISL29003 is an integrated light sensor with a 16-bit integrating type -ADC, I2C user programmable lux range select for optimized counts/lux, and -I2C multi-function control and monitoring capabilities. The internal ADC -provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by -artificial light sources. - -The driver allows to set the lux range, the bit resolution, the operational -mode (see below) and the power state of device and can read the current lux -value, of course. - - -Detection ---------- - -The ISL29003 does not have an ID register which could be used to identify -it, so the detection routine will just try to read from the configured I2C -addess and consider the device to be present as soon as it ACKs the -transfer. - - -Sysfs entries -------------- - -range: - 0: 0 lux to 1000 lux (default) - 1: 0 lux to 4000 lux - 2: 0 lux to 16,000 lux - 3: 0 lux to 64,000 lux - -resolution: - 0: 2^16 cycles (default) - 1: 2^12 cycles - 2: 2^8 cycles - 3: 2^4 cycles - -mode: - 0: diode1's current (unsigned 16bit) (default) - 1: diode1's current (unsigned 16bit) - 2: difference between diodes (l1 - l2, signed 15bit) - -power_state: - 0: device is disabled (default) - 1: device is enabled - -lux (read only): - returns the value from the last sensor reading - diff --git a/trunk/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt b/trunk/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt deleted file mode 100644 index c39ac2891951..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt +++ /dev/null @@ -1,23 +0,0 @@ -MMC/SD/SDIO slot directly connected to a SPI bus - -Required properties: -- compatible : should be "mmc-spi-slot". -- reg : should specify SPI address (chip-select number). -- spi-max-frequency : maximum frequency for this device (Hz). -- voltage-ranges : two cells are required, first cell specifies minimum - slot voltage (mV), second cell specifies maximum slot voltage (mV). - Several ranges could be specified. -- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO, - Write-Protect GPIO. - -Example: - - mmc-slot@0 { - compatible = "fsl,mpc8323rdb-mmc-slot", - "mmc-spi-slot"; - reg = <0>; - gpios = <&qe_pio_d 14 1 - &qe_pio_d 15 0>; - voltage-ranges = <3300 3300>; - spi-max-frequency = <50000000>; - }; diff --git a/trunk/Documentation/sysrq.txt b/trunk/Documentation/sysrq.txt index afa2946892da..9e592c718afb 100644 --- a/trunk/Documentation/sysrq.txt +++ b/trunk/Documentation/sysrq.txt @@ -81,8 +81,6 @@ On all - write a character to /proc/sysrq-trigger. e.g.: 'i' - Send a SIGKILL to all processes, except for init. -'j' - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl. - 'k' - Secure Access Key (SAK) Kills all programs on the current virtual console. NOTE: See important comments below in SAK section. @@ -162,9 +160,6 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you are unable to kill any other way, especially if it's spawning other processes. -"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen -(probably root) filesystem via the FIFREEZE ioctl. - * Sometimes SysRq seems to get 'stuck' after using it, what can I do? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ That happens to me, also. I've found that tapping shift, alt, and control diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a64f2920a8f3..c5f4e9d27b64 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -357,7 +357,6 @@ S: Odd Fixes for 2.4; Maintained for 2.6. P: Ivan Kokshaysky M: ink@jurassic.park.msu.ru S: Maintained for 2.4; PCI support for 2.6. -L: linux-alpha@vger.kernel.org AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER P: Thomas Dahlmann diff --git a/trunk/arch/alpha/include/asm/machvec.h b/trunk/arch/alpha/include/asm/machvec.h index 13cd42743810..fea4ea75b79d 100644 --- a/trunk/arch/alpha/include/asm/machvec.h +++ b/trunk/arch/alpha/include/asm/machvec.h @@ -80,7 +80,7 @@ struct alpha_machine_vector void (*update_irq_hw)(unsigned long, unsigned long, int); void (*ack_irq)(unsigned long); void (*device_interrupt)(unsigned long vector); - void (*machine_check)(unsigned long vector, unsigned long la); + void (*machine_check)(u64 vector, u64 la); void (*smp_callin)(void); void (*init_arch)(void); diff --git a/trunk/arch/alpha/include/asm/system.h b/trunk/arch/alpha/include/asm/system.h index 5aa40cca4f23..afe20fa58c99 100644 --- a/trunk/arch/alpha/include/asm/system.h +++ b/trunk/arch/alpha/include/asm/system.h @@ -309,72 +309,519 @@ extern int __min_ipl; #define tbia() __tbi(-2, /* no second argument */) /* - * Atomic exchange routines. + * Atomic exchange. + * Since it can be used to implement critical sections + * it must clobber "memory" (also for interrupts in UP). */ -#define __ASM__MB -#define ____xchg(type, args...) __xchg ## type ## _local(args) -#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) -#include +static inline unsigned long +__xchg_u8(volatile char *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " insbl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extbl %2,%4,%0\n" + " mskbl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); -#define xchg_local(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) + return ret; +} -#define cmpxchg_local(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, \ - sizeof(*(ptr))); \ - }) +static inline unsigned long +__xchg_u16(volatile short *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " inswl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extwl %2,%4,%0\n" + " mskwl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); -#define cmpxchg64_local(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ - }) + return ret; +} +static inline unsigned long +__xchg_u32(volatile int *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldl_l %0,%4\n" + " bis $31,%3,%1\n" + " stl_c %1,%2\n" + " beq %1,2f\n" #ifdef CONFIG_SMP -#undef __ASM__MB -#define __ASM__MB "\tmb\n" + " mb\n" #endif -#undef ____xchg -#undef ____cmpxchg -#define ____xchg(type, args...) __xchg ##type(args) -#define ____cmpxchg(type, args...) __cmpxchg ##type(args) -#include - -#define xchg(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +static inline unsigned long +__xchg_u64(volatile long *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldq_l %0,%4\n" + " bis $31,%3,%1\n" + " stq_c %1,%2\n" + " beq %1,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); -#define cmpxchg(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr)));\ + return val; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid xchg(). */ +extern void __xchg_called_with_bad_pointer(void); + +#define __xchg(ptr, x, size) \ +({ \ + unsigned long __xchg__res; \ + volatile void *__xchg__ptr = (ptr); \ + switch (size) { \ + case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \ + case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \ + case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \ + case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \ + default: __xchg_called_with_bad_pointer(); __xchg__res = x; \ + } \ + __xchg__res; \ +}) + +#define xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ }) -#define cmpxchg64(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg((ptr), (o), (n)); \ +static inline unsigned long +__xchg_u8_local(volatile char *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " insbl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extbl %2,%4,%0\n" + " mskbl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); + + return ret; +} + +static inline unsigned long +__xchg_u16_local(volatile short *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " inswl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extwl %2,%4,%0\n" + " mskwl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); + + return ret; +} + +static inline unsigned long +__xchg_u32_local(volatile int *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldl_l %0,%4\n" + " bis $31,%3,%1\n" + " stl_c %1,%2\n" + " beq %1,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +static inline unsigned long +__xchg_u64_local(volatile long *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldq_l %0,%4\n" + " bis $31,%3,%1\n" + " stq_c %1,%2\n" + " beq %1,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +#define __xchg_local(ptr, x, size) \ +({ \ + unsigned long __xchg__res; \ + volatile void *__xchg__ptr = (ptr); \ + switch (size) { \ + case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \ + case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \ + case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \ + case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \ + default: __xchg_called_with_bad_pointer(); __xchg__res = x; \ + } \ + __xchg__res; \ +}) + +#define xchg_local(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ }) -#undef __ASM__MB -#undef ____cmpxchg +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + * + * The memory barrier should be placed in SMP only when we actually + * make the change. If we don't change anything (so if the returned + * prev is equal to old) then we aren't acquiring anything new and + * we don't need any memory barrier as far I can tell. + */ #define __HAVE_ARCH_CMPXCHG 1 +static inline unsigned long +__cmpxchg_u8(volatile char *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " insbl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extbl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskbl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u16(volatile short *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " inswl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extwl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskwl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static __always_inline unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 1: + return __cmpxchg_u8(ptr, old, new); + case 2: + return __cmpxchg_u16(ptr, old, new); + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) +#define cmpxchg64(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg((ptr), (o), (n)); \ + }) + +static inline unsigned long +__cmpxchg_u8_local(volatile char *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " insbl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extbl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskbl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u16_local(volatile short *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " inswl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extwl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskwl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u32_local(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static __always_inline unsigned long +__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, + int size) +{ + switch (size) { + case 1: + return __cmpxchg_u8_local(ptr, old, new); + case 2: + return __cmpxchg_u16_local(ptr, old, new); + case 4: + return __cmpxchg_u32_local(ptr, old, new); + case 8: + return __cmpxchg_u64_local(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg_local(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) +#define cmpxchg64_local(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ + }) + + #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) diff --git a/trunk/arch/alpha/include/asm/types.h b/trunk/arch/alpha/include/asm/types.h index f072f344497e..c1541353ccef 100644 --- a/trunk/arch/alpha/include/asm/types.h +++ b/trunk/arch/alpha/include/asm/types.h @@ -8,12 +8,7 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ - -#ifdef __KERNEL__ -#include -#else #include -#endif #ifndef __ASSEMBLY__ diff --git a/trunk/arch/alpha/include/asm/uaccess.h b/trunk/arch/alpha/include/asm/uaccess.h index 163f3053001c..22de3b434a22 100644 --- a/trunk/arch/alpha/include/asm/uaccess.h +++ b/trunk/arch/alpha/include/asm/uaccess.h @@ -498,13 +498,13 @@ struct exception_table_entry }; /* Returns the new pc */ -#define fixup_exception(map_reg, _fixup, pc) \ +#define fixup_exception(map_reg, fixup, pc) \ ({ \ - if ((_fixup)->fixup.bits.valreg != 31) \ - map_reg((_fixup)->fixup.bits.valreg) = 0; \ - if ((_fixup)->fixup.bits.errreg != 31) \ - map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ - (pc) + (_fixup)->fixup.bits.nextinsn; \ + if ((fixup)->fixup.bits.valreg != 31) \ + map_reg((fixup)->fixup.bits.valreg) = 0; \ + if ((fixup)->fixup.bits.errreg != 31) \ + map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \ + (pc) + (fixup)->fixup.bits.nextinsn; \ }) diff --git a/trunk/arch/alpha/include/asm/xchg.h b/trunk/arch/alpha/include/asm/xchg.h deleted file mode 100644 index beba1b803e0d..000000000000 --- a/trunk/arch/alpha/include/asm/xchg.h +++ /dev/null @@ -1,258 +0,0 @@ -#ifndef __ALPHA_SYSTEM_H -#error Do not include xchg.h directly! -#else -/* - * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code - * except that local version do not have the expensive memory barrier. - * So this file is included twice from asm/system.h. - */ - -/* - * Atomic exchange. - * Since it can be used to implement critical sections - * it must clobber "memory" (also for interrupts in UP). - */ - -static inline unsigned long -____xchg(_u8, volatile char *m, unsigned long val) -{ - unsigned long ret, tmp, addr64; - - __asm__ __volatile__( - " andnot %4,7,%3\n" - " insbl %1,%4,%1\n" - "1: ldq_l %2,0(%3)\n" - " extbl %2,%4,%0\n" - " mskbl %2,%4,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%3)\n" - " beq %2,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) - : "r" ((long)m), "1" (val) : "memory"); - - return ret; -} - -static inline unsigned long -____xchg(_u16, volatile short *m, unsigned long val) -{ - unsigned long ret, tmp, addr64; - - __asm__ __volatile__( - " andnot %4,7,%3\n" - " inswl %1,%4,%1\n" - "1: ldq_l %2,0(%3)\n" - " extwl %2,%4,%0\n" - " mskwl %2,%4,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%3)\n" - " beq %2,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) - : "r" ((long)m), "1" (val) : "memory"); - - return ret; -} - -static inline unsigned long -____xchg(_u32, volatile int *m, unsigned long val) -{ - unsigned long dummy; - - __asm__ __volatile__( - "1: ldl_l %0,%4\n" - " bis $31,%3,%1\n" - " stl_c %1,%2\n" - " beq %1,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "rI" (val), "m" (*m) : "memory"); - - return val; -} - -static inline unsigned long -____xchg(_u64, volatile long *m, unsigned long val) -{ - unsigned long dummy; - - __asm__ __volatile__( - "1: ldq_l %0,%4\n" - " bis $31,%3,%1\n" - " stq_c %1,%2\n" - " beq %1,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "rI" (val), "m" (*m) : "memory"); - - return val; -} - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid xchg(). */ -extern void __xchg_called_with_bad_pointer(void); - -static __always_inline unsigned long -____xchg(, volatile void *ptr, unsigned long x, int size) -{ - switch (size) { - case 1: - return ____xchg(_u8, ptr, x); - case 2: - return ____xchg(_u16, ptr, x); - case 4: - return ____xchg(_u32, ptr, x); - case 8: - return ____xchg(_u64, ptr, x); - } - __xchg_called_with_bad_pointer(); - return x; -} - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - * - * The memory barrier should be placed in SMP only when we actually - * make the change. If we don't change anything (so if the returned - * prev is equal to old) then we aren't acquiring anything new and - * we don't need any memory barrier as far I can tell. - */ - -static inline unsigned long -____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new) -{ - unsigned long prev, tmp, cmp, addr64; - - __asm__ __volatile__( - " andnot %5,7,%4\n" - " insbl %1,%5,%1\n" - "1: ldq_l %2,0(%4)\n" - " extbl %2,%5,%0\n" - " cmpeq %0,%6,%3\n" - " beq %3,2f\n" - " mskbl %2,%5,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%4)\n" - " beq %2,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) - : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new) -{ - unsigned long prev, tmp, cmp, addr64; - - __asm__ __volatile__( - " andnot %5,7,%4\n" - " inswl %1,%5,%1\n" - "1: ldq_l %2,0(%4)\n" - " extwl %2,%5,%0\n" - " cmpeq %0,%6,%3\n" - " beq %3,2f\n" - " mskwl %2,%5,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%4)\n" - " beq %2,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) - : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u32, volatile int *m, int old, int new) -{ - unsigned long prev, cmp; - - __asm__ __volatile__( - "1: ldl_l %0,%5\n" - " cmpeq %0,%3,%1\n" - " beq %1,2f\n" - " mov %4,%1\n" - " stl_c %1,%2\n" - " beq %1,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new) -{ - unsigned long prev, cmp; - - __asm__ __volatile__( - "1: ldq_l %0,%5\n" - " cmpeq %0,%3,%1\n" - " beq %1,2f\n" - " mov %4,%1\n" - " stq_c %1,%2\n" - " beq %1,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) : "memory"); - - return prev; -} - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid cmpxchg(). */ -extern void __cmpxchg_called_with_bad_pointer(void); - -static __always_inline unsigned long -____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new, - int size) -{ - switch (size) { - case 1: - return ____cmpxchg(_u8, ptr, old, new); - case 2: - return ____cmpxchg(_u16, ptr, old, new); - case 4: - return ____cmpxchg(_u32, ptr, old, new); - case 8: - return ____cmpxchg(_u64, ptr, old, new); - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#endif diff --git a/trunk/arch/alpha/kernel/err_ev6.c b/trunk/arch/alpha/kernel/err_ev6.c index 985e5c1681ac..11aee012a8ae 100644 --- a/trunk/arch/alpha/kernel/err_ev6.c +++ b/trunk/arch/alpha/kernel/err_ev6.c @@ -157,8 +157,8 @@ ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, err_print_prefix, streamname[stream], bitsname[bits], sourcename[source]); - printk("%s Address: 0x%016llx\n" - " Syndrome[upper.lower]: %02llx.%02llx\n", + printk("%s Address: 0x%016lx\n" + " Syndrome[upper.lower]: %02lx.%02lx\n", err_print_prefix, c_addr, c2_syn, c1_syn); diff --git a/trunk/arch/alpha/kernel/err_ev7.c b/trunk/arch/alpha/kernel/err_ev7.c index 73770c6ca013..68cd493f54c5 100644 --- a/trunk/arch/alpha/kernel/err_ev7.c +++ b/trunk/arch/alpha/kernel/err_ev7.c @@ -246,13 +246,13 @@ ev7_process_pal_subpacket(struct el_subpacket *header) switch(header->type) { case EL_TYPE__PAL__LOGOUT_FRAME: - printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n", + printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n", err_print_prefix, packet->by_type.logout.whami, packet->by_type.logout.rbox_whami); el_print_timestamp(&packet->by_type.logout.timestamp); - printk("%s EXC_ADDR: %016llx\n" - " HALT_CODE: %llx\n", + printk("%s EXC_ADDR: %016lx\n" + " HALT_CODE: %lx\n", err_print_prefix, packet->by_type.logout.exc_addr, packet->by_type.logout.halt_code); diff --git a/trunk/arch/alpha/kernel/err_marvel.c b/trunk/arch/alpha/kernel/err_marvel.c index 6bfd243efba3..413bf37eb094 100644 --- a/trunk/arch/alpha/kernel/err_marvel.c +++ b/trunk/arch/alpha/kernel/err_marvel.c @@ -129,7 +129,7 @@ marvel_print_po7_crrct_sym(u64 crrct_sym) printk("%s Correctable Error Symptoms:\n" - "%s Syndrome: 0x%llx\n", + "%s Syndrome: 0x%lx\n", err_print_prefix, err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN)); marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC)); @@ -186,7 +186,7 @@ marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask) uncrr_sym &= valid_mask; if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN)) - printk("%s Syndrome: 0x%llx\n", + printk("%s Syndrome: 0x%lx\n", err_print_prefix, EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN)); @@ -307,7 +307,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) sprintf(opcode_str, "BlkIO"); break; default: - sprintf(opcode_str, "0x%llx\n", + sprintf(opcode_str, "0x%lx\n", EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)); break; } @@ -321,7 +321,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) opcode_str); if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) - printk("%s Packet Offset 0x%08llx\n", + printk("%s Packet Offset 0x%08lx\n", err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF)); } @@ -480,8 +480,8 @@ marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io) printk("%s Lost Error\n", err_print_prefix); printk("%s Failing Packet:\n" - "%s Cycle 1: %016llx\n" - "%s Cycle 2: %016llx\n", + "%s Cycle 1: %016lx\n" + "%s Cycle 2: %016lx\n", err_print_prefix, err_print_prefix, io->po7_err_pkt0, err_print_prefix, io->po7_err_pkt1); @@ -515,9 +515,9 @@ marvel_print_pox_tlb_err(u64 tlb_err) if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID)) return; - printk("%s TLB Error on index 0x%llx:\n" + printk("%s TLB Error on index 0x%lx:\n" "%s - %s\n" - "%s - Addr: 0x%016llx\n", + "%s - Addr: 0x%016lx\n", err_print_prefix, EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR), err_print_prefix, @@ -579,7 +579,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) sprintf(message, "Uncorrectable Split Write Data Error"); break; default: - sprintf(message, "%08llx\n", + sprintf(message, "%08lx\n", EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE)); break; } @@ -620,9 +620,9 @@ marvel_print_pox_trans_sum(u64 trans_sum) return; printk("%s Transaction Summary:\n" - "%s Command: 0x%llx - %s\n" - "%s Address: 0x%016llx%s\n" - "%s PCI-X Master Slot: 0x%llx\n", + "%s Command: 0x%lx - %s\n" + "%s Address: 0x%016lx%s\n" + "%s PCI-X Master Slot: 0x%lx\n", err_print_prefix, err_print_prefix, EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD), @@ -964,12 +964,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print) #if 0 printk("%s PORT 7 ERROR:\n" - "%s PO7_ERROR_SUM: %016llx\n" - "%s PO7_UNCRR_SYM: %016llx\n" - "%s PO7_CRRCT_SYM: %016llx\n" - "%s PO7_UGBGE_SYM: %016llx\n" - "%s PO7_ERR_PKT0: %016llx\n" - "%s PO7_ERR_PKT1: %016llx\n", + "%s PO7_ERROR_SUM: %016lx\n" + "%s PO7_UNCRR_SYM: %016lx\n" + "%s PO7_CRRCT_SYM: %016lx\n" + "%s PO7_UGBGE_SYM: %016lx\n" + "%s PO7_ERR_PKT0: %016lx\n" + "%s PO7_ERR_PKT1: %016lx\n", err_print_prefix, err_print_prefix, io->po7_error_sum, err_print_prefix, io->po7_uncrr_sym, @@ -987,12 +987,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print) if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum)) continue; - printk("%s PID %u PORT %d POx_ERR_SUM: %016llx\n", + printk("%s PID %u PORT %d POx_ERR_SUM: %016lx\n", err_print_prefix, lf_subpackets->io_pid, i, io->ports[i].pox_err_sum); marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]); - printk("%s [ POx_FIRST_ERR: %016llx ]\n", + printk("%s [ POx_FIRST_ERR: %016lx ]\n", err_print_prefix, io->ports[i].pox_first_err); marvel_print_pox_err(io->ports[i].pox_first_err, &io->ports[i]); diff --git a/trunk/arch/alpha/kernel/err_titan.c b/trunk/arch/alpha/kernel/err_titan.c index c7e28a88d6e3..257449ed15ef 100644 --- a/trunk/arch/alpha/kernel/err_titan.c +++ b/trunk/arch/alpha/kernel/err_titan.c @@ -107,12 +107,12 @@ titan_parse_p_serror(int which, u64 serror, int print) if (!print) return status; - printk("%s PChip %d SERROR: %016llx\n", + printk("%s PChip %d SERROR: %016lx\n", err_print_prefix, which, serror); if (serror & TITAN__PCHIP_SERROR__ECCMASK) { printk("%s %sorrectable ECC Error:\n" " Source: %-6s Command: %-8s Syndrome: 0x%08x\n" - " Address: 0x%llx\n", + " Address: 0x%lx\n", err_print_prefix, (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], @@ -223,7 +223,7 @@ titan_parse_p_perror(int which, int port, u64 perror, int print) if (!print) return status; - printk("%s PChip %d %cPERROR: %016llx\n", + printk("%s PChip %d %cPERROR: %016lx\n", err_print_prefix, which, port ? 'A' : 'G', perror); if (perror & TITAN__PCHIP_PERROR__IPTPW) @@ -316,7 +316,7 @@ titan_parse_p_agperror(int which, u64 agperror, int print) addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); - printk("%s PChip %d AGPERROR: %016llx\n", err_print_prefix, + printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix, which, agperror); if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) printk("%s No Window\n", err_print_prefix); @@ -597,16 +597,16 @@ privateer_process_680_frame(struct el_common *mchk_header, int print) return status; /* TODO - decode instead of just dumping... */ - printk("%s Summary Flags: %016llx\n" - " CChip DIRx: %016llx\n" - " System Management IR: %016llx\n" - " CPU IR: %016llx\n" - " Power Supply IR: %016llx\n" - " LM78 Fault Status: %016llx\n" - " System Doors: %016llx\n" - " Temperature Warning: %016llx\n" - " Fan Control: %016llx\n" - " Fatal Power Down Code: %016llx\n", + printk("%s Summary Flags: %016lx\n" + " CChip DIRx: %016lx\n" + " System Management IR: %016lx\n" + " CPU IR: %016lx\n" + " Power Supply IR: %016lx\n" + " LM78 Fault Status: %016lx\n" + " System Doors: %016lx\n" + " Temperature Warning: %016lx\n" + " Fan Control: %016lx\n" + " Fatal Power Down Code: %016lx\n", err_print_prefix, emchk->summary, emchk->c_dirx, diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index a91ba28999b5..a3b938811400 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -168,7 +168,7 @@ pcibios_align_resource(void *data, struct resource *res, */ /* Align to multiple of size of minimum base. */ - alignto = max_t(resource_size_t, 0x1000, align); + alignto = max(0x1000UL, align); start = ALIGN(start, alignto); if (hose->sparse_mem_base && size <= 7 * 16*MB) { if (((start / (16*MB)) & 0x7) == 0) { diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c index bfb880af959d..b9094da05d7a 100644 --- a/trunk/arch/alpha/kernel/pci_iommu.c +++ b/trunk/arch/alpha/kernel/pci_iommu.c @@ -247,7 +247,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, && paddr + size <= __direct_map_size) { ret = paddr + __direct_map_base; - DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n", cpu_addr, size, ret, __builtin_return_address(0)); return ret; @@ -258,7 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, if (dac_allowed) { ret = paddr + alpha_mv.pci_dac_offset; - DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n", cpu_addr, size, ret, __builtin_return_address(0)); return ret; @@ -299,7 +299,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, ret = arena->dma_base + dma_ofs * PAGE_SIZE; ret += (unsigned long)cpu_addr & ~PAGE_MASK; - DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n", cpu_addr, size, npages, ret, __builtin_return_address(0)); return ret; @@ -355,14 +355,14 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, && dma_addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ - DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n", + DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); return; } if (dma_addr > 0xffffffff) { - DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n", + DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); return; } @@ -373,9 +373,9 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT; if (dma_ofs * PAGE_SIZE >= arena->size) { - printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx " - " base %llx size %x\n", - dma_addr, arena->dma_base, arena->size); + printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx " + " base %lx size %x\n", dma_addr, arena->dma_base, + arena->size); return; BUG(); } @@ -394,7 +394,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, spin_unlock_irqrestore(&arena->lock, flags); - DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n", + DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n", dma_addr, size, npages, __builtin_return_address(0)); } EXPORT_SYMBOL(pci_unmap_single); @@ -444,7 +444,7 @@ __pci_alloc_consistent(struct pci_dev *pdev, size_t size, goto try_again; } - DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n", + DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n", size, cpu_addr, *dma_addrp, __builtin_return_address(0)); return cpu_addr; @@ -464,7 +464,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr, pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); free_pages((unsigned long)cpu_addr, get_order(size)); - DBGA2("pci_free_consistent: [%llx,%zx] from %p\n", + DBGA2("pci_free_consistent: [%x,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); } EXPORT_SYMBOL(pci_free_consistent); @@ -551,7 +551,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = paddr + __direct_map_base; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> direct %llx\n", + DBGA(" sg_fill: [%p,%lx] -> direct %lx\n", __va(paddr), size, out->dma_address); return 0; @@ -563,7 +563,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = paddr + alpha_mv.pci_dac_offset; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> DAC %llx\n", + DBGA(" sg_fill: [%p,%lx] -> DAC %lx\n", __va(paddr), size, out->dma_address); return 0; @@ -589,7 +589,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> sg %llx np %ld\n", + DBGA(" sg_fill: [%p,%lx] -> sg %lx np %ld\n", __va(paddr), size, out->dma_address, npages); /* All virtually contiguous. We need to find the length of each @@ -752,7 +752,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, if (addr > 0xffffffff) { /* It's a DAC address -- nothing to do. */ - DBGA(" (%ld) DAC [%llx,%zx]\n", + DBGA(" (%ld) DAC [%lx,%lx]\n", sg - end + nents, addr, size); continue; } @@ -760,12 +760,12 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, if (addr >= __direct_map_base && addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ - DBGA(" (%ld) direct [%llx,%zx]\n", + DBGA(" (%ld) direct [%lx,%lx]\n", sg - end + nents, addr, size); continue; } - DBGA(" (%ld) sg [%llx,%zx]\n", + DBGA(" (%ld) sg [%lx,%lx]\n", sg - end + nents, addr, size); npages = iommu_num_pages(addr, size, PAGE_SIZE); diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 567f2598d090..fe14c6747cd6 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -20,7 +20,7 @@ struct pci_controller; extern struct pci_ops apecs_pci_ops; extern void apecs_init_arch(void); extern void apecs_pci_clr_err(void); -extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr); +extern void apecs_machine_check(u64, u64); extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_cia.c */ @@ -29,7 +29,7 @@ extern void cia_init_pci(void); extern void cia_init_arch(void); extern void pyxis_init_arch(void); extern void cia_kill_arch(int); -extern void cia_machine_check(unsigned long vector, unsigned long la_ptr); +extern void cia_machine_check(u64, u64); extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_irongate.c */ @@ -42,7 +42,7 @@ extern void irongate_machine_check(u64, u64); /* core_lca.c */ extern struct pci_ops lca_pci_ops; extern void lca_init_arch(void); -extern void lca_machine_check(unsigned long vector, unsigned long la_ptr); +extern void lca_machine_check(u64, u64); extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_marvel.c */ @@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7); extern struct pci_ops mcpcia_pci_ops; extern void mcpcia_init_arch(void); extern void mcpcia_init_hoses(void); -extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr); +extern void mcpcia_machine_check(u64, u64); extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_polaris.c */ @@ -72,14 +72,14 @@ extern struct pci_ops polaris_pci_ops; extern int polaris_read_config_dword(struct pci_dev *, int, u32 *); extern int polaris_write_config_dword(struct pci_dev *, int, u32); extern void polaris_init_arch(void); -extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr); +extern void polaris_machine_check(u64, u64); #define polaris_pci_tbi ((void *)0) /* core_t2.c */ extern struct pci_ops t2_pci_ops; extern void t2_init_arch(void); extern void t2_kill_arch(int); -extern void t2_machine_check(unsigned long vector, unsigned long la_ptr); +extern void t2_machine_check(u64, u64); extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_titan.c */ @@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void); extern struct pci_ops tsunami_pci_ops; extern void tsunami_init_arch(void); extern void tsunami_kill_arch(int); -extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr); +extern void tsunami_machine_check(u64, u64); extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_wildfire.c */ extern struct pci_ops wildfire_pci_ops; extern void wildfire_init_arch(void); extern void wildfire_kill_arch(int); -extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr); +extern void wildfire_machine_check(u64, u64); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern int wildfire_pa_to_nid(unsigned long); extern int wildfire_cpuid_to_nid(int); diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 80df86cd746b..02bee6983ce2 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -1255,7 +1255,7 @@ show_cpuinfo(struct seq_file *f, void *slot) platform_string(), nr_processors); #ifdef CONFIG_SMP - seq_printf(f, "cpus active\t\t: %u\n" + seq_printf(f, "cpus active\t\t: %d\n" "cpu active mask\t\t: %016lx\n", num_online_cpus(), cpus_addr(cpu_possible_map)[0]); #endif diff --git a/trunk/arch/alpha/kernel/smc37c669.c b/trunk/arch/alpha/kernel/smc37c669.c index bca5bda90cde..fd467b207f0f 100644 --- a/trunk/arch/alpha/kernel/smc37c669.c +++ b/trunk/arch/alpha/kernel/smc37c669.c @@ -2542,8 +2542,8 @@ void __init SMC669_Init ( int index ) SMC37c669_display_device_info( ); #endif local_irq_restore(flags); - printk( "SMC37c669 Super I/O Controller found @ 0x%p\n", - SMC_base ); + printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n", + (unsigned long) SMC_base ); } else { local_irq_restore(flags); diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index 2b5caf3d9b15..e2516f9a8967 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -244,11 +244,12 @@ jensen_init_arch(void) } static void -jensen_machine_check(unsigned long vector, unsigned long la) +jensen_machine_check (u64 vector, u64 la) { printk(KERN_CRIT "Machine check\n"); } + /* * The System Vector */ diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index 9e263256a42d..d232e42be018 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -453,7 +453,7 @@ sable_lynx_enable_irq(unsigned int irq) sable_lynx_irq_swizzle->update_irq_hw(bit, mask); spin_unlock(&sable_lynx_irq_lock); #if 0 - printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", __func__, mask, bit, irq); #endif } @@ -469,7 +469,7 @@ sable_lynx_disable_irq(unsigned int irq) sable_lynx_irq_swizzle->update_irq_hw(bit, mask); spin_unlock(&sable_lynx_irq_lock); #if 0 - printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", __func__, mask, bit, irq); #endif } diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c index 6ee7655b7568..cefc5a355ef9 100644 --- a/trunk/arch/alpha/kernel/traps.c +++ b/trunk/arch/alpha/kernel/traps.c @@ -623,7 +623,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, } lock_kernel(); - printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", + printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", pc, va, opcode, reg); do_exit(SIGSEGV); diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c index 62d4abbaa654..ce4e4296b954 100644 --- a/trunk/arch/avr32/mm/fault.c +++ b/trunk/arch/avr32/mm/fault.c @@ -250,3 +250,21 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access, dump_dtlb(); die("Bus Error", regs, SIGKILL); } + +/* + * This functionality is currently not possible to implement because + * we're using segmentation to ensure a fixed mapping of the kernel + * virtual address space. + * + * It would be possible to implement this, but it would require us to + * disable segmentation at startup and load the kernel mappings into + * the TLB like any other pages. There will be lots of trickery to + * avoid recursive invocation of the TLB miss handler, though... + */ +#ifdef CONFIG_DEBUG_PAGEALLOC +void kernel_map_pages(struct page *page, int numpages, int enable) +{ + +} +EXPORT_SYMBOL(kernel_map_pages); +#endif diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index 2bef5261d96d..24b1ad5334cb 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -849,36 +848,38 @@ static int rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct serial_state *state) +static inline int line_info(char *buf, struct serial_state *state) { - seq_printf(m, "%d: uart:%s port:%lX irq:%d\n", + return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", state->line, uart_config[state->type].name, state->port, state->irq); } -static int rs_proc_show(struct seq_file *m, void *v) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - int i; - - seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS; i++) - line_info(m, &rs_table[i]); - return 0; -} - -static int rs_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rs_proc_show, NULL); + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * --------------------------------------------------------------------- * rs_init() and friends @@ -916,7 +917,7 @@ static const struct tty_operations hp_ops = { .start = rs_start, .hangup = rs_hangup, .wait_until_sent = rs_wait_until_sent, - .proc_fops = &rs_proc_fops, + .read_proc = rs_read_proc, }; /* diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index d6747bae52d8..f0ebb342409d 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -406,21 +405,6 @@ static struct irqaction timer_irqaction = { .name = "timer" }; -static struct platform_device rtc_efi_dev = { - .name = "rtc-efi", - .id = -1, -}; - -static int __init rtc_init(void) -{ - if (platform_device_register(&rtc_efi_dev) < 0) - printk(KERN_ERR "unable to register rtc device...\n"); - - /* not necessarily an error */ - return 0; -} -module_init(rtc_init); - void __init time_init (void) { diff --git a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h index 1784fde2e28f..d8ff4cd89ab5 100644 --- a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h @@ -31,28 +31,24 @@ static inline void gpio_set_value(unsigned gpio, int value) static inline int gpio_direction_input(unsigned gpio) { - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); - return 0; + return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); } static inline int gpio_direction_output(unsigned gpio, int value) { - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); - return 0; + return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); } -static inline int gpio_intmask(unsigned gpio, int value) +static int gpio_intmask(unsigned gpio, int value) { - ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); - return 0; + return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, + value ? 1 << gpio : 0); } -static inline int gpio_polarity(unsigned gpio, int value) +static int gpio_polarity(unsigned gpio, int value) { - ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); - return 0; + return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, + value ? 1 << gpio : 0); } diff --git a/trunk/arch/mips/mm/highmem.c b/trunk/arch/mips/mm/highmem.c index 4481656d1065..060d28dca8a8 100644 --- a/trunk/arch/mips/mm/highmem.c +++ b/trunk/arch/mips/mm/highmem.c @@ -42,7 +42,6 @@ void *__kmap_atomic(struct page *page, enum km_type type) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM @@ -89,7 +88,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) pagefault_disable(); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index e75cae6072c5..9d46c43a4152 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -216,14 +216,17 @@ void __init start_cpu_itimer(void) per_cpu(cpu_data, cpu).it_value = next_tick; } -static struct platform_device rtc_parisc_dev = { +struct platform_device rtc_parisc_dev = { .name = "rtc-parisc", .id = -1, }; static int __init rtc_init(void) { - if (platform_device_register(&rtc_parisc_dev) < 0) + int ret; + + ret = platform_device_register(&rtc_parisc_dev); + if (ret < 0) printk(KERN_ERR "unable to register rtc device...\n"); /* not necessarily an error */ diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 45192dce65c4..ad6b1c084fe3 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -228,9 +228,6 @@ config PPC_OF_PLATFORM_PCI depends on PPC64 # not supported on 32 bits yet default n -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index 6aa0b5e087cd..22091bbfdc9b 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -30,7 +30,6 @@ config DEBUG_STACK_USAGE config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL && !HIBERNATION - depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC help Unmap pages from the kernel linear mapping after free_pages(). This results in a large slowdown, but helps to find certain types diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts index 4319bd70a580..dea30910c136 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -152,21 +152,10 @@ }; par_io@1400 { - #address-cells = <1>; - #size-cells = <1>; reg = <0x1400 0x100>; - ranges = <3 0x1448 0x18>; - compatible = "fsl,mpc8323-qe-pario"; device_type = "par_io"; num-ports = <7>; - qe_pio_d: gpio-controller@1448 { - #gpio-cells = <2>; - compatible = "fsl,mpc8323-qe-pario-bank"; - reg = <3 0x18>; - gpio-controller; - }; - ucc2pio:ucc_pin@02 { pio-map = < /* port pin dir open_drain assignment has_irq */ @@ -236,25 +225,12 @@ }; spi@4c0 { - #address-cells = <1>; - #size-cells = <0>; cell-index = <0>; compatible = "fsl,spi"; reg = <0x4c0 0x40>; interrupts = <2>; interrupt-parent = <&qeic>; - gpios = <&qe_pio_d 13 0>; mode = "cpu-qe"; - - mmc-slot@0 { - compatible = "fsl,mpc8323rdb-mmc-slot", - "mmc-spi-slot"; - reg = <0>; - gpios = <&qe_pio_d 14 1 - &qe_pio_d 15 0>; - voltage-ranges = <3300 3300>; - spi-max-frequency = <50000000>; - }; }; spi@500 { diff --git a/trunk/arch/powerpc/include/asm/highmem.h b/trunk/arch/powerpc/include/asm/highmem.h index 684a73f4324f..545028f86488 100644 --- a/trunk/arch/powerpc/include/asm/highmem.h +++ b/trunk/arch/powerpc/include/asm/highmem.h @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -95,7 +94,6 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM diff --git a/trunk/arch/powerpc/include/asm/suspend.h b/trunk/arch/powerpc/include/asm/suspend.h index c6efc3466aa6..cbf2c9404c37 100644 --- a/trunk/arch/powerpc/include/asm/suspend.h +++ b/trunk/arch/powerpc/include/asm/suspend.h @@ -3,4 +3,7 @@ static inline int arch_prepare_suspend(void) { return 0; } +void save_processor_state(void); +void restore_processor_state(void); + #endif /* __ASM_POWERPC_SUSPEND_H */ diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 567ded7c3b9b..2a1295f19832 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -40,116 +39,16 @@ #endif #ifdef CONFIG_QUICC_ENGINE -static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, - struct spi_board_info *board_infos, - unsigned int num_board_infos, - void (*cs_control)(struct spi_device *dev, - bool on)) +static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) { - struct device_node *np; - unsigned int i = 0; - - for_each_compatible_node(np, type, compatible) { - int ret; - unsigned int j; - const void *prop; - struct resource res[2]; - struct platform_device *pdev; - struct fsl_spi_platform_data pdata = { - .cs_control = cs_control, - }; - - memset(res, 0, sizeof(res)); - - pdata.sysclk = sysclk; - - prop = of_get_property(np, "reg", NULL); - if (!prop) - goto err; - pdata.bus_num = *(u32 *)prop; - - prop = of_get_property(np, "cell-index", NULL); - if (prop) - i = *(u32 *)prop; - - prop = of_get_property(np, "mode", NULL); - if (prop && !strcmp(prop, "cpu-qe")) - pdata.qe_mode = 1; - - for (j = 0; j < num_board_infos; j++) { - if (board_infos[j].bus_num == pdata.bus_num) - pdata.max_chipselect++; - } - - if (!pdata.max_chipselect) - continue; - - ret = of_address_to_resource(np, 0, &res[0]); - if (ret) - goto err; - - ret = of_irq_to_resource(np, 0, &res[1]); - if (ret == NO_IRQ) - goto err; - - pdev = platform_device_alloc("mpc83xx_spi", i); - if (!pdev) - goto err; - - ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); - if (ret) - goto unreg; - - ret = platform_device_add_resources(pdev, res, - ARRAY_SIZE(res)); - if (ret) - goto unreg; - - ret = platform_device_add(pdev); - if (ret) - goto unreg; - - goto next; -unreg: - platform_device_del(pdev); -err: - pr_err("%s: registration failed\n", np->full_name); -next: - i++; - } - - return i; + pr_debug("%s %d %d\n", __func__, cs, polarity); + par_io_data_set(3, 13, polarity); } -static int __init fsl_spi_init(struct spi_board_info *board_infos, - unsigned int num_board_infos, - void (*cs_control)(struct spi_device *spi, - bool on)) +static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) { - u32 sysclk = -1; - int ret; - - /* SPI controller is either clocked from QE or SoC clock */ - sysclk = get_brgfreq(); - if (sysclk == -1) { - sysclk = fsl_get_sys_freq(); - if (sysclk == -1) - return -ENODEV; - } - - ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, - num_board_infos, cs_control); - if (!ret) - of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, - num_board_infos, cs_control); - - return spi_register_board_info(board_infos, num_board_infos); -} - -static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) -{ - pr_debug("%s %d %d\n", __func__, spi->chip_select, on); - par_io_data_set(3, 13, on); + pr_debug("%s %d %d\n", __func__, cs, polarity); + par_io_data_set(3, 13, !polarity); } static struct mmc_spi_platform_data mpc832x_mmc_pdata = { @@ -175,13 +74,9 @@ static int __init mpc832x_spi_init(void) par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */ par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */ - /* - * Don't bother with legacy stuff when device tree contains - * mmc-spi-slot node. - */ - if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot")) - return 0; - return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control); + return fsl_spi_init(&mpc832x_spi_boardinfo, 1, + mpc83xx_spi_activate_cs, + mpc83xx_spi_deactivate_cs); } machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); #endif /* CONFIG_QUICC_ENGINE */ diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index afe8dbc964aa..a01c89d3f9bd 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -417,6 +417,115 @@ static int __init fsl_usb_of_init(void) arch_initcall(fsl_usb_of_init); +static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, + struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)) +{ + struct device_node *np; + unsigned int i = 0; + + for_each_compatible_node(np, type, compatible) { + int ret; + unsigned int j; + const void *prop; + struct resource res[2]; + struct platform_device *pdev; + struct fsl_spi_platform_data pdata = { + .activate_cs = activate_cs, + .deactivate_cs = deactivate_cs, + }; + + memset(res, 0, sizeof(res)); + + pdata.sysclk = sysclk; + + prop = of_get_property(np, "reg", NULL); + if (!prop) + goto err; + pdata.bus_num = *(u32 *)prop; + + prop = of_get_property(np, "cell-index", NULL); + if (prop) + i = *(u32 *)prop; + + prop = of_get_property(np, "mode", NULL); + if (prop && !strcmp(prop, "cpu-qe")) + pdata.qe_mode = 1; + + for (j = 0; j < num_board_infos; j++) { + if (board_infos[j].bus_num == pdata.bus_num) + pdata.max_chipselect++; + } + + if (!pdata.max_chipselect) + continue; + + ret = of_address_to_resource(np, 0, &res[0]); + if (ret) + goto err; + + ret = of_irq_to_resource(np, 0, &res[1]); + if (ret == NO_IRQ) + goto err; + + pdev = platform_device_alloc("mpc83xx_spi", i); + if (!pdev) + goto err; + + ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); + if (ret) + goto unreg; + + ret = platform_device_add_resources(pdev, res, + ARRAY_SIZE(res)); + if (ret) + goto unreg; + + ret = platform_device_add(pdev); + if (ret) + goto unreg; + + goto next; +unreg: + platform_device_del(pdev); +err: + pr_err("%s: registration failed\n", np->full_name); +next: + i++; + } + + return i; +} + +int __init fsl_spi_init(struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)) +{ + u32 sysclk = -1; + int ret; + +#ifdef CONFIG_QUICC_ENGINE + /* SPI controller is either clocked from QE or SoC clock */ + sysclk = get_brgfreq(); +#endif + if (sysclk == -1) { + sysclk = fsl_get_sys_freq(); + if (sysclk == -1) + return -ENODEV; + } + + ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, + num_board_infos, activate_cs, deactivate_cs); + if (!ret) + of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, + num_board_infos, activate_cs, deactivate_cs); + + return spi_register_board_info(board_infos, num_board_infos); +} + #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) static __be32 __iomem *rstcr; diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.h b/trunk/arch/powerpc/sysdev/fsl_soc.h index 42381bb6cd51..9c744e4285a0 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.h +++ b/trunk/arch/powerpc/sysdev/fsl_soc.h @@ -4,8 +4,6 @@ #include -struct spi_device; - extern phys_addr_t get_immrbase(void); #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) extern u32 get_brgfreq(void); @@ -19,6 +17,11 @@ extern u32 fsl_get_sys_freq(void); struct spi_board_info; struct device_node; +extern int fsl_spi_init(struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)); + extern void fsl_rstcr_restart(char *cmd); #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index dcb667c4375a..2a8af5e16345 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -72,9 +72,6 @@ config PGSTE config VIRT_CPU_ACCOUNTING def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - mainmenu "Linux Kernel Configuration" config S390 diff --git a/trunk/arch/s390/Kconfig.debug b/trunk/arch/s390/Kconfig.debug index 7e297a3cde34..4599fa06bd82 100644 --- a/trunk/arch/s390/Kconfig.debug +++ b/trunk/arch/s390/Kconfig.debug @@ -9,7 +9,6 @@ source "lib/Kconfig.debug" config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL - depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC help Unmap pages from the kernel linear mapping after free_pages(). This results in a slowdown, but helps to find certain types of diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index cc12cd48bbc5..c3ea215334f6 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -124,9 +124,6 @@ config ARCH_NO_VIRT_TO_BUS config OF def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y if SPARC64 - source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/trunk/arch/sparc/Kconfig.debug b/trunk/arch/sparc/Kconfig.debug index d001b42041a5..b8a15e271bfa 100644 --- a/trunk/arch/sparc/Kconfig.debug +++ b/trunk/arch/sparc/Kconfig.debug @@ -24,8 +24,7 @@ config STACK_DEBUG config DEBUG_PAGEALLOC bool "Debug page memory allocations" - depends on DEBUG_KERNEL && !HIBERNATION - depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC + depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION help Unmap pages from the kernel linear mapping after free_pages(). This results in a large slowdown, but helps to find certain types diff --git a/trunk/arch/sparc/mm/highmem.c b/trunk/arch/sparc/mm/highmem.c index 7916feba6e4a..752d0c9fb544 100644 --- a/trunk/arch/sparc/mm/highmem.c +++ b/trunk/arch/sparc/mm/highmem.c @@ -39,7 +39,6 @@ void *kmap_atomic(struct page *page, enum km_type type) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/trunk/arch/um/drivers/pcap_user.h b/trunk/arch/um/drivers/pcap_user.h index d8ba6153f912..96b80b565eeb 100644 --- a/trunk/arch/um/drivers/pcap_user.h +++ b/trunk/arch/um/drivers/pcap_user.h @@ -19,3 +19,13 @@ extern const struct net_user_info pcap_user_info; extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri); +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/port.h b/trunk/arch/um/drivers/port.h index 372a80c0556a..9117609a575d 100644 --- a/trunk/arch/um/drivers/port.h +++ b/trunk/arch/um/drivers/port.h @@ -18,3 +18,13 @@ extern void port_remove_dev(void *d); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/ssl.h b/trunk/arch/um/drivers/ssl.h index 314d17725ce6..98412aa66607 100644 --- a/trunk/arch/um/drivers/ssl.h +++ b/trunk/arch/um/drivers/ssl.h @@ -11,3 +11,13 @@ extern void ssl_receive_char(int line, char ch); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/stdio_console.h b/trunk/arch/um/drivers/stdio_console.h index 6d8275f71fd4..505a3d5bea5e 100644 --- a/trunk/arch/um/drivers/stdio_console.h +++ b/trunk/arch/um/drivers/stdio_console.h @@ -9,3 +9,13 @@ extern void save_console_flags(void); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index d42f826a8ab9..0a868118cf06 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -17,6 +17,7 @@ * James McMechan */ +#define MAJOR_NR UBD_MAJOR #define UBD_SHIFT 4 #include "linux/kernel.h" @@ -114,7 +115,7 @@ static struct block_device_operations ubd_blops = { }; /* Protected by ubd_lock */ -static int fake_major = UBD_MAJOR; +static int fake_major = MAJOR_NR; static struct gendisk *ubd_gendisk[MAX_DEV]; static struct gendisk *fake_gendisk[MAX_DEV]; @@ -298,7 +299,7 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out) } mutex_lock(&ubd_lock); - if (fake_major != UBD_MAJOR) { + if(fake_major != MAJOR_NR){ *error_out = "Can't assign a fake major twice"; goto out1; } @@ -817,13 +818,13 @@ static int ubd_disk_register(int major, u64 size, int unit, disk->first_minor = unit << UBD_SHIFT; disk->fops = &ubd_blops; set_capacity(disk, size / 512); - if (major == UBD_MAJOR) + if(major == MAJOR_NR) sprintf(disk->disk_name, "ubd%c", 'a' + unit); else sprintf(disk->disk_name, "ubd_fake%d", unit); /* sysfs register (not for ide fake devices) */ - if (major == UBD_MAJOR) { + if (major == MAJOR_NR) { ubd_devs[unit].pdev.id = unit; ubd_devs[unit].pdev.name = DRIVER_NAME; ubd_devs[unit].pdev.dev.release = ubd_device_release; @@ -870,13 +871,13 @@ static int ubd_add(int n, char **error_out) ubd_dev->queue->queuedata = ubd_dev; blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); - err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); + err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; goto out_cleanup; } - if (fake_major != UBD_MAJOR) + if(fake_major != MAJOR_NR) ubd_disk_register(fake_major, ubd_dev->size, n, &fake_gendisk[n]); @@ -1058,10 +1059,10 @@ static int __init ubd_init(void) char *error; int i, err; - if (register_blkdev(UBD_MAJOR, "ubd")) + if (register_blkdev(MAJOR_NR, "ubd")) return -1; - if (fake_major != UBD_MAJOR) { + if (fake_major != MAJOR_NR) { char name[sizeof("ubd_nnn\0")]; snprintf(name, sizeof(name), "ubd_%d", fake_major); diff --git a/trunk/arch/um/drivers/xterm.h b/trunk/arch/um/drivers/xterm.h index 56b9c4aba423..f33a6e77b186 100644 --- a/trunk/arch/um/drivers/xterm.h +++ b/trunk/arch/um/drivers/xterm.h @@ -10,3 +10,13 @@ extern int xterm_fd(int socket, int *pid_out); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/irq_vectors.h b/trunk/arch/um/include/asm/irq_vectors.h index 272a81e0ce14..62ddba6fc733 100644 --- a/trunk/arch/um/include/asm/irq_vectors.h +++ b/trunk/arch/um/include/asm/irq_vectors.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/mmu.h b/trunk/arch/um/include/asm/mmu.h index cf259de51531..2cf35c21d694 100644 --- a/trunk/arch/um/include/asm/mmu.h +++ b/trunk/arch/um/include/asm/mmu.h @@ -10,3 +10,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pda.h b/trunk/arch/um/include/asm/pda.h index ddcd774fc2a0..0d8bf33ffd42 100644 --- a/trunk/arch/um/include/asm/pda.h +++ b/trunk/arch/um/include/asm/pda.h @@ -19,3 +19,13 @@ extern struct foo me; #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pgalloc.h b/trunk/arch/um/include/asm/pgalloc.h index 718984359f8c..9062a6e72241 100644 --- a/trunk/arch/um/include/asm/pgalloc.h +++ b/trunk/arch/um/include/asm/pgalloc.h @@ -60,3 +60,13 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pgtable-3level.h b/trunk/arch/um/include/asm/pgtable-3level.h index 084de4a9fc70..0446f456b428 100644 --- a/trunk/arch/um/include/asm/pgtable-3level.h +++ b/trunk/arch/um/include/asm/pgtable-3level.h @@ -134,3 +134,13 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot) #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/frame_kern.h b/trunk/arch/um/include/shared/frame_kern.h index 76078490c258..ce9514f57211 100644 --- a/trunk/arch/um/include/shared/frame_kern.h +++ b/trunk/arch/um/include/shared/frame_kern.h @@ -20,3 +20,13 @@ extern int setup_signal_stack_si(unsigned long stack_top, int sig, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/initrd.h b/trunk/arch/um/include/shared/initrd.h index 22673bcc273d..439b9a814985 100644 --- a/trunk/arch/um/include/shared/initrd.h +++ b/trunk/arch/um/include/shared/initrd.h @@ -10,3 +10,13 @@ extern int load_initrd(char *filename, void *buf, int size); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/irq_kern.h b/trunk/arch/um/include/shared/irq_kern.h index b05d22f3d84e..fba3895274f9 100644 --- a/trunk/arch/um/include/shared/irq_kern.h +++ b/trunk/arch/um/include/shared/irq_kern.h @@ -16,3 +16,13 @@ extern int um_request_irq(unsigned int irq, int fd, int type, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/mem_kern.h b/trunk/arch/um/include/shared/mem_kern.h index 69be0fd0ce4b..cb7e196d366b 100644 --- a/trunk/arch/um/include/shared/mem_kern.h +++ b/trunk/arch/um/include/shared/mem_kern.h @@ -18,3 +18,13 @@ extern void register_remapper(struct remapper *info); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/ubd_user.h b/trunk/arch/um/include/shared/ubd_user.h index 3845051f1b10..bb66517f0739 100644 --- a/trunk/arch/um/include/shared/ubd_user.h +++ b/trunk/arch/um/include/shared/ubd_user.h @@ -14,3 +14,13 @@ extern int kernel_fd; #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 388ec0a3ea9b..499e5e95e609 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -28,7 +28,7 @@ $(obj)/config.tmp: $(objtree)/.config FORCE $(call if_changed,quote1) quiet_cmd_quote1 = QUOTE $@ - cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n",/' \ + cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' \ $< > $@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE @@ -36,9 +36,9 @@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE quiet_cmd_quote2 = QUOTE $@ cmd_quote2 = sed -e '/CONFIG/{' \ - -e 's/"CONFIG"//' \ + -e 's/"CONFIG"\;/""/' \ -e 'r $(obj)/config.tmp' \ -e 'a \' \ - -e '""' \ + -e '""\;' \ -e '}' \ $< > $@ diff --git a/trunk/arch/um/kernel/config.c.in b/trunk/arch/um/kernel/config.c.in index b7a43feafde7..c062cbfe386e 100644 --- a/trunk/arch/um/kernel/config.c.in +++ b/trunk/arch/um/kernel/config.c.in @@ -7,15 +7,11 @@ #include #include "init.h" -static __initdata const char *config[] = { -"CONFIG" -}; +static __initdata char *config = "CONFIG"; static int __init print_config(char *line, int *add) { - int i; - for (i = 0; i < sizeof(config)/sizeof(config[0]); i++) - printf("%s", config[i]); + printf("%s", config); exit(0); } @@ -24,3 +20,13 @@ __uml_setup("--showconfig", print_config, " Prints the config file that this UML binary was generated from.\n\n" ); +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 02ee9adff54a..183db26d01bf 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -244,7 +244,7 @@ static void __init check_sysemu(void) if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) - fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed"); + fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); while (1) { count++; @@ -252,12 +252,12 @@ static void __init check_sysemu(void) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) - fatal_perror("check_sysemu: wait failed"); + fatal_perror("check_ptrace : wait failed"); if (WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))) { if (!count) { - non_fatal("check_sysemu: SYSEMU_SINGLESTEP " + non_fatal("check_ptrace : SYSEMU_SINGLESTEP " "doesn't singlestep"); goto fail; } @@ -271,7 +271,7 @@ static void __init check_sysemu(void) else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; else { - non_fatal("check_sysemu: expected SIGTRAP or " + non_fatal("check_ptrace : expected SIGTRAP or " "(SIGTRAP | 0x80), got status = %d\n", status); goto fail; diff --git a/trunk/arch/um/sys-i386/asm/archparam.h b/trunk/arch/um/sys-i386/asm/archparam.h index 2a18a884ca1b..93fd723344e5 100644 --- a/trunk/arch/um/sys-i386/asm/archparam.h +++ b/trunk/arch/um/sys-i386/asm/archparam.h @@ -14,3 +14,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/shared/sysdep/checksum.h b/trunk/arch/um/sys-i386/shared/sysdep/checksum.h index ed47445f3905..0cb4645cbeb8 100644 --- a/trunk/arch/um/sys-i386/shared/sysdep/checksum.h +++ b/trunk/arch/um/sys-i386/shared/sysdep/checksum.h @@ -199,3 +199,13 @@ static __inline__ __wsum csum_and_copy_to_user(const void *src, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ia64/sysdep/ptrace.h b/trunk/arch/um/sys-ia64/sysdep/ptrace.h index 0f0f4e6fd334..42dd8fb6f2f9 100644 --- a/trunk/arch/um/sys-ia64/sysdep/ptrace.h +++ b/trunk/arch/um/sys-ia64/sysdep/ptrace.h @@ -14,3 +14,13 @@ struct sys_pt_regs { #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ia64/sysdep/sigcontext.h b/trunk/arch/um/sys-ia64/sysdep/sigcontext.h index 76b43161e779..f15fb25260ba 100644 --- a/trunk/arch/um/sys-ia64/sysdep/sigcontext.h +++ b/trunk/arch/um/sys-ia64/sysdep/sigcontext.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ia64/sysdep/syscalls.h b/trunk/arch/um/sys-ia64/sysdep/syscalls.h index 5f6700c41558..4a1f46ef1ebc 100644 --- a/trunk/arch/um/sys-ia64/sysdep/syscalls.h +++ b/trunk/arch/um/sys-ia64/sysdep/syscalls.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/miscthings.c b/trunk/arch/um/sys-ppc/miscthings.c index 1c11aed9c719..373061c50129 100644 --- a/trunk/arch/um/sys-ppc/miscthings.c +++ b/trunk/arch/um/sys-ppc/miscthings.c @@ -40,3 +40,14 @@ void shove_aux_table(unsigned long sp) } /* END stuff taken from arch/ppc/kernel/process.c */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/ptrace.c b/trunk/arch/um/sys-ppc/ptrace.c index 66ef155248f1..8e71b47f2b8e 100644 --- a/trunk/arch/um/sys-ppc/ptrace.c +++ b/trunk/arch/um/sys-ppc/ptrace.c @@ -56,3 +56,13 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long *) data); } +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/ptrace_user.c b/trunk/arch/um/sys-ppc/ptrace_user.c index 224d2403c37b..ff0b9c077a13 100644 --- a/trunk/arch/um/sys-ppc/ptrace_user.c +++ b/trunk/arch/um/sys-ppc/ptrace_user.c @@ -27,3 +27,13 @@ int ptrace_setregs(long pid, unsigned long *regs_in) } return 0; } +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h b/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h index 0e3230e937e1..df2397dba3e5 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h @@ -91,3 +91,13 @@ extern void shove_aux_table(unsigned long sp); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h b/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h index b7286f0a1e00..f20d965de9c7 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h @@ -50,3 +50,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h b/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h index 1ff81552251c..679df351e19b 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h @@ -41,3 +41,13 @@ int old_mmap(unsigned long addr, unsigned long len, #define LAST_ARCH_SYSCALL __NR_fadvise64 +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/sigcontext.c b/trunk/arch/um/sys-ppc/sigcontext.c index 40694d0f3d15..4bdc15c89edd 100644 --- a/trunk/arch/um/sys-ppc/sigcontext.c +++ b/trunk/arch/um/sys-ppc/sigcontext.c @@ -2,3 +2,13 @@ #include "asm/sigcontext.h" #include "sysdep/ptrace.h" +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/asm/archparam.h b/trunk/arch/um/sys-x86_64/asm/archparam.h index 6c083663b8d9..270ed9586b68 100644 --- a/trunk/arch/um/sys-x86_64/asm/archparam.h +++ b/trunk/arch/um/sys-x86_64/asm/archparam.h @@ -14,3 +14,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/asm/module.h b/trunk/arch/um/sys-x86_64/asm/module.h index 8eb79c2d07d5..35b5491d3e96 100644 --- a/trunk/arch/um/sys-x86_64/asm/module.h +++ b/trunk/arch/um/sys-x86_64/asm/module.h @@ -18,3 +18,13 @@ struct mod_arch_specific #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/mem.c b/trunk/arch/um/sys-x86_64/mem.c index 3f8df8abf347..3f59a0a4f156 100644 --- a/trunk/arch/um/sys-x86_64/mem.c +++ b/trunk/arch/um/sys-x86_64/mem.c @@ -14,3 +14,12 @@ unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; unsigned long vm_force_exec32 = PROT_EXEC; +/* Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 748e50a1a152..45161b816313 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -165,9 +165,6 @@ config AUDIT_ARCH config ARCH_SUPPORTS_OPTIMIZED_INLINING def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - # Use the generic interrupt handling code in kernel/irq/: config GENERIC_HARDIRQS bool diff --git a/trunk/arch/x86/Kconfig.debug b/trunk/arch/x86/Kconfig.debug index a345cb5447a8..fdb45df608b6 100644 --- a/trunk/arch/x86/Kconfig.debug +++ b/trunk/arch/x86/Kconfig.debug @@ -75,7 +75,6 @@ config DEBUG_STACK_USAGE config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL - depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC ---help--- Unmap pages from the kernel linear mapping after free_pages(). This results in a large slowdown, but helps to find certain types diff --git a/trunk/arch/x86/include/asm/suspend_32.h b/trunk/arch/x86/include/asm/suspend_32.h index 48dcfa62ea07..a5074bd0f8be 100644 --- a/trunk/arch/x86/include/asm/suspend_32.h +++ b/trunk/arch/x86/include/asm/suspend_32.h @@ -24,4 +24,28 @@ struct saved_context { unsigned long return_address; } __attribute__((packed)); +#ifdef CONFIG_ACPI +extern unsigned long saved_eip; +extern unsigned long saved_esp; +extern unsigned long saved_ebp; +extern unsigned long saved_ebx; +extern unsigned long saved_esi; +extern unsigned long saved_edi; + +static inline void acpi_save_register_state(unsigned long return_point) +{ + saved_eip = return_point; + asm volatile("movl %%esp,%0" : "=m" (saved_esp)); + asm volatile("movl %%ebp,%0" : "=m" (saved_ebp)); + asm volatile("movl %%ebx,%0" : "=m" (saved_ebx)); + asm volatile("movl %%edi,%0" : "=m" (saved_edi)); + asm volatile("movl %%esi,%0" : "=m" (saved_esi)); +} + +#define acpi_restore_register_state() do {} while (0) + +/* routines for saving/restoring kernel state */ +extern int acpi_save_state_mem(void); +#endif + #endif /* _ASM_X86_SUSPEND_32_H */ diff --git a/trunk/arch/x86/kernel/asm-offsets_32.c b/trunk/arch/x86/kernel/asm-offsets_32.c index 5a6aa1c1162f..fbf2f33e3080 100644 --- a/trunk/arch/x86/kernel/asm-offsets_32.c +++ b/trunk/arch/x86/kernel/asm-offsets_32.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/x86/kernel/asm-offsets_64.c b/trunk/arch/x86/kernel/asm-offsets_64.c index e72f062fb4b5..8793ab33e2c1 100644 --- a/trunk/arch/x86/kernel/asm-offsets_64.c +++ b/trunk/arch/x86/kernel/asm-offsets_64.c @@ -16,7 +16,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/x86/mm/highmem_32.c b/trunk/arch/x86/mm/highmem_32.c index 5bc5d1688c1c..522db5e3d0bf 100644 --- a/trunk/arch/x86/mm/highmem_32.c +++ b/trunk/arch/x86/mm/highmem_32.c @@ -19,6 +19,49 @@ void kunmap(struct page *page) kunmap_high(page); } +static void debug_kmap_atomic_prot(enum km_type type) +{ +#ifdef CONFIG_DEBUG_HIGHMEM + static unsigned warn_count = 10; + + if (unlikely(warn_count == 0)) + return; + + if (unlikely(in_interrupt())) { + if (in_irq()) { + if (type != KM_IRQ0 && type != KM_IRQ1 && + type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && + type != KM_BOUNCE_READ) { + WARN_ON(1); + warn_count--; + } + } else if (!irqs_disabled()) { /* softirq */ + if (type != KM_IRQ0 && type != KM_IRQ1 && + type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && + type != KM_SKB_SUNRPC_DATA && + type != KM_SKB_DATA_SOFTIRQ && + type != KM_BOUNCE_READ) { + WARN_ON(1); + warn_count--; + } + } + } + + if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || + type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) { + if (!irqs_disabled()) { + WARN_ON(1); + warn_count--; + } + } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { + if (irq_count() == 0 && !irqs_disabled()) { + WARN_ON(1); + warn_count--; + } + } +#endif +} + /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because * no global lock is needed and because the kmap code must perform a global TLB @@ -38,9 +81,8 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); + debug_kmap_atomic_prot(type); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte-idx))); diff --git a/trunk/arch/x86/mm/iomap_32.c b/trunk/arch/x86/mm/iomap_32.c index bff0c9032f8c..699c9b2895ae 100644 --- a/trunk/arch/x86/mm/iomap_32.c +++ b/trunk/arch/x86/mm/iomap_32.c @@ -19,7 +19,6 @@ #include #include #include -#include int is_io_mapping_possible(resource_size_t base, unsigned long size) { @@ -72,7 +71,6 @@ iounmap_atomic(void *kvaddr, enum km_type type) unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - debug_kmap_atomic(type); /* * Force other mappings to Oops if they'll try to access this pte * without first remap it. Keeping stale mappings around is a bad idea diff --git a/trunk/arch/x86/power/cpu_32.c b/trunk/arch/x86/power/cpu_32.c index ce702c5b3a2c..274d06082f48 100644 --- a/trunk/arch/x86/power/cpu_32.c +++ b/trunk/arch/x86/power/cpu_32.c @@ -12,7 +12,6 @@ #include #include #include -#include static struct saved_context saved_context; diff --git a/trunk/arch/x86/power/cpu_64.c b/trunk/arch/x86/power/cpu_64.c index 5343540f2607..e3b6cf70d62c 100644 --- a/trunk/arch/x86/power/cpu_64.c +++ b/trunk/arch/x86/power/cpu_64.c @@ -15,7 +15,6 @@ #include #include #include -#include static void fix_processor_context(void); diff --git a/trunk/arch/x86/power/hibernate_64.c b/trunk/arch/x86/power/hibernate_64.c index 65fdc86e923f..6dd000dd7933 100644 --- a/trunk/arch/x86/power/hibernate_64.c +++ b/trunk/arch/x86/power/hibernate_64.c @@ -14,7 +14,6 @@ #include #include #include -#include /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; diff --git a/trunk/arch/xtensa/platforms/iss/console.c b/trunk/arch/xtensa/platforms/iss/console.c index 4c559cf7da2d..25d46c84eb08 100644 --- a/trunk/arch/xtensa/platforms/iss/console.c +++ b/trunk/arch/xtensa/platforms/iss/console.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -177,24 +176,22 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) /* Stub, once again.. */ } -static int rs_proc_show(struct seq_file *m, void *v) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); - return 0; -} + int len = 0; + off_t begin = 0; -static int rs_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rs_proc_show, NULL); + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + *eof = 1; + + if (off >= len + begin) + return 0; + + *start = page + (off - begin); + return ((count < begin + len - off) ? count : begin + len - off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; static struct tty_operations serial_ops = { .open = rs_open, @@ -206,7 +203,7 @@ static struct tty_operations serial_ops = { .chars_in_buffer = rs_chars_in_buffer, .hangup = rs_hangup, .wait_until_sent = rs_wait_until_sent, - .proc_fops = &rs_proc_fops, + .read_proc = rs_read_proc }; int __init rs_init(void) diff --git a/trunk/drivers/auxdisplay/Kconfig b/trunk/drivers/auxdisplay/Kconfig index c07e725ea93d..14b9d5f4c203 100644 --- a/trunk/drivers/auxdisplay/Kconfig +++ b/trunk/drivers/auxdisplay/Kconfig @@ -6,6 +6,7 @@ # menuconfig AUXDISPLAY + depends on PARPORT bool "Auxiliary Display support" ---help--- Say Y here to get to see options for auxiliary display drivers. @@ -13,7 +14,7 @@ menuconfig AUXDISPLAY If you say N, all options in this submenu will be skipped and disabled. -if AUXDISPLAY +if AUXDISPLAY && PARPORT config KS0108 tristate "KS0108 LCD Controller" diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 40b17d3b55a1..2621ed2ce6d2 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -1192,30 +1192,6 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { return err; } -static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) -{ - int err; - sector_t sec; - loff_t sz; - - err = -ENXIO; - if (unlikely(lo->lo_state != Lo_bound)) - goto out; - err = figure_loop_size(lo); - if (unlikely(err)) - goto out; - sec = get_capacity(lo->lo_disk); - /* the width of sector_t may be narrow for bit-shift */ - sz = sec; - sz <<= 9; - mutex_lock(&bdev->bd_mutex); - bd_set_size(bdev, sz); - mutex_unlock(&bdev->bd_mutex); - - out: - return err; -} - static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { @@ -1248,11 +1224,6 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_GET_STATUS64: err = loop_get_status64(lo, (struct loop_info64 __user *) arg); break; - case LOOP_SET_CAPACITY: - err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_capacity(lo, bdev); - break; default: err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } @@ -1400,7 +1371,6 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, lo, (struct compat_loop_info __user *) arg); mutex_unlock(&lo->lo_ctl_mutex); break; - case LOOP_SET_CAPACITY: case LOOP_CLR_FD: case LOOP_GET_STATUS64: case LOOP_SET_STATUS64: diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index fd3ebd1be570..a58869ea8513 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -79,7 +79,6 @@ static char *serial_version = "4.30"; #include #include #include -#include #include #include #include @@ -1826,13 +1825,14 @@ static int rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct serial_state *state) +static inline int line_info(char *buf, struct serial_state *state) { struct async_struct *info = state->info, scr_info; char stat_buf[30], control, status; + int ret; unsigned long flags; - seq_printf(m, "%d: uart:amiga_builtin",state->line); + ret = sprintf(buf, "%d: uart:amiga_builtin",state->line); /* * Figure out the current RS-232 lines @@ -1864,49 +1864,55 @@ static inline void line_info(struct seq_file *m, struct serial_state *state) strcat(stat_buf, "|CD"); if (info->quot) { - seq_printf(m, " baud:%d", state->baud_base / info->quot); + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); } - seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); if (state->icount.frame) - seq_printf(m, " fe:%d", state->icount.frame); + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); if (state->icount.parity) - seq_printf(m, " pe:%d", state->icount.parity); + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); if (state->icount.brk) - seq_printf(m, " brk:%d", state->icount.brk); + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); if (state->icount.overrun) - seq_printf(m, " oe:%d", state->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); /* * Last thing is the RS-232 status lines */ - seq_printf(m, " %s\n", stat_buf+1); -} - -static int rs_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); - line_info(m, &rs_table[0]); - return 0; + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; } -static int rs_proc_open(struct inode *inode, struct file *file) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - return single_open(file, rs_proc_show, NULL); + int len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + l = line_info(page + len, &rs_table[0]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * --------------------------------------------------------------------- * rs_init() and friends @@ -1945,9 +1951,9 @@ static const struct tty_operations serial_ops = { .break_ctl = rs_break, .send_xchar = rs_send_xchar, .wait_until_sent = rs_wait_until_sent, + .read_proc = rs_read_proc, .tiocmget = rs_tiocmget, .tiocmset = rs_tiocmset, - .proc_fops = &rs_proc_fops, }; /* diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 272db0e2b491..6a59f72a9c21 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -657,7 +657,6 @@ #include #include -#include static void cy_throttle(struct tty_struct *tty); static void cy_send_xchar(struct tty_struct *tty, char ch); @@ -869,6 +868,8 @@ static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); static unsigned detect_isa_irq(void __iomem *); #endif /* CONFIG_ISA */ +static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *); + #ifndef CONFIG_CYZ_INTR static void cyz_poll(unsigned long); @@ -5215,22 +5216,31 @@ static struct pci_driver cy_pci_driver = { }; #endif -static int cyclades_proc_show(struct seq_file *m, void *v) +static int +cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, + int *eof, void *data) { struct cyclades_port *info; unsigned int i, j; + int len = 0; + off_t begin = 0; + off_t pos = 0; + int size; __u32 cur_jifs = jiffies; - seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn " + size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn " "IdleIn Overruns Ldisc\n"); + pos += size; + len += size; + /* Output one line for each known port */ for (i = 0; i < NR_CARDS; i++) for (j = 0; j < cy_card[i].nports; j++) { info = &cy_card[i].ports[j]; if (info->port.count) - seq_printf(m, "%3d %8lu %10lu %8lu " + size = sprintf(buf + len, "%3d %8lu %10lu %8lu " "%10lu %8lu %9lu %6ld\n", info->line, (cur_jifs - info->idle_stats.in_use) / HZ, info->idle_stats.xmit_bytes, @@ -5241,26 +5251,30 @@ static int cyclades_proc_show(struct seq_file *m, void *v) /* FIXME: double check locking */ (long)info->port.tty->ldisc.ops->num); else - seq_printf(m, "%3d %8lu %10lu %8lu " + size = sprintf(buf + len, "%3d %8lu %10lu %8lu " "%10lu %8lu %9lu %6ld\n", info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); - } - return 0; -} + len += size; + pos = begin + len; -static int cyclades_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cyclades_proc_show, NULL); + if (pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) + goto done; + } + *eof = 1; +done: + *start = buf + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; /* Ending slop */ + if (len < 0) + len = 0; + return len; } -static const struct file_operations cyclades_proc_fops = { - .owner = THIS_MODULE, - .open = cyclades_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* The serial driver boot-time initialization code! Hardware I/O ports are mapped to character special devices on a first found, first allocated manner. That is, this code searches @@ -5297,9 +5311,9 @@ static const struct tty_operations cy_ops = { .hangup = cy_hangup, .break_ctl = cy_break, .wait_until_sent = cy_wait_until_sent, + .read_proc = cyclades_get_proc_info, .tiocmget = cy_tiocmget, .tiocmset = cy_tiocmset, - .proc_fops = &cyclades_proc_fops, }; static int __init cy_init(void) diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index afd9247cf082..70e0ebc30bd0 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -139,7 +139,7 @@ #include static const struct file_operations ip2mem_proc_fops; -static const struct file_operations ip2_proc_fops; +static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); /********************/ /* Type Definitions */ @@ -446,9 +446,9 @@ static const struct tty_operations ip2_ops = { .stop = ip2_stop, .start = ip2_start, .hangup = ip2_hangup, + .read_proc = ip2_read_proc, .tiocmget = ip2_tiocmget, .tiocmset = ip2_tiocmset, - .proc_fops = &ip2_proc_fops, }; /******************************************************************************/ @@ -3029,17 +3029,19 @@ static const struct file_operations ip2mem_proc_fops = { * different sources including ip2mkdev.c and a couple of other drivers. * The bugs are all mine. :-) =mhw= */ -static int ip2_proc_show(struct seq_file *m, void *v) +static int ip2_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { int i, j, box; + int len = 0; int boxes = 0; int ports = 0; int tports = 0; + off_t begin = 0; i2eBordStrPtr pB; - char *sep; - seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion); - seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", + len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion ); + len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR, IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX); @@ -3051,8 +3053,7 @@ static int ip2_proc_show(struct seq_file *m, void *v) switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) { case POR_ID_FIIEX: - seq_printf(m, "Board %d: EX ports=", i); - sep = ""; + len += sprintf( page+len, "Board %d: EX ports=", i ); for( box = 0; box < ABS_MAX_BOXES; ++box ) { ports = 0; @@ -3064,74 +3065,79 @@ static int ip2_proc_show(struct seq_file *m, void *v) ++ports; } } - seq_printf(m, "%s%d", sep, ports); - sep = ","; + len += sprintf( page+len, "%d,", ports ); tports += ports; } - seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8); + + --len; /* Backup over that last comma */ + + len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 ); break; case POR_ID_II_4: - seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i ); tports = ports = 4; break; case POR_ID_II_8: - seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i ); tports = ports = 8; break; case POR_ID_II_8R: - seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i ); tports = ports = 8; break; default: - seq_printf(m, "Board %d: unknown", i); + len += sprintf(page+len, "Board %d: unknown", i ); /* Don't try and probe for minor numbers */ tports = ports = 0; } } else { /* Don't try and probe for minor numbers */ - seq_printf(m, "Board %d: vacant", i); + len += sprintf(page+len, "Board %d: vacant", i ); tports = ports = 0; } if( tports ) { - seq_puts(m, " minors="); - sep = ""; + len += sprintf(page+len, " minors=" ); + for ( box = 0; box < ABS_MAX_BOXES; ++box ) { for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) { if ( pB->i2eChannelMap[box] & (1 << j) ) { - seq_printf(m, "%s%d", sep, + len += sprintf (page+len,"%d,", j + ABS_BIGGEST_BOX * (box+i*ABS_MAX_BOXES)); - sep = ","; } } } + + page[ len - 1 ] = '\n'; /* Overwrite that last comma */ + } else { + len += sprintf (page+len,"\n" ); + } + + if (len+begin > off+count) + break; + if (len+begin < off) { + begin += len; + len = 0; } - seq_putc(m, '\n'); } - return 0; - } -static int ip2_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ip2_proc_show, NULL); -} + if (i >= IP2_MAX_BOARDS) + *eof = 1; + if (off >= len+begin) + return 0; -static const struct file_operations ip2_proc_fops = { - .owner = THIS_MODULE, - .open = ip2_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); + } /******************************************************************************/ /* Function: ip2trace() */ diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index fff19f7e29d2..5c3dc6b8411c 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -614,6 +613,7 @@ static int stli_breakctl(struct tty_struct *tty, int state); static void stli_waituntilsent(struct tty_struct *tty, int timeout); static void stli_sendxchar(struct tty_struct *tty, char ch); static void stli_hangup(struct tty_struct *tty); +static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos); static int stli_brdinit(struct stlibrd *brdp); static int stli_startbrd(struct stlibrd *brdp); @@ -1893,10 +1893,20 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); } -static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr) +/*****************************************************************************/ + +#define MAXLINE 80 + +/* + * Format info for a specified port. The line is deliberately limited + * to 80 characters. (If it is too long it will be truncated, if too + * short then padded with spaces). + */ + +static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos) { - char *uart; - int rc; + char *sp, *uart; + int rc, cnt; rc = stli_portcmdstats(NULL, portp); @@ -1908,50 +1918,44 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip default:uart = "CD1400"; break; } } - seq_printf(m, "%d: uart:%s ", portnr, uart); - if ((brdp->state & BST_STARTED) && (rc >= 0)) { - char sep; + sp = pos; + sp += sprintf(sp, "%d: uart:%s ", portnr, uart); - seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, + if ((brdp->state & BST_STARTED) && (rc >= 0)) { + sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal, (int) stli_comstats.rxtotal); if (stli_comstats.rxframing) - seq_printf(m, " fe:%d", + sp += sprintf(sp, " fe:%d", (int) stli_comstats.rxframing); if (stli_comstats.rxparity) - seq_printf(m, " pe:%d", + sp += sprintf(sp, " pe:%d", (int) stli_comstats.rxparity); if (stli_comstats.rxbreaks) - seq_printf(m, " brk:%d", + sp += sprintf(sp, " brk:%d", (int) stli_comstats.rxbreaks); if (stli_comstats.rxoverrun) - seq_printf(m, " oe:%d", + sp += sprintf(sp, " oe:%d", (int) stli_comstats.rxoverrun); - sep = ' '; - if (stli_comstats.signals & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } + cnt = sprintf(sp, "%s%s%s%s%s ", + (stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "", + (stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "", + (stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "", + (stli_comstats.signals & TIOCM_CD) ? "|DCD" : "", + (stli_comstats.signals & TIOCM_DSR) ? "|DSR" : ""); + *sp = ' '; + sp += cnt; } - seq_putc(m, '\n'); + + for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++) + *sp++ = ' '; + if (cnt >= MAXLINE) + pos[(MAXLINE - 2)] = '+'; + pos[(MAXLINE - 1)] = '\n'; + + return(MAXLINE); } /*****************************************************************************/ @@ -1960,15 +1964,26 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip * Port info, read from the /proc file system. */ -static int stli_proc_show(struct seq_file *m, void *v) +static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct stlibrd *brdp; struct stliport *portp; unsigned int brdnr, portnr, totalport; + int curoff, maxoff; + char *pos; + pos = page; totalport = 0; - - seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion); + curoff = 0; + + if (off == 0) { + pos += sprintf(pos, "%s: version %s", stli_drvtitle, + stli_drvversion); + while (pos < (page + MAXLINE - 1)) + *pos++ = ' '; + *pos++ = '\n'; + } + curoff = MAXLINE; /* * We scan through for each board, panel and port. The offset is @@ -1981,30 +1996,32 @@ static int stli_proc_show(struct seq_file *m, void *v) if (brdp->state == 0) continue; + maxoff = curoff + (brdp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + continue; + } + totalport = brdnr * STL_MAXPORTS; for (portnr = 0; (portnr < brdp->nrports); portnr++, totalport++) { portp = brdp->ports[portnr]; if (portp == NULL) continue; - stli_portinfo(m, brdp, portp, totalport); + if (off >= (curoff += MAXLINE)) + continue; + if ((pos - page + MAXLINE) > count) + goto stli_readdone; + pos += stli_portinfo(brdp, portp, totalport, pos); } } - return 0; -} -static int stli_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stli_proc_show, NULL); -} + *eof = 1; -static const struct file_operations stli_proc_fops = { - .owner = THIS_MODULE, - .open = stli_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +stli_readdone: + *start = page; + return(pos - page); +} /*****************************************************************************/ @@ -4410,9 +4427,9 @@ static const struct tty_operations stli_ops = { .break_ctl = stli_breakctl, .wait_until_sent = stli_waituntilsent, .send_xchar = stli_sendxchar, + .read_proc = stli_readproc, .tiocmget = stli_tiocmget, .tiocmset = stli_tiocmset, - .proc_fops = &stli_proc_fops, }; static const struct tty_port_operations stli_port_ops = { diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 19d79fc54461..5608a1e5a3b3 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -2620,12 +2619,13 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, MGSLPC_INFO *info) +static inline int line_info(char *buf, MGSLPC_INFO *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s:io:%04X irq:%d", + ret = sprintf(buf, "%s:io:%04X irq:%d", info->device_name, info->io_base, info->irq_level); /* output current serial signal states */ @@ -2649,70 +2649,75 @@ static inline void line_info(struct seq_file *m, MGSLPC_INFO *info) strcat(stat_buf, "|RI"); if (info->params.mode == MGSL_MODE_HDLC) { - seq_printf(m, " HDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, " ASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int mgslpc_proc_show(struct seq_file *m, void *v) +static int mgslpc_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; MGSLPC_INFO *info; - seq_printf(m, "synclink driver:%s\n", driver_version); + len += sprintf(page, "synclink driver:%s\n", driver_version); info = mgslpc_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int mgslpc_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, mgslpc_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations mgslpc_proc_fops = { - .owner = THIS_MODULE, - .open = mgslpc_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int rx_alloc_buffers(MGSLPC_INFO *info) { /* each buffer has header and data */ @@ -2856,13 +2861,13 @@ static const struct tty_operations mgslpc_ops = { .send_xchar = mgslpc_send_xchar, .break_ctl = mgslpc_break, .wait_until_sent = mgslpc_wait_until_sent, + .read_proc = mgslpc_read_proc, .set_termios = mgslpc_set_termios, .stop = tx_pause, .start = tx_release, .hangup = mgslpc_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &mgslpc_proc_fops, }; static void synclink_cs_cleanup(void) diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index 2ad813a801dc..e1e0dd89ac9a 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -1380,47 +1379,52 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) stl_putchar(tty, ch); } -static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) +/*****************************************************************************/ + +#define MAXLINE 80 + +/* + * Format info for a specified port. The line is deliberately limited + * to 80 characters. (If it is too long it will be truncated, if too + * short then padded with spaces). + */ + +static int stl_portinfo(struct stlport *portp, int portnr, char *pos) { - int sigs; - char sep; + char *sp; + int sigs, cnt; - seq_printf(m, "%d: uart:%s tx:%d rx:%d", + sp = pos; + sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d", portnr, (portp->hwid == 1) ? "SC26198" : "CD1400", (int) portp->stats.txtotal, (int) portp->stats.rxtotal); if (portp->stats.rxframing) - seq_printf(m, " fe:%d", (int) portp->stats.rxframing); + sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing); if (portp->stats.rxparity) - seq_printf(m, " pe:%d", (int) portp->stats.rxparity); + sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity); if (portp->stats.rxbreaks) - seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks); + sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks); if (portp->stats.rxoverrun) - seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun); + sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun); sigs = stl_getsignals(portp); - sep = ' '; - if (sigs & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (sigs & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (sigs & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (sigs & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (sigs & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - seq_putc(m, '\n'); + cnt = sprintf(sp, "%s%s%s%s%s ", + (sigs & TIOCM_RTS) ? "|RTS" : "", + (sigs & TIOCM_CTS) ? "|CTS" : "", + (sigs & TIOCM_DTR) ? "|DTR" : "", + (sigs & TIOCM_CD) ? "|DCD" : "", + (sigs & TIOCM_DSR) ? "|DSR" : ""); + *sp = ' '; + sp += cnt; + + for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++) + *sp++ = ' '; + if (cnt >= MAXLINE) + pos[(MAXLINE - 2)] = '+'; + pos[(MAXLINE - 1)] = '\n'; + + return MAXLINE; } /*****************************************************************************/ @@ -1429,17 +1433,30 @@ static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) * Port info, read from the /proc file system. */ -static int stl_proc_show(struct seq_file *m, void *v) +static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct stlbrd *brdp; struct stlpanel *panelp; struct stlport *portp; unsigned int brdnr, panelnr, portnr; - int totalport; + int totalport, curoff, maxoff; + char *pos; - totalport = 0; + pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p," + "data=%p\n", page, start, off, count, eof, data); - seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion); + pos = page; + totalport = 0; + curoff = 0; + + if (off == 0) { + pos += sprintf(pos, "%s: version %s", stl_drvtitle, + stl_drvversion); + while (pos < (page + MAXLINE - 1)) + *pos++ = ' '; + *pos++ = '\n'; + } + curoff = MAXLINE; /* * We scan through for each board, panel and port. The offset is @@ -1452,36 +1469,45 @@ static int stl_proc_show(struct seq_file *m, void *v) if (brdp->state == 0) continue; + maxoff = curoff + (brdp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + continue; + } + totalport = brdnr * STL_MAXPORTS; for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { panelp = brdp->panels[panelnr]; if (panelp == NULL) continue; + maxoff = curoff + (panelp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + totalport += panelp->nrports; + continue; + } + for (portnr = 0; portnr < panelp->nrports; portnr++, totalport++) { portp = panelp->ports[portnr]; if (portp == NULL) continue; - stl_portinfo(m, portp, totalport); + if (off >= (curoff += MAXLINE)) + continue; + if ((pos - page + MAXLINE) > count) + goto stl_readdone; + pos += stl_portinfo(portp, totalport, pos); } } } - return 0; -} -static int stl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stl_proc_show, NULL); -} + *eof = 1; -static const struct file_operations stl_proc_fops = { - .owner = THIS_MODULE, - .open = stl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +stl_readdone: + *start = page; + return pos - page; +} /*****************************************************************************/ @@ -2540,9 +2566,9 @@ static const struct tty_operations stl_ops = { .break_ctl = stl_breakctl, .wait_until_sent = stl_waituntilsent, .send_xchar = stl_sendxchar, + .read_proc = stl_readproc, .tiocmget = stl_tiocmget, .tiocmset = stl_tiocmset, - .proc_fops = &stl_proc_fops, }; static const struct tty_port_operations stl_port_ops = { diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index afd0b26ca056..0057a8f58cb1 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -3460,17 +3459,18 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct mgsl_struct *info) +static inline int line_info(char *buf, struct mgsl_struct *info) { char stat_buf[30]; + int ret; unsigned long flags; if (info->bus_type == MGSL_BUS_TYPE_PCI) { - seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", + ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", info->device_name, info->io_base, info->irq_level, info->phys_memory_base, info->phys_lcr_base); } else { - seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d", + ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d", info->device_name, info->io_base, info->irq_level, info->dma_level); } @@ -3497,37 +3497,37 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info) if (info->params.mode == MGSL_MODE_HDLC || info->params.mode == MGSL_MODE_RAW ) { - seq_printf(m, " HDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, " ASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); @@ -3544,40 +3544,60 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info) u16 Tmr = usc_InReg( info, TMR ); u16 Tccr = usc_InReg( info, TCCR ); u16 Ccar = inw( info->io_base + CCAR ); - seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" + ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n", Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar ); } spin_unlock_irqrestore(&info->irq_spinlock,flags); -} + + return ret; + +} /* end of line_info() */ -/* Called to print information about devices */ -static int mgsl_proc_show(struct seq_file *m, void *v) +/* mgsl_read_proc() + * + * Called to print information about devices + * + * Arguments: + * page page of memory to hold returned info + * start + * off + * count + * eof + * data + * + * Return Value: + */ +static int mgsl_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; struct mgsl_struct *info; - seq_printf(m, "synclink driver:%s\n", driver_version); + len += sprintf(page, "synclink driver:%s\n", driver_version); info = mgsl_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} - -static int mgsl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, mgsl_proc_show, NULL); -} -static const struct file_operations mgsl_proc_fops = { - .owner = THIS_MODULE, - .open = mgsl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); + +} /* end of mgsl_read_proc() */ /* mgsl_allocate_dma_buffers() * @@ -4315,13 +4335,13 @@ static const struct tty_operations mgsl_ops = { .send_xchar = mgsl_send_xchar, .break_ctl = mgsl_break, .wait_until_sent = mgsl_wait_until_sent, + .read_proc = mgsl_read_proc, .set_termios = mgsl_set_termios, .stop = mgsl_stop, .start = mgsl_start, .hangup = mgsl_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &mgsl_proc_fops, }; /* diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 6ec6e13d47d7..efb3dc928a43 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -155,6 +154,7 @@ static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -1229,12 +1229,13 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, /* * proc fs support */ -static inline void line_info(struct seq_file *m, struct slgt_info *info) +static inline int line_info(char *buf, struct slgt_info *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", + ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", info->device_name, info->phys_reg_addr, info->irq_level, info->max_frame_size); @@ -1259,70 +1260,75 @@ static inline void line_info(struct seq_file *m, struct slgt_info *info) strcat(stat_buf, "|RI"); if (info->params.mode != MGSL_MODE_ASYNC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int synclink_gt_proc_show(struct seq_file *m, void *v) +static int read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; struct slgt_info *info; - seq_puts(m, "synclink_gt driver\n"); + len += sprintf(page, "synclink_gt driver\n"); info = slgt_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int synclink_gt_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclink_gt_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations synclink_gt_proc_fops = { - .owner = THIS_MODULE, - .open = synclink_gt_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * return count of bytes in transmit buffer */ @@ -3556,13 +3562,13 @@ static const struct tty_operations ops = { .send_xchar = send_xchar, .break_ctl = set_break, .wait_until_sent = wait_until_sent, + .read_proc = read_proc, .set_termios = set_termios, .stop = tx_hold, .start = tx_release, .hangup = hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &synclink_gt_proc_fops, }; static void slgt_cleanup(void) diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 26de60efe4b2..8eb6c89a980e 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -521,6 +520,7 @@ static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -1354,12 +1354,13 @@ static int ioctl(struct tty_struct *tty, struct file *file, * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, SLMP_INFO *info) +static inline int line_info(char *buf, SLMP_INFO *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" + ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" "\tIRQ=%d MaxFrameSize=%u\n", info->device_name, info->phys_sca_base, @@ -1390,70 +1391,75 @@ static inline void line_info(struct seq_file *m, SLMP_INFO *info) strcat(stat_buf, "|RI"); if (info->params.mode == MGSL_MODE_HDLC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxlong:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc); } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int synclinkmp_proc_show(struct seq_file *m, void *v) +static int read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; SLMP_INFO *info; - seq_printf(m, "synclinkmp driver:%s\n", driver_version); + len += sprintf(page, "synclinkmp driver:%s\n", driver_version); info = synclinkmp_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int synclinkmp_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclinkmp_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations synclinkmp_proc_fops = { - .owner = THIS_MODULE, - .open = synclinkmp_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* Return the count of bytes in transmit buffer */ static int chars_in_buffer(struct tty_struct *tty) @@ -3899,13 +3905,13 @@ static const struct tty_operations ops = { .send_xchar = send_xchar, .break_ctl = set_break, .wait_until_sent = wait_until_sent, + .read_proc = read_proc, .set_termios = set_termios, .stop = tx_hold, .start = tx_release, .hangup = hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &synclinkmp_proc_fops, }; diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index 5afe7316c72e..3df694e54545 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -346,19 +346,6 @@ static struct sysrq_key_op sysrq_moom_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -#ifdef CONFIG_BLOCK -static void sysrq_handle_thaw(int key, struct tty_struct *tty) -{ - emergency_thaw_all(); -} -static struct sysrq_key_op sysrq_thaw_op = { - .handler = sysrq_handle_thaw, - .help_msg = "thaw-filesystems(J)", - .action_msg = "Emergency Thaw of all frozen filesystems", - .enable_mask = SYSRQ_ENABLE_SIGNAL, -}; -#endif - static void sysrq_handle_kill(int key, struct tty_struct *tty) { send_sig_all(SIGKILL); @@ -409,13 +396,9 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_moom_op, /* f */ /* g: May be registered by ppc for kgdb */ NULL, /* g */ - NULL, /* h - reserved for help */ + NULL, /* h */ &sysrq_kill_op, /* i */ -#ifdef CONFIG_BLOCK - &sysrq_thaw_op, /* j */ -#else NULL, /* j */ -#endif &sysrq_SAK_op, /* k */ #ifdef CONFIG_SMP &sysrq_showallcpus_op, /* l */ diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 33dac94922a7..224f271d8cbe 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty) tty_ldisc_deref(ld); } } - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); + wake_up_interruptible(&tty->write_wait); } EXPORT_SYMBOL_GPL(tty_wakeup); @@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_struct *work) * FIXME: Once we trust the LDISC code better we can wait here for * ldisc completion and fix the driver call race */ - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); - wake_up_interruptible_poll(&tty->read_wait, POLLIN); + wake_up_interruptible(&tty->write_wait); + wake_up_interruptible(&tty->read_wait); /* * Shutdown the current line discipline, and reset it to * N_TTY. @@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty) if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_START; tty->ctrl_status |= TIOCPKT_STOP; - wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); + wake_up_interruptible(&tty->link->read_wait); } spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (tty->ops->stop) @@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty) if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_STOP; tty->ctrl_status |= TIOCPKT_START; - wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); + wake_up_interruptible(&tty->link->read_wait); } spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (tty->ops->start) @@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, void tty_write_unlock(struct tty_struct *tty) { mutex_unlock(&tty->atomic_write_lock); - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); + wake_up_interruptible(&tty->write_wait); } int tty_write_lock(struct tty_struct *tty, int ndelay) @@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp) if (tty_closing) { if (waitqueue_active(&tty->read_wait)) { - wake_up_poll(&tty->read_wait, POLLIN); + wake_up(&tty->read_wait); do_sleep++; } if (waitqueue_active(&tty->write_wait)) { - wake_up_poll(&tty->write_wait, POLLOUT); + wake_up(&tty->write_wait); do_sleep++; } } if (o_tty_closing) { if (waitqueue_active(&o_tty->read_wait)) { - wake_up_poll(&o_tty->read_wait, POLLIN); + wake_up(&o_tty->read_wait); do_sleep++; } if (waitqueue_active(&o_tty->write_wait)) { - wake_up_poll(&o_tty->write_wait, POLLOUT); + wake_up(&o_tty->write_wait); do_sleep++; } } diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index ce52bf2f235e..51ff9b3d7ea2 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -571,17 +571,6 @@ config SENSORS_LM93 This driver can also be built as a module. If so, the module will be called lm93. -config SENSORS_LTC4215 - tristate "Linear Technology LTC4215" - depends on I2C && EXPERIMENTAL - default n - help - If you say yes here you get support for Linear Technology LTC4215 - Hot Swap Controller I2C interface. - - This driver can also be built as a module. If so, the module will - be called ltc4215. - config SENSORS_LTC4245 tristate "Linear Technology LTC4245" depends on I2C && EXPERIMENTAL @@ -593,15 +582,6 @@ config SENSORS_LTC4245 This driver can also be built as a module. If so, the module will be called ltc4245. -config SENSORS_LM95241 - tristate "National Semiconductor LM95241 sensor chip" - depends on I2C - help - If you say yes here you get support for LM95241 sensor chip. - - This driver can also be built as a module. If so, the module - will be called lm95241. - config SENSORS_MAX1111 tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" depends on SPI_MASTER @@ -932,22 +912,6 @@ config SENSORS_LIS3LV02D Say Y here if you have an applicable laptop and want to experience the awesome power of lis3lv02d. -config SENSORS_LIS3_SPI - tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" - depends on !ACPI && SPI_MASTER && INPUT - default n - help - This driver provides support for the LIS3LV02Dx accelerometer connected - via SPI. The accelerometer data is readable via - /sys/devices/platform/lis3lv02d. - - This driver also provides an absolute input class device, allowing - the laptop to act as a pinball machine-esque joystick. - - This driver can also be built as modules. If so, the core module - will be called lis3lv02d and a specific module for the SPI transport - is called lis3lv02d_spi. - config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" depends on INPUT && X86 diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index 3a6b1f06f8f4..e332d6267920 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o -obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM75) += lm75.o @@ -65,8 +64,6 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o -obj-$(CONFIG_SENSORS_LM95241) += lm95241.o -obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o obj-$(CONFIG_SENSORS_MAX1111) += max1111.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o diff --git a/trunk/drivers/hwmon/hp_accel.c b/trunk/drivers/hwmon/hp_accel.c index 55d3dc565be6..29c83b5b9697 100644 --- a/trunk/drivers/hwmon/hp_accel.c +++ b/trunk/drivers/hwmon/hp_accel.c @@ -85,31 +85,25 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); /** * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. - * @lis3: pointer to the device struct + * @handle: the handle of the device * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_init(struct lis3lv02d *lis3) +acpi_status lis3lv02d_acpi_init(acpi_handle handle) { - struct acpi_device *dev = lis3->bus_priv; - if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, - NULL, NULL) != AE_OK) - return -EINVAL; - - return 0; + return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL); } /** * lis3lv02d_acpi_read - ACPI ALRD method: read a register - * @lis3: pointer to the device struct + * @handle: the handle of the device * @reg: the register to read * @ret: result of the operation * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) +acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) { - struct acpi_device *dev = lis3->bus_priv; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; unsigned long long lret; @@ -117,22 +111,21 @@ int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) arg0.integer.value = reg; - status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret); + status = acpi_evaluate_integer(handle, "ALRD", &args, &lret); *ret = lret; - return (status != AE_OK) ? -EINVAL : 0; + return status; } /** * lis3lv02d_acpi_write - ACPI ALWR method: write to a register - * @lis3: pointer to the device struct + * @handle: the handle of the device * @reg: the register to write to * @val: the value to write * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) +acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) { - struct acpi_device *dev = lis3->bus_priv; unsigned long long ret; /* Not used when writting */ union acpi_object in_obj[2]; struct acpi_object_list args = { 2, in_obj }; @@ -142,15 +135,12 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) in_obj[1].type = ACPI_TYPE_INTEGER; in_obj[1].integer.value = val; - if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK) - return -EINVAL; - - return 0; + return acpi_evaluate_integer(handle, "ALWR", &args, &ret); } static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) { - lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data); + adev.ac = *((struct axis_conversion *)dmi->driver_data); printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); return 1; @@ -197,7 +187,6 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), - AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted), AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), @@ -212,8 +201,6 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { PRODUCT_NAME, "HP Pavilion dv5", BOARD_NAME, "3600", y_inverted), - AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted), - AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted), { NULL, } /* Laptop models without axis info (yet): * "NC6910" "HP Compaq 6910" @@ -227,7 +214,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value) { - struct acpi_device *dev = lis3_dev.bus_priv; + acpi_handle handle = adev.device->handle; unsigned long long ret; /* Not used when writing */ union acpi_object in_obj[1]; struct acpi_object_list args = { 1, in_obj }; @@ -235,7 +222,7 @@ static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness in_obj[0].type = ACPI_TYPE_INTEGER; in_obj[0].integer.value = !!value; - acpi_evaluate_integer(dev->handle, "ALED", &args, &ret); + acpi_evaluate_integer(handle, "ALED", &args, &ret); } static struct delayed_led_classdev hpled_led = { @@ -267,11 +254,28 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) acpi_status status; status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, - lis3lv02d_get_resource, &lis3_dev.irq); + lis3lv02d_get_resource, &adev.irq); if (ACPI_FAILURE(status)) printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); } +static s16 lis3lv02d_read_16(acpi_handle handle, int reg) +{ + u8 lo, hi; + + adev.read(handle, reg - 1, &lo); + adev.read(handle, reg, &hi); + /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ + return (s16)((hi << 8) | lo); +} + +static s16 lis3lv02d_read_8(acpi_handle handle, int reg) +{ + s8 lo; + adev.read(handle, reg, &lo); + return lo; +} + static int lis3lv02d_add(struct acpi_device *device) { int ret; @@ -279,35 +283,51 @@ static int lis3lv02d_add(struct acpi_device *device) if (!device) return -EINVAL; - lis3_dev.bus_priv = device; - lis3_dev.init = lis3lv02d_acpi_init; - lis3_dev.read = lis3lv02d_acpi_read; - lis3_dev.write = lis3lv02d_acpi_write; + adev.device = device; + adev.init = lis3lv02d_acpi_init; + adev.read = lis3lv02d_acpi_read; + adev.write = lis3lv02d_acpi_write; strcpy(acpi_device_name(device), DRIVER_NAME); strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); - device->driver_data = &lis3_dev; - - /* obtain IRQ number of our device from ACPI */ - lis3lv02d_enum_resources(device); + device->driver_data = &adev; + + lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); + switch (adev.whoami) { + case LIS_DOUBLE_ID: + printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); + adev.read_data = lis3lv02d_read_16; + adev.mdps_max_val = 2048; + break; + case LIS_SINGLE_ID: + printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); + adev.read_data = lis3lv02d_read_8; + adev.mdps_max_val = 128; + break; + default: + printk(KERN_ERR DRIVER_NAME + ": unknown sensor type 0x%X\n", adev.whoami); + return -EINVAL; + } /* If possible use a "standard" axes order */ if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " "using default axes configuration\n"); - lis3_dev.ac = lis3lv02d_axis_normal; + adev.ac = lis3lv02d_axis_normal; } - /* call the core layer do its init */ - ret = lis3lv02d_init_device(&lis3_dev); + INIT_WORK(&hpled_led.work, delayed_set_status_worker); + ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) return ret; - INIT_WORK(&hpled_led.work, delayed_set_status_worker); - ret = led_classdev_register(NULL, &hpled_led.led_classdev); + /* obtain IRQ number of our device from ACPI */ + lis3lv02d_enum_resources(adev.device); + + ret = lis3lv02d_init_device(&adev); if (ret) { - lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); + led_classdev_unregister(&hpled_led.led_classdev); return ret; } @@ -320,7 +340,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) return -EINVAL; lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(&lis3_dev); + lis3lv02d_poweroff(device->handle); flush_work(&hpled_led.work); led_classdev_unregister(&hpled_led.led_classdev); @@ -333,19 +353,19 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) { /* make sure the device is off when we suspend */ - lis3lv02d_poweroff(&lis3_dev); + lis3lv02d_poweroff(device->handle); return 0; } static int lis3lv02d_resume(struct acpi_device *device) { /* put back the device in the right state (ACPI might turn it on) */ - mutex_lock(&lis3_dev.lock); - if (lis3_dev.usage > 0) - lis3lv02d_poweron(&lis3_dev); + mutex_lock(&adev.lock); + if (adev.usage > 0) + lis3lv02d_poweron(device->handle); else - lis3lv02d_poweroff(&lis3_dev); - mutex_unlock(&lis3_dev.lock); + lis3lv02d_poweroff(device->handle); + mutex_unlock(&adev.lock); return 0; } #else diff --git a/trunk/drivers/hwmon/lis3lv02d.c b/trunk/drivers/hwmon/lis3lv02d.c index 778eb7795983..8bb2158f0453 100644 --- a/trunk/drivers/hwmon/lis3lv02d.c +++ b/trunk/drivers/hwmon/lis3lv02d.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "lis3lv02d.h" @@ -52,30 +53,13 @@ * joystick. */ -struct lis3lv02d lis3_dev = { - .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), +struct acpi_lis3lv02d adev = { + .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), }; -EXPORT_SYMBOL_GPL(lis3_dev); +EXPORT_SYMBOL_GPL(adev); -static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg) -{ - s8 lo; - if (lis3->read(lis3, reg, &lo) < 0) - return 0; - - return lo; -} - -static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg) -{ - u8 lo, hi; - - lis3->read(lis3, reg - 1, &lo); - lis3->read(lis3, reg, &hi); - /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ - return (s16)((hi << 8) | lo); -} +static int lis3lv02d_add_fs(struct acpi_device *device); /** * lis3lv02d_get_axis - For the given axis, give the value converted @@ -94,36 +78,36 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3]) /** * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer - * @lis3: pointer to the device struct - * @x: where to store the X axis value - * @y: where to store the Y axis value - * @z: where to store the Z axis value + * @handle: the handle to the device + * @x: where to store the X axis value + * @y: where to store the Y axis value + * @z: where to store the Z axis value * * Note that 40Hz input device can eat up about 10% CPU at 800MHZ */ -static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) +static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) { int position[3]; - position[0] = lis3_dev.read_data(lis3, OUTX); - position[1] = lis3_dev.read_data(lis3, OUTY); - position[2] = lis3_dev.read_data(lis3, OUTZ); + position[0] = adev.read_data(handle, OUTX); + position[1] = adev.read_data(handle, OUTY); + position[2] = adev.read_data(handle, OUTZ); - *x = lis3lv02d_get_axis(lis3_dev.ac.x, position); - *y = lis3lv02d_get_axis(lis3_dev.ac.y, position); - *z = lis3lv02d_get_axis(lis3_dev.ac.z, position); + *x = lis3lv02d_get_axis(adev.ac.x, position); + *y = lis3lv02d_get_axis(adev.ac.y, position); + *z = lis3lv02d_get_axis(adev.ac.z, position); } -void lis3lv02d_poweroff(struct lis3lv02d *lis3) +void lis3lv02d_poweroff(acpi_handle handle) { - lis3_dev.is_on = 0; + adev.is_on = 0; } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); -void lis3lv02d_poweron(struct lis3lv02d *lis3) +void lis3lv02d_poweron(acpi_handle handle) { - lis3_dev.is_on = 1; - lis3_dev.init(lis3); + adev.is_on = 1; + adev.init(handle); } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -132,13 +116,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron); * device will always be on until a call to lis3lv02d_decrease_use(). Not to be * used from interrupt context. */ -static void lis3lv02d_increase_use(struct lis3lv02d *dev) +static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) { mutex_lock(&dev->lock); dev->usage++; if (dev->usage == 1) { if (!dev->is_on) - lis3lv02d_poweron(dev); + lis3lv02d_poweron(dev->device->handle); } mutex_unlock(&dev->lock); } @@ -147,12 +131,12 @@ static void lis3lv02d_increase_use(struct lis3lv02d *dev) * To be called whenever a usage of the device is stopped. * It will make sure to turn off the device when there is not usage. */ -static void lis3lv02d_decrease_use(struct lis3lv02d *dev) +static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) { mutex_lock(&dev->lock); dev->usage--; if (dev->usage == 0) - lis3lv02d_poweroff(dev); + lis3lv02d_poweroff(dev->device->handle); mutex_unlock(&dev->lock); } @@ -163,10 +147,10 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) * the lid is closed. This leads to interrupts as soon as a little move * is done. */ - atomic_inc(&lis3_dev.count); + atomic_inc(&adev.count); - wake_up_interruptible(&lis3_dev.misc_wait); - kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); + wake_up_interruptible(&adev.misc_wait); + kill_fasync(&adev.async_queue, SIGIO, POLL_IN); return IRQ_HANDLED; } @@ -174,10 +158,10 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) { int ret; - if (test_and_set_bit(0, &lis3_dev.misc_opened)) + if (test_and_set_bit(0, &adev.misc_opened)) return -EBUSY; /* already open */ - atomic_set(&lis3_dev.count, 0); + atomic_set(&adev.count, 0); /* * The sensor can generate interrupts for free-fall and direction @@ -190,25 +174,25 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) * io-apic is not configurable (and generates a warning) but I keep it * in case of support for other hardware. */ - ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, - DRIVER_NAME, &lis3_dev); + ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, + DRIVER_NAME, &adev); if (ret) { - clear_bit(0, &lis3_dev.misc_opened); - printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); + clear_bit(0, &adev.misc_opened); + printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); return -EBUSY; } - lis3lv02d_increase_use(&lis3_dev); - printk("lis3: registered interrupt %d\n", lis3_dev.irq); + lis3lv02d_increase_use(&adev); + printk("lis3: registered interrupt %d\n", adev.irq); return 0; } static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { - fasync_helper(-1, file, 0, &lis3_dev.async_queue); - lis3lv02d_decrease_use(&lis3_dev); - free_irq(lis3_dev.irq, &lis3_dev); - clear_bit(0, &lis3_dev.misc_opened); /* release the device */ + fasync_helper(-1, file, 0, &adev.async_queue); + lis3lv02d_decrease_use(&adev); + free_irq(adev.irq, &adev); + clear_bit(0, &adev.misc_opened); /* release the device */ return 0; } @@ -223,10 +207,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, if (count < 1) return -EINVAL; - add_wait_queue(&lis3_dev.misc_wait, &wait); + add_wait_queue(&adev.misc_wait, &wait); while (true) { set_current_state(TASK_INTERRUPTIBLE); - data = atomic_xchg(&lis3_dev.count, 0); + data = atomic_xchg(&adev.count, 0); if (data) break; @@ -256,22 +240,22 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, out: __set_current_state(TASK_RUNNING); - remove_wait_queue(&lis3_dev.misc_wait, &wait); + remove_wait_queue(&adev.misc_wait, &wait); return retval; } static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) { - poll_wait(file, &lis3_dev.misc_wait, wait); - if (atomic_read(&lis3_dev.count)) + poll_wait(file, &adev.misc_wait, wait); + if (atomic_read(&adev.count)) return POLLIN | POLLRDNORM; return 0; } static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) { - return fasync_helper(fd, file, on, &lis3_dev.async_queue); + return fasync_helper(fd, file, on, &adev.async_queue); } static const struct file_operations lis3lv02d_misc_fops = { @@ -299,12 +283,12 @@ static int lis3lv02d_joystick_kthread(void *data) int x, y, z; while (!kthread_should_stop()) { - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib); - input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib); - input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib); + lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); + input_report_abs(adev.idev, ABS_X, x - adev.xcalib); + input_report_abs(adev.idev, ABS_Y, y - adev.ycalib); + input_report_abs(adev.idev, ABS_Z, z - adev.zcalib); - input_sync(lis3_dev.idev); + input_sync(adev.idev); try_to_freeze(); msleep_interruptible(MDPS_POLL_INTERVAL); @@ -315,11 +299,11 @@ static int lis3lv02d_joystick_kthread(void *data) static int lis3lv02d_joystick_open(struct input_dev *input) { - lis3lv02d_increase_use(&lis3_dev); - lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); - if (IS_ERR(lis3_dev.kthread)) { - lis3lv02d_decrease_use(&lis3_dev); - return PTR_ERR(lis3_dev.kthread); + lis3lv02d_increase_use(&adev); + adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); + if (IS_ERR(adev.kthread)) { + lis3lv02d_decrease_use(&adev); + return PTR_ERR(adev.kthread); } return 0; @@ -327,46 +311,45 @@ static int lis3lv02d_joystick_open(struct input_dev *input) static void lis3lv02d_joystick_close(struct input_dev *input) { - kthread_stop(lis3_dev.kthread); - lis3lv02d_decrease_use(&lis3_dev); + kthread_stop(adev.kthread); + lis3lv02d_decrease_use(&adev); } static inline void lis3lv02d_calibrate_joystick(void) { - lis3lv02d_get_xyz(&lis3_dev, - &lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib); + lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); } int lis3lv02d_joystick_enable(void) { int err; - if (lis3_dev.idev) + if (adev.idev) return -EINVAL; - lis3_dev.idev = input_allocate_device(); - if (!lis3_dev.idev) + adev.idev = input_allocate_device(); + if (!adev.idev) return -ENOMEM; lis3lv02d_calibrate_joystick(); - lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer"; - lis3_dev.idev->phys = DRIVER_NAME "/input0"; - lis3_dev.idev->id.bustype = BUS_HOST; - lis3_dev.idev->id.vendor = 0; - lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev; - lis3_dev.idev->open = lis3lv02d_joystick_open; - lis3_dev.idev->close = lis3lv02d_joystick_close; + adev.idev->name = "ST LIS3LV02DL Accelerometer"; + adev.idev->phys = DRIVER_NAME "/input0"; + adev.idev->id.bustype = BUS_HOST; + adev.idev->id.vendor = 0; + adev.idev->dev.parent = &adev.pdev->dev; + adev.idev->open = lis3lv02d_joystick_open; + adev.idev->close = lis3lv02d_joystick_close; - set_bit(EV_ABS, lis3_dev.idev->evbit); - input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); - input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); - input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); + set_bit(EV_ABS, adev.idev->evbit); + input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); - err = input_register_device(lis3_dev.idev); + err = input_register_device(adev.idev); if (err) { - input_free_device(lis3_dev.idev); - lis3_dev.idev = NULL; + input_free_device(adev.idev); + adev.idev = NULL; } return err; @@ -375,40 +358,71 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); void lis3lv02d_joystick_disable(void) { - if (!lis3_dev.idev) + if (!adev.idev) return; misc_deregister(&lis3lv02d_misc_device); - input_unregister_device(lis3_dev.idev); - lis3_dev.idev = NULL; + input_unregister_device(adev.idev); + adev.idev = NULL; } EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); +/* + * Initialise the accelerometer and the various subsystems. + * Should be rather independant of the bus system. + */ +int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) +{ + mutex_init(&dev->lock); + lis3lv02d_add_fs(dev->device); + lis3lv02d_increase_use(dev); + + if (lis3lv02d_joystick_enable()) + printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); + + printk("lis3_init_device: irq %d\n", dev->irq); + + /* if we did not get an IRQ from ACPI - we have nothing more to do */ + if (!dev->irq) { + printk(KERN_ERR DRIVER_NAME + ": No IRQ in ACPI. Disabling /dev/freefall\n"); + goto out; + } + + printk("lis3: registering device\n"); + if (misc_register(&lis3lv02d_misc_device)) + printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); +out: + lis3lv02d_decrease_use(dev); + return 0; +} +EXPORT_SYMBOL_GPL(lis3lv02d_init_device); + /* Sysfs stuff */ static ssize_t lis3lv02d_position_show(struct device *dev, struct device_attribute *attr, char *buf) { int x, y, z; - lis3lv02d_increase_use(&lis3_dev); - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_increase_use(&adev); + lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); + lis3lv02d_decrease_use(&adev); return sprintf(buf, "(%d,%d,%d)\n", x, y, z); } static ssize_t lis3lv02d_calibrate_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib); + return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib); } static ssize_t lis3lv02d_calibrate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - lis3lv02d_increase_use(&lis3_dev); + lis3lv02d_increase_use(&adev); lis3lv02d_calibrate_joystick(); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_decrease_use(&adev); return count; } @@ -420,9 +434,9 @@ static ssize_t lis3lv02d_rate_show(struct device *dev, u8 ctrl; int val; - lis3lv02d_increase_use(&lis3_dev); - lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_increase_use(&adev); + adev.read(adev.device->handle, CTRL_REG1, &ctrl); + lis3lv02d_decrease_use(&adev); val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); } @@ -444,73 +458,23 @@ static struct attribute_group lis3lv02d_attribute_group = { }; -static int lis3lv02d_add_fs(struct lis3lv02d *lis3) +static int lis3lv02d_add_fs(struct acpi_device *device) { - lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (IS_ERR(lis3_dev.pdev)) - return PTR_ERR(lis3_dev.pdev); + adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + if (IS_ERR(adev.pdev)) + return PTR_ERR(adev.pdev); - return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); + return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); } int lis3lv02d_remove_fs(void) { - sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); - platform_device_unregister(lis3_dev.pdev); + sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); + platform_device_unregister(adev.pdev); return 0; } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); -/* - * Initialise the accelerometer and the various subsystems. - * Should be rather independant of the bus system. - */ -int lis3lv02d_init_device(struct lis3lv02d *dev) -{ - dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); - - switch (dev->whoami) { - case LIS_DOUBLE_ID: - printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); - dev->read_data = lis3lv02d_read_16; - dev->mdps_max_val = 2048; - break; - case LIS_SINGLE_ID: - printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); - dev->read_data = lis3lv02d_read_8; - dev->mdps_max_val = 128; - break; - default: - printk(KERN_ERR DRIVER_NAME - ": unknown sensor type 0x%X\n", lis3_dev.whoami); - return -EINVAL; - } - - mutex_init(&dev->lock); - lis3lv02d_add_fs(dev); - lis3lv02d_increase_use(dev); - - if (lis3lv02d_joystick_enable()) - printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); - - printk("lis3_init_device: irq %d\n", dev->irq); - - /* bail if we did not get an IRQ from the bus layer */ - if (!dev->irq) { - printk(KERN_ERR DRIVER_NAME - ": No IRQ. Disabling /dev/freefall\n"); - goto out; - } - - printk("lis3: registering device\n"); - if (misc_register(&lis3lv02d_misc_device)) - printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); -out: - lis3lv02d_decrease_use(dev); - return 0; -} -EXPORT_SYMBOL_GPL(lis3lv02d_init_device); - MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/lis3lv02d.h b/trunk/drivers/hwmon/lis3lv02d.h index 745ec96806d4..75972bf372ff 100644 --- a/trunk/drivers/hwmon/lis3lv02d.h +++ b/trunk/drivers/hwmon/lis3lv02d.h @@ -159,14 +159,14 @@ struct axis_conversion { s8 z; }; -struct lis3lv02d { - void *bus_priv; /* used by the bus layer only */ - int (*init) (struct lis3lv02d *lis3); - int (*write) (struct lis3lv02d *lis3, int reg, u8 val); - int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); +struct acpi_lis3lv02d { + struct acpi_device *device; /* The ACPI device */ + acpi_status (*init) (acpi_handle handle); + acpi_status (*write) (acpi_handle handle, int reg, u8 val); + acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */ - s16 (*read_data) (struct lis3lv02d *lis3, int reg); + s16 (*read_data) (acpi_handle handle, int reg); int mdps_max_val; struct input_dev *idev; /* input device */ @@ -187,11 +187,11 @@ struct lis3lv02d { unsigned long misc_opened; /* bit0: whether the device is open */ }; -int lis3lv02d_init_device(struct lis3lv02d *lis3); +int lis3lv02d_init_device(struct acpi_lis3lv02d *dev); int lis3lv02d_joystick_enable(void); void lis3lv02d_joystick_disable(void); -void lis3lv02d_poweroff(struct lis3lv02d *lis3); -void lis3lv02d_poweron(struct lis3lv02d *lis3); +void lis3lv02d_poweroff(acpi_handle handle); +void lis3lv02d_poweron(acpi_handle handle); int lis3lv02d_remove_fs(void); -extern struct lis3lv02d lis3_dev; +extern struct acpi_lis3lv02d adev; diff --git a/trunk/drivers/hwmon/lis3lv02d_spi.c b/trunk/drivers/hwmon/lis3lv02d_spi.c deleted file mode 100644 index 07ae74b0e191..000000000000 --- a/trunk/drivers/hwmon/lis3lv02d_spi.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * lis3lv02d_spi - SPI glue layer for lis3lv02d - * - * Copyright (c) 2009 Daniel Mack - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * publishhed by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lis3lv02d.h" - -#define DRV_NAME "lis3lv02d_spi" -#define LIS3_SPI_READ 0x80 - -static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v) -{ - struct spi_device *spi = lis3->bus_priv; - int ret = spi_w8r8(spi, reg | LIS3_SPI_READ); - if (ret < 0) - return -EINVAL; - - *v = (u8) ret; - return 0; -} - -static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val) -{ - u8 tmp[2] = { reg, val }; - struct spi_device *spi = lis3->bus_priv; - return spi_write(spi, tmp, sizeof(tmp)); -} - -static int lis3_spi_init(struct lis3lv02d *lis3) -{ - u8 reg; - int ret; - - /* power up the device */ - ret = lis3->read(lis3, CTRL_REG1, ®); - if (ret < 0) - return ret; - - reg |= CTRL1_PD0; - return lis3->write(lis3, CTRL_REG1, reg); -} - -static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 }; - -static int __devinit lis302dl_spi_probe(struct spi_device *spi) -{ - int ret; - - spi->bits_per_word = 8; - spi->mode = SPI_MODE_0; - ret = spi_setup(spi); - if (ret < 0) - return ret; - - lis3_dev.bus_priv = spi; - lis3_dev.init = lis3_spi_init; - lis3_dev.read = lis3_spi_read; - lis3_dev.write = lis3_spi_write; - lis3_dev.irq = spi->irq; - lis3_dev.ac = lis3lv02d_axis_normal; - spi_set_drvdata(spi, &lis3_dev); - - ret = lis3lv02d_init_device(&lis3_dev); - return ret; -} - -static int __devexit lis302dl_spi_remove(struct spi_device *spi) -{ - struct lis3lv02d *lis3 = spi_get_drvdata(spi); - lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(lis3); - return 0; -} - -static struct spi_driver lis302dl_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = lis302dl_spi_probe, - .remove = __devexit_p(lis302dl_spi_remove), -}; - -static int __init lis302dl_init(void) -{ - return spi_register_driver(&lis302dl_spi_driver); -} - -static void __exit lis302dl_exit(void) -{ - spi_unregister_driver(&lis302dl_spi_driver); -} - -module_init(lis302dl_init); -module_exit(lis302dl_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("lis3lv02d SPI glue layer"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/hwmon/lm95241.c b/trunk/drivers/hwmon/lm95241.c deleted file mode 100644 index 091d95f38aaa..000000000000 --- a/trunk/drivers/hwmon/lm95241.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring - * Copyright (C) 2008 Davide Rizzo - * - * Based on the max1619 driver. The LM95241 is a sensor chip made by National - * Semiconductors. - * It reports up to three temperatures (its own plus up to - * two external ones). Complete datasheet can be - * obtained from National's website at: - * http://www.national.com/ds.cgi/LM/LM95241.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const unsigned short normal_i2c[] = { - 0x19, 0x2a, 0x2b, I2C_CLIENT_END}; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm95241); - -/* LM95241 registers */ -#define LM95241_REG_R_MAN_ID 0xFE -#define LM95241_REG_R_CHIP_ID 0xFF -#define LM95241_REG_R_STATUS 0x02 -#define LM95241_REG_RW_CONFIG 0x03 -#define LM95241_REG_RW_REM_FILTER 0x06 -#define LM95241_REG_RW_TRUTHERM 0x07 -#define LM95241_REG_W_ONE_SHOT 0x0F -#define LM95241_REG_R_LOCAL_TEMPH 0x10 -#define LM95241_REG_R_REMOTE1_TEMPH 0x11 -#define LM95241_REG_R_REMOTE2_TEMPH 0x12 -#define LM95241_REG_R_LOCAL_TEMPL 0x20 -#define LM95241_REG_R_REMOTE1_TEMPL 0x21 -#define LM95241_REG_R_REMOTE2_TEMPL 0x22 -#define LM95241_REG_RW_REMOTE_MODEL 0x30 - -/* LM95241 specific bitfields */ -#define CFG_STOP 0x40 -#define CFG_CR0076 0x00 -#define CFG_CR0182 0x10 -#define CFG_CR1000 0x20 -#define CFG_CR2700 0x30 -#define R1MS_SHIFT 0 -#define R2MS_SHIFT 2 -#define R1MS_MASK (0x01 << (R1MS_SHIFT)) -#define R2MS_MASK (0x01 << (R2MS_SHIFT)) -#define R1DF_SHIFT 1 -#define R2DF_SHIFT 2 -#define R1DF_MASK (0x01 << (R1DF_SHIFT)) -#define R2DF_MASK (0x01 << (R2DF_SHIFT)) -#define R1FE_MASK 0x01 -#define R2FE_MASK 0x05 -#define TT1_SHIFT 0 -#define TT2_SHIFT 4 -#define TT_OFF 0 -#define TT_ON 1 -#define TT_MASK 7 -#define MANUFACTURER_ID 0x01 -#define DEFAULT_REVISION 0xA4 - -/* Conversions and various macros */ -#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \ - (val_h)) * 1000 + (val_l) * 1000 / 256) - -/* Functions declaration */ -static int lm95241_attach_adapter(struct i2c_adapter *adapter); -static int lm95241_detect(struct i2c_adapter *adapter, int address, - int kind); -static void lm95241_init_client(struct i2c_client *client); -static int lm95241_detach_client(struct i2c_client *client); -static struct lm95241_data *lm95241_update_device(struct device *dev); - -/* Driver data (common to all clients) */ -static struct i2c_driver lm95241_driver = { - .driver = { - .name = "lm95241", - }, - .attach_adapter = lm95241_attach_adapter, - .detach_client = lm95241_detach_client, -}; - -/* Client data (each client gets its own) */ -struct lm95241_data { - struct i2c_client client; - struct device *hwmon_dev; - struct mutex update_lock; - unsigned long last_updated, rate; /* in jiffies */ - char valid; /* zero until following fields are valid */ - /* registers values */ - u8 local_h, local_l; /* local */ - u8 remote1_h, remote1_l; /* remote1 */ - u8 remote2_h, remote2_l; /* remote2 */ - u8 config, model, trutherm; -}; - -/* Sysfs stuff */ -#define show_temp(value) \ -static ssize_t show_##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct lm95241_data *data = lm95241_update_device(dev); \ - snprintf(buf, PAGE_SIZE - 1, "%d\n", \ - TEMP_FROM_REG(data->value##_h, data->value##_l)); \ - return strlen(buf); \ -} -show_temp(local); -show_temp(remote1); -show_temp(remote2); - -static ssize_t show_rate(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct lm95241_data *data = lm95241_update_device(dev); - - snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ); - return strlen(buf); -} - -static ssize_t set_rate(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - strict_strtol(buf, 10, &data->rate); - data->rate = data->rate * HZ / 1000; - - return count; -} - -#define show_type(flag) \ -static ssize_t show_type##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \ - return strlen(buf); \ -} -show_type(1); -show_type(2); - -#define show_min(flag) \ -static ssize_t show_min##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->config & R##flag##DF_MASK ? \ - "-127000\n" : "0\n"); \ - return strlen(buf); \ -} -show_min(1); -show_min(2); - -#define show_max(flag) \ -static ssize_t show_max##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->config & R##flag##DF_MASK ? \ - "127000\n" : "255000\n"); \ - return strlen(buf); \ -} -show_max(1); -show_max(2); - -#define set_type(flag) \ -static ssize_t set_type##flag(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - if ((val == 1) || (val == 2)) { \ -\ - mutex_lock(&data->update_lock); \ -\ - data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \ - if (val == 1) { \ - data->model |= R##flag##MS_MASK; \ - data->trutherm |= (TT_ON << TT##flag##_SHIFT); \ - } \ - else { \ - data->model &= ~R##flag##MS_MASK; \ - data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \ - } \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \ - data->model); \ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \ - data->trutherm); \ -\ - mutex_unlock(&data->update_lock); \ -\ - } \ - return count; \ -} -set_type(1); -set_type(2); - -#define set_min(flag) \ -static ssize_t set_min##flag(struct device *dev, \ - struct device_attribute *devattr, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - mutex_lock(&data->update_lock); \ -\ - if (val < 0) \ - data->config |= R##flag##DF_MASK; \ - else \ - data->config &= ~R##flag##DF_MASK; \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ - data->config); \ -\ - mutex_unlock(&data->update_lock); \ -\ - return count; \ -} -set_min(1); -set_min(2); - -#define set_max(flag) \ -static ssize_t set_max##flag(struct device *dev, \ - struct device_attribute *devattr, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - mutex_lock(&data->update_lock); \ -\ - if (val <= 127000) \ - data->config |= R##flag##DF_MASK; \ - else \ - data->config &= ~R##flag##DF_MASK; \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ - data->config); \ -\ - mutex_unlock(&data->update_lock); \ -\ - return count; \ -} -set_max(1); -set_max(2); - -static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL); -static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL); -static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL); -static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1); -static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2); -static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1); -static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); -static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); -static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); -static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate); - -static struct attribute *lm95241_attributes[] = { - &dev_attr_temp1_input.attr, - &dev_attr_temp2_input.attr, - &dev_attr_temp3_input.attr, - &dev_attr_temp2_type.attr, - &dev_attr_temp3_type.attr, - &dev_attr_temp2_min.attr, - &dev_attr_temp3_min.attr, - &dev_attr_temp2_max.attr, - &dev_attr_temp3_max.attr, - &dev_attr_rate.attr, - NULL -}; - -static const struct attribute_group lm95241_group = { - .attrs = lm95241_attributes, -}; - -/* Init/exit code */ -static int lm95241_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm95241_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *new_client; - struct lm95241_data *data; - int err = 0; - const char *name = ""; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - LM95241-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm95241_driver; - new_client->flags = 0; - - /* - * Now we do the remaining detection. A negative kind means that - * the driver was loaded with no force parameter (default), so we - * must both detect and identify the chip. A zero kind means that - * the driver was loaded with the force parameter, the detection - * step shall be skipped. A positive kind means that the driver - * was loaded with the force parameter and a given kind of chip is - * requested, so both the detection and the identification steps - * are skipped. - */ - if (kind < 0) { /* detection */ - if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) - != MANUFACTURER_ID) - || (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) - < DEFAULT_REVISION)) { - dev_dbg(&adapter->dev, - "LM95241 detection failed at 0x%02x.\n", - address); - goto exit_free; - } - } - - if (kind <= 0) { /* identification */ - if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) - == MANUFACTURER_ID) - && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) - >= DEFAULT_REVISION)) { - - kind = lm95241; - - if (kind <= 0) { /* identification failed */ - dev_info(&adapter->dev, "Unsupported chip\n"); - goto exit_free; - } - } - } - - if (kind == lm95241) - name = "lm95241"; - - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); - data->valid = 0; - mutex_init(&data->update_lock); - - /* Tell the I2C layer a new client has arrived */ - err = i2c_attach_client(new_client); - if (err) - goto exit_free; - - /* Initialize the LM95241 chip */ - lm95241_init_client(new_client); - - /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); - if (err) - goto exit_detach; - - data->hwmon_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); -exit_detach: - i2c_detach_client(new_client); -exit_free: - kfree(data); -exit: - return err; -} - -static void lm95241_init_client(struct i2c_client *client) -{ - struct lm95241_data *data = i2c_get_clientdata(client); - - data->rate = HZ; /* 1 sec default */ - data->valid = 0; - data->config = CFG_CR0076; - data->model = 0; - data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, - data->config); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, - R1FE_MASK | R2FE_MASK); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, - data->trutherm); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, - data->model); -} - -static int lm95241_detach_client(struct i2c_client *client) -{ - struct lm95241_data *data = i2c_get_clientdata(client); - int err; - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm95241_group); - - err = i2c_detach_client(client); - if (err) - return err; - - kfree(data); - return 0; -} - -static struct lm95241_data *lm95241_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->rate) || - !data->valid) { - dev_dbg(&client->dev, "Updating lm95241 data.\n"); - data->local_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_LOCAL_TEMPH); - data->local_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_LOCAL_TEMPL); - data->remote1_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE1_TEMPH); - data->remote1_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE1_TEMPL); - data->remote2_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE2_TEMPH); - data->remote2_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE2_TEMPL); - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init sensors_lm95241_init(void) -{ - return i2c_add_driver(&lm95241_driver); -} - -static void __exit sensors_lm95241_exit(void) -{ - i2c_del_driver(&lm95241_driver); -} - -MODULE_AUTHOR("Davide Rizzo "); -MODULE_DESCRIPTION("LM95241 sensor driver"); -MODULE_LICENSE("GPL"); - -module_init(sensors_lm95241_init); -module_exit(sensors_lm95241_exit); diff --git a/trunk/drivers/hwmon/ltc4215.c b/trunk/drivers/hwmon/ltc4215.c deleted file mode 100644 index 9386e2a39211..000000000000 --- a/trunk/drivers/hwmon/ltc4215.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Driver for Linear Technology LTC4215 I2C Hot Swap Controller - * - * Copyright (C) 2009 Ira W. Snyder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * Datasheet: - * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(ltc4215); - -/* Here are names of the chip's registers (a.k.a. commands) */ -enum ltc4215_cmd { - LTC4215_CONTROL = 0x00, /* rw */ - LTC4215_ALERT = 0x01, /* rw */ - LTC4215_STATUS = 0x02, /* ro */ - LTC4215_FAULT = 0x03, /* rw */ - LTC4215_SENSE = 0x04, /* rw */ - LTC4215_SOURCE = 0x05, /* rw */ - LTC4215_ADIN = 0x06, /* rw */ -}; - -struct ltc4215_data { - struct device *hwmon_dev; - - struct mutex update_lock; - bool valid; - unsigned long last_updated; /* in jiffies */ - - /* Registers */ - u8 regs[7]; -}; - -static struct ltc4215_data *ltc4215_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ltc4215_data *data = i2c_get_clientdata(client); - s32 val; - int i; - - mutex_lock(&data->update_lock); - - /* The chip's A/D updates 10 times per second */ - if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) { - - dev_dbg(&client->dev, "Starting ltc4215 update\n"); - - /* Read all registers */ - for (i = 0; i < ARRAY_SIZE(data->regs); i++) { - val = i2c_smbus_read_byte_data(client, i); - if (unlikely(val < 0)) - data->regs[i] = 0; - else - data->regs[i] = val; - } - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -/* Return the voltage from the given register in millivolts */ -static int ltc4215_get_voltage(struct device *dev, u8 reg) -{ - struct ltc4215_data *data = ltc4215_update_device(dev); - const u8 regval = data->regs[reg]; - u32 voltage = 0; - - switch (reg) { - case LTC4215_SENSE: - /* 151 uV per increment */ - voltage = regval * 151 / 1000; - break; - case LTC4215_SOURCE: - /* 60.5 mV per increment */ - voltage = regval * 605 / 10; - break; - case LTC4215_ADIN: - /* The ADIN input is divided by 12.5, and has 4.82 mV - * per increment, so we have the additional multiply */ - voltage = regval * 482 * 125 / 1000; - break; - default: - /* If we get here, the developer messed up */ - WARN_ON_ONCE(1); - break; - } - - return voltage; -} - -/* Return the current from the sense resistor in mA */ -static unsigned int ltc4215_get_current(struct device *dev) -{ - struct ltc4215_data *data = ltc4215_update_device(dev); - - /* The strange looking conversions that follow are fixed-point - * math, since we cannot do floating point in the kernel. - * - * Step 1: convert sense register to microVolts - * Step 2: convert voltage to milliAmperes - * - * If you play around with the V=IR equation, you come up with - * the following: X uV / Y mOhm == Z mA - * - * With the resistors that are fractions of a milliOhm, we multiply - * the voltage and resistance by 10, to shift the decimal point. - * Now we can use the normal division operator again. - */ - - /* Calculate voltage in microVolts (151 uV per increment) */ - const unsigned int voltage = data->regs[LTC4215_SENSE] * 151; - - /* Calculate current in milliAmperes (4 milliOhm sense resistor) */ - const unsigned int curr = voltage / 4; - - return curr; -} - -static ssize_t ltc4215_show_voltage(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - const int voltage = ltc4215_get_voltage(dev, attr->index); - - return snprintf(buf, PAGE_SIZE, "%d\n", voltage); -} - -static ssize_t ltc4215_show_current(struct device *dev, - struct device_attribute *da, - char *buf) -{ - const unsigned int curr = ltc4215_get_current(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", curr); -} - -static ssize_t ltc4215_show_power(struct device *dev, - struct device_attribute *da, - char *buf) -{ - const unsigned int curr = ltc4215_get_current(dev); - const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN); - - /* current in mA * voltage in mV == power in uW */ - const unsigned int power = abs(output_voltage * curr); - - return snprintf(buf, PAGE_SIZE, "%u\n", power); -} - -static ssize_t ltc4215_show_alarm(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); - struct ltc4215_data *data = ltc4215_update_device(dev); - const u8 reg = data->regs[attr->index]; - const u32 mask = attr->nr; - - return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); -} - -/* These macros are used below in constructing device attribute objects - * for use with sysfs_create_group() to make a sysfs device file - * for each register. - */ - -#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_voltage, NULL, ltc4215_cmd_idx) - -#define LTC4215_CURRENT(name) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_current, NULL, 0); - -#define LTC4215_POWER(name) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_power, NULL, 0); - -#define LTC4215_ALARM(name, mask, reg) \ - static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ - ltc4215_show_alarm, NULL, (mask), reg) - -/* Construct a sensor_device_attribute structure for each register */ - -/* Current */ -LTC4215_CURRENT(curr1_input); -LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); - -/* Power (virtual) */ -LTC4215_POWER(power1_input); -LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); - -/* Input Voltage */ -LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); -LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS); -LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); - -/* Output Voltage */ -LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); - -/* Finally, construct an array of pointers to members of the above objects, - * as required for sysfs_create_group() - */ -static struct attribute *ltc4215_attributes[] = { - &sensor_dev_attr_curr1_input.dev_attr.attr, - &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, - - &sensor_dev_attr_power1_input.dev_attr.attr, - &sensor_dev_attr_power1_alarm.dev_attr.attr, - - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in1_max_alarm.dev_attr.attr, - &sensor_dev_attr_in1_min_alarm.dev_attr.attr, - - &sensor_dev_attr_in2_input.dev_attr.attr, - - NULL, -}; - -static const struct attribute_group ltc4215_group = { - .attrs = ltc4215_attributes, -}; - -static int ltc4215_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct ltc4215_data *data; - int ret; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto out_kzalloc; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Initialize the LTC4215 chip */ - /* TODO */ - - /* Register sysfs hooks */ - ret = sysfs_create_group(&client->dev.kobj, <c4215_group); - if (ret) - goto out_sysfs_create_group; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_hwmon_device_register; - } - - return 0; - -out_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, <c4215_group); -out_sysfs_create_group: - kfree(data); -out_kzalloc: - return ret; -} - -static int ltc4215_remove(struct i2c_client *client) -{ - struct ltc4215_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, <c4215_group); - - kfree(data); - - return 0; -} - -static int ltc4215_detect(struct i2c_client *client, - int kind, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = client->adapter; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - if (kind < 0) { /* probed detection - check the chip type */ - s32 v; /* 8 bits from the chip, or -ERRNO */ - - /* - * Register 0x01 bit b7 is reserved, expect 0 - * Register 0x03 bit b6 and b7 are reserved, expect 0 - */ - v = i2c_smbus_read_byte_data(client, LTC4215_ALERT); - if (v < 0 || (v & (1 << 7)) != 0) - return -ENODEV; - - v = i2c_smbus_read_byte_data(client, LTC4215_FAULT); - if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0) - return -ENODEV; - } - - strlcpy(info->type, "ltc4215", I2C_NAME_SIZE); - dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n", - kind < 0 ? "probed" : "forced", - client->addr); - - return 0; -} - -static const struct i2c_device_id ltc4215_id[] = { - { "ltc4215", ltc4215 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ltc4215_id); - -/* This is the driver that will be inserted */ -static struct i2c_driver ltc4215_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ltc4215", - }, - .probe = ltc4215_probe, - .remove = ltc4215_remove, - .id_table = ltc4215_id, - .detect = ltc4215_detect, - .address_data = &addr_data, -}; - -static int __init ltc4215_init(void) -{ - return i2c_add_driver(<c4215_driver); -} - -static void __exit ltc4215_exit(void) -{ - i2c_del_driver(<c4215_driver); -} - -MODULE_AUTHOR("Ira W. Snyder "); -MODULE_DESCRIPTION("LTC4215 driver"); -MODULE_LICENSE("GPL"); - -module_init(ltc4215_init); -module_exit(ltc4215_exit); diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 2d8352419c0d..3e468d2cf730 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -1331,6 +1331,12 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) #endif } +static int capinc_tty_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return 0; +} + static struct tty_driver *capinc_tty_driver; static const struct tty_operations capinc_ops = { @@ -1352,6 +1358,7 @@ static const struct tty_operations capinc_ops = { .flush_buffer = capinc_tty_flush_buffer, .set_ldisc = capinc_tty_set_ldisc, .send_xchar = capinc_tty_send_xchar, + .read_proc = capinc_tty_read_proc, }; static int capinc_tty_init(void) diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 5f3bff434621..1c484084ed4f 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -223,16 +223,6 @@ config DELL_LAPTOP This driver adds support for rfkill and backlight control to Dell laptops. -config ISL29003 - tristate "Intersil ISL29003 ambient light sensor" - depends on I2C && SYSFS - help - If you say yes here you get support for the Intersil ISL29003 - ambient light sensor. - - This driver can also be built as a module. If so, the module - will be called isl29003. - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 7871f05dcb9b..bc1199830554 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -18,6 +18,5 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_HP_ILO) += hpilo.o -obj-$(CONFIG_ISL29003) += isl29003.o obj-$(CONFIG_C2PORT) += c2port/ obj-y += eeprom/ diff --git a/trunk/drivers/misc/hpilo.c b/trunk/drivers/misc/hpilo.c index 880ccf39e23b..cf991850f01b 100644 --- a/trunk/drivers/misc/hpilo.c +++ b/trunk/drivers/misc/hpilo.c @@ -209,7 +209,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) /* give iLO some time to process stop request */ for (retries = MAX_WAIT; retries > 0; retries--) { doorbell_set(driver_ccb); - udelay(WAIT_TIME); + udelay(1); if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) && !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A))) @@ -312,7 +312,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) for (i = MAX_WAIT; i > 0; i--) { if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) break; - udelay(WAIT_TIME); + udelay(1); } if (i) { @@ -759,7 +759,7 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.1"); +MODULE_VERSION("1.0"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli "); diff --git a/trunk/drivers/misc/hpilo.h b/trunk/drivers/misc/hpilo.h index 03a14c82aad9..b64a20ef07e3 100644 --- a/trunk/drivers/misc/hpilo.h +++ b/trunk/drivers/misc/hpilo.h @@ -19,12 +19,8 @@ #define MAX_ILO_DEV 1 /* max number of files */ #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) -/* total wait time in usec */ -#define MAX_WAIT_TIME 10000 -/* per spin wait time in usec */ -#define WAIT_TIME 10 /* spin counter for open/close delay */ -#define MAX_WAIT (MAX_WAIT_TIME / WAIT_TIME) +#define MAX_WAIT 10000 /* * Per device, used to track global memory allocations. diff --git a/trunk/drivers/misc/isl29003.c b/trunk/drivers/misc/isl29003.c deleted file mode 100644 index 2e2a5923d4c2..000000000000 --- a/trunk/drivers/misc/isl29003.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * isl29003.c - Linux kernel module for - * Intersil ISL29003 ambient light sensor - * - * See file:Documentation/misc-devices/isl29003 - * - * Copyright (c) 2009 Daniel Mack - * - * Based on code written by - * Rodolfo Giometti - * Eurotech S.p.A. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include - -#define ISL29003_DRV_NAME "isl29003" -#define DRIVER_VERSION "1.0" - -#define ISL29003_REG_COMMAND 0x00 -#define ISL29003_ADC_ENABLED (1 << 7) -#define ISL29003_ADC_PD (1 << 6) -#define ISL29003_TIMING_INT (1 << 5) -#define ISL29003_MODE_SHIFT (2) -#define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT) -#define ISL29003_RES_SHIFT (0) -#define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT) - -#define ISL29003_REG_CONTROL 0x01 -#define ISL29003_INT_FLG (1 << 5) -#define ISL29003_RANGE_SHIFT (2) -#define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT) -#define ISL29003_INT_PERSISTS_SHIFT (0) -#define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT) - -#define ISL29003_REG_IRQ_THRESH_HI 0x02 -#define ISL29003_REG_IRQ_THRESH_LO 0x03 -#define ISL29003_REG_LSB_SENSOR 0x04 -#define ISL29003_REG_MSB_SENSOR 0x05 -#define ISL29003_REG_LSB_TIMER 0x06 -#define ISL29003_REG_MSB_TIMER 0x07 - -#define ISL29003_NUM_CACHABLE_REGS 4 - -struct isl29003_data { - struct i2c_client *client; - struct mutex lock; - u8 reg_cache[ISL29003_NUM_CACHABLE_REGS]; -}; - -static int gain_range[] = { - 1000, 4000, 16000, 64000 -}; - -/* - * register access helpers - */ - -static int __isl29003_read_reg(struct i2c_client *client, - u32 reg, u8 mask, u8 shift) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - return (data->reg_cache[reg] & mask) >> shift; -} - -static int __isl29003_write_reg(struct i2c_client *client, - u32 reg, u8 mask, u8 shift, u8 val) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int ret = 0; - u8 tmp; - - if (reg >= ISL29003_NUM_CACHABLE_REGS) - return -EINVAL; - - mutex_lock(&data->lock); - - tmp = data->reg_cache[reg]; - tmp &= ~mask; - tmp |= val << shift; - - ret = i2c_smbus_write_byte_data(client, reg, tmp); - if (!ret) - data->reg_cache[reg] = tmp; - - mutex_unlock(&data->lock); - return ret; -} - -/* - * internally used functions - */ - -/* range */ -static int isl29003_get_range(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_CONTROL, - ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT); -} - -static int isl29003_set_range(struct i2c_client *client, int range) -{ - return __isl29003_write_reg(client, ISL29003_REG_CONTROL, - ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range); -} - -/* resolution */ -static int isl29003_get_resolution(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT); -} - -static int isl29003_set_resolution(struct i2c_client *client, int res) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT, res); -} - -/* mode */ -static int isl29003_get_mode(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT); -} - -static int isl29003_set_mode(struct i2c_client *client, int mode) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode); -} - -/* power_state */ -static int isl29003_set_power_state(struct i2c_client *client, int state) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0, - state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD); -} - -static int isl29003_get_power_state(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND]; - return ~cmdreg & ISL29003_ADC_PD; -} - -static int isl29003_get_adc_value(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int lsb, msb, range, bitdepth; - - mutex_lock(&data->lock); - lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR); - - if (lsb < 0) { - mutex_unlock(&data->lock); - return lsb; - } - - msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR); - mutex_unlock(&data->lock); - - if (msb < 0) - return msb; - - range = isl29003_get_range(client); - bitdepth = (4 - isl29003_get_resolution(client)) * 4; - return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth; -} - -/* - * sysfs layer - */ - -/* range */ -static ssize_t isl29003_show_range(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%i\n", isl29003_get_range(client)); -} - -static ssize_t isl29003_store_range(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) - return -EINVAL; - - ret = isl29003_set_range(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(range, S_IWUSR | S_IRUGO, - isl29003_show_range, isl29003_store_range); - - -/* resolution */ -static ssize_t isl29003_show_resolution(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_resolution(client)); -} - -static ssize_t isl29003_store_resolution(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) - return -EINVAL; - - ret = isl29003_set_resolution(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO, - isl29003_show_resolution, isl29003_store_resolution); - -/* mode */ -static ssize_t isl29003_show_mode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_mode(client)); -} - -static ssize_t isl29003_store_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2)) - return -EINVAL; - - ret = isl29003_set_mode(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, - isl29003_show_mode, isl29003_store_mode); - - -/* power state */ -static ssize_t isl29003_show_power_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_power_state(client)); -} - -static ssize_t isl29003_store_power_state(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1)) - return -EINVAL; - - ret = isl29003_set_power_state(client, val); - return ret ? ret : count; -} - -static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, - isl29003_show_power_state, isl29003_store_power_state); - - -/* lux */ -static ssize_t isl29003_show_lux(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - - /* No LUX data if not operational */ - if (!isl29003_get_power_state(client)) - return -EBUSY; - - return sprintf(buf, "%d\n", isl29003_get_adc_value(client)); -} - -static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL); - -static struct attribute *isl29003_attributes[] = { - &dev_attr_range.attr, - &dev_attr_resolution.attr, - &dev_attr_mode.attr, - &dev_attr_power_state.attr, - &dev_attr_lux.attr, - NULL -}; - -static const struct attribute_group isl29003_attr_group = { - .attrs = isl29003_attributes, -}; - -static int isl29003_init_client(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int i; - - /* read all the registers once to fill the cache. - * if one of the reads fails, we consider the init failed */ - for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) { - int v = i2c_smbus_read_byte_data(client, i); - if (v < 0) - return -ENODEV; - - data->reg_cache[i] = v; - } - - /* set defaults */ - isl29003_set_range(client, 0); - isl29003_set_resolution(client, 0); - isl29003_set_mode(client, 0); - isl29003_set_power_state(client, 0); - - return 0; -} - -/* - * I2C layer - */ - -static int __devinit isl29003_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct isl29003_data *data; - int err = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) - return -EIO; - - data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->lock); - - /* initialize the ISL29003 chip */ - err = isl29003_init_client(client); - if (err) - goto exit_kfree; - - /* register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group); - if (err) - goto exit_kfree; - - dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION); - return 0; - -exit_kfree: - kfree(data); - return err; -} - -static int __devexit isl29003_remove(struct i2c_client *client) -{ - sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group); - isl29003_set_power_state(client, 0); - kfree(i2c_get_clientdata(client)); - return 0; -} - -#ifdef CONFIG_PM -static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg) -{ - return isl29003_set_power_state(client, 0); -} - -static int isl29003_resume(struct i2c_client *client) -{ - int i; - struct isl29003_data *data = i2c_get_clientdata(client); - - /* restore registers from cache */ - for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) - if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i])) - return -EIO; - - return 0; -} - -#else -#define isl29003_suspend NULL -#define isl29003_resume NULL -#endif /* CONFIG_PM */ - -static const struct i2c_device_id isl29003_id[] = { - { "isl29003", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, isl29003_id); - -static struct i2c_driver isl29003_driver = { - .driver = { - .name = ISL29003_DRV_NAME, - .owner = THIS_MODULE, - }, - .suspend = isl29003_suspend, - .resume = isl29003_resume, - .probe = isl29003_probe, - .remove = __devexit_p(isl29003_remove), - .id_table = isl29003_id, -}; - -static int __init isl29003_init(void) -{ - return i2c_add_driver(&isl29003_driver); -} - -static void __exit isl29003_exit(void) -{ - i2c_del_driver(&isl29003_driver); -} - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("ISL29003 ambient light sensor driver"); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION(DRIVER_VERSION); - -module_init(isl29003_init); -module_exit(isl29003_exit); - diff --git a/trunk/drivers/mmc/card/sdio_uart.c b/trunk/drivers/mmc/card/sdio_uart.c index 36a8d53ad2a2..78ad48718ab0 100644 --- a/trunk/drivers/mmc/card/sdio_uart.c +++ b/trunk/drivers/mmc/card/sdio_uart.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -934,64 +933,67 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, return result; } -static int sdio_uart_proc_show(struct seq_file *m, void *v) +static int sdio_uart_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - int i; + int i, len = 0; + off_t begin = 0; - seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", + len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) { struct sdio_uart_port *port = sdio_uart_port_get(i); if (port) { - seq_printf(m, "%d: uart:SDIO", i); + len += sprintf(page+len, "%d: uart:SDIO", i); if(capable(CAP_SYS_ADMIN)) { - seq_printf(m, " tx:%d rx:%d", + len += sprintf(page + len, " tx:%d rx:%d", port->icount.tx, port->icount.rx); if (port->icount.frame) - seq_printf(m, " fe:%d", + len += sprintf(page + len, " fe:%d", port->icount.frame); if (port->icount.parity) - seq_printf(m, " pe:%d", + len += sprintf(page + len, " pe:%d", port->icount.parity); if (port->icount.brk) - seq_printf(m, " brk:%d", + len += sprintf(page + len, " brk:%d", port->icount.brk); if (port->icount.overrun) - seq_printf(m, " oe:%d", + len += sprintf(page + len, " oe:%d", port->icount.overrun); if (port->icount.cts) - seq_printf(m, " cts:%d", + len += sprintf(page + len, " cts:%d", port->icount.cts); if (port->icount.dsr) - seq_printf(m, " dsr:%d", + len += sprintf(page + len, " dsr:%d", port->icount.dsr); if (port->icount.rng) - seq_printf(m, " rng:%d", + len += sprintf(page + len, " rng:%d", port->icount.rng); if (port->icount.dcd) - seq_printf(m, " dcd:%d", + len += sprintf(page + len, " dcd:%d", port->icount.dcd); } + strcat(page, "\n"); + len++; sdio_uart_port_put(port); - seq_putc(m, '\n'); + } + + if (len + begin > off + count) + goto done; + if (len + begin < off) { + begin += len; + len = 0; } } - return 0; -} + *eof = 1; -static int sdio_uart_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, sdio_uart_proc_show, NULL); +done: + if (off >= len + begin) + return 0; + *start = page + (off - begin); + return (count < begin + len - off) ? count : (begin + len - off); } -static const struct file_operations sdio_uart_proc_fops = { - .owner = THIS_MODULE, - .open = sdio_uart_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct tty_operations sdio_uart_ops = { .open = sdio_uart_open, .close = sdio_uart_close, @@ -1005,7 +1007,7 @@ static const struct tty_operations sdio_uart_ops = { .break_ctl = sdio_uart_break_ctl, .tiocmget = sdio_uart_tiocmget, .tiocmset = sdio_uart_tiocmset, - .proc_fops = &sdio_uart_proc_fops, + .read_proc = sdio_uart_read_proc, }; static struct tty_driver *sdio_uart_tty_driver; diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index 41c5dfd85358..cd17092b82bd 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -446,7 +446,6 @@ struct of_modalias_table { }; static struct of_modalias_table of_modalias_table[] = { { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, - { "mmc-spi-slot", "mmc_spi" }, }; /** diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 09d5cd33a3f6..81450fbd8b12 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -129,14 +129,13 @@ comment "I2C RTC drivers" if I2C config RTC_DRV_DS1307 - tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" + tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" help If you say yes here you get support for various compatible RTC chips (often with battery backup) connected with I2C. This driver should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, - EPSON RX-8025 and probably other chips. In some cases the RTC - must already have been initialized (by manufacturing or a - bootloader). + and probably other chips. In some cases the RTC must already + have been initialized (by manufacturing or a bootloader). The first seven registers on these chips hold an RTC, and other registers may add features such as NVRAM, a trickle charger for @@ -441,16 +440,6 @@ config RTC_DRV_DS1742 This driver can also be built as a module. If so, the module will be called rtc-ds1742. -config RTC_DRV_EFI - tristate "EFI RTC" - depends on IA64 - help - If you say yes here you will get support for the EFI - Real Time Clock. - - This driver can also be built as a module. If so, the module - will be called rtc-efi. - config RTC_DRV_STK17TA8 tristate "Simtek STK17TA8" depends on RTC_CLASS diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index e7b09986d26e..0e697aa51caa 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o -obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index 2c4a65302a9d..7e5155e88ac7 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -3,7 +3,6 @@ * * Copyright (C) 2005 James Chapman (ds1337 core) * Copyright (C) 2006 David Brownell - * Copyright (C) 2009 Matthias Fuchs (rx8025 support) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -32,7 +31,6 @@ enum ds_type { ds_1339, ds_1340, m41t00, - rx_8025, // rs5c372 too? different address... }; @@ -85,12 +83,6 @@ enum ds_type { #define DS1339_REG_ALARM1_SECS 0x07 #define DS1339_REG_TRICKLE 0x10 -#define RX8025_REG_CTRL1 0x0e -# define RX8025_BIT_2412 0x20 -#define RX8025_REG_CTRL2 0x0f -# define RX8025_BIT_PON 0x10 -# define RX8025_BIT_VDET 0x40 -# define RX8025_BIT_XST 0x20 struct ds1307 { @@ -102,10 +94,6 @@ struct ds1307 { struct i2c_client *client; struct rtc_device *rtc; struct work_struct work; - s32 (*read_block_data)(struct i2c_client *client, u8 command, - u8 length, u8 *values); - s32 (*write_block_data)(struct i2c_client *client, u8 command, - u8 length, const u8 *values); }; struct chip_desc { @@ -129,8 +117,6 @@ static const struct chip_desc chips[] = { [ds_1340] = { }, [m41t00] = { -}, -[rx_8025] = { }, }; static const struct i2c_device_id ds1307_id[] = { @@ -140,86 +126,12 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1339", ds_1339 }, { "ds1340", ds_1340 }, { "m41t00", m41t00 }, - { "rx8025", rx_8025 }, { } }; MODULE_DEVICE_TABLE(i2c, ds1307_id); /*----------------------------------------------------------------------*/ -#define BLOCK_DATA_MAX_TRIES 10 - -static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command, - u8 length, u8 *values) -{ - s32 i, data; - - for (i = 0; i < length; i++) { - data = i2c_smbus_read_byte_data(client, command + i); - if (data < 0) - return data; - values[i] = data; - } - return i; -} - -static s32 ds1307_read_block_data(struct i2c_client *client, u8 command, - u8 length, u8 *values) -{ - u8 oldvalues[I2C_SMBUS_BLOCK_MAX]; - s32 ret; - int tries = 0; - - dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length); - ret = ds1307_read_block_data_once(client, command, length, values); - if (ret < 0) - return ret; - do { - if (++tries > BLOCK_DATA_MAX_TRIES) { - dev_err(&client->dev, - "ds1307_read_block_data failed\n"); - return -EIO; - } - memcpy(oldvalues, values, length); - ret = ds1307_read_block_data_once(client, command, length, - values); - if (ret < 0) - return ret; - } while (memcmp(oldvalues, values, length)); - return length; -} - -static s32 ds1307_write_block_data(struct i2c_client *client, u8 command, - u8 length, const u8 *values) -{ - u8 currvalues[I2C_SMBUS_BLOCK_MAX]; - int tries = 0; - - dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length); - do { - s32 i, ret; - - if (++tries > BLOCK_DATA_MAX_TRIES) { - dev_err(&client->dev, - "ds1307_write_block_data failed\n"); - return -EIO; - } - for (i = 0; i < length; i++) { - ret = i2c_smbus_write_byte_data(client, command + i, - values[i]); - if (ret < 0) - return ret; - } - ret = ds1307_read_block_data_once(client, command, length, - currvalues); - if (ret < 0) - return ret; - } while (memcmp(currvalues, values, length)); - return length; -} - -/*----------------------------------------------------------------------*/ - /* * The IRQ logic includes a "real" handler running in IRQ context just * long enough to schedule this workqueue entry. We need a task context @@ -290,7 +202,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) int tmp; /* read the RTC date and time registers all at once */ - tmp = ds1307->read_block_data(ds1307->client, + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, DS1307_REG_SECS, 7, ds1307->regs); if (tmp != 7) { dev_err(dev, "%s error %d\n", "read", tmp); @@ -367,7 +279,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) "write", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - result = ds1307->write_block_data(ds1307->client, 0, 7, buf); + result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); if (result < 0) { dev_err(dev, "%s error %d\n", "write", result); return result; @@ -385,7 +297,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) return -EINVAL; /* read all ALARM1, ALARM2, and status registers at once */ - ret = ds1307->read_block_data(client, + ret = i2c_smbus_read_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, ds1307->regs); if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm read", ret); @@ -444,7 +356,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) t->enabled, t->pending); /* read current status of both alarms and the chip */ - ret = ds1307->read_block_data(client, + ret = i2c_smbus_read_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, buf); if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm write", ret); @@ -479,7 +391,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) } buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); - ret = ds1307->write_block_data(client, + ret = i2c_smbus_write_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, buf); if (ret < 0) { dev_err(dev, "can't set alarm time\n"); @@ -567,7 +479,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, if (unlikely(!count)) return count; - result = ds1307->read_block_data(client, 8 + off, count, buf); + result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); if (result < 0) dev_err(&client->dev, "%s error %d\n", "nvram read", result); return result; @@ -578,11 +490,9 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; - struct ds1307 *ds1307; int result; client = kobj_to_i2c_client(kobj); - ds1307 = i2c_get_clientdata(client); if (unlikely(off >= NVRAM_SIZE)) return -EFBIG; @@ -591,7 +501,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, if (unlikely(!count)) return count; - result = ds1307->write_block_data(client, 8 + off, count, buf); + result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); if (result < 0) { dev_err(&client->dev, "%s error %d\n", "nvram write", result); return result; @@ -625,8 +535,9 @@ static int __devinit ds1307_probe(struct i2c_client *client, int want_irq = false; unsigned char *buf; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA) - && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) + if (!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) @@ -636,13 +547,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, i2c_set_clientdata(client, ds1307); ds1307->type = id->driver_data; buf = ds1307->regs; - if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { - ds1307->read_block_data = i2c_smbus_read_i2c_block_data; - ds1307->write_block_data = i2c_smbus_write_i2c_block_data; - } else { - ds1307->read_block_data = ds1307_read_block_data; - ds1307->write_block_data = ds1307_write_block_data; - } switch (ds1307->type) { case ds_1337: @@ -653,7 +557,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, want_irq = true; } /* get registers that the "rtc" read below won't read... */ - tmp = ds1307->read_block_data(ds1307->client, + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, DS1337_REG_CONTROL, 2, buf); if (tmp != 2) { pr_debug("read error %d\n", tmp); @@ -685,79 +589,13 @@ static int __devinit ds1307_probe(struct i2c_client *client, dev_warn(&client->dev, "SET TIME!\n"); } break; - - case rx_8025: - tmp = i2c_smbus_read_i2c_block_data(ds1307->client, - RX8025_REG_CTRL1 << 4 | 0x08, 2, buf); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - /* oscillator off? turn it on, so clock can tick. */ - if (!(ds1307->regs[1] & RX8025_BIT_XST)) { - ds1307->regs[1] |= RX8025_BIT_XST; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, - "oscillator stop detected - SET TIME!\n"); - } - - if (ds1307->regs[1] & RX8025_BIT_PON) { - ds1307->regs[1] &= ~RX8025_BIT_PON; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, "power-on detected\n"); - } - - if (ds1307->regs[1] & RX8025_BIT_VDET) { - ds1307->regs[1] &= ~RX8025_BIT_VDET; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, "voltage drop detected\n"); - } - - /* make sure we are running in 24hour mode */ - if (!(ds1307->regs[0] & RX8025_BIT_2412)) { - u8 hour; - - /* switch to 24 hour mode */ - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL1 << 4 | 0x08, - ds1307->regs[0] | - RX8025_BIT_2412); - - tmp = i2c_smbus_read_i2c_block_data(ds1307->client, - RX8025_REG_CTRL1 << 4 | 0x08, 2, buf); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - /* correct hour */ - hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]); - if (hour == 12) - hour = 0; - if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) - hour += 12; - - i2c_smbus_write_byte_data(client, - DS1307_REG_HOUR << 4 | 0x08, - hour); - } - break; default: break; } read_rtc: /* read RTC registers */ - tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf); + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; @@ -811,7 +649,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, dev_warn(&client->dev, "SET TIME!\n"); } break; - case rx_8025: case ds_1337: case ds_1339: break; @@ -825,8 +662,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, * systems that will run through year 2100. */ break; - case rx_8025: - break; default: if (!(tmp & DS1307_BIT_12HR)) break; diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index 4d32e328f6cd..a5b0fc09f0c6 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -222,16 +222,16 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_tm_to_time(&alarm->time, &new_alarm); rtc_tm_to_time(&now, &itime); + new_alarm -= itime; + /* This can happen due to races, in addition to dates that are * truly in the past. To avoid requiring the caller to check for * races, dates in the past are assumed to be in the recent past * (i.e. not something that we'd rather the caller know about via * an error), and the alarm is set to go off as soon as possible. */ - if (time_before_eq(new_alarm, itime)) + if (new_alarm <= 0) new_alarm = 1; - else - new_alarm -= itime; mutex_lock(&ds1374->mutex); diff --git a/trunk/drivers/rtc/rtc-efi.c b/trunk/drivers/rtc/rtc-efi.c deleted file mode 100644 index 550292304b0f..000000000000 --- a/trunk/drivers/rtc/rtc-efi.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * rtc-efi: RTC Class Driver for EFI-based systems - * - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * - * Author: dann frazier - * Based on efirtc.c by Stephane Eranian - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include - -#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT) -/* - * EFI Epoch is 1/1/1998 - */ -#define EFI_RTC_EPOCH 1998 - -/* - * returns day of the year [0-365] - */ -static inline int -compute_yday(efi_time_t *eft) -{ - /* efi_time_t.month is in the [1-12] so, we need -1 */ - return rtc_year_days(eft->day - 1, eft->month - 1, eft->year); -} -/* - * returns day of the week [0-6] 0=Sunday - * - * Don't try to provide a year that's before 1998, please ! - */ -static int -compute_wday(efi_time_t *eft) -{ - int y; - int ndays = 0; - - if (eft->year < 1998) { - printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n"); - return -1; - } - - for (y = EFI_RTC_EPOCH; y < eft->year; y++) - ndays += 365 + (is_leap_year(y) ? 1 : 0); - - ndays += compute_yday(eft); - - /* - * 4=1/1/1998 was a Thursday - */ - return (ndays + 4) % 7; -} - -static void -convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) -{ - eft->year = wtime->tm_year + 1900; - eft->month = wtime->tm_mon + 1; - eft->day = wtime->tm_mday; - eft->hour = wtime->tm_hour; - eft->minute = wtime->tm_min; - eft->second = wtime->tm_sec; - eft->nanosecond = 0; - eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; - eft->timezone = EFI_UNSPECIFIED_TIMEZONE; -} - -static void -convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) -{ - memset(wtime, 0, sizeof(*wtime)); - wtime->tm_sec = eft->second; - wtime->tm_min = eft->minute; - wtime->tm_hour = eft->hour; - wtime->tm_mday = eft->day; - wtime->tm_mon = eft->month - 1; - wtime->tm_year = eft->year - 1900; - - /* day of the week [0-6], Sunday=0 */ - wtime->tm_wday = compute_wday(eft); - - /* day in the year [1-365]*/ - wtime->tm_yday = compute_yday(eft); - - - switch (eft->daylight & EFI_ISDST) { - case EFI_ISDST: - wtime->tm_isdst = 1; - break; - case EFI_TIME_ADJUST_DAYLIGHT: - wtime->tm_isdst = 0; - break; - default: - wtime->tm_isdst = -1; - } -} - -static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - /* - * As of EFI v1.10, this call always returns an unsupported status - */ - status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled, - (efi_bool_t *)&wkalrm->pending, &eft); - - if (status != EFI_SUCCESS) - return -EINVAL; - - convert_from_efi_time(&eft, &wkalrm->time); - - return rtc_valid_tm(&wkalrm->time); -} - -static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - convert_to_efi_time(&wkalrm->time, &eft); - - /* - * XXX Fixme: - * As of EFI 0.92 with the firmware I have on my - * machine this call does not seem to work quite - * right - * - * As of v1.10, this call always returns an unsupported status - */ - status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); - - printk(KERN_WARNING "write status is %d\n", (int)status); - - return status == EFI_SUCCESS ? 0 : -EINVAL; -} - -static int efi_read_time(struct device *dev, struct rtc_time *tm) -{ - efi_status_t status; - efi_time_t eft; - efi_time_cap_t cap; - - status = efi.get_time(&eft, &cap); - - if (status != EFI_SUCCESS) { - /* should never happen */ - printk(KERN_ERR "efitime: can't read time\n"); - return -EINVAL; - } - - convert_from_efi_time(&eft, tm); - - return rtc_valid_tm(tm); -} - -static int efi_set_time(struct device *dev, struct rtc_time *tm) -{ - efi_status_t status; - efi_time_t eft; - - convert_to_efi_time(tm, &eft); - - status = efi.set_time(&eft); - - return status == EFI_SUCCESS ? 0 : -EINVAL; -} - -static const struct rtc_class_ops efi_rtc_ops = { - .read_time = efi_read_time, - .set_time = efi_set_time, - .read_alarm = efi_read_alarm, - .set_alarm = efi_set_alarm, -}; - -static int __init efi_rtc_probe(struct platform_device *dev) -{ - struct rtc_device *rtc; - - rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(dev, rtc); - - return 0; -} - -static int __exit efi_rtc_remove(struct platform_device *dev) -{ - struct rtc_device *rtc = platform_get_drvdata(dev); - - rtc_device_unregister(rtc); - - return 0; -} - -static struct platform_driver efi_rtc_driver = { - .driver = { - .name = "rtc-efi", - .owner = THIS_MODULE, - }, - .probe = efi_rtc_probe, - .remove = __exit_p(efi_rtc_remove), -}; - -static int __init efi_rtc_init(void) -{ - return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe); -} - -static void __exit efi_rtc_exit(void) -{ - platform_driver_unregister(&efi_rtc_driver); -} - -module_init(efi_rtc_init); -module_exit(efi_rtc_exit); - -MODULE_AUTHOR("dann frazier "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("EFI RTC driver"); diff --git a/trunk/drivers/rtc/rtc-lib.c b/trunk/drivers/rtc/rtc-lib.c index 773851f338b8..dd70bf73ce9d 100644 --- a/trunk/drivers/rtc/rtc-lib.c +++ b/trunk/drivers/rtc/rtc-lib.c @@ -26,13 +26,14 @@ static const unsigned short rtc_ydays[2][13] = { }; #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) /* * The number of days in the month. */ int rtc_month_days(unsigned int month, unsigned int year) { - return rtc_days_in_month[month] + (is_leap_year(year) && month == 1); + return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); } EXPORT_SYMBOL(rtc_month_days); @@ -41,7 +42,7 @@ EXPORT_SYMBOL(rtc_month_days); */ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) { - return rtc_ydays[is_leap_year(year)][month] + day-1; + return rtc_ydays[LEAP_YEAR(year)][month] + day-1; } EXPORT_SYMBOL(rtc_year_days); @@ -65,7 +66,7 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) - LEAPS_THRU_END_OF(1970 - 1); if (days < 0) { year -= 1; - days += 365 + is_leap_year(year); + days += 365 + LEAP_YEAR(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; diff --git a/trunk/drivers/rtc/rtc-parisc.c b/trunk/drivers/rtc/rtc-parisc.c index b966f56da976..c6bfa6fe1a2a 100644 --- a/trunk/drivers/rtc/rtc-parisc.c +++ b/trunk/drivers/rtc/rtc-parisc.c @@ -7,25 +7,41 @@ #include #include #include -#include #include +/* as simple as can be, and no simpler. */ +struct parisc_rtc { + struct rtc_device *rtc; + spinlock_t lock; +}; + static int parisc_get_time(struct device *dev, struct rtc_time *tm) { - unsigned long ret; + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags, ret; + spin_lock_irqsave(&p->lock, flags); ret = get_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); if (ret & RTC_BATT_BAD) return -EOPNOTSUPP; - return rtc_valid_tm(tm); + return 0; } static int parisc_set_time(struct device *dev, struct rtc_time *tm) { - if (set_rtc_time(tm) < 0) + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&p->lock, flags); + ret = set_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); + + if (ret < 0) return -EOPNOTSUPP; return 0; @@ -36,25 +52,35 @@ static const struct rtc_class_ops parisc_rtc_ops = { .set_time = parisc_set_time, }; -static int __init parisc_rtc_probe(struct platform_device *dev) +static int __devinit parisc_rtc_probe(struct platform_device *dev) { - struct rtc_device *rtc; + struct parisc_rtc *p; + + p = kzalloc(sizeof (*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + spin_lock_init(&p->lock); - rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, + THIS_MODULE); + if (IS_ERR(p->rtc)) { + int err = PTR_ERR(p->rtc); + kfree(p); + return err; + } - platform_set_drvdata(dev, rtc); + platform_set_drvdata(dev, p); return 0; } -static int __exit parisc_rtc_remove(struct platform_device *dev) +static int __devexit parisc_rtc_remove(struct platform_device *dev) { - struct rtc_device *rtc = platform_get_drvdata(dev); + struct parisc_rtc *p = platform_get_drvdata(dev); - rtc_device_unregister(rtc); + rtc_device_unregister(p->rtc); + kfree(p); return 0; } @@ -70,7 +96,7 @@ static struct platform_driver parisc_rtc_driver = { static int __init parisc_rtc_init(void) { - return platform_driver_probe(&parisc_rtc_driver, parisc_rtc_probe); + return platform_driver_register(&parisc_rtc_driver); } static void __exit parisc_rtc_fini(void) diff --git a/trunk/drivers/rtc/rtc-v3020.c b/trunk/drivers/rtc/rtc-v3020.c index 66955cc9c746..14d4f036a768 100644 --- a/trunk/drivers/rtc/rtc-v3020.c +++ b/trunk/drivers/rtc/rtc-v3020.c @@ -28,7 +28,7 @@ #include #include -#include +#include #undef DEBUG @@ -63,7 +63,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) { - unsigned int data = 0; + unsigned int data=0; int i; for (i = 0; i < 4; i++) { @@ -106,14 +106,16 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt) tmp = v3020_get_reg(chip, V3020_YEAR); dt->tm_year = bcd2bin(tmp)+100; - dev_dbg(dev, "\n%s : Read RTC values\n", __func__); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); - dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); +#ifdef DEBUG + printk("\n%s : Read RTC values\n",__func__); + printk("tm_hour: %i\n",dt->tm_hour); + printk("tm_min : %i\n",dt->tm_min); + printk("tm_sec : %i\n",dt->tm_sec); + printk("tm_year: %i\n",dt->tm_year); + printk("tm_mon : %i\n",dt->tm_mon); + printk("tm_mday: %i\n",dt->tm_mday); + printk("tm_wday: %i\n",dt->tm_wday); +#endif return 0; } @@ -123,13 +125,15 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt) { struct v3020 *chip = dev_get_drvdata(dev); - dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); +#ifdef DEBUG + printk("\n%s : Setting RTC values\n",__func__); + printk("tm_sec : %i\n",dt->tm_sec); + printk("tm_min : %i\n",dt->tm_min); + printk("tm_hour: %i\n",dt->tm_hour); + printk("tm_mday: %i\n",dt->tm_mday); + printk("tm_wday: %i\n",dt->tm_wday); + printk("tm_year: %i\n",dt->tm_year); +#endif /* Write all the values to ram... */ v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec)); @@ -187,7 +191,7 @@ static int rtc_probe(struct platform_device *pdev) /* Test chip by doing a write/read sequence * to the chip ram */ v3020_set_reg(chip, V3020_SECONDS, 0x33); - if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) { + if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) { retval = -ENODEV; goto err_io; } diff --git a/trunk/drivers/rtc/rtc-wm8350.c b/trunk/drivers/rtc/rtc-wm8350.c index c91edc572eb6..5c5e3aa91385 100644 --- a/trunk/drivers/rtc/rtc-wm8350.c +++ b/trunk/drivers/rtc/rtc-wm8350.c @@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) do { rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); schedule_timeout_uninterruptible(msecs_to_jiffies(1)); - } while (--retries && !(rtc_ctrl & WM8350_RTC_STS)); + } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS)); if (!retries) { dev_err(dev, "timed out on set confirmation\n"); @@ -236,17 +236,6 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) return 0; } -static int wm8350_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct wm8350 *wm8350 = dev_get_drvdata(dev); - - if (enabled) - return wm8350_rtc_start_alarm(wm8350); - else - return wm8350_rtc_stop_alarm(wm8350); -} - static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct wm8350 *wm8350 = dev_get_drvdata(dev); @@ -302,15 +291,30 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int wm8350_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) +/* + * Handle commands from user-space + */ +static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { struct wm8350 *wm8350 = dev_get_drvdata(dev); - if (enabled) - wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); - else + switch (cmd) { + case RTC_AIE_OFF: + return wm8350_rtc_stop_alarm(wm8350); + case RTC_AIE_ON: + return wm8350_rtc_start_alarm(wm8350); + + case RTC_UIE_OFF: wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); + break; + case RTC_UIE_ON: + wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); + break; + + default: + return -ENOIOCTLCMD; + } return 0; } @@ -341,12 +345,11 @@ static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq, } static const struct rtc_class_ops wm8350_rtc_ops = { + .ioctl = wm8350_rtc_ioctl, .read_time = wm8350_rtc_readtime, .set_time = wm8350_rtc_settime, .read_alarm = wm8350_rtc_readalarm, .set_alarm = wm8350_rtc_setalarm, - .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, - .update_irq_enable = wm8350_rtc_update_irq_enable, }; #ifdef CONFIG_PM @@ -437,7 +440,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev) do { timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); - } while (timectl & WM8350_RTC_STS && --retries); + } while (timectl & WM8350_RTC_STS && retries--); if (retries == 0) { dev_err(&pdev->dev, "failed to start: timeout\n"); diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index bf3c0e32a334..42f4e66fccaf 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include @@ -1684,20 +1682,20 @@ static const char *uart_type(struct uart_port *port) #ifdef CONFIG_PROC_FS -static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) +static int uart_line_info(char *buf, struct uart_driver *drv, int i) { struct uart_state *state = drv->state + i; int pm_state; struct uart_port *port = state->port; char stat_buf[32]; unsigned int status; - int mmio; + int mmio, ret; if (!port) - return; + return 0; mmio = port->iotype >= UPIO_MEM; - seq_printf(m, "%d: uart:%s %s%08llX irq:%d", + ret = sprintf(buf, "%d: uart:%s %s%08llX irq:%d", port->line, uart_type(port), mmio ? "mmio:0x" : "port:", mmio ? (unsigned long long)port->mapbase @@ -1705,8 +1703,8 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) port->irq); if (port->type == PORT_UNKNOWN) { - seq_putc(m, '\n'); - return; + strcat(buf, "\n"); + return ret + 1; } if (capable(CAP_SYS_ADMIN)) { @@ -1721,19 +1719,19 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) uart_change_pm(state, pm_state); mutex_unlock(&state->mutex); - seq_printf(m, " tx:%d rx:%d", + ret += sprintf(buf + ret, " tx:%d rx:%d", port->icount.tx, port->icount.rx); if (port->icount.frame) - seq_printf(m, " fe:%d", + ret += sprintf(buf + ret, " fe:%d", port->icount.frame); if (port->icount.parity) - seq_printf(m, " pe:%d", + ret += sprintf(buf + ret, " pe:%d", port->icount.parity); if (port->icount.brk) - seq_printf(m, " brk:%d", + ret += sprintf(buf + ret, " brk:%d", port->icount.brk); if (port->icount.overrun) - seq_printf(m, " oe:%d", + ret += sprintf(buf + ret, " oe:%d", port->icount.overrun); #define INFOBIT(bit, str) \ @@ -1755,39 +1753,45 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) STATBIT(TIOCM_RNG, "|RI"); if (stat_buf[0]) stat_buf[0] = ' '; + strcat(stat_buf, "\n"); - seq_puts(m, stat_buf); + ret += sprintf(buf + ret, stat_buf); + } else { + strcat(buf, "\n"); + ret++; } - seq_putc(m, '\n'); #undef STATBIT #undef INFOBIT + return ret; } -static int uart_proc_show(struct seq_file *m, void *v) +static int uart_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - struct tty_driver *ttydrv = v; + struct tty_driver *ttydrv = data; struct uart_driver *drv = ttydrv->driver_state; - int i; + int i, len = 0, l; + off_t begin = 0; - seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", + len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); - for (i = 0; i < drv->nr; i++) - uart_line_info(m, drv, i); - return 0; -} - -static int uart_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, uart_proc_show, PDE(inode)->data); + for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) { + l = uart_line_info(page + len, drv, i); + len += l; + if (len + begin > off + count) + goto done; + if (len + begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; + done: + if (off >= len + begin) + return 0; + *start = page + (off - begin); + return (count < begin + len - off) ? count : (begin + len - off); } - -static const struct file_operations uart_proc_fops = { - .owner = THIS_MODULE, - .open = uart_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; #endif #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) @@ -2295,7 +2299,7 @@ static const struct tty_operations uart_ops = { .break_ctl = uart_break_ctl, .wait_until_sent= uart_wait_until_sent, #ifdef CONFIG_PROC_FS - .proc_fops = &uart_proc_fops, + .read_proc = uart_read_proc, #endif .tiocmget = uart_tiocmget, .tiocmset = uart_tiocmset, diff --git a/trunk/drivers/spi/spi_mpc83xx.c b/trunk/drivers/spi/spi_mpc83xx.c index f4573a96af24..44a2b46ccb79 100644 --- a/trunk/drivers/spi/spi_mpc83xx.c +++ b/trunk/drivers/spi/spi_mpc83xx.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -25,13 +23,7 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include @@ -87,7 +79,7 @@ struct mpc83xx_spi { u32(*get_tx) (struct mpc83xx_spi *); unsigned int count; - unsigned int irq; + int irq; unsigned nsecs; /* (clock cycle time)/2 */ @@ -97,6 +89,9 @@ struct mpc83xx_spi { bool qe_mode; + void (*activate_cs) (u8 cs, u8 polarity); + void (*deactivate_cs) (u8 cs, u8 polarity); + u8 busy; struct workqueue_struct *workqueue; @@ -128,7 +123,6 @@ static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg) } #define MPC83XX_SPI_RX_BUF(type) \ -static \ void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ { \ type * rx = mpc83xx_spi->rx; \ @@ -137,7 +131,6 @@ void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ } #define MPC83XX_SPI_TX_BUF(type) \ -static \ u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \ { \ u32 data; \ @@ -158,14 +151,15 @@ MPC83XX_SPI_TX_BUF(u32) static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) { - struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; - bool pol = spi->mode & SPI_CS_HIGH; + struct mpc83xx_spi *mpc83xx_spi; + u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0; struct spi_mpc83xx_cs *cs = spi->controller_state; + mpc83xx_spi = spi_master_get_devdata(spi->master); + if (value == BITBANG_CS_INACTIVE) { - if (pdata->cs_control) - pdata->cs_control(spi, !pol); + if (mpc83xx_spi->deactivate_cs) + mpc83xx_spi->deactivate_cs(spi->chip_select, pol); } if (value == BITBANG_CS_ACTIVE) { @@ -178,7 +172,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + void *tmp_ptr = &mpc83xx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time that @@ -186,12 +180,12 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); local_irq_restore(flags); } - if (pdata->cs_control) - pdata->cs_control(spi, pol); + if (mpc83xx_spi->activate_cs) + mpc83xx_spi->activate_cs(spi->chip_select, pol); } } @@ -290,7 +284,7 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + void *tmp_ptr = &mpc83xx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time @@ -298,8 +292,8 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); local_irq_restore(flags); } return 0; @@ -489,7 +483,7 @@ static int mpc83xx_spi_setup(struct spi_device *spi) return 0; } -static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) +irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) { struct mpc83xx_spi *mpc83xx_spi = context_data; u32 event; @@ -551,28 +545,43 @@ static void mpc83xx_spi_cleanup(struct spi_device *spi) kfree(spi->controller_state); } -static struct spi_master * __devinit -mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) +static int __init mpc83xx_spi_probe(struct platform_device *dev) { - struct fsl_spi_platform_data *pdata = dev->platform_data; struct spi_master *master; struct mpc83xx_spi *mpc83xx_spi; + struct fsl_spi_platform_data *pdata; + struct resource *r; u32 regval; int ret = 0; - master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi)); + /* Get resources(memory, IRQ) associated with the device */ + master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi)); + if (master == NULL) { ret = -ENOMEM; goto err; } - dev_set_drvdata(dev, master); + platform_set_drvdata(dev, master); + pdata = dev->dev.platform_data; + if (pdata == NULL) { + ret = -ENODEV; + goto free_master; + } + + r = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (r == NULL) { + ret = -ENODEV; + goto free_master; + } master->setup = mpc83xx_spi_setup; master->transfer = mpc83xx_spi_transfer; master->cleanup = mpc83xx_spi_cleanup; mpc83xx_spi = spi_master_get_devdata(master); + mpc83xx_spi->activate_cs = pdata->activate_cs; + mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; mpc83xx_spi->qe_mode = pdata->qe_mode; mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; @@ -587,13 +596,18 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) init_completion(&mpc83xx_spi->done); - mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); + mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1); if (mpc83xx_spi->base == NULL) { ret = -ENOMEM; goto put_master; } - mpc83xx_spi->irq = irq; + mpc83xx_spi->irq = platform_get_irq(dev, 0); + + if (mpc83xx_spi->irq < 0) { + ret = -ENXIO; + goto unmap_io; + } /* Register for SPI Interrupt */ ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, @@ -635,9 +649,9 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) printk(KERN_INFO "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", - dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq); + dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq); - return master; + return ret; unreg_master: destroy_workqueue(mpc83xx_spi->workqueue); @@ -647,16 +661,18 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) iounmap(mpc83xx_spi->base); put_master: spi_master_put(master); +free_master: + kfree(master); err: - return ERR_PTR(ret); + return ret; } -static int __devexit mpc83xx_spi_remove(struct device *dev) +static int __exit mpc83xx_spi_remove(struct platform_device *dev) { struct mpc83xx_spi *mpc83xx_spi; struct spi_master *master; - master = dev_get_drvdata(dev); + master = platform_get_drvdata(dev); mpc83xx_spi = spi_master_get_devdata(master); flush_workqueue(mpc83xx_spi->workqueue); @@ -669,293 +685,23 @@ static int __devexit mpc83xx_spi_remove(struct device *dev) return 0; } -struct mpc83xx_spi_probe_info { - struct fsl_spi_platform_data pdata; - int *gpios; - bool *alow_flags; -}; - -static struct mpc83xx_spi_probe_info * -to_of_pinfo(struct fsl_spi_platform_data *pdata) -{ - return container_of(pdata, struct mpc83xx_spi_probe_info, pdata); -} - -static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) -{ - struct device *dev = spi->dev.parent; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); - u16 cs = spi->chip_select; - int gpio = pinfo->gpios[cs]; - bool alow = pinfo->alow_flags[cs]; - - gpio_set_value(gpio, on ^ alow); -} - -static int of_mpc83xx_spi_get_chipselects(struct device *dev) -{ - struct device_node *np = dev_archdata_get_node(&dev->archdata); - struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); - unsigned int ngpios; - int i = 0; - int ret; - - ngpios = of_gpio_count(np); - if (!ngpios) { - /* - * SPI w/o chip-select line. One SPI device is still permitted - * though. - */ - pdata->max_chipselect = 1; - return 0; - } - - pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL); - if (!pinfo->gpios) - return -ENOMEM; - memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios)); - - pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags), - GFP_KERNEL); - if (!pinfo->alow_flags) { - ret = -ENOMEM; - goto err_alloc_flags; - } - - for (; i < ngpios; i++) { - int gpio; - enum of_gpio_flags flags; - - gpio = of_get_gpio_flags(np, i, &flags); - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio #%d: %d\n", i, gpio); - goto err_loop; - } - - ret = gpio_request(gpio, dev_name(dev)); - if (ret) { - dev_err(dev, "can't request gpio #%d: %d\n", i, ret); - goto err_loop; - } - - pinfo->gpios[i] = gpio; - pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW; - - ret = gpio_direction_output(pinfo->gpios[i], - pinfo->alow_flags[i]); - if (ret) { - dev_err(dev, "can't set output direction for gpio " - "#%d: %d\n", i, ret); - goto err_loop; - } - } - - pdata->max_chipselect = ngpios; - pdata->cs_control = mpc83xx_spi_cs_control; - - return 0; - -err_loop: - while (i >= 0) { - if (gpio_is_valid(pinfo->gpios[i])) - gpio_free(pinfo->gpios[i]); - i--; - } - - kfree(pinfo->alow_flags); - pinfo->alow_flags = NULL; -err_alloc_flags: - kfree(pinfo->gpios); - pinfo->gpios = NULL; - return ret; -} - -static int of_mpc83xx_spi_free_chipselects(struct device *dev) -{ - struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); - int i; - - if (!pinfo->gpios) - return 0; - - for (i = 0; i < pdata->max_chipselect; i++) { - if (gpio_is_valid(pinfo->gpios[i])) - gpio_free(pinfo->gpios[i]); - } - - kfree(pinfo->gpios); - kfree(pinfo->alow_flags); - return 0; -} - -static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, - const struct of_device_id *ofid) -{ - struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; - struct mpc83xx_spi_probe_info *pinfo; - struct fsl_spi_platform_data *pdata; - struct spi_master *master; - struct resource mem; - struct resource irq; - const void *prop; - int ret = -ENOMEM; - - pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; - - pdata = &pinfo->pdata; - dev->platform_data = pdata; - - /* Allocate bus num dynamically. */ - pdata->bus_num = -1; - - /* SPI controller is either clocked from QE or SoC clock. */ - pdata->sysclk = get_brgfreq(); - if (pdata->sysclk == -1) { - pdata->sysclk = fsl_get_sys_freq(); - if (pdata->sysclk == -1) { - ret = -ENODEV; - goto err_clk; - } - } - - prop = of_get_property(np, "mode", NULL); - if (prop && !strcmp(prop, "cpu-qe")) - pdata->qe_mode = 1; - - ret = of_mpc83xx_spi_get_chipselects(dev); - if (ret) - goto err; - - ret = of_address_to_resource(np, 0, &mem); - if (ret) - goto err; - - ret = of_irq_to_resource(np, 0, &irq); - if (!ret) { - ret = -EINVAL; - goto err; - } - - master = mpc83xx_spi_probe(dev, &mem, irq.start); - if (IS_ERR(master)) { - ret = PTR_ERR(master); - goto err; - } - - of_register_spi_devices(master, np); - - return 0; - -err: - of_mpc83xx_spi_free_chipselects(dev); -err_clk: - kfree(pinfo); - return ret; -} - -static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev) -{ - int ret; - - ret = mpc83xx_spi_remove(&ofdev->dev); - if (ret) - return ret; - of_mpc83xx_spi_free_chipselects(&ofdev->dev); - return 0; -} - -static const struct of_device_id of_mpc83xx_spi_match[] = { - { .compatible = "fsl,spi" }, - {}, -}; -MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match); - -static struct of_platform_driver of_mpc83xx_spi_driver = { - .name = "mpc83xx_spi", - .match_table = of_mpc83xx_spi_match, - .probe = of_mpc83xx_spi_probe, - .remove = __devexit_p(of_mpc83xx_spi_remove), -}; - -#ifdef CONFIG_MPC832x_RDB -/* - * XXX XXX XXX - * This is "legacy" platform driver, was used by the MPC8323E-RDB boards - * only. The driver should go away soon, since newer MPC8323E-RDB's device - * tree can work with OpenFirmware driver. But for now we support old trees - * as well. - */ -static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev) -{ - struct resource *mem; - unsigned int irq; - struct spi_master *master; - - if (!pdev->dev.platform_data) - return -EINVAL; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -EINVAL; - - irq = platform_get_irq(pdev, 0); - if (!irq) - return -EINVAL; - - master = mpc83xx_spi_probe(&pdev->dev, mem, irq); - if (IS_ERR(master)) - return PTR_ERR(master); - return 0; -} - -static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev) -{ - return mpc83xx_spi_remove(&pdev->dev); -} - MODULE_ALIAS("platform:mpc83xx_spi"); static struct platform_driver mpc83xx_spi_driver = { - .probe = plat_mpc83xx_spi_probe, - .remove = __exit_p(plat_mpc83xx_spi_remove), + .remove = __exit_p(mpc83xx_spi_remove), .driver = { .name = "mpc83xx_spi", .owner = THIS_MODULE, }, }; -static bool legacy_driver_failed; - -static void __init legacy_driver_register(void) -{ - legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver); -} - -static void __exit legacy_driver_unregister(void) -{ - if (legacy_driver_failed) - return; - platform_driver_unregister(&mpc83xx_spi_driver); -} -#else -static void __init legacy_driver_register(void) {} -static void __exit legacy_driver_unregister(void) {} -#endif /* CONFIG_MPC832x_RDB */ - static int __init mpc83xx_spi_init(void) { - legacy_driver_register(); - return of_register_platform_driver(&of_mpc83xx_spi_driver); + return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe); } static void __exit mpc83xx_spi_exit(void) { - of_unregister_platform_driver(&of_mpc83xx_spi_driver); - legacy_driver_unregister(); + platform_driver_unregister(&mpc83xx_spi_driver); } module_init(mpc83xx_spi_init); diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 2a70563bbee1..742a5bc44be8 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -422,52 +421,57 @@ static int serial_break(struct tty_struct *tty, int break_state) return 0; } -static int serial_proc_show(struct seq_file *m, void *v) +static int serial_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { struct usb_serial *serial; + int length = 0; int i; + off_t begin = 0; char tmp[40]; dbg("%s", __func__); - seq_puts(m, "usbserinfo:1.0 driver:2.0\n"); - for (i = 0; i < SERIAL_TTY_MINORS; ++i) { + length += sprintf(page, "usbserinfo:1.0 driver:2.0\n"); + for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { serial = usb_serial_get_by_index(i); if (serial == NULL) continue; - seq_printf(m, "%d:", i); + length += sprintf(page+length, "%d:", i); if (serial->type->driver.owner) - seq_printf(m, " module:%s", + length += sprintf(page+length, " module:%s", module_name(serial->type->driver.owner)); - seq_printf(m, " name:\"%s\"", + length += sprintf(page+length, " name:\"%s\"", serial->type->description); - seq_printf(m, " vendor:%04x product:%04x", + length += sprintf(page+length, " vendor:%04x product:%04x", le16_to_cpu(serial->dev->descriptor.idVendor), le16_to_cpu(serial->dev->descriptor.idProduct)); - seq_printf(m, " num_ports:%d", serial->num_ports); - seq_printf(m, " port:%d", i - serial->minor + 1); + length += sprintf(page+length, " num_ports:%d", + serial->num_ports); + length += sprintf(page+length, " port:%d", + i - serial->minor + 1); usb_make_path(serial->dev, tmp, sizeof(tmp)); - seq_printf(m, " path:%s", tmp); + length += sprintf(page+length, " path:%s", tmp); - seq_putc(m, '\n'); + length += sprintf(page+length, "\n"); + if ((length + begin) > (off + count)) { + usb_serial_put(serial); + goto done; + } + if ((length + begin) < off) { + begin += length; + length = 0; + } usb_serial_put(serial); } - return 0; -} - -static int serial_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, serial_proc_show, NULL); + *eof = 1; +done: + if (off >= (length + begin)) + return 0; + *start = page + (off-begin); + return (count < begin+length-off) ? count : begin+length-off; } -static const struct file_operations serial_proc_fops = { - .owner = THIS_MODULE, - .open = serial_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int serial_tiocmget(struct tty_struct *tty, struct file *file) { struct usb_serial_port *port = tty->driver_data; @@ -1109,9 +1113,9 @@ static const struct tty_operations serial_ops = { .unthrottle = serial_unthrottle, .break_ctl = serial_break, .chars_in_buffer = serial_chars_in_buffer, + .read_proc = serial_read_proc, .tiocmget = serial_tiocmget, .tiocmset = serial_tiocmset, - .proc_fops = &serial_proc_fops, }; struct tty_driver *usb_serial_tty_driver; diff --git a/trunk/drivers/video/68328fb.c b/trunk/drivers/video/68328fb.c index 0b17824b0eb5..7f907fb23b8a 100644 --- a/trunk/drivers/video/68328fb.c +++ b/trunk/drivers/video/68328fb.c @@ -471,11 +471,9 @@ int __init mc68x328fb_init(void) fb_info.pseudo_palette = &mc68x328fb_pseudo_palette; fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; - if (fb_alloc_cmap(&fb_info.cmap, 256, 0)) - return -ENOMEM; + fb_alloc_cmap(&fb_info.cmap, 256, 0); if (register_framebuffer(&fb_info) < 0) { - fb_dealloc_cmap(&fb_info.cmap); return -EINVAL; } @@ -496,7 +494,6 @@ module_init(mc68x328fb_init); static void __exit mc68x328fb_cleanup(void) { unregister_framebuffer(&fb_info); - fb_dealloc_cmap(&fb_info.cmap); } module_exit(mc68x328fb_cleanup); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index ffe2f2796e29..41c27a44bd82 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1597,8 +1597,32 @@ config FB_VT8623 Driver for CastleRock integrated graphics core in the VIA VT8623 [Apollo CLE266] chipset. +config FB_CYBLA + tristate "Cyberblade/i1 support" + depends on FB && PCI && X86_32 && !64BIT + select FB_CFB_IMAGEBLIT + ---help--- + This driver is supposed to support the Trident Cyberblade/i1 + graphics core integrated in the VIA VT8601A North Bridge, + also known as VIA Apollo PLE133. + + Status: + - Developed, tested and working on EPIA 5000 and EPIA 800. + - Does work reliable on all systems with CRT/LCD connected to + normal VGA ports. + - Should work on systems that do use the internal LCD port, but + this is absolutely not tested. + + Character imageblit, copyarea and rectangle fill are hw accelerated, + ypan scrolling is used by default. + + Please do read . + + To compile this driver as a module, choose M here: the + module will be called cyblafb. + config FB_TRIDENT - tristate "Trident/CyberXXX/CyberBlade support" + tristate "Trident support" depends on FB && PCI select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1609,14 +1633,21 @@ config FB_TRIDENT and Blade XP. There are also integrated versions of these chips called CyberXXXX, CyberImage or CyberBlade. These chips are mostly found in laptops - but also on some motherboards including early VIA EPIA motherboards. - For more information, read + but also on some motherboards. For more information, read + Say Y if you have such a graphics board. To compile this driver as a module, choose M here: the module will be called tridentfb. +config FB_TRIDENT_ACCEL + bool "Trident Acceleration functions (EXPERIMENTAL)" + depends on FB_TRIDENT && EXPERIMENTAL + ---help--- + This will compile the Trident frame buffer device with + acceleration functions. + config FB_ARK tristate "ARK 2000PV support" depends on FB && PCI @@ -1889,30 +1920,6 @@ config FB_TMIO_ACCELL depends on FB_TMIO default y -config FB_S3C - tristate "Samsung S3C framebuffer support" - depends on FB && ARCH_S3C64XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in FB controller in the Samsung - SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, - and the S3C64XX series such as the S3C6400 and S3C6410. - - These chips all have the same basic framebuffer design with the - actual capabilities depending on the chip. For instance the S3C6400 - and S3C6410 support 4 hardware windows whereas the S3C24XX series - currently only have two. - - Currently the support is only for the S3C6400 and S3C6410 SoCs. - -config FB_S3C_DEBUG_REGWRITE - bool "Debug register writes" - depends on FB_S3C - ---help--- - Show all register writes via printk(KERN_DEBUG) - config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" depends on FB && ARCH_S3C2410 diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 0dbd6c68d76b..bb265eca7d57 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -76,7 +76,6 @@ obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o obj-$(CONFIG_FB_MAC) += macfb.o obj-$(CONFIG_FB_HECUBA) += hecubafb.o -obj-$(CONFIG_FB_N411) += n411.o obj-$(CONFIG_FB_HGA) += hgafb.o obj-$(CONFIG_FB_XVR500) += sunxvr500.o obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o @@ -111,7 +110,6 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o -obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o diff --git a/trunk/drivers/video/amba-clcd.c b/trunk/drivers/video/amba-clcd.c index 61050ab14128..4e046fed1380 100644 --- a/trunk/drivers/video/amba-clcd.c +++ b/trunk/drivers/video/amba-clcd.c @@ -408,9 +408,7 @@ static int clcdfb_register(struct clcd_fb *fb) /* * Allocate colourmap. */ - ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0); - if (ret) - goto unmap; + fb_alloc_cmap(&fb->fb.cmap, 256, 0); /* * Ensure interrupts are disabled. @@ -428,8 +426,6 @@ static int clcdfb_register(struct clcd_fb *fb) printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret); - fb_dealloc_cmap(&fb->fb.cmap); - unmap: iounmap(fb->regs); free_clk: clk_put(fb->clk); @@ -489,8 +485,6 @@ static int clcdfb_remove(struct amba_device *dev) clcdfb_disable(fb); unregister_framebuffer(&fb->fb); - if (fb->fb.cmap.len) - fb_dealloc_cmap(&fb->fb.cmap); iounmap(fb->regs); clk_put(fb->clk); diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index 82bedd7f7789..100f23661465 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -2437,9 +2437,7 @@ static int __init amifb_init(void) goto amifb_error; } - err = fb_alloc_cmap(&fb_info.cmap, 1<fix = asiliantfb_fix; p->fix.smem_start = addr; p->var = asiliantfb_var; p->fbops = &asiliantfb_ops; p->flags = FBINFO_DEFAULT; - err = fb_alloc_cmap(&p->cmap, 256, 0); - if (err) { - printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n"); - return err; - } + fb_alloc_cmap(&p->cmap, 256, 0); - err = register_framebuffer(p); - if (err < 0) { + if (register_framebuffer(p) < 0) { printk(KERN_ERR "C&T 69000 framebuffer failed to register\n"); - fb_dealloc_cmap(&p->cmap); - return err; + return; } printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n", @@ -540,7 +532,6 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) { unsigned long addr, size; struct fb_info *p; - int err; if ((dp->resource[0].flags & IORESOURCE_MEM) == 0) return -ENODEV; @@ -569,13 +560,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) pci_write_config_dword(dp, 4, 0x02800083); writeb(3, p->screen_base + 0x400784); - err = init_asiliant(p, addr); - if (err) { - iounmap(p->screen_base); - release_mem_region(addr, size); - framebuffer_release(p); - return err; - } + init_asiliant(p, addr); pci_set_drvdata(dp, p); return 0; @@ -586,7 +571,6 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp) struct fb_info *p = pci_get_drvdata(dp); unregister_framebuffer(p); - fb_dealloc_cmap(&p->cmap); iounmap(p->screen_base); release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0)); pci_set_drvdata(dp, NULL); diff --git a/trunk/drivers/video/aty/mach64_accel.c b/trunk/drivers/video/aty/mach64_accel.c index 0cc9724e61a2..a8f60c33863c 100644 --- a/trunk/drivers/video/aty/mach64_accel.c +++ b/trunk/drivers/video/aty/mach64_accel.c @@ -39,8 +39,7 @@ void aty_reset_engine(const struct atyfb_par *par) { /* reset engine */ aty_st_le32(GEN_TEST_CNTL, - aty_ld_le32(GEN_TEST_CNTL, par) & - ~(GUI_ENGINE_ENABLE | HWCURSOR_ENABLE), par); + aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par); /* enable engine */ aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par); diff --git a/trunk/drivers/video/aty/mach64_cursor.c b/trunk/drivers/video/aty/mach64_cursor.c index 04c710804bb0..faf95da8fcbc 100644 --- a/trunk/drivers/video/aty/mach64_cursor.c +++ b/trunk/drivers/video/aty/mach64_cursor.c @@ -77,13 +77,9 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) if (par->asleep) return -EPERM; + /* Hide cursor */ wait_for_fifo(1, par); - if (cursor->enable) - aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) - | HWCURSOR_ENABLE, par); - else - aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) - & ~HWCURSOR_ENABLE, par); + aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par); /* set position */ if (cursor->set & FB_CUR_SETPOS) { @@ -113,7 +109,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) y<<=1; h<<=1; } - wait_for_fifo(3, par); + wait_for_fifo(4, par); aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par); aty_st_le32(CUR_HORZ_VERT_OFF, ((u32) (64 - h + yoff) << 16) | xoff, par); @@ -181,6 +177,11 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) } } + if (cursor->enable) { + wait_for_fifo(1, par); + aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) + | HWCURSOR_ENABLE, par); + } return 0; } diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index 97a1f095f327..1de0c0032468 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -89,9 +89,6 @@ static struct radeon_device_id radeon_workaround_list[] = { BUGFIX("Acer Aspire 2010", PCI_VENDOR_ID_AI, 0x0061, radeon_pm_off, radeon_reinitialize_M10), - BUGFIX("Acer Travelmate 290D/292LMi", - PCI_VENDOR_ID_AI, 0x005a, - radeon_pm_off, radeon_reinitialize_M10), { .ident = NULL } }; diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index dd37cbcaf8ce..157057c79ca3 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -35,8 +35,6 @@ static int fb_notifier_callback(struct notifier_block *self, return 0; bd = container_of(self, struct backlight_device, fb_notif); - if (!lock_fb_info(evdata->info)) - return -ENODEV; mutex_lock(&bd->ops_lock); if (bd->ops) if (!bd->ops->check_fb || @@ -49,7 +47,6 @@ static int fb_notifier_callback(struct notifier_block *self, backlight_update_status(bd); } mutex_unlock(&bd->ops_lock); - unlock_fb_info(evdata->info); return 0; } diff --git a/trunk/drivers/video/backlight/lcd.c b/trunk/drivers/video/backlight/lcd.c index 0bb13df0fa89..b6449470106c 100644 --- a/trunk/drivers/video/backlight/lcd.c +++ b/trunk/drivers/video/backlight/lcd.c @@ -40,8 +40,6 @@ static int fb_notifier_callback(struct notifier_block *self, if (!ld->ops) return 0; - if (!lock_fb_info(evdata->info)) - return -ENODEV; mutex_lock(&ld->ops_lock); if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { if (event == FB_EVENT_BLANK) { @@ -53,7 +51,6 @@ static int fb_notifier_callback(struct notifier_block *self, } } mutex_unlock(&ld->ops_lock); - unlock_fb_info(evdata->info); return 0; } diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index d42e385f091c..a2aa6ddffbe2 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -34,6 +34,8 @@ * */ +#define CIRRUSFB_VERSION "2.0-pre2" + #include #include #include @@ -70,9 +72,20 @@ * */ +/* enable debug output? */ +/* #define CIRRUSFB_DEBUG 1 */ + /* disable runtime assertions? */ /* #define CIRRUSFB_NDEBUG */ +/* debug output */ +#ifdef CIRRUSFB_DEBUG +#define DPRINTK(fmt, args...) \ + printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) +#else +#define DPRINTK(fmt, args...) +#endif + /* debugging assertions */ #ifndef CIRRUSFB_NDEBUG #define assert(expr) \ @@ -95,15 +108,14 @@ /* board types */ enum cirrus_board { BT_NONE = 0, - BT_SD64, /* GD5434 */ - BT_PICCOLO, /* GD5426 */ - BT_PICASSO, /* GD5426 or GD5428 */ - BT_SPECTRUM, /* GD5426 or GD5428 */ + BT_SD64, + BT_PICCOLO, + BT_PICASSO, + BT_SPECTRUM, BT_PICASSO4, /* GD5446 */ BT_ALPINE, /* GD543x/4x */ BT_GD5480, - BT_LAGUNA, /* GD5462/64 */ - BT_LAGUNAB, /* GD5465 */ + BT_LAGUNA, /* GD546x */ }; /* @@ -138,17 +150,15 @@ static const struct cirrusfb_board_info_rec { .maxclock = { /* guess */ /* the SD64/P4 have a higher max. videoclock */ - 135100, 135100, 85500, 85500, 0 + 140000, 140000, 140000, 140000, 140000, }, .init_sr07 = true, .init_sr1f = true, .scrn_start_bit19 = true, .sr07 = 0xF0, .sr07_1bpp = 0xF0, - .sr07_1bpp_mux = 0xF6, .sr07_8bpp = 0xF1, - .sr07_8bpp_mux = 0xF7, - .sr1f = 0x1E + .sr1f = 0x20 }, [BT_PICCOLO] = { .name = "CL Piccolo", @@ -200,11 +210,9 @@ static const struct cirrusfb_board_info_rec { .init_sr07 = true, .init_sr1f = false, .scrn_start_bit19 = true, - .sr07 = 0xA0, - .sr07_1bpp = 0xA0, - .sr07_1bpp_mux = 0xA6, - .sr07_8bpp = 0xA1, - .sr07_8bpp_mux = 0xA7, + .sr07 = 0x20, + .sr07_1bpp = 0x20, + .sr07_8bpp = 0x21, .sr1f = 0 }, [BT_ALPINE] = { @@ -217,8 +225,8 @@ static const struct cirrusfb_board_info_rec { .init_sr1f = true, .scrn_start_bit19 = true, .sr07 = 0xA0, - .sr07_1bpp = 0xA0, - .sr07_1bpp_mux = 0xA6, + .sr07_1bpp = 0xA1, + .sr07_1bpp_mux = 0xA7, .sr07_8bpp = 0xA1, .sr07_8bpp_mux = 0xA7, .sr1f = 0x1C @@ -239,18 +247,8 @@ static const struct cirrusfb_board_info_rec { [BT_LAGUNA] = { .name = "CL Laguna", .maxclock = { - /* taken from X11 code */ - 170000, 170000, 170000, 170000, 135100, - }, - .init_sr07 = false, - .init_sr1f = false, - .scrn_start_bit19 = true, - }, - [BT_LAGUNAB] = { - .name = "CL Laguna AGP", - .maxclock = { - /* taken from X11 code */ - 170000, 250000, 170000, 170000, 135100, + /* guess */ + 135100, 135100, 135100, 135100, 135100, }, .init_sr07 = false, .init_sr1f = false, @@ -264,8 +262,8 @@ static const struct cirrusfb_board_info_rec { static struct pci_device_id cirrusfb_pci_table[] = { CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), - CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64), - CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64), + CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE), + CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), @@ -273,7 +271,7 @@ static struct pci_device_id cirrusfb_pci_table[] = { CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */ CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */ CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */ - CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/ + CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/ { 0, } }; MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); @@ -328,6 +326,10 @@ static const struct { }; #endif /* CONFIG_ZORRO */ +struct cirrusfb_regs { + int multiplexing; +}; + #ifdef CIRRUSFB_DEBUG enum cirrusfb_dbg_reg_class { CRT, @@ -338,12 +340,10 @@ enum cirrusfb_dbg_reg_class { /* info about board */ struct cirrusfb_info { u8 __iomem *regbase; - u8 __iomem *laguna_mmio; enum cirrus_board btype; unsigned char SFR; /* Shadow of special function register */ - int multiplexing; - int doubleVCLK; + struct cirrusfb_regs currentmode; int blank_mode; u32 pseudo_palette[16]; @@ -357,8 +357,43 @@ static char *mode_option __devinitdata = "640x480@60"; /**** BEGIN PROTOTYPES ******************************************************/ /*--- Interface used by the world ------------------------------------------*/ +static int cirrusfb_init(void); +#ifndef MODULE +static int cirrusfb_setup(char *options); +#endif + +static int cirrusfb_open(struct fb_info *info, int user); +static int cirrusfb_release(struct fb_info *info, int user); +static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info); +static int cirrusfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info); +static int cirrusfb_set_par(struct fb_info *info); static int cirrusfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); +static int cirrusfb_blank(int blank_mode, struct fb_info *info); +static void cirrusfb_fillrect(struct fb_info *info, + const struct fb_fillrect *region); +static void cirrusfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +static void cirrusfb_imageblit(struct fb_info *info, + const struct fb_image *image); + +/* function table of the above functions */ +static struct fb_ops cirrusfb_ops = { + .owner = THIS_MODULE, + .fb_open = cirrusfb_open, + .fb_release = cirrusfb_release, + .fb_setcolreg = cirrusfb_setcolreg, + .fb_check_var = cirrusfb_check_var, + .fb_set_par = cirrusfb_set_par, + .fb_pan_display = cirrusfb_pan_display, + .fb_blank = cirrusfb_blank, + .fb_fillrect = cirrusfb_fillrect, + .fb_copyarea = cirrusfb_copyarea, + .fb_imageblit = cirrusfb_imageblit, +}; /*--- Internal routines ----------------------------------------------------*/ static void init_vgachip(struct fb_info *info); @@ -386,27 +421,22 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, - u32 fg_color, u32 bg_color, - u_short line_length, u_char blitmode); + u_char color, u_short line_length); static void bestclock(long freq, int *nom, int *den, int *div); #ifdef CIRRUSFB_DEBUG -static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase); -static void cirrusfb_dbg_print_regs(struct fb_info *info, - caddr_t regbase, +static void cirrusfb_dump(void); +static void cirrusfb_dbg_reg_dump(caddr_t regbase); +static void cirrusfb_dbg_print_regs(caddr_t regbase, enum cirrusfb_dbg_reg_class reg_class, ...); +static void cirrusfb_dbg_print_byte(const char *name, unsigned char val); #endif /* CIRRUSFB_DEBUG */ /*** END PROTOTYPES ********************************************************/ /*****************************************************************************/ /*** BEGIN Interface Used by the World ***************************************/ -static inline int is_laguna(const struct cirrusfb_info *cinfo) -{ - return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB; -} - static int opencount; /*--- Open /dev/fbx ---------------------------------------------------------*/ @@ -430,94 +460,85 @@ static int cirrusfb_release(struct fb_info *info, int user) /**** BEGIN Hardware specific Routines **************************************/ /* Check if the MCLK is not a better clock source */ -static int cirrusfb_check_mclk(struct fb_info *info, long freq) +static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq) { - struct cirrusfb_info *cinfo = info->par; long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; /* Read MCLK value */ mclk = (14318 * mclk) >> 3; - dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk); + DPRINTK("Read MCLK of %ld kHz\n", mclk); /* Determine if we should use MCLK instead of VCLK, and if so, what we * should divide it by to get VCLK */ if (abs(freq - mclk) < 250) { - dev_dbg(info->device, "Using VCLK = MCLK\n"); + DPRINTK("Using VCLK = MCLK\n"); return 1; } else if (abs(freq - (mclk / 2)) < 250) { - dev_dbg(info->device, "Using VCLK = MCLK/2\n"); + DPRINTK("Using VCLK = MCLK/2\n"); return 2; } return 0; } -static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var, - struct fb_info *info) +static int cirrusfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { - long freq; - long maxclock; - struct cirrusfb_info *cinfo = info->par; - unsigned maxclockidx = var->bits_per_pixel >> 3; - - /* convert from ps to kHz */ - freq = PICOS2KHZ(var->pixclock); - - dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq); - - maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; - cinfo->multiplexing = 0; + int yres; + /* memory size in pixels */ + unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; - /* If the frequency is greater than we can support, we might be able - * to use multiplexing for the video mode */ - if (freq > maxclock) { - dev_err(info->device, - "Frequency greater than maxclock (%ld kHz)\n", - maxclock); + switch (var->bits_per_pixel) { + case 1: + pixels /= 4; + break; /* 8 pixel per byte, only 1/4th of mem usable */ + case 8: + case 16: + case 32: + break; /* 1 pixel == 1 byte */ + default: + printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..." + "color depth not supported.\n", + var->xres, var->yres, var->bits_per_pixel); + DPRINTK("EXIT - EINVAL error\n"); return -EINVAL; } - /* - * Additional constraint: 8bpp uses DAC clock doubling to allow maximum - * pixel clock - */ - if (var->bits_per_pixel == 8) { - switch (cinfo->btype) { - case BT_ALPINE: - case BT_SD64: - case BT_PICASSO4: - if (freq > 85500) - cinfo->multiplexing = 1; - break; - case BT_GD5480: - if (freq > 135100) - cinfo->multiplexing = 1; - break; - default: - break; - } + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + /* use highest possible virtual resolution */ + if (var->yres_virtual == -1) { + var->yres_virtual = pixels / var->xres_virtual; + + printk(KERN_INFO "cirrusfb: virtual resolution set to " + "maximum of %dx%d\n", var->xres_virtual, + var->yres_virtual); } + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; - /* If we have a 1MB 5434, we need to put ourselves in a mode where - * the VCLK is double the pixel clock. */ - cinfo->doubleVCLK = 0; - if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ && - var->bits_per_pixel == 16) { - cinfo->doubleVCLK = 1; + if (var->xres_virtual * var->yres_virtual > pixels) { + printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... " + "virtual resolution too high to fit into video memory!\n", + var->xres_virtual, var->yres_virtual, + var->bits_per_pixel); + DPRINTK("EXIT - EINVAL error\n"); + return -EINVAL; } - return 0; -} -static int cirrusfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - int yres; - /* memory size in pixels */ - unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; - struct cirrusfb_info *cinfo = info->par; + if (var->xoffset < 0) + var->xoffset = 0; + if (var->yoffset < 0) + var->yoffset = 0; + + /* truncate xoffset and yoffset to maximum if too high */ + if (var->xoffset > var->xres_virtual - var->xres) + var->xoffset = var->xres_virtual - var->xres - 1; + if (var->yoffset > var->yres_virtual - var->yres) + var->yoffset = var->yres_virtual - var->yres - 1; switch (var->bits_per_pixel) { case 1: @@ -529,7 +550,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, case 8: var->red.offset = 0; - var->red.length = 8; + var->red.length = 6; var->green = var->red; var->blue = var->red; break; @@ -540,20 +561,20 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, var->green.offset = -3; var->blue.offset = 8; } else { - var->red.offset = 11; + var->red.offset = 10; var->green.offset = 5; var->blue.offset = 0; } var->red.length = 5; - var->green.length = 6; + var->green.length = 5; var->blue.length = 5; break; - case 24: + case 32: if (isPReP) { - var->red.offset = 0; - var->green.offset = 8; - var->blue.offset = 16; + var->red.offset = 8; + var->green.offset = 16; + var->blue.offset = 24; } else { var->red.offset = 16; var->green.offset = 8; @@ -565,45 +586,12 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, break; default: - dev_dbg(info->device, - "Unsupported bpp size: %d\n", var->bits_per_pixel); + DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); assert(false); /* should never occur */ break; } - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - /* use highest possible virtual resolution */ - if (var->yres_virtual == -1) { - var->yres_virtual = pixels / var->xres_virtual; - - dev_info(info->device, - "virtual resolution set to maximum of %dx%d\n", - var->xres_virtual, var->yres_virtual); - } - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; - - if (var->xres_virtual * var->yres_virtual > pixels) { - dev_err(info->device, "mode %dx%dx%d rejected... " - "virtual resolution too high to fit into video memory!\n", - var->xres_virtual, var->yres_virtual, - var->bits_per_pixel); - return -EINVAL; - } - - if (var->xoffset < 0) - var->xoffset = 0; - if (var->yoffset < 0) - var->yoffset = 0; - - /* truncate xoffset and yoffset to maximum if too high */ - if (var->xoffset > var->xres_virtual - var->xres) - var->xoffset = var->xres_virtual - var->xres - 1; - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - var->red.msb_right = var->green.msb_right = var->blue.msb_right = @@ -618,31 +606,99 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, yres = (yres + 1) / 2; if (yres >= 1280) { - dev_err(info->device, "ERROR: VerticalTotal >= 1280; " + printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; " "special treatment required! (TODO)\n"); + DPRINTK("EXIT - EINVAL error\n"); return -EINVAL; } - if (cirrusfb_check_pixclock(var, info)) - return -EINVAL; + return 0; +} + +static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, + struct cirrusfb_regs *regs, + struct fb_info *info) +{ + long freq; + long maxclock; + int maxclockidx = var->bits_per_pixel >> 3; + struct cirrusfb_info *cinfo = info->par; + + switch (var->bits_per_pixel) { + case 1: + info->fix.line_length = var->xres_virtual / 8; + info->fix.visual = FB_VISUAL_MONO10; + break; + + case 8: + info->fix.line_length = var->xres_virtual; + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + break; + + case 16: + case 32: + info->fix.line_length = var->xres_virtual * maxclockidx; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + + default: + DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); + assert(false); + /* should never occur */ + break; + } + + info->fix.type = FB_TYPE_PACKED_PIXELS; + + /* convert from ps to kHz */ + freq = PICOS2KHZ(var->pixclock); + + DPRINTK("desired pixclock: %ld kHz\n", freq); + + maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; + regs->multiplexing = 0; - if (!is_laguna(cinfo)) - var->accel_flags = FB_ACCELF_TEXT; + /* If the frequency is greater than we can support, we might be able + * to use multiplexing for the video mode */ + if (freq > maxclock) { + switch (cinfo->btype) { + case BT_ALPINE: + case BT_GD5480: + regs->multiplexing = 1; + break; + default: + printk(KERN_ERR "cirrusfb: Frequency greater " + "than maxclock (%ld kHz)\n", maxclock); + DPRINTK("EXIT - return -EINVAL\n"); + return -EINVAL; + } + } +#if 0 + /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where + * the VCLK is double the pixel clock. */ + switch (var->bits_per_pixel) { + case 16: + case 32: + if (var->xres <= 800) + /* Xbh has this type of clock for 32-bit */ + freq /= 2; + break; + } +#endif return 0; } -static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div) +static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo, + int div) { - struct cirrusfb_info *cinfo = info->par; unsigned char old1f, old1e; - assert(cinfo != NULL); old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; if (div) { - dev_dbg(info->device, "Set %s as pixclock source.\n", - (div == 2) ? "MCLK/2" : "MCLK"); + DPRINTK("Set %s as pixclock source.\n", + (div == 2) ? "MCLK/2" : "MCLK"); old1f |= 0x40; old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; if (div == 2) @@ -662,119 +718,101 @@ static int cirrusfb_set_par_foo(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; struct fb_var_screeninfo *var = &info->var; + struct cirrusfb_regs regs; u8 __iomem *regbase = cinfo->regbase; unsigned char tmp; - int pitch; + int offset = 0, err; const struct cirrusfb_board_info_rec *bi; int hdispend, hsyncstart, hsyncend, htotal; int yres, vdispend, vsyncstart, vsyncend, vtotal; long freq; int nom, den, div; - unsigned int control = 0, format = 0, threshold = 0; - dev_dbg(info->device, "Requested mode: %dx%dx%d\n", + DPRINTK("ENTER\n"); + DPRINTK("Requested mode: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel); + DPRINTK("pixclock: %d\n", var->pixclock); - switch (var->bits_per_pixel) { - case 1: - info->fix.line_length = var->xres_virtual / 8; - info->fix.visual = FB_VISUAL_MONO10; - break; - - case 8: - info->fix.line_length = var->xres_virtual; - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; + init_vgachip(info); - case 16: - case 24: - info->fix.line_length = var->xres_virtual * - var->bits_per_pixel >> 3; - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; + err = cirrusfb_decode_var(var, ®s, info); + if (err) { + /* should never happen */ + DPRINTK("mode change aborted. invalid var.\n"); + return -EINVAL; } - info->fix.type = FB_TYPE_PACKED_PIXELS; - - init_vgachip(info); bi = &cirrusfb_board_info[cinfo->btype]; hsyncstart = var->xres + var->right_margin; hsyncend = hsyncstart + var->hsync_len; - htotal = (hsyncend + var->left_margin) / 8; - hdispend = var->xres / 8; - hsyncstart = hsyncstart / 8; - hsyncend = hsyncend / 8; + htotal = (hsyncend + var->left_margin) / 8 - 5; + hdispend = var->xres / 8 - 1; + hsyncstart = hsyncstart / 8 + 1; + hsyncend = hsyncend / 8 + 1; - vdispend = var->yres; - vsyncstart = vdispend + var->lower_margin; + yres = var->yres; + vsyncstart = yres + var->lower_margin; vsyncend = vsyncstart + var->vsync_len; vtotal = vsyncend + var->upper_margin; + vdispend = yres - 1; if (var->vmode & FB_VMODE_DOUBLE) { - vdispend *= 2; + yres *= 2; vsyncstart *= 2; vsyncend *= 2; vtotal *= 2; } else if (var->vmode & FB_VMODE_INTERLACED) { - vdispend = (vdispend + 1) / 2; + yres = (yres + 1) / 2; vsyncstart = (vsyncstart + 1) / 2; vsyncend = (vsyncend + 1) / 2; vtotal = (vtotal + 1) / 2; } - yres = vdispend; + + vtotal -= 2; + vsyncstart -= 1; + vsyncend -= 1; + if (yres >= 1024) { vtotal /= 2; vsyncstart /= 2; vsyncend /= 2; vdispend /= 2; } - - vdispend -= 1; - vsyncstart -= 1; - vsyncend -= 1; - vtotal -= 2; - - if (cinfo->multiplexing) { + if (regs.multiplexing) { htotal /= 2; hsyncstart /= 2; hsyncend /= 2; hdispend /= 2; } - - htotal -= 5; - hdispend -= 1; - hsyncstart += 1; - hsyncend += 1; - /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ /* if debugging is enabled, all parameters get output before writing */ - dev_dbg(info->device, "CRT0: %d\n", htotal); + DPRINTK("CRT0: %d\n", htotal); vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); - dev_dbg(info->device, "CRT1: %d\n", hdispend); + DPRINTK("CRT1: %d\n", hdispend); vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); - dev_dbg(info->device, "CRT2: %d\n", var->xres / 8); + DPRINTK("CRT2: %d\n", var->xres / 8); vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); /* + 128: Compatible read */ - dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32); + DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32); vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, 128 + ((htotal + 5) % 32)); - dev_dbg(info->device, "CRT4: %d\n", hsyncstart); + DPRINTK("CRT4: %d\n", hsyncstart); vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); tmp = hsyncend % 32; if ((htotal + 5) & 32) tmp += 128; - dev_dbg(info->device, "CRT5: %d\n", tmp); + DPRINTK("CRT5: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); - dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff); + DPRINTK("CRT6: %d\n", vtotal & 0xff); vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); tmp = 16; /* LineCompare bit #9 */ @@ -792,7 +830,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) tmp |= 64; if (vsyncstart & 512) tmp |= 128; - dev_dbg(info->device, "CRT7: %d\n", tmp); + DPRINTK("CRT7: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); tmp = 0x40; /* LineCompare bit #8 */ @@ -800,25 +838,25 @@ static int cirrusfb_set_par_foo(struct fb_info *info) tmp |= 0x20; if (var->vmode & FB_VMODE_DOUBLE) tmp |= 0x80; - dev_dbg(info->device, "CRT9: %d\n", tmp); + DPRINTK("CRT9: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); - dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff); + DPRINTK("CRT10: %d\n", vsyncstart & 0xff); vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); - dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16); + DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16); vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); - dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff); + DPRINTK("CRT12: %d\n", vdispend & 0xff); vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); - dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff); + DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff); vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); - dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff); + DPRINTK("CRT16: %d\n", vtotal & 0xff); vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); - dev_dbg(info->device, "CRT18: 0xff\n"); + DPRINTK("CRT18: 0xff\n"); vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); tmp = 0; @@ -833,75 +871,41 @@ static int cirrusfb_set_par_foo(struct fb_info *info) if (vtotal & 512) tmp |= 128; - dev_dbg(info->device, "CRT1a: %d\n", tmp); + DPRINTK("CRT1a: %d\n", tmp); vga_wcrt(regbase, CL_CRT1A, tmp); freq = PICOS2KHZ(var->pixclock); - if (var->bits_per_pixel == 24) - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) - freq *= 3; - if (cinfo->multiplexing) - freq /= 2; - if (cinfo->doubleVCLK) - freq *= 2; - bestclock(freq, &nom, &den, &div); - dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n", - freq, nom, den, div); - /* set VCLK0 */ /* hardware RefClock: 14.31818 MHz */ /* formula: VClk = (OSC * N) / (D * (1+P)) */ /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 || - cinfo->btype == BT_SD64) { + if (cinfo->btype == BT_ALPINE) { /* if freq is close to mclk or mclk/2 select mclk * as clock source */ - int divMCLK = cirrusfb_check_mclk(info, freq); - if (divMCLK) + int divMCLK = cirrusfb_check_mclk(cinfo, freq); + if (divMCLK) { nom = 0; - cirrusfb_set_mclk_as_source(info, divMCLK); - } - if (is_laguna(cinfo)) { - long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); - unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407); - unsigned short tile_control; - - if (cinfo->btype == BT_LAGUNAB) { - tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4); - tile_control &= ~0x80; - fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4); + cirrusfb_set_mclk_as_source(cinfo, divMCLK); } - - fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc); - fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407); - control = fb_readw(cinfo->laguna_mmio + 0x402); - threshold = fb_readw(cinfo->laguna_mmio + 0xea); - control &= ~0x6800; - format = 0; - threshold &= 0xffc0 & 0x3fbf; } if (nom) { + vga_wseq(regbase, CL_SEQRB, nom); tmp = den << 1; if (div != 0) tmp |= 1; + /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ if ((cinfo->btype == BT_SD64) || (cinfo->btype == BT_ALPINE) || (cinfo->btype == BT_GD5480)) tmp |= 0x80; - /* Laguna chipset has reversed clock registers */ - if (is_laguna(cinfo)) { - vga_wseq(regbase, CL_SEQRE, tmp); - vga_wseq(regbase, CL_SEQR1E, nom); - } else { - vga_wseq(regbase, CL_SEQRE, nom); - vga_wseq(regbase, CL_SEQR1E, tmp); - } + DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); + vga_wseq(regbase, CL_SEQR1B, tmp); } if (yres >= 1024) @@ -912,6 +916,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info) * address wrap, no compat. */ vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3); +/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); + * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */ + /* don't know if it would hurt to also program this if no interlaced */ /* mode is used, but I feel better this way.. :-) */ if (var->vmode & FB_VMODE_INTERLACED) @@ -919,15 +926,19 @@ static int cirrusfb_set_par_foo(struct fb_info *info) else vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ - /* adjust horizontal/vertical sync type (low/high), use VCLK3 */ + vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0); + + /* adjust horizontal/vertical sync type (low/high) */ /* enable display memory & CRTC I/O address for color mode */ - tmp = 0x03 | 0xc; + tmp = 0x03; if (var->sync & FB_SYNC_HOR_HIGH_ACT) tmp |= 0x40; if (var->sync & FB_SYNC_VERT_HIGH_ACT) tmp |= 0x80; WGen(cinfo, VGA_MIS_W, tmp); + /* Screen A Preset Row-Scan register */ + vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0); /* text cursor on and start line */ vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0); /* text cursor end line */ @@ -941,7 +952,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) /* programming for different color depths */ if (var->bits_per_pixel == 1) { - dev_dbg(info->device, "preparing for 1 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 1 bit deep display\n"); vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */ /* SR07 */ @@ -953,53 +964,68 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: + DPRINTK(" (for GD54xx)\n"); vga_wseq(regbase, CL_SEQR7, - cinfo->multiplexing ? + regs.multiplexing ? bi->sr07_1bpp_mux : bi->sr07_1bpp); break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* Extended Sequencer Mode */ switch (cinfo->btype) { + case BT_SD64: + /* setting the SEQRF on SD64 is not necessary + * (only during init) + */ + DPRINTK("(for SD64)\n"); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1a); + break; case BT_PICCOLO: case BT_SPECTRUM: + DPRINTK("(for Piccolo/Spectrum)\n"); + /* ### ueberall 0x22? */ + /* ##vorher 1c MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ vga_wseq(regbase, CL_SEQRF, 0xb0); break; case BT_PICASSO: + DPRINTK("(for Picasso)\n"); + /* ##vorher 22 MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* ## vorher d0 avoid FIFO underruns..? */ vga_wseq(regbase, CL_SEQRF, 0xd0); break; - case BT_SD64: case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* pixel mask: pass-through for first plane */ WGen(cinfo, VGA_PEL_MSK, 0x01); - if (cinfo->multiplexing) + if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else @@ -1009,6 +1035,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* plane mask: only write to first plane */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01); + offset = var->xres_virtual / 16; } /****************************************************** @@ -1018,7 +1045,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 8) { - dev_dbg(info->device, "preparing for 8 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 8 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: case BT_PICCOLO: @@ -1027,27 +1054,34 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: + DPRINTK(" (for GD54xx)\n"); vga_wseq(regbase, CL_SEQR7, - cinfo->multiplexing ? + regs.multiplexing ? bi->sr07_8bpp_mux : bi->sr07_8bpp); break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) | 0x01); - threshold |= 0x10; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } switch (cinfo->btype) { + case BT_SD64: + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1d); + break; + case BT_PICCOLO: case BT_PICASSO: case BT_SPECTRUM: + /* ### vorher 1c MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); break; @@ -1057,27 +1091,40 @@ static int cirrusfb_set_par_foo(struct fb_info *info) /* ### INCOMPLETE!! */ vga_wseq(regbase, CL_SEQRF, 0xb8); #endif +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - case BT_SD64: + DPRINTK(" (for GD543x)\n"); + /* We already set SRF and SR1F */ + break; + case BT_GD5480: case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: - dev_warn(info->device, "unknown board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); - if (cinfo->multiplexing) + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); + if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else /* hidden dac: nothing */ WHDR(cinfo, 0); + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 8; } /****************************************************** @@ -1087,110 +1134,147 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 16) { - dev_dbg(info->device, "preparing for 16 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 16 bit deep display\n"); switch (cinfo->btype) { + case BT_SD64: + /* Extended Sequencer Mode: 256c col. mode */ + vga_wseq(regbase, CL_SEQR7, 0xf7); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1e); + break; + case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x87); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x27); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; - case BT_SD64: case BT_PICASSO4: + vga_wseq(regbase, CL_SEQR7, 0x27); +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - /* Extended Sequencer Mode: 256c col. mode */ - vga_wseq(regbase, CL_SEQR7, - cinfo->doubleVCLK ? 0xa3 : 0xa7); + DPRINTK(" (for GD543x)\n"); + vga_wseq(regbase, CL_SEQR7, 0xa7); break; case BT_GD5480: + DPRINTK(" (for GD5480)\n"); vga_wseq(regbase, CL_SEQR7, 0x17); /* We already set SRF and SR1F */ break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); - control |= 0x2000; - format |= 0x1400; - threshold |= 0x10; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "CIRRUSFB: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); #ifdef CONFIG_PCI - WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1); + WHDR(cinfo, 0xc0); /* Copy Xbh */ #elif defined(CONFIG_ZORRO) /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ #endif + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 4; } /****************************************************** * - * 24 bpp + * 32 bpp * */ - else if (var->bits_per_pixel == 24) { - dev_dbg(info->device, "preparing for 24 bit deep display\n"); + else if (var->bits_per_pixel == 32) { + DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); switch (cinfo->btype) { + case BT_SD64: + /* Extended Sequencer Mode: 256c col. mode */ + vga_wseq(regbase, CL_SEQR7, 0xf9); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1e); + break; + case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x85); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x25); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; - case BT_SD64: case BT_PICASSO4: + vga_wseq(regbase, CL_SEQR7, 0x25); +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - /* Extended Sequencer Mode: 256c col. mode */ - vga_wseq(regbase, CL_SEQR7, 0xa5); + DPRINTK(" (for GD543x)\n"); + vga_wseq(regbase, CL_SEQR7, 0xa9); break; case BT_GD5480: - vga_wseq(regbase, CL_SEQR7, 0x15); + DPRINTK(" (for GD5480)\n"); + vga_wseq(regbase, CL_SEQR7, 0x19); /* We already set SRF and SR1F */ break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); - control |= 0x4000; - format |= 0x2400; - threshold |= 0x20; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); /* hidden dac reg: 8-8-8 mode (24 or 32) */ WHDR(cinfo, 0xc5); + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 4; } /****************************************************** @@ -1200,55 +1284,67 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else - dev_err(info->device, - "What's this? requested color depth == %d.\n", + printk(KERN_ERR "cirrusfb: What's this?? " + " requested color depth == %d.\n", var->bits_per_pixel); - pitch = info->fix.line_length >> 3; - vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff); + vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff); tmp = 0x22; - if (pitch & 0x100) + if (offset & 0x100) tmp |= 0x10; /* offset overflow bit */ /* screen start addr #16-18, fastpagemode cycles */ vga_wcrt(regbase, CL_CRT1B, tmp); - /* screen start address bit 19 */ - if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) - vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1); - - if (is_laguna(cinfo)) { - tmp = 0; - if ((htotal + 5) & 256) - tmp |= 128; - if (hdispend & 256) - tmp |= 64; - if (hsyncstart & 256) - tmp |= 48; - if (vtotal & 1024) - tmp |= 8; - if (vdispend & 1024) - tmp |= 4; - if (vsyncstart & 1024) - tmp |= 3; - - vga_wcrt(regbase, CL_CRT1E, tmp); - dev_dbg(info->device, "CRT1e: %d\n", tmp); - } - + if (cinfo->btype == BT_SD64 || + cinfo->btype == BT_PICASSO4 || + cinfo->btype == BT_ALPINE || + cinfo->btype == BT_GD5480) + /* screen start address bit 19 */ + vga_wcrt(regbase, CL_CRT1D, 0x00); + + /* text cursor location high */ + vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0); + /* text cursor location low */ + vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0); + /* underline row scanline = at very bottom */ + vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0); + + /* controller mode */ + vga_wattr(regbase, VGA_ATC_MODE, 1); + /* overscan (border) color */ + vga_wattr(regbase, VGA_ATC_OVERSCAN, 0); + /* color plane enable */ + vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15); /* pixel panning */ vga_wattr(regbase, CL_AR33, 0); + /* color select */ + vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0); /* [ EGS: SetOffset(); ] */ /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ AttrOn(cinfo); - if (is_laguna(cinfo)) { - /* no tiles */ - fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402); - fb_writew(format, cinfo->laguna_mmio + 0xc0); - fb_writew(threshold, cinfo->laguna_mmio + 0xea); - } + /* set/reset register */ + vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0); + /* set/reset enable */ + vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0); + /* color compare */ + vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0); + /* data rotate */ + vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0); + /* read map select */ + vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0); + /* miscellaneous register */ + vga_wgfx(regbase, VGA_GFX_MISC, 1); + /* color don't care */ + vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15); + /* bit mask */ + vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255); + + /* graphics cursor attributes: nothing special */ + vga_wseq(regbase, CL_SEQR12, 0x0); + /* finally, turn on everything - turn off "FullBandwidth" bit */ /* also, set "DotClock%2" bit where requested */ tmp = 0x01; @@ -1259,12 +1355,18 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); - dev_dbg(info->device, "CL_SEQR1: %d\n", tmp); + DPRINTK("CL_SEQR1: %d\n", tmp); + + cinfo->currentmode = regs; + + /* pan to requested offset */ + cirrusfb_pan_display(var, info); #ifdef CIRRUSFB_DEBUG - cirrusfb_dbg_reg_dump(info, NULL); + cirrusfb_dump(); #endif + DPRINTK("EXIT\n"); return 0; } @@ -1316,19 +1418,27 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, static int cirrusfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - int xoffset; + int xoffset = 0; + int yoffset = 0; unsigned long base; - unsigned char tmp, xpix; + unsigned char tmp = 0, tmp2 = 0, xpix; struct cirrusfb_info *cinfo = info->par; + DPRINTK("ENTER\n"); + DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset); + /* no range checks for xoffset and yoffset, */ /* as fb_pan_display has already done this */ if (var->vmode & FB_VMODE_YWRAP) return -EINVAL; + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + xoffset = var->xoffset * info->var.bits_per_pixel / 8; + yoffset = var->yoffset; - base = var->yoffset * info->fix.line_length + xoffset; + base = yoffset * info->fix.line_length + xoffset; if (info->var.bits_per_pixel == 1) { /* base is already correct */ @@ -1338,15 +1448,14 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, xpix = (unsigned char) ((xoffset % 4) * 2); } - if (!is_laguna(cinfo)) - cirrusfb_WaitBLT(cinfo->regbase); + cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ /* lower 8 + 8 bits of screen start address */ - vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff); - vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff); + vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, + (unsigned char) (base & 0xff)); + vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, + (unsigned char) (base >> 8)); - /* 0xf2 is %11110010, exclude tmp bits */ - tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2; /* construct bits 16, 17 and 18 of screen start address */ if (base & 0x10000) tmp |= 0x01; @@ -1355,17 +1464,13 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, if (base & 0x40000) tmp |= 0x08; - vga_wcrt(cinfo->regbase, CL_CRT1B, tmp); + /* 0xf2 is %11110010, exclude tmp bits */ + tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; + vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2); /* construct bit 19 of screen start address */ - if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { - tmp = vga_rcrt(cinfo->regbase, CL_CRT1D); - if (is_laguna(cinfo)) - tmp = (tmp & ~0x18) | ((base >> 16) & 0x18); - else - tmp = (tmp & ~0x80) | ((base >> 12) & 0x80); - vga_wcrt(cinfo->regbase, CL_CRT1D, tmp); - } + if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) + vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80); /* write pixel panning value to AR33; this does not quite work in 8bpp * @@ -1374,6 +1479,9 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, if (info->var.bits_per_pixel == 1) vga_wattr(cinfo->regbase, CL_AR33, xpix); + cirrusfb_WaitBLT(cinfo->regbase); + + DPRINTK("EXIT\n"); return 0; } @@ -1394,54 +1502,57 @@ static int cirrusfb_blank(int blank_mode, struct fb_info *info) struct cirrusfb_info *cinfo = info->par; int current_mode = cinfo->blank_mode; - dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode); + DPRINTK("ENTER, blank mode = %d\n", blank_mode); if (info->state != FBINFO_STATE_RUNNING || current_mode == blank_mode) { - dev_dbg(info->device, "EXIT, returning 0\n"); + DPRINTK("EXIT, returning 0\n"); return 0; } /* Undo current */ if (current_mode == FB_BLANK_NORMAL || - current_mode == FB_BLANK_UNBLANK) + current_mode == FB_BLANK_UNBLANK) { + /* unblank the screen */ + val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE); /* clear "FullBandwidth" bit */ - val = 0; - else - /* set "FullBandwidth" bit */ - val = 0x20; + vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); + /* and undo VESA suspend trickery */ + vga_wgfx(cinfo->regbase, CL_GRE, 0x00); + } - val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf; - vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val); + /* set new */ + if (blank_mode > FB_BLANK_NORMAL) { + /* blank the screen */ + val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE); + /* set "FullBandwidth" bit */ + vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); + } switch (blank_mode) { case FB_BLANK_UNBLANK: case FB_BLANK_NORMAL: - val = 0x00; break; case FB_BLANK_VSYNC_SUSPEND: - val = 0x04; + vga_wgfx(cinfo->regbase, CL_GRE, 0x04); break; case FB_BLANK_HSYNC_SUSPEND: - val = 0x02; + vga_wgfx(cinfo->regbase, CL_GRE, 0x02); break; case FB_BLANK_POWERDOWN: - val = 0x06; + vga_wgfx(cinfo->regbase, CL_GRE, 0x06); break; default: - dev_dbg(info->device, "EXIT, returning 1\n"); + DPRINTK("EXIT, returning 1\n"); return 1; } - vga_wgfx(cinfo->regbase, CL_GRE, val); - cinfo->blank_mode = blank_mode; - dev_dbg(info->device, "EXIT, returning 0\n"); + DPRINTK("EXIT, returning 0\n"); /* Let fbcon do a soft blank for us */ return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; } - /**** END Hardware specific Routines **************************************/ /****************************************************************************/ /**** BEGIN Internal Routines ***********************************************/ @@ -1451,6 +1562,8 @@ static void init_vgachip(struct fb_info *info) struct cirrusfb_info *cinfo = info->par; const struct cirrusfb_board_info_rec *bi; + DPRINTK("ENTER\n"); + assert(cinfo != NULL); bi = &cirrusfb_board_info[cinfo->btype]; @@ -1478,23 +1591,25 @@ static void init_vgachip(struct fb_info *info) /* disable flickerfixer */ vga_wcrt(cinfo->regbase, CL_CRT51, 0x00); mdelay(100); - /* mode */ - vga_wgfx(cinfo->regbase, CL_GR31, 0x00); - case BT_GD5480: /* fall through */ /* from Klaus' NetBSD driver: */ vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); - case BT_ALPINE: /* fall through */ /* put blitter into 542x compat */ vga_wgfx(cinfo->regbase, CL_GR33, 0x00); + /* mode */ + vga_wgfx(cinfo->regbase, CL_GR31, 0x00); + break; + + case BT_GD5480: + /* from Klaus' NetBSD driver: */ + vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); break; - case BT_LAGUNA: - case BT_LAGUNAB: + case BT_ALPINE: /* Nothing to do to reset the board. */ break; default: - dev_err(info->device, "Warning: Unknown board type\n"); + printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n"); break; } @@ -1514,28 +1629,31 @@ static void init_vgachip(struct fb_info *info) WGen(cinfo, CL_VSSM2, 0x01); /* reset sequencer logic */ - vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03); + vga_wseq(cinfo->regbase, CL_SEQR0, 0x03); /* FullBandwidth (video off) and 8/9 dot clock */ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); + /* polarity (-/-), disable access to display memory, + * VGA_CRTC_START_HI base address: color + */ + WGen(cinfo, VGA_MIS_W, 0xc1); /* "magic cookie" - doesn't make any sense to me.. */ /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ /* unlock all extension registers */ vga_wseq(cinfo->regbase, CL_SEQR6, 0x12); + /* reset blitter */ + vga_wgfx(cinfo->regbase, CL_GR31, 0x04); + switch (cinfo->btype) { case BT_GD5480: vga_wseq(cinfo->regbase, CL_SEQRF, 0x98); break; case BT_ALPINE: - case BT_LAGUNA: - case BT_LAGUNAB: break; case BT_SD64: -#ifdef CONFIG_ZORRO vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); -#endif break; default: vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); @@ -1547,8 +1665,8 @@ static void init_vgachip(struct fb_info *info) vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* character map select: doesn't even matter in gx mode */ vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); - /* memory mode: chain4, ext. memory */ - vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* memory mode: chain-4, no odd/even, ext. memory */ + vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); /* controller-internal base address of video memory */ if (bi->init_sr07) @@ -1574,12 +1692,20 @@ static void init_vgachip(struct fb_info *info) vga_wseq(cinfo->regbase, CL_SEQR18, 0x02); } + /* MCLK select etc. */ + if (bi->init_sr1f) + vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f); + /* Screen A preset row scan: none */ vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); /* Text cursor start: disable text cursor */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor end: - */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); + /* Screen start address high: 0 */ + vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00); + /* Screen start address low: 0 */ + vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00); /* text cursor location high: 0 */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location low: 0 */ @@ -1587,6 +1713,10 @@ static void init_vgachip(struct fb_info *info) /* Underline Row scanline: - */ vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); + /* mode control: timing enable, byte mode, no compat modes */ + vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3); + /* Line Compare: not needed */ + vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00); /* ### add 0x40 for text modes with > 30 MHz pixclock */ /* ext. display controls: ext.adr. wrap */ vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); @@ -1609,9 +1739,7 @@ static void init_vgachip(struct fb_info *info) vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); /* Bit Mask: no mask at all */ vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); - - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 || - is_laguna(cinfo)) + if (cinfo->btype == BT_ALPINE) /* (5434 can't have bit 3 set for bitblt) */ vga_wgfx(cinfo->regbase, CL_GRB, 0x20); else @@ -1651,11 +1779,18 @@ static void init_vgachip(struct fb_info *info) vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); /* Color Plane enable: Enable all 4 planes */ vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); +/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */ /* Color Select: - */ vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ + if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480) + /* polarity (-/-), enable display mem, + * VGA_CRTC_START_HI i/o base = color + */ + WGen(cinfo, VGA_MIS_W, 0xc3); + /* BLT Start/status: Blitter reset */ vga_wgfx(cinfo->regbase, CL_GR31, 0x04); /* - " - : "end-of-reset" */ @@ -1663,6 +1798,8 @@ static void init_vgachip(struct fb_info *info) /* misc... */ WHDR(cinfo, 0); /* Hidden DAC register: - */ + + DPRINTK("EXIT\n"); return; } @@ -1671,6 +1808,8 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) #ifdef CONFIG_ZORRO /* only works on Zorro boards */ static int IsOn = 0; /* XXX not ok for multiple boards */ + DPRINTK("ENTER\n"); + if (cinfo->btype == BT_PICASSO4) return; /* nothing to switch */ if (cinfo->btype == BT_ALPINE) @@ -1680,6 +1819,8 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) if (cinfo->btype == BT_PICASSO) { if ((on && !IsOn) || (!on && IsOn)) WSFR(cinfo, 0xff); + + DPRINTK("EXIT\n"); return; } if (on) { @@ -1706,10 +1847,11 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) case BT_SPECTRUM: WSFR(cinfo, 0x4f); break; - default: /* do nothing */ - break; + default: /* do nothing */ break; } } + + DPRINTK("EXIT\n"); #endif /* CONFIG_ZORRO */ } @@ -1717,17 +1859,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) /* Linux 2.6-style accelerated functions */ /******************************************/ -static int cirrusfb_sync(struct fb_info *info) -{ - struct cirrusfb_info *cinfo = info->par; - - if (!is_laguna(cinfo)) { - while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03) - cpu_relax(); - } - return 0; -} - static void cirrusfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) { @@ -1763,8 +1894,8 @@ static void cirrusfb_fillrect(struct fb_info *info, info->var.bits_per_pixel, (region->dx * m) / 8, region->dy, (region->width * m) / 8, region->height, - color, color, - info->fix.line_length, 0x40); + color, + info->fix.line_length); } static void cirrusfb_copyarea(struct fb_info *info, @@ -1812,46 +1943,9 @@ static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct cirrusfb_info *cinfo = info->par; - unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4; - if (info->state != FBINFO_STATE_RUNNING) - return; - /* Alpine/SD64 does not work at 24bpp ??? */ - if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) - cfb_imageblit(info, image); - else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) && - op == 0xc) - cfb_imageblit(info, image); - else { - unsigned size = ((image->width + 7) >> 3) * image->height; - int m = info->var.bits_per_pixel; - u32 fg, bg; - - if (info->var.bits_per_pixel == 8) { - fg = image->fg_color; - bg = image->bg_color; - } else { - fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; - bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; - } - if (info->var.bits_per_pixel == 24) { - /* clear background first */ - cirrusfb_RectFill(cinfo->regbase, - info->var.bits_per_pixel, - (image->dx * m) / 8, image->dy, - (image->width * m) / 8, - image->height, - bg, bg, - info->fix.line_length, 0x40); - } - cirrusfb_RectFill(cinfo->regbase, - info->var.bits_per_pixel, - (image->dx * m) / 8, image->dy, - (image->width * m) / 8, image->height, - fg, bg, - info->fix.line_length, op); - memcpy(info->screen_base, image->data, size); - } + cirrusfb_WaitBLT(cinfo->regbase); + cfb_imageblit(info, image); } #ifdef CONFIG_PPC_PREP @@ -1859,8 +1953,12 @@ static void cirrusfb_imageblit(struct fb_info *info, #define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) static void get_prep_addrs(unsigned long *display, unsigned long *registers) { + DPRINTK("ENTER\n"); + *display = PREP_VIDEO_BASE; *registers = (unsigned long) PREP_IO_BASE; + + DPRINTK("EXIT\n"); } #endif /* CONFIG_PPC_PREP */ @@ -1872,43 +1970,40 @@ static int release_io_ports; * based on the DRAM bandwidth bit and DRAM bank switching bit. This * works with 1MB, 2MB and 4MB configurations (which the Motorola boards * seem to have. */ -static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info, - u8 __iomem *regbase) +static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase) { unsigned long mem; - struct cirrusfb_info *cinfo = info->par; + unsigned char SRF; - if (is_laguna(cinfo)) { - unsigned char SR14 = vga_rseq(regbase, CL_SEQR14); + DPRINTK("ENTER\n"); - mem = ((SR14 & 7) + 1) << 20; - } else { - unsigned char SRF = vga_rseq(regbase, CL_SEQRF); - switch ((SRF & 0x18)) { - case 0x08: - mem = 512 * 1024; - break; - case 0x10: - mem = 1024 * 1024; - break; - /* 64-bit DRAM data bus width; assume 2MB. - * Also indicates 2MB memory on the 5430. - */ - case 0x18: - mem = 2048 * 1024; - break; - default: - dev_warn(info->device, "Unknown memory size!\n"); - mem = 1024 * 1024; - } - /* If DRAM bank switching is enabled, there must be - * twice as much memory installed. (4MB on the 5434) - */ - if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0) - mem *= 2; + SRF = vga_rseq(regbase, CL_SEQRF); + switch ((SRF & 0x18)) { + case 0x08: + mem = 512 * 1024; + break; + case 0x10: + mem = 1024 * 1024; + break; + /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory + * on the 5430. + */ + case 0x18: + mem = 2048 * 1024; + break; + default: + printk(KERN_WARNING "CLgenfb: Unknown memory size!\n"); + mem = 1024 * 1024; } + if (SRF & 0x80) + /* If DRAM bank switching is enabled, there must be twice as much + * memory installed. (4MB on the 5434) + */ + mem *= 2; /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ + + DPRINTK("EXIT\n"); return mem; } @@ -1919,6 +2014,8 @@ static void get_pci_addrs(const struct pci_dev *pdev, assert(display != NULL); assert(registers != NULL); + DPRINTK("ENTER\n"); + *display = 0; *registers = 0; @@ -1933,15 +2030,14 @@ static void get_pci_addrs(const struct pci_dev *pdev, } assert(*display != 0); + + DPRINTK("EXIT\n"); } static void cirrusfb_pci_unmap(struct fb_info *info) { struct pci_dev *pdev = to_pci_dev(info->device); - struct cirrusfb_info *cinfo = info->par; - if (cinfo->laguna_mmio == NULL) - iounmap(cinfo->laguna_mmio); iounmap(info->screen_base); #if 0 /* if system didn't claim this region, we would... */ release_mem_region(0xA0000, 65535); @@ -1971,22 +2067,6 @@ static void cirrusfb_zorro_unmap(struct fb_info *info) } #endif /* CONFIG_ZORRO */ -/* function table of the above functions */ -static struct fb_ops cirrusfb_ops = { - .owner = THIS_MODULE, - .fb_open = cirrusfb_open, - .fb_release = cirrusfb_release, - .fb_setcolreg = cirrusfb_setcolreg, - .fb_check_var = cirrusfb_check_var, - .fb_set_par = cirrusfb_set_par, - .fb_pan_display = cirrusfb_pan_display, - .fb_blank = cirrusfb_blank, - .fb_fillrect = cirrusfb_fillrect, - .fb_copyarea = cirrusfb_copyarea, - .fb_sync = cirrusfb_sync, - .fb_imageblit = cirrusfb_imageblit, -}; - static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; @@ -1997,16 +2077,10 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_FILLRECT - | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA; - if (noaccel || is_laguna(cinfo)) { + if (noaccel) info->flags |= FBINFO_HWACCEL_DISABLED; - info->fix.accel = FB_ACCEL_NONE; - } else - info->fix.accel = FB_ACCEL_CIRRUS_ALPINE; - info->fbops = &cirrusfb_ops; - if (cinfo->btype == BT_GD5480) { if (var->bits_per_pixel == 16) info->screen_base += 1 * MB_; @@ -2030,6 +2104,7 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) /* FIXME: map region at 0xB8000 if available, fill in here */ info->fix.mmio_len = 0; + info->fix.accel = FB_ACCEL_NONE; fb_alloc_cmap(&info->cmap, 256, 0); @@ -2040,56 +2115,70 @@ static int __devinit cirrusfb_register(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; int err; + enum cirrus_board btype; + + DPRINTK("ENTER\n"); + + printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based " + "graphic boards, v" CIRRUSFB_VERSION "\n"); + + btype = cinfo->btype; /* sanity checks */ - assert(cinfo->btype != BT_NONE); + assert(btype != BT_NONE); /* set all the vital stuff */ cirrusfb_set_fbinfo(info); - dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base); + DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); if (!err) { - dev_dbg(info->device, "wrong initial video mode\n"); + DPRINTK("wrong initial video mode\n"); err = -EINVAL; goto err_dealloc_cmap; } info->var.activate = FB_ACTIVATE_NOW; - err = cirrusfb_check_var(&info->var, info); + err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); if (err < 0) { /* should never happen */ - dev_dbg(info->device, - "choking on default var... umm, no good.\n"); + DPRINTK("choking on default var... umm, no good.\n"); goto err_dealloc_cmap; } err = register_framebuffer(info); if (err < 0) { - dev_err(info->device, - "could not register fb device; err = %d!\n", err); + printk(KERN_ERR "cirrusfb: could not register " + "fb device; err = %d!\n", err); goto err_dealloc_cmap; } + DPRINTK("EXIT, returning 0\n"); return 0; err_dealloc_cmap: fb_dealloc_cmap(&info->cmap); + cinfo->unmap(info); + framebuffer_release(info); return err; } static void __devexit cirrusfb_cleanup(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; + DPRINTK("ENTER\n"); switch_monitor(cinfo, 0); + unregister_framebuffer(info); fb_dealloc_cmap(&info->cmap); - dev_dbg(info->device, "Framebuffer unregistered\n"); + printk("Framebuffer unregistered\n"); cinfo->unmap(info); framebuffer_release(info); + + DPRINTK("EXIT\n"); } #ifdef CONFIG_PCI @@ -2098,6 +2187,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, { struct cirrusfb_info *cinfo; struct fb_info *info; + enum cirrus_board btype; unsigned long board_addr, board_size; int ret; @@ -2111,17 +2201,15 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, if (!info) { printk(KERN_ERR "cirrusfb: could not allocate memory\n"); ret = -ENOMEM; - goto err_out; + goto err_disable; } cinfo = info->par; - cinfo->btype = (enum cirrus_board) ent->driver_data; + cinfo->btype = btype = (enum cirrus_board) ent->driver_data; - dev_dbg(info->device, - " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n", - (unsigned long long)pdev->resource[0].start, cinfo->btype); - dev_dbg(info->device, " base address 1 is 0x%Lx\n", - (unsigned long long)pdev->resource[1].start); + DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", + pdev->resource[0].start, btype); + DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start); if (isPReP) { pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000); @@ -2131,30 +2219,30 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, /* PReP dies if we ioremap the IO registers, but it works w/out... */ cinfo->regbase = (char __iomem *) info->fix.mmio_start; } else { - dev_dbg(info->device, - "Attempt to get PCI info for Cirrus Graphics Card\n"); + DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n"); get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); /* FIXME: this forces VGA. alternatives? */ cinfo->regbase = NULL; - cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000); } - dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", + DPRINTK("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fix.mmio_start); - board_size = (cinfo->btype == BT_GD5480) ? - 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase); + board_size = (btype == BT_GD5480) ? + 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase); ret = pci_request_regions(pdev, "cirrusfb"); if (ret < 0) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - board_addr); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " + "abort\n", + board_addr); goto err_release_fb; } #if 0 /* if the system didn't claim this region, we would... */ if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - 0xA0000L); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n" +, + 0xA0000L); ret = -EBUSY; goto err_release_regions; } @@ -2172,17 +2260,16 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, info->screen_size = board_size; cinfo->unmap = cirrusfb_pci_unmap; - dev_info(info->device, - "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n", - info->screen_size >> 10, board_addr); + printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " + "Logic chipset on PCI bus\n", + info->screen_size >> 10, board_addr); pci_set_drvdata(pdev, info); ret = cirrusfb_register(info); - if (!ret) - return 0; + if (ret) + iounmap(info->screen_base); + return ret; - pci_set_drvdata(pdev, NULL); - iounmap(info->screen_base); err_release_legacy: if (release_io_ports) release_region(0x3C0, 32); @@ -2192,9 +2279,8 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, #endif pci_release_regions(pdev); err_release_fb: - if (cinfo->laguna_mmio != NULL) - iounmap(cinfo->laguna_mmio); framebuffer_release(info); +err_disable: err_out: return ret; } @@ -2202,8 +2288,11 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); + DPRINTK("ENTER\n"); cirrusfb_cleanup(info); + + DPRINTK("EXIT\n"); } static struct pci_driver cirrusfb_pci_driver = { @@ -2235,6 +2324,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (cirrusfb_zorro_table2[btype].id2) z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL); size = cirrusfb_zorro_table2[btype].size; + printk(KERN_INFO "cirrusfb: %s board detected; ", + cirrusfb_board_info[btype].name); info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); if (!info) { @@ -2243,9 +2334,6 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, goto err_out; } - dev_info(info->device, "%s board detected\n", - cirrusfb_board_info[btype].name); - cinfo = info->par; cinfo->btype = btype; @@ -2257,16 +2345,19 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, info->screen_size = size; if (!zorro_request_device(z, "cirrusfb")) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - board_addr); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " + "abort\n", + board_addr); ret = -EBUSY; goto err_release_fb; } + printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr); + ret = -EIO; if (btype == BT_PICASSO4) { - dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000); + printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000); /* To be precise, for the P4 this is not the */ /* begin of the board, but the begin of RAM. */ @@ -2276,7 +2367,7 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (!cinfo->regbase) goto err_release_region; - dev_dbg(info->device, "Virtual address for board set to: $%p\n", + DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); cinfo->regbase += 0x600000; info->fix.mmio_start = board_addr + 0x600000; @@ -2286,8 +2377,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (!info->screen_base) goto err_unmap_regbase; } else { - dev_info(info->device, " REG at $%lx\n", - (unsigned long) z2->resource.start); + printk(KERN_INFO " REG at $%lx\n", + (unsigned long) z2->resource.start); info->fix.smem_start = board_addr; if (board_addr > 0x01000000) @@ -2301,32 +2392,27 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start); info->fix.mmio_start = z2->resource.start; - dev_dbg(info->device, "Virtual address for board set to: $%p\n", + DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); } cinfo->unmap = cirrusfb_zorro_unmap; - dev_info(info->device, - "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n", - board_size / MB_, board_addr); - + printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); zorro_set_drvdata(z, info); - /* MCLK select etc. */ - if (cirrusfb_board_info[btype].init_sr1f) - vga_wseq(cinfo->regbase, CL_SEQR1F, - cirrusfb_board_info[btype].sr1f); - ret = cirrusfb_register(info); - if (!ret) - return 0; - - if (btype == BT_PICASSO4 || board_addr > 0x01000000) - iounmap(info->screen_base); + if (ret) { + if (btype == BT_PICASSO4) { + iounmap(info->screen_base); + iounmap(cinfo->regbase - 0x600000); + } else if (board_addr > 0x01000000) + iounmap(info->screen_base); + } + return ret; err_unmap_regbase: - if (btype == BT_PICASSO4) - iounmap(cinfo->regbase - 0x600000); + /* Parental advisory: explicit hack */ + iounmap(cinfo->regbase - 0x600000); err_release_region: release_region(board_addr, board_size); err_release_fb: @@ -2338,8 +2424,11 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) { struct fb_info *info = zorro_get_drvdata(z); + DPRINTK("ENTER\n"); cirrusfb_cleanup(info); + + DPRINTK("EXIT\n"); } static struct zorro_driver cirrusfb_zorro_driver = { @@ -2350,11 +2439,33 @@ static struct zorro_driver cirrusfb_zorro_driver = { }; #endif /* CONFIG_ZORRO */ -#ifndef MODULE -static int __init cirrusfb_setup(char *options) +static int __init cirrusfb_init(void) { + int error = 0; + +#ifndef MODULE + char *option = NULL; + + if (fb_get_options("cirrusfb", &option)) + return -ENODEV; + cirrusfb_setup(option); +#endif + +#ifdef CONFIG_ZORRO + error |= zorro_register_driver(&cirrusfb_zorro_driver); +#endif +#ifdef CONFIG_PCI + error |= pci_register_driver(&cirrusfb_pci_driver); +#endif + return error; +} + +#ifndef MODULE +static int __init cirrusfb_setup(char *options) { char *this_opt; + DPRINTK("ENTER\n"); + if (!options || !*options) return 0; @@ -2362,6 +2473,8 @@ static int __init cirrusfb_setup(char *options) if (!*this_opt) continue; + DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); + if (!strcmp(this_opt, "noaccel")) noaccel = 1; else if (!strncmp(this_opt, "mode:", 5)) @@ -2381,27 +2494,6 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik "); MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); MODULE_LICENSE("GPL"); -static int __init cirrusfb_init(void) -{ - int error = 0; - -#ifndef MODULE - char *option = NULL; - - if (fb_get_options("cirrusfb", &option)) - return -ENODEV; - cirrusfb_setup(option); -#endif - -#ifdef CONFIG_ZORRO - error |= zorro_register_driver(&cirrusfb_zorro_driver); -#endif -#ifdef CONFIG_PCI - error |= pci_register_driver(&cirrusfb_pci_driver); -#endif - return error; -} - static void __exit cirrusfb_exit(void) { #ifdef CONFIG_PCI @@ -2468,6 +2560,8 @@ static void AttrOn(const struct cirrusfb_info *cinfo) { assert(cinfo != NULL); + DPRINTK("ENTER\n"); + if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { /* if we're just in "write value" mode, write back the */ /* same value as before to not modify anything */ @@ -2480,6 +2574,8 @@ static void AttrOn(const struct cirrusfb_info *cinfo) /* dummy write on Reg0 to be on "write index" mode next time */ vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); + + DPRINTK("EXIT\n"); } /*** WHDR() - write into the Hidden DAC register ***/ @@ -2492,8 +2588,6 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) { unsigned char dummy; - if (is_laguna(cinfo)) - return; if (cinfo->btype == BT_PICASSO) { /* Klaus' hint for correct access to HDR on some boards */ /* first write 0 to pixel mask (3c6) */ @@ -2561,8 +2655,7 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch vga_w(cinfo->regbase, VGA_PEL_IW, regnum); if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || - cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || - cinfo->btype == BT_SD64 || is_laguna(cinfo)) { + cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { /* but DAC data register IS, at least for Picasso II */ if (cinfo->btype == BT_PICASSO) data += 0xfff; @@ -2609,8 +2702,9 @@ static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch /* FIXME: use interrupts instead */ static void cirrusfb_WaitBLT(u8 __iomem *regbase) { + /* now busy-wait until we're done */ while (vga_rgfx(regbase, CL_GR31) & 0x08) - cpu_relax(); + /* do nothing */ ; } /******************************************************************* @@ -2619,12 +2713,60 @@ static void cirrusfb_WaitBLT(u8 __iomem *regbase) perform accelerated "scrolling" ********************************************************************/ -static void cirrusfb_set_blitter(u8 __iomem *regbase, - u_short nwidth, u_short nheight, - u_long nsrc, u_long ndest, - u_short bltmode, u_short line_length) - +static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, + u_short curx, u_short cury, + u_short destx, u_short desty, + u_short width, u_short height, + u_short line_length) { + u_short nwidth, nheight; + u_long nsrc, ndest; + u_char bltmode; + + DPRINTK("ENTER\n"); + + nwidth = width - 1; + nheight = height - 1; + + bltmode = 0x00; + /* if source adr < dest addr, do the Blt backwards */ + if (cury <= desty) { + if (cury == desty) { + /* if src and dest are on the same line, check x */ + if (curx < destx) + bltmode |= 0x01; + } else + bltmode |= 0x01; + } + if (!bltmode) { + /* standard case: forward blitting */ + nsrc = (cury * line_length) + curx; + ndest = (desty * line_length) + destx; + } else { + /* this means start addresses are at the end, + * counting backwards + */ + nsrc = cury * line_length + curx + + nheight * line_length + nwidth; + ndest = desty * line_length + destx + + nheight * line_length + nwidth; + } + + /* + run-down of registers to be programmed: + destination pitch + source pitch + BLT width/height + source start + destination start + BLT mode + BLT ROP + VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color" + start/stop + */ + + cirrusfb_WaitBLT(regbase); + /* pitch: set to line_length */ /* dest pitch low */ vga_wgfx(regbase, CL_GR24, line_length & 0xff); @@ -2671,50 +2813,8 @@ static void cirrusfb_set_blitter(u8 __iomem *regbase, /* and finally: GO! */ vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ -} - -/******************************************************************* - cirrusfb_BitBLT() - - perform accelerated "scrolling" -********************************************************************/ - -static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, - u_short curx, u_short cury, - u_short destx, u_short desty, - u_short width, u_short height, - u_short line_length) -{ - u_short nwidth = width - 1; - u_short nheight = height - 1; - u_long nsrc, ndest; - u_char bltmode; - - bltmode = 0x00; - /* if source adr < dest addr, do the Blt backwards */ - if (cury <= desty) { - if (cury == desty) { - /* if src and dest are on the same line, check x */ - if (curx < destx) - bltmode |= 0x01; - } else - bltmode |= 0x01; - } - /* standard case: forward blitting */ - nsrc = (cury * line_length) + curx; - ndest = (desty * line_length) + destx; - if (bltmode) { - /* this means start addresses are at the end, - * counting backwards - */ - nsrc += nheight * line_length + nwidth; - ndest += nheight * line_length + nwidth; - } - - cirrusfb_WaitBLT(regbase); - cirrusfb_set_blitter(regbase, nwidth, nheight, - nsrc, ndest, bltmode, line_length); + DPRINTK("EXIT\n"); } /******************************************************************* @@ -2725,37 +2825,79 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, - u32 fg_color, u32 bg_color, u_short line_length, - u_char blitmode) + u_char color, u_short line_length) { - u_long ndest = (y * line_length) + x; + u_short nwidth, nheight; + u_long ndest; u_char op; + DPRINTK("ENTER\n"); + + nwidth = width - 1; + nheight = height - 1; + + ndest = (y * line_length) + x; + cirrusfb_WaitBLT(regbase); + /* pitch: set to line_length */ + vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ + vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */ + vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */ + vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */ + + /* BLT width: actual number of pixels - 1 */ + vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ + vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */ + + /* BLT height: actual number of lines -1 */ + vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */ + vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */ + + /* BLT destination */ + /* BLT dest low */ + vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); + /* BLT dest mid */ + vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); + /* BLT dest hi */ + vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); + + /* BLT source: set to 0 (is a dummy here anyway) */ + vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */ + vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */ + vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */ + /* This is a ColorExpand Blt, using the */ /* same color for foreground and background */ - vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); - vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); - - op = 0x80; - if (bits_per_pixel >= 16) { - vga_wgfx(regbase, CL_GR10, bg_color >> 8); - vga_wgfx(regbase, CL_GR11, fg_color >> 8); - op = 0x90; - } - if (bits_per_pixel >= 24) { - vga_wgfx(regbase, CL_GR12, bg_color >> 16); - vga_wgfx(regbase, CL_GR13, fg_color >> 16); - op = 0xa0; - } - if (bits_per_pixel == 32) { - vga_wgfx(regbase, CL_GR14, bg_color >> 24); - vga_wgfx(regbase, CL_GR15, fg_color >> 24); - op = 0xb0; - } - cirrusfb_set_blitter(regbase, width - 1, height - 1, - 0, ndest, op | blitmode, line_length); + vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ + vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */ + + op = 0xc0; + if (bits_per_pixel == 16) { + vga_wgfx(regbase, CL_GR10, color); /* foreground color */ + vga_wgfx(regbase, CL_GR11, color); /* background color */ + op = 0x50; + op = 0xd0; + } else if (bits_per_pixel == 32) { + vga_wgfx(regbase, CL_GR10, color); /* foreground color */ + vga_wgfx(regbase, CL_GR11, color); /* background color */ + vga_wgfx(regbase, CL_GR12, color); /* foreground color */ + vga_wgfx(regbase, CL_GR13, color); /* background color */ + vga_wgfx(regbase, CL_GR14, 0); /* foreground color */ + vga_wgfx(regbase, CL_GR15, 0); /* background color */ + op = 0x50; + op = 0xf0; + } + /* BLT mode: color expand, Enable 8x8 copy (faster?) */ + vga_wgfx(regbase, CL_GR30, op); /* BLT mode */ + + /* BLT ROP: SrcCopy */ + vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */ + + /* and finally: GO! */ + vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ + + DPRINTK("EXIT\n"); } /************************************************************************** @@ -2775,6 +2917,8 @@ static void bestclock(long freq, int *nom, int *den, int *div) *den = 0; *div = 0; + DPRINTK("ENTER\n"); + if (freq < 8000) freq = 8000; @@ -2816,6 +2960,12 @@ static void bestclock(long freq, int *nom, int *den, int *div) } } } + + DPRINTK("Best possible values for given frequency:\n"); + DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n", + freq, *nom, *den, *div); + + DPRINTK("EXIT\n"); } /* ------------------------------------------------------------------------- @@ -2827,6 +2977,32 @@ static void bestclock(long freq, int *nom, int *den, int *div) #ifdef CIRRUSFB_DEBUG +/** + * cirrusfb_dbg_print_byte + * @name: name associated with byte value to be displayed + * @val: byte value to be displayed + * + * DESCRIPTION: + * Display an indented string, along with a hexidecimal byte value, and + * its decoded bits. Bits 7 through 0 are listed in left-to-right + * order. + */ + +static +void cirrusfb_dbg_print_byte(const char *name, unsigned char val) +{ + DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n", + name, val, + val & 0x80 ? '1' : '0', + val & 0x40 ? '1' : '0', + val & 0x20 ? '1' : '0', + val & 0x10 ? '1' : '0', + val & 0x08 ? '1' : '0', + val & 0x04 ? '1' : '0', + val & 0x02 ? '1' : '0', + val & 0x01 ? '1' : '0'); +} + /** * cirrusfb_dbg_print_regs * @base: If using newmmio, the newmmio base address, otherwise %NULL @@ -2838,9 +3014,9 @@ static void bestclock(long freq, int *nom, int *den, int *div) * used at the given @base address to query the information. */ -static void cirrusfb_dbg_print_regs(struct fb_info *info, - caddr_t regbase, - enum cirrusfb_dbg_reg_class reg_class, ...) +static +void cirrusfb_dbg_print_regs(caddr_t regbase, + enum cirrusfb_dbg_reg_class reg_class, ...) { va_list list; unsigned char val = 0; @@ -2866,7 +3042,7 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, break; } - dev_dbg(info->device, "%8s = 0x%02X\n", name, val); + cirrusfb_dbg_print_byte(name, val); name = va_arg(list, char *); } @@ -2874,6 +3050,18 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, va_end(list); } +/** + * cirrusfb_dump + * @cirrusfbinfo: + * + * DESCRIPTION: + */ + +static void cirrusfb_dump(void) +{ + cirrusfb_dbg_reg_dump(NULL); +} + /** * cirrusfb_dbg_reg_dump * @base: If using newmmio, the newmmio base address, otherwise %NULL @@ -2884,11 +3072,12 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, * used at the given @base address to query the information. */ -static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) +static +void cirrusfb_dbg_reg_dump(caddr_t regbase) { - dev_dbg(info->device, "VGA CRTC register dump:\n"); + DPRINTK("CIRRUSFB VGA CRTC register dump:\n"); - cirrusfb_dbg_print_regs(info, regbase, CRT, + cirrusfb_dbg_print_regs(regbase, CRT, "CR00", 0x00, "CR01", 0x01, "CR02", 0x02, @@ -2938,11 +3127,11 @@ static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) "CR3F", 0x3F, NULL); - dev_dbg(info->device, "\n"); + DPRINTK("\n"); - dev_dbg(info->device, "VGA SEQ register dump:\n"); + DPRINTK("CIRRUSFB VGA SEQ register dump:\n"); - cirrusfb_dbg_print_regs(info, regbase, SEQ, + cirrusfb_dbg_print_regs(regbase, SEQ, "SR00", 0x00, "SR01", 0x01, "SR02", 0x02, @@ -2971,7 +3160,7 @@ static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) "SR1F", 0x1F, NULL); - dev_dbg(info->device, "\n"); + DPRINTK("\n"); } #endif /* CIRRUSFB_DEBUG */ diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 2cd500a304f2..1657b9608b04 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -2954,11 +2954,8 @@ static int fbcon_fb_unbind(int idx) static int fbcon_fb_unregistered(struct fb_info *info) { - int i, idx; + int i, idx = info->node; - if (!lock_fb_info(info)) - return -ENODEV; - idx = info->node; for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] == idx) con2fb_map[i] = -1; @@ -2982,14 +2979,13 @@ static int fbcon_fb_unregistered(struct fb_info *info) } } - if (primary_device == idx) - primary_device = -1; - - unlock_fb_info(info); - if (!num_registered_fb) unregister_con_driver(&fb_con); + + if (primary_device == idx) + primary_device = -1; + return 0; } @@ -3025,13 +3021,9 @@ static inline void fbcon_select_primary(struct fb_info *info) static int fbcon_fb_registered(struct fb_info *info) { - int ret = 0, i, idx; + int ret = 0, i, idx = info->node; - if (!lock_fb_info(info)) - return -ENODEV; - idx = info->node; fbcon_select_primary(info); - unlock_fb_info(info); if (info_idx == -1) { for (i = first_fb_vc; i <= last_fb_vc; i++) { @@ -3132,7 +3124,7 @@ static void fbcon_get_requirement(struct fb_info *info, } } -static int fbcon_event_notify(struct notifier_block *self, +static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { struct fb_event *event = data; @@ -3140,7 +3132,7 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_videomode *mode; struct fb_con2fbmap *con2fb; struct fb_blit_caps *caps; - int idx, ret = 0; + int ret = 0; /* * ignore all events except driver registration and deregistration @@ -3152,54 +3144,23 @@ static int fbcon_event_notify(struct notifier_block *self, switch(action) { case FB_EVENT_SUSPEND: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_suspended(info); - unlock_fb_info(info); break; case FB_EVENT_RESUME: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_resumed(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_CHANGE: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_modechanged(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_CHANGE_ALL: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_set_all_vcs(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_DELETE: mode = event->data; - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } ret = fbcon_mode_deleted(info, mode); - unlock_fb_info(info); break; case FB_EVENT_FB_UNBIND: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } - idx = info->node; - unlock_fb_info(info); - ret = fbcon_fb_unbind(idx); + ret = fbcon_fb_unbind(info->node); break; case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info); @@ -3217,31 +3178,17 @@ static int fbcon_event_notify(struct notifier_block *self, con2fb->framebuffer = con2fb_map[con2fb->console - 1]; break; case FB_EVENT_BLANK: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_fb_blanked(info, *(int *)event->data); - unlock_fb_info(info); break; case FB_EVENT_NEW_MODELIST: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_new_modelist(info); - unlock_fb_info(info); break; case FB_EVENT_GET_REQ: caps = event->data; - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_get_requirement(info, caps); - unlock_fb_info(info); break; } + done: return ret; } diff --git a/trunk/drivers/video/cyblafb.c b/trunk/drivers/video/cyblafb.c new file mode 100644 index 000000000000..9704b73135f5 --- /dev/null +++ b/trunk/drivers/video/cyblafb.c @@ -0,0 +1,1683 @@ +/* + * Frame buffer driver for Trident Cyberblade/i1 graphics core + * + * Copyright 2005 Knut Petersen + * + * CREDITS: + * tridentfb.c by Jani Monoses + * see files above for further credits + * + */ + +#define CYBLAFB_DEBUG 0 +#define CYBLAFB_KD_GRAPHICS_QUIRK 1 + +#define CYBLAFB_PIXMAPSIZE 8192 + +#include +#include +#include +#include +#include +#include +#include