Merge git://oak/home/sfr/kernels/iseries/work
authorPaul Mackerras <paulus@samba.org>
Mon, 14 Nov 2005 06:15:45 +0000 (17:15 +1100)
committerPaul Mackerras <paulus@samba.org>
Mon, 14 Nov 2005 06:15:45 +0000 (17:15 +1100)
293 files changed:
CREDITS
Documentation/DocBook/Makefile
Documentation/DocBook/kernel-api.tmpl
Documentation/DocBook/stylesheet.xsl
Documentation/atomic_ops.txt
Documentation/oops-tracing.txt
Documentation/video4linux/CARDLIST.bttv
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/CARDLIST.tuner
MAINTAINERS
Makefile
README
arch/arm/Kconfig
arch/arm/common/locomo.c
arch/arm/common/scoop.c
arch/arm/kernel/apm.c
arch/arm/kernel/smp.c
arch/arm/mach-footbridge/common.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/akita-ioexp.c [new file with mode: 0644]
arch/arm/mach-pxa/corgi_pm.c [new file with mode: 0644]
arch/arm/mach-pxa/sharpsl.h
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/spitz_pm.c [new file with mode: 0644]
arch/frv/kernel/pm.c
arch/i386/Kconfig
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/intel.c
arch/i386/kernel/entry.S
arch/i386/kernel/timers/timer_pit.c
arch/i386/mm/init.c
arch/m68k/fpsp040/skeleton.S
arch/m68k/ifpsp060/iskeleton.S
arch/m68k/kernel/asm-offsets.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/ptrace.c
arch/mips/au1000/common/power.c
arch/mips/au1000/common/usbdev.c
arch/powerpc/Makefile
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/rtas-rtc.c [new file with mode: 0644]
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/vdso32/datapage.S
arch/powerpc/kernel/vdso32/gettimeofday.S
arch/powerpc/kernel/vdso64/datapage.S
arch/powerpc/kernel/vdso64/gettimeofday.S
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/oprofile/op_model_fsl_booke.c
arch/powerpc/platforms/powermac/time.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/xmon/xmon.c
arch/ppc/kernel/head_fsl_booke.S
arch/ppc/mm/fsl_booke_mmu.c
arch/ppc/platforms/83xx/mpc834x_sys.c
arch/ppc/platforms/83xx/mpc834x_sys.h
arch/ppc/platforms/85xx/mpc8540_ads.c
arch/ppc/platforms/85xx/mpc8540_ads.h
arch/ppc/platforms/85xx/mpc8555_cds.h
arch/ppc/platforms/85xx/mpc8560_ads.c
arch/ppc/platforms/85xx/mpc8560_ads.h
arch/ppc/platforms/85xx/mpc85xx_ads_common.c
arch/ppc/platforms/85xx/mpc85xx_ads_common.h
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.h
arch/ppc/platforms/85xx/sbc8560.c
arch/ppc/platforms/pmac_feature.c
arch/ppc/platforms/pq2ads.c
arch/ppc/syslib/ipic.h
arch/ppc/syslib/mpc83xx_devices.c
arch/ppc/syslib/mpc83xx_sys.c
arch/ppc/syslib/mpc85xx_devices.c
arch/ppc/syslib/mpc85xx_sys.c
arch/ppc/syslib/mpc8xx_devices.c
arch/ppc/syslib/mpc8xx_sys.c
arch/ppc/syslib/ppc83xx_setup.c
arch/ppc/syslib/ppc83xx_setup.h
arch/ppc/syslib/ppc85xx_common.c
arch/ppc/syslib/ppc85xx_common.h
arch/ppc/syslib/ppc85xx_setup.c
arch/ppc/syslib/ppc85xx_setup.h
arch/ppc/syslib/ppc_sys.c
arch/ppc/syslib/pq2_devices.c
arch/ppc/syslib/pq2_sys.c
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/machine_kexec.c
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/rtc.c [deleted file]
arch/sparc/lib/atomic32.c
arch/sparc/lib/bitext.c
arch/um/Kconfig
arch/um/Kconfig.i386
arch/um/Makefile-i386
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.c
arch/um/drivers/daemon_user.c
arch/um/drivers/fd.c
arch/um/drivers/mcast_user.c
arch/um/drivers/port_user.c
arch/um/drivers/pty.c
arch/um/drivers/tty.c
arch/um/drivers/xterm.c
arch/um/include/chan_user.h
arch/um/include/um_uaccess.h
arch/um/kernel/skas/include/uaccess-skas.h
arch/um/kernel/skas/uaccess.c
arch/um/kernel/trap_kern.c
arch/um/kernel/tt/include/uaccess-tt.h
arch/um/kernel/tt/uaccess.c
arch/x86_64/kernel/i8259.c
drivers/acpi/bus.c
drivers/base/firmware_class.c
drivers/block/pktcdvd.c
drivers/char/Kconfig
drivers/char/agp/uninorth-agp.c
drivers/char/pcmcia/Kconfig
drivers/char/pcmcia/Makefile
drivers/char/pcmcia/cm4000_cs.c [new file with mode: 0644]
drivers/char/pcmcia/cm4040_cs.c [new file with mode: 0644]
drivers/char/pcmcia/cm4040_cs.h [new file with mode: 0644]
drivers/char/synclink.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_atmel.h [new file with mode: 0644]
drivers/char/watchdog/booke_wdt.c
drivers/ide/pci/sl82c105.c
drivers/ide/ppc/pmac.c
drivers/media/common/ir-common.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-driver.c
drivers/media/video/bttv-gpio.c
drivers/media/video/bttv.h
drivers/media/video/bttvp.h
drivers/media/video/cx25840/Makefile [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-audio.c [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-core.c [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-firmware.c [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-vbi.c [new file with mode: 0644]
drivers/media/video/cx25840/cx25840.h [new file with mode: 0644]
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/ir-kbd-gpio.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/saa7115.c [new file with mode: 0644]
drivers/media/video/saa711x.c
drivers/media/video/saa7127.c [new file with mode: 0644]
drivers/media/video/saa7134/Kconfig
drivers/media/video/saa7134/Makefile
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-oss.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda8290.c
drivers/media/video/tuner-core.c
drivers/media/video/tuner-simple.c
drivers/media/video/wm8775.c
drivers/mmc/mmci.c
drivers/net/3c509.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/gianfar_mii.c
drivers/net/gianfar_mii.h
drivers/net/irda/ali-ircc.c
drivers/net/irda/nsc-ircc.c
drivers/net/smc91x.h
drivers/net/sungem.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pcmcia/cs.c
drivers/pcmcia/ds.c
drivers/pcmcia/i82365.c
drivers/serial/68328serial.c
drivers/serial/8250.c
drivers/serial/8250_pnp.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm1.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/dz.c
drivers/serial/mpc52xx_uart.c
drivers/serial/sa1100.c
drivers/serial/serial_core.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_cw.c
drivers/video/console/fbcon_ud.c
drivers/video/nvidia/nv_proto.h
drivers/video/nvidia/nvidia.c
drivers/video/vesafb.c
drivers/video/w100fb.c
fs/aio.c
fs/ext2/super.c
fs/ext3/inode.c
fs/proc/task_mmu.c
include/asm-alpha/atomic.h
include/asm-arm/arch-pxa/akita.h
include/asm-arm/atomic.h
include/asm-arm26/atomic.h
include/asm-cris/atomic.h
include/asm-frv/atomic.h
include/asm-h8300/atomic.h
include/asm-i386/atomic.h
include/asm-i386/system.h
include/asm-ia64/atomic.h
include/asm-m68k/atomic.h
include/asm-m68k/processor.h
include/asm-m68k/thread_info.h
include/asm-m68knommu/atomic.h
include/asm-mips/atomic.h
include/asm-parisc/atomic.h
include/asm-powerpc/atomic.h
include/asm-powerpc/kexec.h
include/asm-powerpc/machdep.h
include/asm-powerpc/page.h [new file with mode: 0644]
include/asm-powerpc/page_32.h [new file with mode: 0644]
include/asm-powerpc/page_64.h [new file with mode: 0644]
include/asm-powerpc/vdso_datapage.h
include/asm-ppc/immap_85xx.h
include/asm-ppc/ipic.h
include/asm-ppc/mpc83xx.h
include/asm-ppc/mpc85xx.h
include/asm-ppc/ppc_sys.h
include/asm-s390/atomic.h
include/asm-sh/atomic.h
include/asm-sh64/atomic.h
include/asm-sparc/atomic.h
include/asm-sparc64/atomic.h
include/asm-v850/atomic.h
include/asm-x86_64/atomic.h
include/asm-x86_64/desc.h
include/asm-xtensa/atomic.h
include/linux/acct.h
include/linux/aio.h
include/linux/cm4000_cs.h [new file with mode: 0644]
include/linux/file.h
include/linux/fsl_devices.h
include/linux/gfp.h
include/linux/hardirq.h
include/linux/hugetlb.h
include/linux/i2c-id.h
include/linux/init_task.h
include/linux/interrupt.h
include/linux/mmzone.h
include/linux/pagemap.h
include/linux/pci_ids.h
include/linux/percpu.h
include/linux/pm.h
include/linux/pm_legacy.h [new file with mode: 0644]
include/linux/preempt.h
include/linux/sched.h
include/linux/smp_lock.h
include/linux/thread_info.h
include/linux/time.h
include/linux/usb.h
include/linux/videodev2.h
include/media/ir-common.h
include/media/ir-kbd-i2c.h
include/media/tuner.h
include/media/v4l2-common.h [new file with mode: 0644]
kernel/cpuset.c
kernel/exit.c
kernel/fork.c
kernel/posix-timers.c
kernel/power/Kconfig
kernel/power/Makefile
kernel/power/pm.c
kernel/printk.c
kernel/ptrace.c
kernel/rcutorture.c
kernel/sched.c
kernel/signal.c
kernel/stop_machine.c
mm/memory.c
mm/page_alloc.c
mm/slab.c
mm/vmscan.c
scripts/kernel-doc
sound/oss/ad1848.c
sound/oss/cs4281/cs4281m.c
sound/oss/maestro.c
sound/oss/nm256_audio.c
sound/oss/opl3sa2.c

diff --git a/CREDITS b/CREDITS
index 7fb4c73e02288494856ae67eb9a37e461035f2b5..192f749eba25b38007b7a32e362e06896f7a368c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1097,7 +1097,7 @@ S: 80050-430 - Curitiba - Paran
 S: Brazil
 
 N: Kumar Gala
-E: kumar.gala@freescale.com
+E: galak@kernel.crashing.org
 D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support
 S: Austin, Texas 78729
 S: USA
index 7018f5c6a447b392a8ccd316d49380ce5307e936..1c955883cf58864015c7dd93243e819dd0b18429 100644 (file)
@@ -20,6 +20,12 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
 #                        +--> DIR=file  (htmldocs)
 #                        +--> man/      (mandocs)
 
+
+# for PDF and PS output you can choose between xmlto and docbook-utils tools
+PDF_METHOD     = $(prefer-db2x)
+PS_METHOD      = $(prefer-db2x)
+
+
 ###
 # The targets that may be used.
 .PHONY:        xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
@@ -93,27 +99,39 @@ C-procfs-example = procfs_example.xml
 C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
 $(obj)/procfs-guide.xml: $(C-procfs-example2)
 
-###
-# Rules to generate postscript, PDF and HTML
-# db2html creates a directory. Generate a html file used for timestamp
+notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
+                  exit 1
+db2xtemplate = db2TYPE -o $(dir $@) $<
+xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
+
+# determine which methods are available
+ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
+       use-db2x = db2x
+       prefer-db2x = db2x
+else
+       use-db2x = notfound
+       prefer-db2x = $(use-xmlto)
+endif
+ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found)
+       use-xmlto = xmlto
+       prefer-xmlto = xmlto
+else
+       use-xmlto = notfound
+       prefer-xmlto = $(use-db2x)
+endif
 
-quiet_cmd_db2ps = XMLTO    $@
-      cmd_db2ps = xmlto ps $(XMLTOFLAGS) -o $(dir $@) $<
+# the commands, generated from the chosen template
+quiet_cmd_db2ps = PS      $@
+      cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
 %.ps : %.xml
-       @(which xmlto > /dev/null 2>&1) || \
-        (echo "*** You need to install xmlto ***"; \
-         exit 1)
        $(call cmd,db2ps)
 
-quiet_cmd_db2pdf = XMLTO   $@
-      cmd_db2pdf = xmlto pdf $(XMLTOFLAGS) -o $(dir $@) $<
+quiet_cmd_db2pdf = PDF      $@
+      cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
 %.pdf : %.xml
-       @(which xmlto > /dev/null 2>&1) || \
-        (echo "*** You need to install xmlto ***"; \
-         exit 1)
        $(call cmd,db2pdf)
 
-quiet_cmd_db2html = XMLTO  $@
+quiet_cmd_db2html = HTML   $@
       cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
                echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
          Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
@@ -127,7 +145,7 @@ quiet_cmd_db2html = XMLTO  $@
        @if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
             cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
 
-quiet_cmd_db2man = XMLTO   $@
+quiet_cmd_db2man = MAN     $@
       cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; gzip -f $(obj)/man/*.9; fi
 %.9 : %.xml
        @(which xmlto > /dev/null 2>&1) || \
index a8316b1a3e3d45e3368a1a4b3dddb732bab65b32..0519c9dc00659f0691de16fddbd861a71a752766 100644 (file)
@@ -68,9 +68,7 @@ X!Iinclude/linux/kobject.h
 
      <sect1><title>Kernel utility functions</title>
 !Iinclude/linux/kernel.h
-<!-- This needs to clean up to make kernel-doc happy
-X!Ekernel/printk.c
- -->
+!Ekernel/printk.c
 !Ekernel/panic.c
 !Ekernel/sys.c
 !Ekernel/rcupdate.c
index 64be9f7ee3bba74a415d10c0f9508c7c4105e176..3ccce886c349d4ab3d5e357213d651b82d204eb4 100644 (file)
@@ -3,4 +3,5 @@
 <param name="chunk.quietly">1</param>
 <param name="funcsynopsis.style">ansi</param>
 <param name="funcsynopsis.tabular.threshold">80</param>
+<!-- <param name="paper.type">A4</param> -->
 </stylesheet>
index 8eedaa24f5e284f09dcfce6b2164bc53cfaed579..23a1c2402bccf3ec6d8bbf97bba3becfcf149272 100644 (file)
@@ -115,6 +115,33 @@ boolean is return which indicates whether the resulting counter value
 is negative.  It requires explicit memory barrier semantics around the
 operation.
 
+Then:
+
+       int atomic_cmpxchg(atomic_t *v, int old, int new);
+
+This performs an atomic compare exchange operation on the atomic value v,
+with the given old and new values. Like all atomic_xxx operations,
+atomic_cmpxchg will only satisfy its atomicity semantics as long as all
+other accesses of *v are performed through atomic_xxx operations.
+
+atomic_cmpxchg requires explicit memory barriers around the operation.
+
+The semantics for atomic_cmpxchg are the same as those defined for 'cas'
+below.
+
+Finally:
+
+       int atomic_add_unless(atomic_t *v, int a, int u);
+
+If the atomic value v is not equal to u, this function adds a to v, and
+returns non zero. If v is equal to u then it returns zero. This is done as
+an atomic operation.
+
+atomic_add_unless requires explicit memory barriers around the operation.
+
+atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)
+
+
 If a caller requires memory barrier semantics around an atomic_t
 operation which does not return a value, a set of interfaces are
 defined which accomplish this:
index c563842ed8057e1ee960ff0faa75d87c6b797a56..9f30ac6ca47b4caa382a281523b27a8abc95f541 100644 (file)
@@ -30,7 +30,9 @@ the disk is not available then you have three options :-
 
 (1) Hand copy the text from the screen and type it in after the machine
     has restarted.  Messy but it is the only option if you have not
-    planned for a crash.
+    planned for a crash. Alternatively, you can take a picture of
+    the screen with a digital camera - not nice, but better than
+    nothing.
 
 (2) Boot with a serial console (see Documentation/serial-console.txt),
     run a null modem to a second machine and capture the output there
index 2404099996ac40d83a6e5512eb98498749c5bc83..330246ac80f80f282e987d83d78acac8856ddc14 100644 (file)
 139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
 140 -> Osprey 440                                          [0070:ff07]
 141 -> Asound Skyeye PCTV
+142 -> Sabrent TV-FM (bttv version)
index 57c9d631db56210359ee75cce70825b41e78e631..efb708ec116ace349ccabdb31ccc0a1123fe5238 100644 (file)
@@ -80,3 +80,5 @@
  79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
  80 -> ASUS Digimatrix TV                       [1043:0210]
  81 -> Philips Tiger reference design           [1131:2018]
+ 82 -> MSI TV@Anywhere plus                     [1462:6231]
+
index ec840ca6f45501e215c52fe6b4a6540f7702512a..9d6544ea9f41881f0df7fea74f4f31b90211b9e5 100644 (file)
@@ -67,3 +67,4 @@ tuner=65 - Ymec TVF66T5-B/DFF
 tuner=66 - LG NTSC (TALN mini series)
 tuner=67 - Philips TD1316 Hybrid Tuner
 tuner=68 - Philips TUV1236D ATSC/NTSC dual in
+tuner=69 - Tena TNF 5335 MF
index 2313de23b0dad531fa6821a0c8a44d01f145ce24..509927e40bbbf92c9802aac8064a7ae82e18e5aa 100644 (file)
@@ -1565,7 +1565,7 @@ S:        Maintained
 
 LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
 P:     Kumar Gala
-M:     kumar.gala@freescale.com
+M:     galak@kernel.crashing.org
 W:     http://www.penguinppc.org/
 L:     linuxppc-embedded@ozlabs.org
 S:     Maintained
@@ -1873,6 +1873,16 @@ L:       linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
 
+OMNIKEY CARDMAN 4000 DRIVER
+P:     Harald Welte
+M:     laforge@gnumonks.org
+S:     Maintained
+
+OMNIKEY CARDMAN 4040 DRIVER
+P:     Harald Welte
+M:     laforge@gnumonks.org
+S:     Maintained
+
 ONSTREAM SCSI TAPE DRIVER
 P:     Willem Riede
 M:     osst@riede.org
index 8560b79268ba1aa2b1648e85311a11aeef83d302..c31914400953b05438b6cda4e793d166094b2ee4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1193,6 +1193,17 @@ else
 __srctree = $(srctree)/
 endif
 
+ifeq ($(ALLSOURCE_ARCHS),)
+ifeq ($(ARCH),um)
+ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
+else
+ALLINCLUDE_ARCHS := $(ARCH)
+endif
+else
+#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour.
+ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
+endif
+
 ALLSOURCE_ARCHS := $(ARCH)
 
 define all-sources
@@ -1208,7 +1219,7 @@ define all-sources
          find $(__srctree)include $(RCS_FIND_IGNORE) \
               \( -name config -o -name 'asm-*' \) -prune \
               -o -name '*.[chS]' -print; \
-         for ARCH in $(ALLSOURCE_ARCHS) ; do \
+         for ARCH in $(ALLINCLUDE_ARCHS) ; do \
               find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
                    -name '*.[chS]' -print; \
          done ; \
diff --git a/README b/README
index 4ee7dda88ba3956f0bea64072ee456ddf27fe8f9..61c4f7429233d509f26c267cf95fa01742b81e3e 100644 (file)
--- a/README
+++ b/README
@@ -81,6 +81,11 @@ INSTALLING the kernel:
    failed patches (xxx# or xxx.rej). If there are, either you or me has
    made a mistake.
 
+   Unlike patches for the 2.6.x kernels, patches for the 2.6.x.y kernels
+   (also known as the -stable kernels) are not incremental but instead apply
+   directly to the base 2.6.x kernel.  Please read
+   Documentation/applying-patches.txt for more information.
+
    Alternatively, the script patch-kernel can be used to automate this
    process.  It determines the current kernel version and applies any
    patches found.
index 3df7cbd924a10c0b859cfecb0ce708ccf531d9cd..70b007e66926c1cb9841170ce148bba06716659f 100644 (file)
@@ -702,6 +702,8 @@ menu "Device Drivers"
 
 source "drivers/base/Kconfig"
 
+source "drivers/connector/Kconfig"
+
 if ALIGNMENT_TRAP
 source "drivers/mtd/Kconfig"
 endif
index 557e52c1c869d9b15341955965f7122d37ddc355..1b7eaab02b9ec66263b0c66cd15e4522ab72f06f 100644 (file)
@@ -623,8 +623,6 @@ static int locomo_resume(struct platform_device *dev)
        locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
 
        spin_unlock_irqrestore(&lchip->lock, flags);
-
-       dev->power.saved_state = NULL;
        kfree(save);
 
        return 0;
@@ -775,7 +773,7 @@ static int locomo_probe(struct platform_device *dev)
 
 static int locomo_remove(struct platform_device *dev)
 {
-       struct locomo *lchip = platform__get_drvdata(dev);
+       struct locomo *lchip = platform_get_drvdata(dev);
 
        if (lchip) {
                __locomo_remove(lchip);
index 32924c6714fe54217f8db47b1cfe6684e8f3bb37..0c3cbd9a388b90d085f0e7b98113f375a2bfd512 100644 (file)
@@ -153,7 +153,7 @@ int __init scoop_probe(struct platform_device *pdev)
        printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
 
        SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
-       reset_scoop(dev);
+       reset_scoop(&pdev->dev);
        SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
        SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
 
index b0bbd1e62ebb70e107268ce7b176de0ffcd13c8e..a2843be0555733feaa8fc5cc29574817ce5c6c4d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/apm_bios.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
index e55ea952f7aa1d9f84ecce020d5caaa548f244fd..373c0959bc2f64ff02e72610e3091f53b6cd9763 100644 (file)
@@ -256,9 +256,7 @@ void __cpuexit cpu_die(void)
 asmlinkage void __cpuinit secondary_start_kernel(void)
 {
        struct mm_struct *mm = &init_mm;
-       unsigned int cpu;
-
-       cpu = smp_processor_id();
+       unsigned int cpu = smp_processor_id();
 
        printk("CPU%u: Booted secondary processor\n", cpu);
 
index dc09fd200c164543f87f26bb665aa492f3650e65..bbe6e4a0bf6ab0457defaa8e990466ca3af282cd 100644 (file)
@@ -132,14 +132,14 @@ void __init footbridge_init_irq(void)
 static struct map_desc fb_common_io_desc[] __initdata = {
        {
                .virtual        = ARMCSR_BASE,
-               .pfn            = DC21285_ARMCSR_BASE,
+               .pfn            = __phys_to_pfn(DC21285_ARMCSR_BASE),
                .length         = ARMCSR_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = XBUS_BASE,
                .pfn            = __phys_to_pfn(0x40000000),
                .length         = XBUS_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }
 };
 
@@ -153,28 +153,28 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
                .virtual        = PCIMEM_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_MEM),
                .length         = PCIMEM_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = PCICFG0_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
                .length         = PCICFG0_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = PCICFG1_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
                .length         = PCICFG1_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = PCIIACK_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_IACK),
                .length         = PCIIACK_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = PCIO_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_IO),
                .length         = PCIO_SIZE,
-               .type           = MT_DEVICE
-       }
+               .type           = MT_DEVICE,
+       },
 #endif
 };
 
@@ -187,13 +187,13 @@ static struct map_desc co285_io_desc[] __initdata = {
                .virtual        = PCIO_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_IO),
                .length         = PCIO_SIZE,
-               .type           = MT_DEVICE
+               .type           = MT_DEVICE,
        }, {
                .virtual        = PCIMEM_BASE,
                .pfn            = __phys_to_pfn(DC21285_PCI_MEM),
                .length         = PCIMEM_SIZE,
-               .type           = MT_DEVICE
-       }
+               .type           = MT_DEVICE,
+       },
 #endif
 };
 
index e201aa9765b9c0bc8ee15e87d45bd80393a4075d..cd506646801a4d576dad1de3f4f08b613534843c 100644 (file)
@@ -72,6 +72,12 @@ config MACH_HUSKY
        depends PXA_SHARPSL_25x
        select PXA_SHARP_C7xx
 
+config MACH_AKITA
+       bool "Enable Sharp SL-1000 (Akita) Support"
+       depends PXA_SHARPSL_27x
+       select PXA_SHARP_Cxx00
+       select MACH_SPITZ
+
 config MACH_SPITZ
        bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
        depends PXA_SHARPSL_27x
index d210bd5032ced956d0eed5da63e2be025e857d15..32526a0a6f861241089db559937b579e49d18960 100644 (file)
@@ -11,8 +11,9 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARP_C7xx)   += corgi.o corgi_ssp.o corgi_lcd.o
-obj-$(CONFIG_PXA_SHARP_Cxx00)  += spitz.o corgi_ssp.o corgi_lcd.o
+obj-$(CONFIG_PXA_SHARP_C7xx)   += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
+obj-$(CONFIG_PXA_SHARP_Cxx00)  += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
+obj-$(CONFIG_MACH_AKITA)       += akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)      += poodle.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
new file mode 100644 (file)
index 0000000..f6d73cc
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
+ * (uses a Maxim MAX7310 8 Port IO Expander)
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@openedhand.com>
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <asm/arch/akita.h>
+
+/* MAX7310 Regiser Map */
+#define MAX7310_INPUT    0x00
+#define MAX7310_OUTPUT   0x01
+#define MAX7310_POLINV   0x02
+#define MAX7310_IODIR    0x03 /* 1 = Input, 0 = Output */
+#define MAX7310_TIMEOUT  0x04
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
+
+/* I2C Magic */
+I2C_CLIENT_INSMOD;
+
+static int max7310_write(struct i2c_client *client, int address, int data);
+static struct i2c_client max7310_template;
+static void akita_ioexp_work(void *private_);
+
+static struct device *akita_ioexp_device;
+static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
+DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);
+
+
+/*
+ * MAX7310 Access
+ */
+static int max7310_config(struct device *dev, int iomode, int polarity)
+{
+       int ret;
+       struct i2c_client *client = to_i2c_client(dev);
+
+       ret = max7310_write(client, MAX7310_POLINV, polarity);
+       if (ret < 0)
+               return ret;
+       ret = max7310_write(client, MAX7310_IODIR, iomode);
+       return ret;
+}
+
+static int max7310_set_ouputs(struct device *dev, int outputs)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+
+       return max7310_write(client, MAX7310_OUTPUT, outputs);
+}
+
+/*
+ * I2C Functions
+ */
+static int max7310_write(struct i2c_client *client, int address, int value)
+{
+       u8 data[2];
+
+       data[0] = address & 0xff;
+       data[1] = value & 0xff;
+
+       if (i2c_master_send(client, data, 2) == 2)
+               return 0;
+       return -1;
+}
+
+static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+       struct i2c_client *new_client;
+       int err;
+
+       if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
+               return -ENOMEM;
+
+       max7310_template.adapter = adapter;
+       max7310_template.addr = address;
+
+       memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
+
+       if ((err = i2c_attach_client(new_client))) {
+               kfree(new_client);
+               return err;
+       }
+
+       max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
+       akita_ioexp_device = &new_client->dev;
+       schedule_work(&akita_ioexp);
+
+       return 0;
+}
+
+static int max7310_attach_adapter(struct i2c_adapter *adapter)
+{
+       return i2c_probe(adapter, &addr_data, max7310_detect);
+}
+
+static int max7310_detach_client(struct i2c_client *client)
+{
+       int err;
+
+       akita_ioexp_device = NULL;
+
+       if ((err = i2c_detach_client(client)))
+               return err;
+
+       kfree(client);
+       return 0;
+}
+
+static struct i2c_driver max7310_i2c_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "akita-max7310",
+       .id             = I2C_DRIVERID_AKITAIOEXP,
+       .flags          = I2C_DF_NOTIFY,
+       .attach_adapter = max7310_attach_adapter,
+       .detach_client  = max7310_detach_client,
+};
+
+static struct i2c_client max7310_template = {
+       name:   "akita-max7310",
+       flags:  I2C_CLIENT_ALLOW_USE,
+       driver: &max7310_i2c_driver,
+};
+
+void akita_set_ioexp(struct device *dev, unsigned char bit)
+{
+       ioexp_output_value |= bit;
+
+       if (akita_ioexp_device)
+               schedule_work(&akita_ioexp);
+       return;
+}
+
+void akita_reset_ioexp(struct device *dev, unsigned char bit)
+{
+       ioexp_output_value &= ~bit;
+
+       if (akita_ioexp_device)
+               schedule_work(&akita_ioexp);
+       return;
+}
+
+EXPORT_SYMBOL(akita_set_ioexp);
+EXPORT_SYMBOL(akita_reset_ioexp);
+
+static void akita_ioexp_work(void *private_)
+{
+       if (akita_ioexp_device)
+               max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
+}
+
+
+#ifdef CONFIG_PM
+static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       flush_scheduled_work();
+       return 0;
+}
+
+static int akita_ioexp_resume(struct platform_device *pdev)
+{
+       schedule_work(&akita_ioexp);
+       return 0;
+}
+#else
+#define akita_ioexp_suspend NULL
+#define akita_ioexp_resume NULL
+#endif
+
+static int __init akita_ioexp_probe(struct platform_device *pdev)
+{
+       return i2c_add_driver(&max7310_i2c_driver);
+}
+
+static int akita_ioexp_remove(struct platform_device *pdev)
+{
+       i2c_del_driver(&max7310_i2c_driver);
+       return 0;
+}
+
+static struct platform_driver akita_ioexp_driver = {
+       .probe          = akita_ioexp_probe,
+       .remove         = akita_ioexp_remove,
+       .suspend        = akita_ioexp_suspend,
+       .resume         = akita_ioexp_resume,
+       .driver         = {
+               .name   = "akita-ioexp",
+       },
+};
+
+static int __init akita_ioexp_init(void)
+{
+       return platform_driver_register(&akita_ioexp_driver);
+}
+
+static void __exit akita_ioexp_exit(void)
+{
+       platform_driver_unregister(&akita_ioexp_driver);
+}
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
+MODULE_DESCRIPTION("Akita IO-Expander driver");
+MODULE_LICENSE("GPL");
+
+fs_initcall(akita_ioexp_init);
+module_exit(akita_ioexp_exit);
+
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
new file mode 100644 (file)
index 0000000..599be14
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/apm.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+static void corgi_charger_init(void)
+{
+       pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
+       pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
+       pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
+       pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
+}
+
+static void corgi_charge_led(int val)
+{
+       if (val == SHARPSL_LED_ERROR) {
+               dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
+       } else if (val == SHARPSL_LED_ON) {
+               dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+               GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
+       } else {
+               dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+               GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
+       }
+}
+
+static void corgi_measure_temp(int on)
+{
+       if (on)
+               GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+       else
+               GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+}
+
+static void corgi_charge(int on)
+{
+       if (on) {
+               if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
+                       GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+                       GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+               } else {
+                       GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+                       GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+               }
+       } else {
+               GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+               GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+       }
+}
+
+static void corgi_discharge(int on)
+{
+       if (on)
+               GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+       else
+               GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+}
+
+static void corgi_presuspend(void)
+{
+       int i;
+       unsigned long wakeup_mask;
+
+       /* charging , so CHARGE_ON bit is HIGH during OFF. */
+       if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
+               PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
+       else
+               PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
+
+       if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
+               PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
+       else
+               PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
+
+       if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
+               PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
+       else
+               PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
+
+       /* Resume on keyboard power key */
+       PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
+
+       wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
+
+       if (!machine_is_corgi())
+               wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
+
+       PWER = wakeup_mask | PWER_RTC;
+       PRER = wakeup_mask;
+       PFER = wakeup_mask;
+
+       for (i = 0; i <=15; i++) {
+               if (PRER & PFER & GPIO_bit(i)) {
+                       if (GPLR0 & GPIO_bit(i) )
+                               PRER &= ~GPIO_bit(i);
+                       else
+                               PFER &= ~GPIO_bit(i);
+               }
+       }
+}
+
+static void corgi_postsuspend(void)
+{
+}
+
+/*
+ * Check what brought us out of the suspend.
+ * Return: 0 to sleep, otherwise wake
+ */
+static int corgi_should_wakeup(unsigned int resume_on_alarm)
+{
+       int is_resume = 0;
+
+       dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
+
+       if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
+               if (STATUS_AC_IN()) {
+                       /* charge on */
+                       dev_dbg(sharpsl_pm.dev, "ac insert\n");
+                       sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+               } else {
+                       /* charge off */
+                       dev_dbg(sharpsl_pm.dev, "ac remove\n");
+                       CHARGE_LED_OFF();
+                       CHARGE_OFF();
+                       sharpsl_pm.charge_mode = CHRG_OFF;
+               }
+       }
+
+       if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL)))
+               dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
+
+       if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT))
+               is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
+
+       if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP))
+               is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
+
+       if (resume_on_alarm && (PEDR & PWER_RTC))
+               is_resume |= PWER_RTC;
+
+       dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+       return is_resume;
+}
+
+static unsigned long corgi_charger_wakeup(void)
+{
+       return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
+}
+
+static int corgi_acin_status(void)
+{
+       return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
+}
+
+static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
+       .init            = corgi_charger_init,
+       .gpio_batlock    = CORGI_GPIO_BAT_COVER,
+       .gpio_acin       = CORGI_GPIO_AC_IN,
+       .gpio_batfull    = CORGI_GPIO_CHRG_FULL,
+       .status_acin     = corgi_acin_status,
+       .discharge       = corgi_discharge,
+       .charge          = corgi_charge,
+       .chargeled       = corgi_charge_led,
+       .measure_temp    = corgi_measure_temp,
+       .presuspend      = corgi_presuspend,
+       .postsuspend     = corgi_postsuspend,
+       .charger_wakeup  = corgi_charger_wakeup,
+       .should_wakeup   = corgi_should_wakeup,
+       .bat_levels      = 40,
+       .bat_levels_noac = spitz_battery_levels_noac,
+       .bat_levels_acin = spitz_battery_levels_acin,
+       .status_high_acin = 188,
+       .status_low_acin  = 178,
+       .status_high_noac = 185,
+       .status_low_noac  = 175,
+};
+
+static struct platform_device *corgipm_device;
+
+static int __devinit corgipm_init(void)
+{
+       int ret;
+
+       corgipm_device = platform_device_alloc("sharpsl-pm", -1);
+       if (!corgipm_device)
+               return -ENOMEM;
+
+       corgipm_device->dev.platform_data = &corgi_pm_machinfo;
+       ret = platform_device_add(corgipm_device);
+
+       if (ret)
+               platform_device_put(corgipm_device);
+
+       return ret;
+}
+
+static void corgipm_exit(void)
+{
+       platform_device_unregister(corgipm_device);
+}
+
+module_init(corgipm_init);
+module_exit(corgipm_exit);
index 4879c0f7da72ce733b799c03f7a50234a0a8d35b..b0c40a1d6671e17d5b5f78cd4f12e8734a8e61b4 100644 (file)
@@ -115,7 +115,7 @@ extern struct battery_thresh spitz_battery_levels_noac[];
 #define CHARGE_LED_ERR()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
 #define DISCHARGE_ON()      sharpsl_pm.machinfo->discharge(1)
 #define DISCHARGE_OFF()     sharpsl_pm.machinfo->discharge(0)
-#define STATUS_AC_IN        sharpsl_pm.machinfo->status_acin()
-#define STATUS_BATT_LOCKED  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
-#define STATUS_CHRG_FULL    READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
-#define STATUS_FATAL        READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
+#define STATUS_AC_IN()      sharpsl_pm.machinfo->status_acin()
+#define STATUS_BATT_LOCKED()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
+#define STATUS_CHRG_FULL()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
+#define STATUS_FATAL()      READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
index 6c9e871c53d86830598b23529411ae52d0eb2edf..c10be00fb52671ae7e7dc6fd2e1ccc93cb8ac722 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/apm_bios.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/hardware/scoop.h>
 #define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD  10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN   10  /* 10 msec */
 #define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
 #define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
 #define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
 #define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
-#define SHARPSL_CHARGE_ON_JKVAD_HIGH   0x9b  /* 6V */
-#define SHARPSL_CHARGE_ON_JKVAD_LOW    0x34  /* 2V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
 #define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
 #define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
 
@@ -160,9 +160,10 @@ struct battery_thresh  spitz_battery_levels_noac[] = {
 /*
  * Prototypes
  */
-static int sharpsl_read_MainBattery(void);
+static int sharpsl_read_main_battery(void);
 static int sharpsl_off_charge_battery(void);
-static int sharpsl_check_battery(int mode);
+static int sharpsl_check_battery_temp(void);
+static int sharpsl_check_battery_voltage(void);
 static int sharpsl_ac_check(void);
 static int sharpsl_fatal_check(void);
 static int sharpsl_average_value(int ad);
@@ -228,7 +229,7 @@ static void sharpsl_battery_thread(void *private_)
        if (!sharpsl_pm.machinfo)
                return;
 
-       sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
+       sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE);
 
        /* Corgi cannot confirm when battery fully charged so periodically kick! */
        if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
@@ -236,7 +237,7 @@ static void sharpsl_battery_thread(void *private_)
                schedule_work(&toggle_charger);
 
        while(1) {
-               voltage = sharpsl_read_MainBattery();
+               voltage = sharpsl_read_main_battery();
                if (voltage > 0) break;
                if (i++ > 5) {
                        voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
@@ -317,10 +318,10 @@ static void sharpsl_charge_toggle(void *private_)
 {
        dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
 
-       if (STATUS_AC_IN == 0) {
+       if (STATUS_AC_IN() == 0) {
                sharpsl_charge_off();
                return;
-       } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
+       } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
                sharpsl_charge_error();
                return;
        }
@@ -335,7 +336,7 @@ static void sharpsl_charge_toggle(void *private_)
 
 static void sharpsl_ac_timer(unsigned long data)
 {
-       int acin = STATUS_AC_IN;
+       int acin = STATUS_AC_IN();
 
        dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
 
@@ -364,7 +365,7 @@ static void sharpsl_chrg_full_timer(unsigned long data)
 
        sharpsl_pm.full_count++;
 
-       if (STATUS_AC_IN == 0) {
+       if (STATUS_AC_IN() == 0) {
                dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
                if (sharpsl_pm.charge_mode == CHRG_ON)
                        sharpsl_charge_off();
@@ -399,12 +400,12 @@ static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
 {
        int is_fatal = 0;
 
-       if (STATUS_BATT_LOCKED == 0) {
+       if (STATUS_BATT_LOCKED() == 0) {
                dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
                is_fatal = 1;
        }
 
-       if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
+       if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) {
                dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
                is_fatal = 1;
        }
@@ -461,12 +462,12 @@ static int read_max1111(int channel)
                        | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
 }
 
-static int sharpsl_read_MainBattery(void)
+static int sharpsl_read_main_battery(void)
 {
        return read_max1111(BATT_AD);
 }
 
-static int sharpsl_read_Temp(void)
+static int sharpsl_read_temp(void)
 {
        int temp;
 
@@ -480,7 +481,7 @@ static int sharpsl_read_Temp(void)
        return temp;
 }
 
-static int sharpsl_read_jkvad(void)
+static int sharpsl_read_acin(void)
 {
        return read_max1111(JK_VAD);
 }
@@ -522,16 +523,14 @@ static int get_select_val(int *val)
        return (sum/3);
 }
 
-/*  mode 0 - Check temperature and voltage
- *       1 - Check temperature only */
-static int sharpsl_check_battery(int mode)
+static int sharpsl_check_battery_temp(void)
 {
        int val, i, buff[5];
 
        /* Check battery temperature */
        for (i=0; i<5; i++) {
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-               buff[i] = sharpsl_read_Temp();
+               buff[i] = sharpsl_read_temp();
        }
 
        val = get_select_val(buff);
@@ -539,8 +538,13 @@ static int sharpsl_check_battery(int mode)
        dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
        if (val > SHARPSL_CHARGE_ON_TEMP)
                return -1;
-       if (mode == 1)
-               return 0;
+
+       return 0;
+}
+
+static int sharpsl_check_battery_voltage(void)
+{
+       int val, i, buff[5];
 
        /* disable charge, enable discharge */
        CHARGE_OFF();
@@ -552,7 +556,7 @@ static int sharpsl_check_battery(int mode)
 
        /* Check battery voltage */
        for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_MainBattery();
+               buff[i] = sharpsl_read_main_battery();
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
        }
 
@@ -575,14 +579,14 @@ static int sharpsl_ac_check(void)
        int temp, i, buff[5];
 
        for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_jkvad();
-               mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
+               buff[i] = sharpsl_read_acin();
+               mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
        }
 
        temp = get_select_val(buff);
        dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
 
-       if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
+       if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
                dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
                return -1;
        }
@@ -591,7 +595,7 @@ static int sharpsl_ac_check(void)
 }
 
 #ifdef CONFIG_PM
-static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
+static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
 {
        sharpsl_pm.flags |= SHARPSL_SUSPENDED;
        flush_scheduled_work();
@@ -604,7 +608,7 @@ static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
        return 0;
 }
 
-static int sharpsl_pm_resume(struct device *dev)
+static int sharpsl_pm_resume(struct platform_device *pdev)
 {
        /* Clear the reset source indicators as they break the bootloader upon reboot */
        RCSR = 0x0f;
@@ -622,7 +626,7 @@ static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable
        dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
        /* not charging and AC-IN! */
 
-       if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
+       if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) {
                dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
                sharpsl_pm.charge_mode = CHRG_OFF;
                sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
@@ -671,7 +675,7 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
                dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
        }
 
-       if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
+       if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) )
        {
                dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
                corgi_goto_sleep(alarm_time, alarm_enable, state);
@@ -711,7 +715,7 @@ static int sharpsl_fatal_check(void)
        dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
 
        /* Check AC-Adapter */
-       acin = STATUS_AC_IN;
+       acin = STATUS_AC_IN();
 
        if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
                CHARGE_OFF();
@@ -725,7 +729,7 @@ static int sharpsl_fatal_check(void)
 
        /* Check battery : check inserting battery ? */
        for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_MainBattery();
+               buff[i] = sharpsl_read_main_battery();
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
        }
 
@@ -739,7 +743,7 @@ static int sharpsl_fatal_check(void)
        }
 
        temp = get_select_val(buff);
-       dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
+       dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery());
 
        if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
                        (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
@@ -771,7 +775,7 @@ static int sharpsl_off_charge_battery(void)
                dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
 
                /* AC Check */
-               if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
+               if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
                        return sharpsl_off_charge_error();
 
                /* Start Charging */
@@ -793,7 +797,7 @@ static int sharpsl_off_charge_battery(void)
 
                dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
 
-               if (sharpsl_check_battery(0) < 0)
+               if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
                        return sharpsl_off_charge_error();
 
                CHARGE_OFF();
@@ -811,7 +815,7 @@ static int sharpsl_off_charge_battery(void)
                        /* Check for timeout */
                        if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
                                return 1;
-                       if (STATUS_CHRG_FULL) {
+                       if (STATUS_CHRG_FULL()) {
                                dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
                                sharpsl_pm.full_count++;
                                CHARGE_OFF();
@@ -840,7 +844,7 @@ static int sharpsl_off_charge_battery(void)
                        sharpsl_pm.full_count++;
                        return 1;
                }
-               if (STATUS_CHRG_FULL) {
+               if (STATUS_CHRG_FULL()) {
                        dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
                        CHARGE_LED_OFF();
                        CHARGE_OFF();
@@ -886,13 +890,13 @@ static struct pm_ops sharpsl_pm_ops = {
        .finish         = pxa_pm_finish,
 };
 
-static int __init sharpsl_pm_probe(struct device *dev)
+static int __init sharpsl_pm_probe(struct platform_device *pdev)
 {
-       if (!dev->platform_data)
+       if (!pdev->dev.platform_data)
                return -EINVAL;
 
-       sharpsl_pm.dev = dev;
-       sharpsl_pm.machinfo = dev->platform_data;
+       sharpsl_pm.dev = &pdev->dev;
+       sharpsl_pm.machinfo = pdev->dev.platform_data;
        sharpsl_pm.charge_mode = CHRG_OFF;
        sharpsl_pm.flags = 0;
 
@@ -935,8 +939,8 @@ static int __init sharpsl_pm_probe(struct device *dev)
                else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
        }
 
-       device_create_file(dev, &dev_attr_battery_percentage);
-       device_create_file(dev, &dev_attr_battery_voltage);
+       device_create_file(&pdev->dev, &dev_attr_battery_percentage);
+       device_create_file(&pdev->dev, &dev_attr_battery_voltage);
 
        apm_get_power_status = sharpsl_apm_get_power_status;
 
@@ -947,12 +951,12 @@ static int __init sharpsl_pm_probe(struct device *dev)
        return 0;
 }
 
-static int sharpsl_pm_remove(struct device *dev)
+static int sharpsl_pm_remove(struct platform_device *pdev)
 {
        pm_set_ops(NULL);
 
-       device_remove_file(dev, &dev_attr_battery_percentage);
-       device_remove_file(dev, &dev_attr_battery_voltage);
+       device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
+       device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
 
        free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
        free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
@@ -969,23 +973,24 @@ static int sharpsl_pm_remove(struct device *dev)
        return 0;
 }
 
-static struct device_driver sharpsl_pm_driver = {
-       .name           = "sharpsl-pm",
-       .bus            = &platform_bus_type,
+static struct platform_driver sharpsl_pm_driver = {
        .probe          = sharpsl_pm_probe,
        .remove         = sharpsl_pm_remove,
        .suspend        = sharpsl_pm_suspend,
        .resume         = sharpsl_pm_resume,
+       .driver         = {
+               .name           = "sharpsl-pm",
+       },
 };
 
 static int __devinit sharpsl_pm_init(void)
 {
-       return driver_register(&sharpsl_pm_driver);
+       return platform_driver_register(&sharpsl_pm_driver);
 }
 
 static void sharpsl_pm_exit(void)
 {
-       driver_unregister(&sharpsl_pm_driver);
+       platform_driver_unregister(&sharpsl_pm_driver);
 }
 
 late_initcall(sharpsl_pm_init);
index 4e9a699ee4280e61560a5672e9bd6c276c36a284..2df1b56615b1029601d405b958f682aae41d8b98 100644 (file)
@@ -345,6 +345,16 @@ static void spitz_irda_transceiver_mode(struct device *dev, int mode)
                reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
 }
 
+#ifdef CONFIG_MACH_AKITA
+static void akita_irda_transceiver_mode(struct device *dev, int mode)
+{
+       if (mode & IR_OFF)
+               akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+       else
+               akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+}
+#endif
+
 static struct pxaficp_platform_data spitz_ficp_platform_data = {
        .transceiver_cap  = IR_SIRMODE | IR_OFF,
        .transceiver_mode = spitz_irda_transceiver_mode,
@@ -417,6 +427,32 @@ static void __init spitz_init(void)
        platform_device_register(&spitzscoop2_device);
 }
 
+#ifdef CONFIG_MACH_AKITA
+/*
+ * Akita IO Expander
+ */
+struct platform_device akitaioexp_device = {
+       .name           = "akita-ioexp",
+       .id             = -1,
+};
+
+static void __init akita_init(void)
+{
+       spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
+
+       /* We just pretend the second element of the array doesn't exist */
+       spitz_pcmcia_config.num_devs = 1;
+       platform_scoop_config = &spitz_pcmcia_config;
+       spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity;
+
+       platform_device_register(&akitaioexp_device);
+
+       spitzscoop_device.dev.parent = &akitaioexp_device.dev;
+       common_init();
+}
+#endif
+
+
 static void __init fixup_spitz(struct machine_desc *desc,
                struct tag *tags, char **cmdline, struct meminfo *mi)
 {
@@ -452,3 +488,16 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
        .timer          = &pxa_timer,
 MACHINE_END
 #endif
+
+#ifdef CONFIG_MACH_AKITA
+MACHINE_START(AKITA, "SHARP Akita")
+       .phys_ram       = 0xa0000000,
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup          = fixup_spitz,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa_init_irq,
+       .init_machine   = akita_init,
+       .timer          = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
new file mode 100644 (file)
index 0000000..3ce7486
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Battery and Power Management code for the Sharp SL-Cxx00
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/apm.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/spitz.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+static int spitz_last_ac_status;
+
+static void spitz_charger_init(void)
+{
+       pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
+       pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+}
+
+static void spitz_charge_led(int val)
+{
+       if (val == SHARPSL_LED_ERROR) {
+               dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
+       } else if (val == SHARPSL_LED_ON) {
+               dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+               set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
+       } else {
+               dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+               reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
+       }
+}
+
+static void spitz_measure_temp(int on)
+{
+       if (on)
+               set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
+       else
+               reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
+}
+
+static void spitz_charge(int on)
+{
+       if (on) {
+               if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
+                       set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+                       reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+               } else {
+                       reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+                       reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+               }
+       } else {
+               reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+               set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+       }
+}
+
+static void spitz_discharge(int on)
+{
+       if (on)
+               set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
+       else
+               reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
+}
+
+/* HACK - For unknown reasons, accurate voltage readings are only made with a load
+   on the power bus which the green led on spitz provides */
+static void spitz_discharge1(int on)
+{
+       if (on)
+               set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
+       else
+               reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
+}
+
+static void spitz_presuspend(void)
+{
+       spitz_last_ac_status = STATUS_AC_IN();
+
+       /* GPIO Sleep Register */
+       PGSR0 = 0x00144018;
+       PGSR1 = 0x00EF0000;
+       if (machine_is_akita()) {
+               PGSR2 = 0x2121C000;
+               PGSR3 = 0x00600400;
+       } else {
+               PGSR2 = 0x0121C000;
+               PGSR3 = 0x00600000;
+       }
+
+       PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+       PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+       PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+       PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+       PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
+
+       pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
+
+       PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
+       PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+       PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
+       PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+       PKSR = 0xffffffff; // clear
+
+       /* nRESET_OUT Disable */
+       PSLR |= PSLR_SL_ROD;
+
+       /* Clear reset status */
+       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+       /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+       PCFR = PCFR_GPR_EN | PCFR_OPDE;
+}
+
+static void spitz_postsuspend(void)
+{
+       pxa_gpio_mode(GPIO18_RDY_MD);
+       pxa_gpio_mode(10 | GPIO_IN);
+}
+
+static int spitz_should_wakeup(unsigned int resume_on_alarm)
+{
+       int is_resume = 0;
+       int acin = STATUS_AC_IN();
+
+       if (spitz_last_ac_status != acin) {
+               if (acin) {
+                       /* charge on */
+                       sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+                       dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
+               } else {
+                       /* charge off */
+                       dev_dbg(sharpsl_pm.dev, "AC Removed\n");
+                       CHARGE_LED_OFF();
+                       CHARGE_OFF();
+                       sharpsl_pm.charge_mode = CHRG_OFF;
+               }
+               spitz_last_ac_status = acin;
+               /* Return to suspend as this must be what we were woken for */
+               return 0;
+       }
+
+       if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
+               is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
+
+       if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
+               is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
+
+       if (resume_on_alarm && (PEDR & PWER_RTC))
+               is_resume |= PWER_RTC;
+
+       dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+       return is_resume;
+}
+
+static unsigned long spitz_charger_wakeup(void)
+{
+       return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
+}
+
+static int spitz_acin_status(void)
+{
+       return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
+}
+
+struct sharpsl_charger_machinfo spitz_pm_machinfo = {
+       .init             = spitz_charger_init,
+       .gpio_batlock     = SPITZ_GPIO_BAT_COVER,
+       .gpio_acin        = SPITZ_GPIO_AC_IN,
+       .gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
+       .gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
+       .status_acin      = spitz_acin_status,
+       .discharge        = spitz_discharge,
+       .discharge1       = spitz_discharge1,
+       .charge           = spitz_charge,
+       .chargeled        = spitz_charge_led,
+       .measure_temp     = spitz_measure_temp,
+       .presuspend       = spitz_presuspend,
+       .postsuspend      = spitz_postsuspend,
+       .charger_wakeup   = spitz_charger_wakeup,
+       .should_wakeup    = spitz_should_wakeup,
+       .bat_levels       = 40,
+       .bat_levels_noac  = spitz_battery_levels_noac,
+       .bat_levels_acin  = spitz_battery_levels_acin,
+       .status_high_acin = 188,
+       .status_low_acin  = 178,
+       .status_high_noac = 185,
+       .status_low_noac  = 175,
+};
+
+static struct platform_device *spitzpm_device;
+
+static int __devinit spitzpm_init(void)
+{
+       int ret;
+
+       spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
+       if (!spitzpm_device)
+               return -ENOMEM;
+
+       spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
+       ret = platform_device_add(spitzpm_device);
+
+       if (ret)
+               platform_device_put(spitzpm_device);
+
+       return ret;
+}
+
+static void spitzpm_exit(void)
+{
+       platform_device_unregister(spitzpm_device);
+}
+
+module_init(spitzpm_init);
+module_exit(spitzpm_exit);
index 1a1e8a119c3d722aa7d9b64ddabe820ace45bc4b..712c3c24c954008d520f7925a492eee0a85f97e5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
index dbf90ad6eac363a082deae5141c7fcac7a385279..6004bb0795e0992687ffdc2548798c7661736e2a 100644 (file)
@@ -699,7 +699,7 @@ depends on PM && !X86_VISWS
 
 config APM
        tristate "APM (Advanced Power Management) BIOS support"
-       depends on PM
+       depends on PM && PM_LEGACY
        ---help---
          APM is a BIOS specification for saving power using several different
          techniques. This is mostly useful for battery powered laptops with
index 003548b8735f961b24794da2306bff45944ee63e..1e60acbed3c1468189d6323437a03420383deb25 100644 (file)
 #include <linux/time.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
index 43601de0f6331415aaa8b19594112a3de080ae4f..c28d26fb5f241891c02b3fd5fd7f508083315334 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/bitops.h>
 #include <linux/smp.h>
 #include <linux/thread_info.h>
+#include <linux/module.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -264,5 +265,52 @@ __init int intel_cpu_init(void)
        return 0;
 }
 
+#ifndef CONFIG_X86_CMPXCHG
+unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
+{
+       u8 prev;
+       unsigned long flags;
+
+       /* Poor man's cmpxchg for 386. Unsuitable for SMP */
+       local_irq_save(flags);
+       prev = *(u8 *)ptr;
+       if (prev == old)
+               *(u8 *)ptr = new;
+       local_irq_restore(flags);
+       return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u8);
+
+unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
+{
+       u16 prev;
+       unsigned long flags;
+
+       /* Poor man's cmpxchg for 386. Unsuitable for SMP */
+       local_irq_save(flags);
+       prev = *(u16 *)ptr;
+       if (prev == old)
+               *(u16 *)ptr = new;
+       local_irq_restore(flags);
+       return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u16);
+
+unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
+{
+       u32 prev;
+       unsigned long flags;
+
+       /* Poor man's cmpxchg for 386. Unsuitable for SMP */
+       local_irq_save(flags);
+       prev = *(u32 *)ptr;
+       if (prev == old)
+               *(u32 *)ptr = new;
+       local_irq_restore(flags);
+       return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u32);
+#endif
+
 // arch_initcall(intel_cpu_init);
 
index 9e24f7b207ee1636eabcafc48f6f630b56ed8d3e..e50b93155249b79732378ccbc6d4bc41c2d74207 100644 (file)
@@ -560,11 +560,10 @@ nmi_stack_fixup:
 nmi_debug_stack_check:
        cmpw $__KERNEL_CS,16(%esp)
        jne nmi_stack_correct
-       cmpl $debug - 1,(%esp)
-       jle nmi_stack_correct
+       cmpl $debug,(%esp)
+       jb nmi_stack_correct
        cmpl $debug_esp_fix_insn,(%esp)
-       jle nmi_debug_stack_fixup
-nmi_debug_stack_fixup:
+       ja nmi_stack_correct
        FIX_STACK(24,nmi_stack_correct, 1)
        jmp nmi_stack_correct
 
index e42e46d351591d583782921f6b30e5b302b2285a..b9b6bd56b9bafc27b2be1d3dd2621c4a47a8a782 100644 (file)
@@ -25,8 +25,9 @@ static int __init init_pit(char* override)
 {
        /* check clock override */
        if (override[0] && strncmp(override,"pit",3))
-               printk(KERN_ERR "Warning: clock= override failed. Defaulting to PIT\n");
+               printk(KERN_ERR "Warning: clock= override failed. Defaulting "
+                               "to PIT\n");
+       init_cpu_khz();
        count_p = LATCH;
        return 0;
 }
index 542d9298da5e91571bf75f45152e8901d473a684..06e26f0062382301e02c13a6c2fa24617a48b663 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/efi.h>
 #include <linux/memory_hotplug.h>
+#include <linux/initrd.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -267,7 +268,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
        pkmap_page_table = pte; 
 }
 
-void __devinit free_new_highpage(struct page *page)
+static void __devinit free_new_highpage(struct page *page)
 {
        set_page_count(page, 1);
        __free_page(page);
index 9571a21d6ad42b0d0f9de6a63038fd1d4f5cee9c..a1629194e3fd917260604e372371416a1def8b64 100644 (file)
@@ -381,10 +381,8 @@ fpsp_done:
 .Lnotkern:
        SAVE_ALL_INT
        GET_CURRENT(%d0)
-       tstb    %curptr@(TASK_NEEDRESCHED)
-       jne     ret_from_exception      | deliver signals,
-                                       | reschedule etc..
-       RESTORE_ALL
+       | deliver signals, reschedule etc..
+       jra     ret_from_exception
 
 |
 |      mem_write --- write to user or supervisor address space
index 4ba2c74da93da6070d80e26cd754ca59b671d046..b2dbdf5ee3090ba7359eda1fcdca7971aa76ecae 100644 (file)
@@ -75,10 +75,8 @@ _060_isp_done:
 .Lnotkern:
        SAVE_ALL_INT
        GET_CURRENT(%d0)
-       tstb    %curptr@(TASK_NEEDRESCHED)
-       jne     ret_from_exception      | deliver signals,
-                                       | reschedule etc..
-       RESTORE_ALL
+       | deliver signals, reschedule etc..
+       jra     ret_from_exception
 
 |
 | _060_real_chk():
index cee3317b866505da52f3d3e5afe16abec5846f77..c787c5ba951310fe13f53e2e99d949c79f868e37 100644 (file)
@@ -25,12 +25,8 @@ int main(void)
        DEFINE(TASK_STATE, offsetof(struct task_struct, state));
        DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
        DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
-       DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
-       DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
-       DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
-       DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
-       DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
        DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+       DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
        DEFINE(TASK_MM, offsetof(struct task_struct, mm));
        DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
 
@@ -45,6 +41,10 @@ int main(void)
        DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
        DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
 
+       /* offsets into the thread_info struct */
+       DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
+       DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
+
        /* offsets into the pt_regs */
        DEFINE(PT_D0, offsetof(struct pt_regs, d0));
        DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
index 23ca60a4555249af81024a3d53b27ba2e8a28d03..320fde05dc631a646d7b51dee0c8fbf2ea6d65a5 100644 (file)
@@ -44,9 +44,7 @@
 
 #include <asm/asm-offsets.h>
 
-.globl system_call, buserr, trap
-.globl resume, ret_from_exception
-.globl ret_from_signal
+.globl system_call, buserr, trap, resume
 .globl inthandler, sys_call_table
 .globl sys_fork, sys_clone, sys_vfork
 .globl ret_from_interrupt, bad_interrupt
@@ -58,7 +56,7 @@ ENTRY(buserr)
        movel   %sp,%sp@-               | stack frame pointer argument
        bsrl    buserr_c
        addql   #4,%sp
-       jra     ret_from_exception
+       jra     .Lret_from_exception
 
 ENTRY(trap)
        SAVE_ALL_INT
@@ -66,7 +64,7 @@ ENTRY(trap)
        movel   %sp,%sp@-               | stack frame pointer argument
        bsrl    trap_c
        addql   #4,%sp
-       jra     ret_from_exception
+       jra     .Lret_from_exception
 
        | After a fork we jump here directly from resume,
        | so that %d1 contains the previous task
@@ -75,30 +73,31 @@ ENTRY(ret_from_fork)
        movel   %d1,%sp@-
        jsr     schedule_tail
        addql   #4,%sp
-       jra     ret_from_exception
+       jra     .Lret_from_exception
 
-badsys:
-       movel   #-ENOSYS,%sp@(PT_D0)
-       jra     ret_from_exception
-
-do_trace:
+do_trace_entry:
        movel   #-ENOSYS,%sp@(PT_D0)    | needed for strace
        subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
        RESTORE_SWITCH_STACK
        addql   #4,%sp
-       movel   %sp@(PT_ORIG_D0),%d1
-       movel   #-ENOSYS,%d0
-       cmpl    #NR_syscalls,%d1
-       jcc     1f
-       jbsr    @(sys_call_table,%d1:l:4)@(0)
-1:     movel   %d0,%sp@(PT_D0)         | save the return value
-       subql   #4,%sp                  | dummy return address
+       movel   %sp@(PT_ORIG_D0),%d0
+       cmpl    #NR_syscalls,%d0
+       jcs     syscall
+badsys:
+       movel   #-ENOSYS,%sp@(PT_D0)
+       jra     ret_from_syscall
+
+do_trace_exit:
+       subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       jra     .Lret_from_exception
 
-ret_from_signal:
+ENTRY(ret_from_signal)
        RESTORE_SWITCH_STACK
        addql   #4,%sp
 /* on 68040 complete pending writebacks if any */
@@ -111,7 +110,7 @@ ret_from_signal:
        addql   #4,%sp
 1:
 #endif
-       jra     ret_from_exception
+       jra     .Lret_from_exception
 
 ENTRY(system_call)
        SAVE_ALL_SYS
@@ -120,30 +119,34 @@ ENTRY(system_call)
        | save top of frame
        movel   %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
 
-       tstb    %curptr@(TASK_SYSCALL_TRACE)
-       jne     do_trace
+       | syscall trace?
+       tstb    %curptr@(TASK_INFO+TINFO_FLAGS+2)
+       jmi     do_trace_entry
        cmpl    #NR_syscalls,%d0
        jcc     badsys
+syscall:
        jbsr    @(sys_call_table,%d0:l:4)@(0)
        movel   %d0,%sp@(PT_D0)         | save the return value
-
+ret_from_syscall:
        |oriw   #0x0700,%sr
-       movel   %curptr@(TASK_WORK),%d0
+       movew   %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
        jne     syscall_exit_work
 1:     RESTORE_ALL
 
 syscall_exit_work:
        btst    #5,%sp@(PT_SR)          | check if returning to kernel
        bnes    1b                      | if so, skip resched, signals
-       tstw    %d0
-       jeq     do_signal_return
-       tstb    %d0
-       jne     do_delayed_trace
-
+       lslw    #1,%d0
+       jcs     do_trace_exit
+       jmi     do_delayed_trace
+       lslw    #8,%d0
+       jmi     do_signal_return
        pea     resume_userspace
-       jmp     schedule
+       jra     schedule
+
 
-ret_from_exception:
+ENTRY(ret_from_exception)
+.Lret_from_exception:
        btst    #5,%sp@(PT_SR)          | check if returning to kernel
        bnes    1f                      | if so, skip resched, signals
        | only allow interrupts when we are really the last one on the
@@ -152,19 +155,18 @@ ret_from_exception:
        andw    #ALLOWINT,%sr
 
 resume_userspace:
-       movel   %curptr@(TASK_WORK),%d0
-       lsrl    #8,%d0
+       moveb   %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
        jne     exit_work
 1:     RESTORE_ALL
 
 exit_work:
        | save top of frame
        movel   %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
-       tstb    %d0
-       jeq     do_signal_return
-
+       lslb    #1,%d0
+       jmi     do_signal_return
        pea     resume_userspace
-       jmp     schedule
+       jra     schedule
+
 
 do_signal_return:
        |andw   #ALLOWINT,%sr
@@ -254,7 +256,7 @@ ret_from_interrupt:
 
        /* check if we need to do software interrupts */
        tstl    irq_stat+CPUSTAT_SOFTIRQ_PENDING
-       jeq     ret_from_exception
+       jeq     .Lret_from_exception
        pea     ret_from_exception
        jra     do_softirq
 
index 7e54422685cfc1ed8737d29bac74124b3a4f8cdd..540638ca81f9832fe390b1f0b381d54ea7b2b20e 100644 (file)
@@ -109,7 +109,7 @@ static inline void singlestep_disable(struct task_struct *child)
 {
        unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
        put_reg(child, PT_SR, tmp);
-       child->thread.work.delayed_trace = 0;
+       clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
 }
 
 /*
@@ -118,7 +118,7 @@ static inline void singlestep_disable(struct task_struct *child)
 void ptrace_disable(struct task_struct *child)
 {
        singlestep_disable(child);
-       child->thread.work.syscall_trace = 0;
+       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -198,9 +198,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        goto out_eio;
 
                if (request == PTRACE_SYSCALL)
-                       child->thread.work.syscall_trace = ~0;
+                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                else
-                       child->thread.work.syscall_trace = 0;
+                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                child->exit_code = data;
                singlestep_disable(child);
                wake_up_process(child);
@@ -223,10 +223,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                if (!valid_signal(data))
                        goto out_eio;
 
-               child->thread.work.syscall_trace = 0;
+               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
                put_reg(child, PT_SR, tmp);
-               child->thread.work.delayed_trace = 1;
+               set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
 
                child->exit_code = data;
                /* give it a chance to run. */
@@ -288,9 +288,6 @@ out_eio:
 
 asmlinkage void syscall_trace(void)
 {
-       if (!current->thread.work.delayed_trace &&
-           !current->thread.work.syscall_trace)
-               return;
        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
                                 ? 0x80 : 0));
        /*
index f85093b8d54dca800e6f0e8a0cdfd5e5d3cfa23f..f4926315fb683feaae38234b06d150c6603946ad 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/jiffies.h>
index 0b21bed7ee553f5413253bc7808bc64b03f26ebb..2cab7629702c3f6b6066250c8c9bc8db2dd36241 100644 (file)
@@ -348,7 +348,7 @@ endpoint_stall(endpoint_t * ep)
 {
        u32 cs;
 
-       warn(__FUNCTION__);
+       warn("%s", __FUNCTION__);
 
        cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
        au_writel(cs, ep->reg->ctrl_stat);
@@ -360,7 +360,7 @@ endpoint_unstall(endpoint_t * ep)
 {
        u32 cs;
 
-       warn(__FUNCTION__);
+       warn("%s", __FUNCTION__);
 
        cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
        au_writel(cs, ep->reg->ctrl_stat);
index 5bc11bd36c1f8eba426466ba7e4b136ca51bb2aa..d41ad2e675dbace2c626b8881484558ba302a5fa 100644 (file)
@@ -187,7 +187,7 @@ archprepare: checkbin
 
 # Temporary hack until we have migrated to asm-powerpc
 include/asm: arch/$(ARCH)/include/asm
-arch/$(ARCH)/include/asm:
+arch/$(ARCH)/include/asm: FORCE
        $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
        $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
 
index 9f09dff9e11a5c5c2f0fc130985103d00cb5e4a1..913962c1dae0e727913f9d9599cd1f45ed2af77a 100644 (file)
@@ -1,18 +1,33 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc4
-# Thu Oct 20 08:32:17 2005
+# Linux kernel version: 2.6.15-rc1
+# Mon Nov 14 15:27:00 2005
 #
+CONFIG_PPC64=y
 CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
 
 #
 # Code maturity level options
@@ -68,75 +83,103 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
-CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
 
 #
 # Platform support
 #
-# CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
 CONFIG_PPC_PSERIES=y
-# CONFIG_PPC_BPA is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
-CONFIG_PPC=y
-CONFIG_PPC64=y
+# CONFIG_PPC_CELL is not set
 CONFIG_PPC_OF=y
 CONFIG_XICS=y
+# CONFIG_U3_DART is not set
 CONFIG_MPIC=y
-CONFIG_ALTIVEC=y
-CONFIG_PPC_SPLPAR=y
-CONFIG_KEXEC=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=m
+# CONFIG_MMIO_NVRAM is not set
 CONFIG_IBMVIO=y
-# CONFIG_U3_DART is not set
-# CONFIG_BOOTX_TEXT is not set
-# CONFIG_POWER4_ONLY is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_IOMMU_VMERGE=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=128
+CONFIG_HOTPLUG_CPU=y
+CONFIG_KEXEC=y
+# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_PPC_SPLPAR=y
+CONFIG_EEH=y
+CONFIG_SCANLOG=m
+CONFIG_LPARCFG=y
+CONFIG_NUMA=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM_MANUAL=y
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
 CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_NODES_SPAN_OTHER_NODES=y
-CONFIG_NUMA=y
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_PREEMPT_BKL is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_EEH=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_PPC_RTAS=y
-CONFIG_RTAS_PROC=y
-CONFIG_RTAS_FLASH=m
-CONFIG_SCANLOG=m
-CONFIG_LPARCFG=y
-CONFIG_SECCOMP=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_HOTPLUG_CPU=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus Options
+# Bus options
 #
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_LEGACY_PROC=y
@@ -156,6 +199,7 @@ CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
+CONFIG_KERNEL_START=0xc000000000000000
 
 #
 # Networking
@@ -197,6 +241,10 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 CONFIG_NETFILTER_NETLINK=y
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
@@ -299,6 +347,10 @@ CONFIG_LLC=y
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
 
@@ -368,14 +420,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=65536
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -473,6 +517,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -559,6 +604,7 @@ CONFIG_DM_MULTIPATH_EMC=m
 #
 # Macintosh device drivers
 #
+# CONFIG_WINDFARM is not set
 
 #
 # Network device support
@@ -645,7 +691,6 @@ CONFIG_IXGB=m
 # CONFIG_IXGB_NAPI is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
-# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -674,6 +719,7 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
@@ -784,6 +830,8 @@ CONFIG_HVCS=m
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -801,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=1024
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -852,6 +901,7 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -893,7 +943,6 @@ CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
@@ -905,6 +954,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
@@ -927,7 +977,6 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -936,6 +985,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -990,12 +1040,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1106,6 +1159,7 @@ CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+# CONFIG_INFINIBAND_SRP is not set
 
 #
 # SN Devices
@@ -1288,10 +1342,25 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_UTF8 is not set
 
 #
-# Profiling support
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+
+#
+# Instrumentation Support
 #
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
+# CONFIG_KPROBES is not set
 
 #
 # Kernel hacking
@@ -1308,14 +1377,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_KPROBES is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUGGER=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
-# CONFIG_PPCDBG is not set
 CONFIG_IRQSTACKS=y
+# CONFIG_BOOTX_TEXT is not set
 
 #
 # Security options
@@ -1355,17 +1425,3 @@ CONFIG_CRYPTO_TEST=m
 #
 # Hardware crypto devices
 #
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
index 9a74b7ab03a4ee7da46e3c839de790493dc6fffa..046b4bf1f21e306f986da556bce4909f0413d34d 100644 (file)
@@ -25,7 +25,7 @@ obj-$(CONFIG_PPC_OF)          += of_device.o
 procfs-$(CONFIG_PPC64)         := proc_ppc64.o
 obj-$(CONFIG_PROC_FS)          += $(procfs-y)
 rtaspci-$(CONFIG_PPC64)                := rtas_pci.o
-obj-$(CONFIG_PPC_RTAS)         += rtas.o $(rtaspci-y)
+obj-$(CONFIG_PPC_RTAS)         += rtas.o rtas-rtc.o $(rtaspci-y)
 obj-$(CONFIG_RTAS_FLASH)       += rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)                += rtas-proc.o
 obj-$(CONFIG_LPARCFG)          += lparcfg.o
index 4550eb4f4fbd48f2997c334f26ec8e54b262ef3d..91538d2445bfa2e29e60237439acd985c4f583a3 100644 (file)
@@ -270,13 +270,15 @@ int main(void)
        DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
        DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
        DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+       DEFINE(TSPC64_TV_SEC, offsetof(struct timespec, tv_sec));
+       DEFINE(TSPC64_TV_NSEC, offsetof(struct timespec, tv_nsec));
        DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec));
        DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
 #else
        DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
        DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
-       DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec));
-       DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
+       DEFINE(TSPC32_TV_SEC, offsetof(struct timespec, tv_sec));
+       DEFINE(TSPC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
 #endif
        /* timeval/timezone offsets for use by vdso */
        DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
index 5063c603fad441e56a92ee9ff3de3a165c11ab4f..8d60fa99fc4b992a402ec73dfa516b139f049d08 100644 (file)
@@ -24,7 +24,7 @@
  *    Copyright 2002-2004 MontaVista Software, Inc.
  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
  *    Copyright 2004 Freescale Semiconductor, Inc
- *      PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *      PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
  *
  * 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
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
new file mode 100644 (file)
index 0000000..7b94866
--- /dev/null
@@ -0,0 +1,105 @@
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/time.h>
+
+
+#define MAX_RTC_WAIT 5000      /* 5 sec */
+#define RTAS_CLOCK_BUSY (-2)
+unsigned long __init rtas_get_boot_time(void)
+{
+       int ret[8];
+       int error, wait_time;
+       unsigned long max_wait_tb;
+
+       max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+       do {
+               error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+                       wait_time = rtas_extended_busy_delay_time(error);
+                       /* This is boot time so we spin. */
+                       udelay(wait_time*1000);
+                       error = RTAS_CLOCK_BUSY;
+               }
+       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+       if (error != 0 && printk_ratelimit()) {
+               printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+                       error);
+               return 0;
+       }
+
+       return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
+}
+
+/* NOTE: get_rtc_time will get an error if executed in interrupt context
+ * and if a delay is needed to read the clock.  In this case we just
+ * silently return without updating rtc_tm.
+ */
+void rtas_get_rtc_time(struct rtc_time *rtc_tm)
+{
+        int ret[8];
+       int error, wait_time;
+       unsigned long max_wait_tb;
+
+       max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+       do {
+               error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+                       if (in_interrupt() && printk_ratelimit()) {
+                               memset(&rtc_tm, 0, sizeof(struct rtc_time));
+                               printk(KERN_WARNING "error: reading clock"
+                                      " would delay interrupt\n");
+                               return; /* delay not allowed */
+                       }
+                       wait_time = rtas_extended_busy_delay_time(error);
+                       msleep(wait_time);
+                       error = RTAS_CLOCK_BUSY;
+               }
+       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+        if (error != 0 && printk_ratelimit()) {
+                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+                      error);
+               return;
+        }
+
+       rtc_tm->tm_sec = ret[5];
+       rtc_tm->tm_min = ret[4];
+       rtc_tm->tm_hour = ret[3];
+       rtc_tm->tm_mday = ret[2];
+       rtc_tm->tm_mon = ret[1] - 1;
+       rtc_tm->tm_year = ret[0] - 1900;
+}
+
+int rtas_set_rtc_time(struct rtc_time *tm)
+{
+       int error, wait_time;
+       unsigned long max_wait_tb;
+
+       max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+       do {
+               error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
+                                 tm->tm_year + 1900, tm->tm_mon + 1,
+                                 tm->tm_mday, tm->tm_hour, tm->tm_min,
+                                 tm->tm_sec, 0);
+               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+                       if (in_interrupt())
+                               return 1;       /* probably decrementer */
+                       wait_time = rtas_extended_busy_delay_time(error);
+                       msleep(wait_time);
+                       error = RTAS_CLOCK_BUSY;
+               }
+       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+        if (error != 0 && printk_ratelimit())
+                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
+                      error);
+
+        return 0;
+}
index fdbd9f9122f2a69e5212aa30857e6330826cb5e5..608fee7c7e20621dcf829507e893cbaee4ea05da 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
+#include <asm/kexec.h>
 
 #include "setup.h"
 
@@ -415,6 +416,10 @@ void __init setup_system(void)
         */
        unflatten_device_tree();
 
+#ifdef CONFIG_KEXEC
+       kexec_setup();  /* requires unflattened device tree. */
+#endif
+
        /*
         * Fill the ppc64_caches & systemcfg structures with informations
         * retreived from the device-tree. Need to be called before
index a08c26e878350d869de74ae4acf105d5e8dc5a50..f6b38472318d64fb4c4c0ac3591c2d017670aca5 100644 (file)
@@ -77,8 +77,9 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
        mflr    r12
   .cfi_register lr,r12
        bl      __get_datapage@local
-       lwz     r3,CFG_TB_TICKS_PER_SEC(r3)
        lwz     r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
+       lwz     r3,CFG_TB_TICKS_PER_SEC(r3)
        mtlr    r12
+       blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
index aeb5fc9b87b3a317f211f9fda74b74f54c7ca4aa..0a32a41d50b0bcfba3158514c68b0822a7b626c8 100644 (file)
@@ -83,7 +83,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        /* Check for supported clock IDs */
        cmpli   cr0,r3,CLOCK_REALTIME
        cmpli   cr1,r3,CLOCK_MONOTONIC
-       cror    cr0,cr0,cr1
+       cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
        mflr    r12                     /* r12 saves lr */
@@ -91,7 +91,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        mr      r10,r3                  /* r10 saves id */
        mr      r11,r4                  /* r11 saves tp */
        bl      __get_datapage@local    /* get data page */
-       mr      r9, r3                  /* datapage ptr in r9 */
+       mr      r9,r3                   /* datapage ptr in r9 */
        beq     cr1,50f                 /* if monotonic -> jump there */
 
        /*
@@ -173,10 +173,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        add     r4,r4,r7
        lis     r5,NSEC_PER_SEC@h
        ori     r5,r5,NSEC_PER_SEC@l
-       cmpli   cr0,r4,r5
+       cmpl    cr0,r4,r5
+       cmpli   cr1,r4,0
        blt     1f
        subf    r4,r5,r4
        addi    r3,r3,1
+1:     bge     cr1,1f
+       addi    r3,r3,-1
+       add     r4,r4,r5
 1:     stw     r3,TSPC32_TV_SEC(r11)
        stw     r4,TSPC32_TV_NSEC(r11)
 
@@ -210,7 +214,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        /* Check for supported clock IDs */
        cmpwi   cr0,r3,CLOCK_REALTIME
        cmpwi   cr1,r3,CLOCK_MONOTONIC
-       cror    cr0,cr0,cr1
+       cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
        li      r3,0
index e67eda0f8cdab01aa38322300c3f014a32ff76e8..6393e4137bc7e3dfb0a1b82f0cb6e0c8bd72d95c 100644 (file)
@@ -80,5 +80,6 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
        bl      V_LOCAL_FUNC(__get_datapage)
        ld      r3,CFG_TB_TICKS_PER_SEC(r3)
        mtlr    r12
+       blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
index d371c02a8c0e3f47e295aa30f4d8f001dd8279ab..1a89094715cca61a5221079334c9f1ada796b5da 100644 (file)
@@ -1,4 +1,5 @@
-/*
+
+       /*
  * Userland implementation of gettimeofday() for 64 bits processes in a
  * ppc64 kernel for use in the vDSO
  *
@@ -68,7 +69,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        /* Check for supported clock IDs */
        cmpwi   cr0,r3,CLOCK_REALTIME
        cmpwi   cr1,r3,CLOCK_MONOTONIC
-       cror    cr0,cr0,cr1
+       cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
        mflr    r12                     /* r12 saves lr */
@@ -84,16 +85,17 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 
        bl      V_LOCAL_FUNC(__do_get_xsec)     /* get xsec from tb & kernel */
 
-       lis     r7,0x3b9a               /* r7 = 1000000000 = NSEC_PER_SEC */
-       ori     r7,r7,0xca00
+       lis     r7,15                   /* r7 = 1000000 = USEC_PER_SEC */
+       ori     r7,r7,16960
        rldicl  r5,r4,44,20             /* r5 = sec = xsec / XSEC_PER_SEC */
        rldicr  r6,r5,20,43             /* r6 = sec * XSEC_PER_SEC */
        std     r5,TSPC64_TV_SEC(r11)   /* store sec in tv */
        subf    r0,r6,r4                /* r0 = xsec = (xsec - r6) */
-       mulld   r0,r0,r7                /* nsec = (xsec * NSEC_PER_SEC) /
+       mulld   r0,r0,r7                /* usec = (xsec * USEC_PER_SEC) /
                                         * XSEC_PER_SEC
                                         */
        rldicl  r0,r0,44,20
+       mulli   r0,r0,1000              /* nsec = usec * 1000 */
        std     r0,TSPC64_TV_NSEC(r11)  /* store nsec in tp */
 
        mtlr    r12
@@ -106,15 +108,16 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 
 50:    bl      V_LOCAL_FUNC(__do_get_xsec)     /* get xsec from tb & kernel */
 
-       lis     r7,0x3b9a               /* r7 = 1000000000 = NSEC_PER_SEC */
-       ori     r7,r7,0xca00
+       lis     r7,15                   /* r7 = 1000000 = USEC_PER_SEC */
+       ori     r7,r7,16960
        rldicl  r5,r4,44,20             /* r5 = sec = xsec / XSEC_PER_SEC */
        rldicr  r6,r5,20,43             /* r6 = sec * XSEC_PER_SEC */
        subf    r0,r6,r4                /* r0 = xsec = (xsec - r6) */
-       mulld   r0,r0,r7                /* nsec = (xsec * NSEC_PER_SEC) /
+       mulld   r0,r0,r7                /* usec = (xsec * USEC_PER_SEC) /
                                         * XSEC_PER_SEC
                                         */
        rldicl  r6,r0,44,20
+       mulli   r6,r6,1000              /* nsec = usec * 1000 */
 
        /* now we must fixup using wall to monotonic. We need to snapshot
         * that value and do the counter trick again. Fortunately, we still
@@ -123,8 +126,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
         * can be used
         */
 
-       lwz     r4,WTOM_CLOCK_SEC(r9)
-       lwz     r7,WTOM_CLOCK_NSEC(r9)
+       lwa     r4,WTOM_CLOCK_SEC(r3)
+       lwa     r7,WTOM_CLOCK_NSEC(r3)
 
        /* We now have our result in r4,r7. We create a fake dependency
         * on that result and re-check the counter
@@ -144,10 +147,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        add     r7,r7,r6
        lis     r9,NSEC_PER_SEC@h
        ori     r9,r9,NSEC_PER_SEC@l
-       cmpli   cr0,r7,r9
+       cmpl    cr0,r7,r9
+       cmpli   cr1,r7,0
        blt     1f
        subf    r7,r9,r7
        addi    r4,r4,1
+1:     bge     cr1,1f
+       addi    r4,r4,-1
+       add     r7,r7,r9
 1:     std     r4,TSPC64_TV_SEC(r11)
        std     r7,TSPC64_TV_NSEC(r11)
 
@@ -181,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        /* Check for supported clock IDs */
        cmpwi   cr0,r3,CLOCK_REALTIME
        cmpwi   cr1,r3,CLOCK_MONOTONIC
-       cror    cr0,cr0,cr1
+       cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
        bne     cr0,99f
 
        li      r3,0
index af9ca0eb6d55b6aba7fd0903371cbeef313c2199..5d581bb3aa1249fa8826fe16a648f818c3f33cae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
  * Copyright 2004 Freescale Semiconductor, Inc
index 86124a94c9afbb8aea10ef6fce4e5e61639d7d25..26539cda602360ed1438b212ff6893e3a33d2818 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2004 Freescale Semiconductor, Inc
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala <Kumar.Gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
index 5947b21a8588251ec47af261841b7a2c3fe5d033..b1714f9bd920212856791b422011d1a8940ae41f 100644 (file)
@@ -102,7 +102,7 @@ static unsigned long from_rtc_time(struct rtc_time *tm)
 static unsigned long cuda_get_time(void)
 {
        struct adb_request req;
-       unsigned long now;
+       unsigned int now;
 
        if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
                return 0;
@@ -113,7 +113,7 @@ static unsigned long cuda_get_time(void)
                       req.reply_len);
        now = (req.reply[3] << 24) + (req.reply[4] << 16)
                + (req.reply[5] << 8) + req.reply[6];
-       return now - RTC_OFFSET;
+       return ((unsigned long)now) - RTC_OFFSET;
 }
 
 #define cuda_get_rtc_time(tm)  to_rtc_time(cuda_get_time(), (tm))
@@ -146,7 +146,7 @@ static int cuda_set_rtc_time(struct rtc_time *tm)
 static unsigned long pmu_get_time(void)
 {
        struct adb_request req;
-       unsigned long now;
+       unsigned int now;
 
        if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
                return 0;
@@ -156,7 +156,7 @@ static unsigned long pmu_get_time(void)
                       req.reply_len);
        now = (req.reply[0] << 24) + (req.reply[1] << 16)
                + (req.reply[2] << 8) + req.reply[3];
-       return now - RTC_OFFSET;
+       return ((unsigned long)now) - RTC_OFFSET;
 }
 
 #define pmu_get_rtc_time(tm)   to_rtc_time(pmu_get_time(), (tm))
@@ -199,7 +199,7 @@ static unsigned long smu_get_time(void)
 #define smu_set_rtc_time(tm, spin)     0
 #endif
 
-unsigned long pmac_get_boot_time(void)
+unsigned long __init pmac_get_boot_time(void)
 {
        /* Get the time from the RTC, used only at boot time */
        switch (sys_ctrler) {
index 31990829310c325716c6cad160863f8ee0847c6b..b9d9732b2e0668fc06f797590d893ee76eb7416c 100644 (file)
@@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(void)
        if (ppc64_interrupt_controller == IC_OPEN_PIC) {
                ppc_md.init_IRQ       = pSeries_init_mpic;
                ppc_md.get_irq        = mpic_get_irq;
-               ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
                /* Allocate the mpic now, so that find_and_init_phbs() can
                 * fill the ISUs */
                pSeries_setup_mpic();
        } else {
                ppc_md.init_IRQ       = xics_init_IRQ;
                ppc_md.get_irq        = xics_get_irq;
-               ppc_md.cpu_irq_down   = xics_teardown_cpu;
        }
 
 #ifdef CONFIG_SMP
@@ -595,6 +593,27 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
        return PCI_PROBE_NORMAL;
 }
 
+#ifdef CONFIG_KEXEC
+static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+       /* Don't risk a hypervisor call if we're crashing */
+       if (!crash_shutdown) {
+               unsigned long vpa = __pa(&get_paca()->lppaca);
+
+               if (unregister_vpa(hard_smp_processor_id(), vpa)) {
+                       printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
+                                       "failed\n", smp_processor_id(),
+                                       hard_smp_processor_id());
+               }
+       }
+
+       if (ppc64_interrupt_controller == IC_OPEN_PIC)
+               mpic_teardown_this_cpu(secondary);
+       else
+               xics_teardown_cpu(secondary);
+}
+#endif
+
 struct machdep_calls __initdata pSeries_md = {
        .probe                  = pSeries_probe,
        .setup_arch             = pSeries_setup_arch,
@@ -617,4 +636,7 @@ struct machdep_calls __initdata pSeries_md = {
        .check_legacy_ioport    = pSeries_check_legacy_ioport,
        .system_reset_exception = pSeries_system_reset_exception,
        .machine_check_exception = pSeries_machine_check_exception,
+#ifdef CONFIG_KEXEC
+       .kexec_cpu_down         = pseries_kexec_cpu_down,
+#endif
 };
index ef4356b29a979ff08459c9c500dd5d9a93fdded6..c45a6ad5f3b75d55dfe0d44a78b5dd255bb7ffde 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpumask.h>
 #include <linux/module.h>
 #include <linux/sysrq.h>
+#include <linux/interrupt.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
index 5063c603fad441e56a92ee9ff3de3a165c11ab4f..8d60fa99fc4b992a402ec73dfa516b139f049d08 100644 (file)
@@ -24,7 +24,7 @@
  *    Copyright 2002-2004 MontaVista Software, Inc.
  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
  *    Copyright 2004 Freescale Semiconductor, Inc
- *      PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *      PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
  *
  * 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
index af9ca0eb6d55b6aba7fd0903371cbeef313c2199..5d581bb3aa1249fa8826fe16a648f818c3f33cae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
  * Copyright 2004 Freescale Semiconductor, Inc
index 98edc75f4105b22149a967b3dfd624ffee64e766..04bdc39bf47b473f762ffbfc8d4a3d58c70671d9 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC834x SYS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
@@ -73,12 +73,19 @@ mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
             *       A      B      C      D
             */
        {
-               {PIRQA, PIRQB,  PIRQC,  PIRQD}, /* idsel 0x11 */
-               {PIRQC, PIRQD,  PIRQA,  PIRQB}, /* idsel 0x12 */
-               {PIRQD, PIRQA,  PIRQB,  PIRQC}  /* idsel 0x13 */
+               {PIRQA, PIRQB, PIRQC, PIRQD},   /* idsel 0x11 */
+               {PIRQC, PIRQD, PIRQA, PIRQB},   /* idsel 0x12 */
+               {PIRQD, PIRQA, PIRQB, PIRQC},   /* idsel 0x13 */
+               {0, 0, 0, 0},
+               {PIRQA, PIRQB, PIRQC, PIRQD},   /* idsel 0x15 */
+               {PIRQD, PIRQA, PIRQB, PIRQC},   /* idsel 0x16 */
+               {PIRQC, PIRQD, PIRQA, PIRQB},   /* idsel 0x17 */
+               {PIRQB, PIRQC, PIRQD, PIRQA},   /* idsel 0x18 */
+               {0, 0, 0, 0},                   /* idsel 0x19 */
+               {0, 0, 0, 0},                   /* idsel 0x20 */
        };
 
-       const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
+       const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
        return PCI_IRQ_TABLE_LOOKUP;
 }
 
index 58e44c042535bb6a11d2ab3bb6b1bb559ead4e7b..2e514d316fb85c3f651bd001d95923483390bd8d 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC834X SYS common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc.
  *
index 7e952c1228cba50c4cd3823e4612f4b0ef7705ca..c5cde97c6ef00b2832a9949c884b977d83578ba7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 3d05d7c4a938f2a36d54a3f3cd18de77c69ccf17..e48ca3a97397c37fdf80c71af2e3730b28767f76 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index e0e75568bc579213089e01eb71245588f1fad487..1a8e6c67355d67771651b61e7ec978df38501c15 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8555CDS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 208433f1e93ae32a1bcf207073374146da8ef6a0..8e39a551709292fd8935d88a9c8591110cb42068 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8560ADS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 7df885d73e9dc558f5dd4eb4a7843d20ea2794cd..143ae7eefa7c501341c5a3ce1c64ddb9be8ceb25 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 16ad092d8a06396a4ffed0f44037c5dce99a44ec..17ce48fe3503e8ad4d5c54bd57dba949cdaaf36b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx ADS board common routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 84acf6e8d45ef895e02b02ed753a0514bf91fe8a..7b26bcc5d10d146cebc3befa7eefe600bf0fdde8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85XX ADS common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index a21156967a5e130ea0ca70f76c9503965156edff..d8991b88dc9c531692584548fc601eafe898a7c0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx CDS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
index 12b292c6ae3225bb41eeea720de35a8770bdca0a..5b588cfd0e41bc16c3b102b685d4f11eb852546d 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx CDS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
index b4ee1707a836ce81693f4eae22d8bc5efae75a2d..45a5b81b4ed1ae4da5e81fa88fe280ea930b3401 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * Wind River SBC8560 board specific routines
  * 
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  * 
index 58884a63ebdbed4983e509ff3d24dec6fe045468..1e69b05931620a2f1420adea43a27cac67644f6b 100644 (file)
@@ -2317,6 +2317,14 @@ static struct pmac_mb_def pmac_mb_defs[] = {
                PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
                PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
        },
+       {       "PowerBook5,8",                 "PowerBook G4 15\"",
+               PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
+               PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+       },
+       {       "PowerBook5,9",                 "PowerBook G4 17\"",
+               PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
+               PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+       },
        {       "PowerBook6,1",                 "PowerBook G4 12\"",
                PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
                PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
index 6a1475c1e128ea30e39628c684fbea415963535d..71c9fca1fe9b9d4ce293e2793dcfe0a943cf04be 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PQ2ADS platform support
  *
- * Author: Kumar Gala <kumar.gala@freescale.com>
+ * Author: Kumar Gala <galak@kernel.crashing.org>
  * Derived from: est8260_setup.c by Allen Curtis
  *
  * Copyright 2004 Freescale Semiconductor, Inc.
index 2b56a4fcf373e1e5e7a0aaa2ae03ae0c88f25058..a7ce7da8785c4c2ef256dd8144f9e2aa4cff7126 100644 (file)
@@ -3,7 +3,7 @@
  *
  * IPIC private definitions and structure.
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc
  *
index f43fbf9a9389c05cbc4e6303c35f7d64a5909ce7..847df4409982af4298af2852920127ab28c2bfee 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC83xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index da743446789b01882ae9375adc55145538e2b48c..a1523989aff4dfed46b9021aeb99e5cc235325d0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC83xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index 2ede677a0a53c37d24ad208a8a9447f7acb195b7..69949d255658c93b76fb24d3d6e52df6f7479a34 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index cb68d8c58348528d98a4414f7d607fe5c4ced4cf..397cfbcce5ea10b88e4834385415809de26b4c0e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index 2b5f0e70168717ed1ceafd8fee0912d9282d746f..92dc98b36bdeffb3145d4a2057bb0eb975db5235 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.com>
  *
index 3cc27d29e3af64e59fdf3a78d0549dfd6ac78070..d3c61752160398411682e2f0986c9461305ce1b4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC8xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
index 4da168a6ad0310777403b52b35ac3a9068963d97..1b5fe9e398d405b353d68018dbf1641b2ae37e6c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC83XX common board code
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index c766c1a5f786d62fee8413145563cf5634e0627d..a122a7322e5eeda3d5c1457985e3aea0a213b16c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC83XX common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
index da841dacdc135175b92c6ff0d23be212bdf18655..19ad537225e4340c4c49485e082490144ecbd0ac 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx support routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 2c8f304441bfcb943cd6ab4be5f32172d8c7e3b9..94edf32151dda0a80de4193d3a1550d41783562d 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85xx support routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index de2f90576577198d6019374173dc5e98192e6b89..1a47ff4b831d3d75e33eca61669c3fe869ea79cd 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85XX common board code
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 6e6cfe162faf9b28bb6bd8fb043bef07ae92abc7..e340b0545fb5e2bbc7842ecba8066c75ccac53bf 100644 (file)
@@ -3,7 +3,7 @@
  *
  * MPC85XX common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
index 603f0119081602e866d83324acf09f7c7a93808d..c0b93c4191eeac2b73e1803b1646bb61f61e4e3c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PPC System library functions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
index e960fe9353256b82e611da8226988d679b2ba433..6ff3aab82fc3374c362951b82ab70d36315e3c16 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PQ2 Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
index 7b6c9ebdb9e3eaac47bda5c78fb46171586210ea..36d6e217994019200f0ccb390a8ac47e88721c6f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PQ2 System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
index dac4cc20fa939af64fdec5502df18e8f68142c36..d0edea503c49e78af5cd849bcce5a24493ce18b9 100644 (file)
@@ -13,7 +13,6 @@ endif
 
 obj-y               += idle.o dma.o \
                        align.o \
-                       rtc.o \
                        iommu.o
 
 pci-obj-$(CONFIG_PPC_MULTIPLATFORM)    += pci_dn.o pci_direct_iommu.o
index 07ea03598c004774cfed9fde43bf0c587592eec8..97c51e452be74c16fb8cfca957c8ca5b7bf00f75 100644 (file)
@@ -185,8 +185,8 @@ void kexec_copy_flush(struct kimage *image)
  */
 void kexec_smp_down(void *arg)
 {
-       if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down(1);
+       if (ppc_md.kexec_cpu_down)
+               ppc_md.kexec_cpu_down(0, 1);
 
        local_irq_disable();
        kexec_smp_wait();
@@ -233,8 +233,8 @@ static void kexec_prepare_cpus(void)
        }
 
        /* after we tell the others to go down */
-       if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down(0);
+       if (ppc_md.kexec_cpu_down)
+               ppc_md.kexec_cpu_down(0, 0);
 
        put_cpu();
 
@@ -255,8 +255,8 @@ static void kexec_prepare_cpus(void)
         * UP to an SMP kernel.
         */
        smp_release_cpus();
-       if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down(0);
+       if (ppc_md.kexec_cpu_down)
+               ppc_md.kexec_cpu_down(0, 0);
        local_irq_disable();
 }
 
@@ -305,3 +305,54 @@ void machine_kexec(struct kimage *image)
                        ppc_md.hpte_clear_all);
        /* NOTREACHED */
 }
+
+/* Values we need to export to the second kernel via the device tree. */
+static unsigned long htab_base, htab_size, kernel_end;
+
+static struct property htab_base_prop = {
+       .name = "linux,htab-base",
+       .length = sizeof(unsigned long),
+       .value = (unsigned char *)&htab_base,
+};
+
+static struct property htab_size_prop = {
+       .name = "linux,htab-size",
+       .length = sizeof(unsigned long),
+       .value = (unsigned char *)&htab_size,
+};
+
+static struct property kernel_end_prop = {
+       .name = "linux,kernel-end",
+       .length = sizeof(unsigned long),
+       .value = (unsigned char *)&kernel_end,
+};
+
+static void __init export_htab_values(void)
+{
+       struct device_node *node;
+
+       node = of_find_node_by_path("/chosen");
+       if (!node)
+               return;
+
+       kernel_end = __pa(_end);
+       prom_add_property(node, &kernel_end_prop);
+
+       /* On machines with no htab htab_address is NULL */
+       if (NULL == htab_address)
+               goto out;
+
+       htab_base = __pa(htab_address);
+       prom_add_property(node, &htab_base_prop);
+
+       htab_size = 1UL << ppc64_pft_size;
+       prom_add_property(node, &htab_size_prop);
+
+ out:
+       of_node_put(node);
+}
+
+void __init kexec_setup(void)
+{
+       export_htab_values();
+}
index fbad2c360784edaa0d181812fdf0f8af39730c7e..47cc26e78957168500a5b22a7b598a25f156dc9c 100644 (file)
@@ -1261,6 +1261,7 @@ prom_n_addr_cells(struct device_node* np)
        /* No #address-cells property for the root node, default to 1 */
        return 1;
 }
+EXPORT_SYMBOL_GPL(prom_n_addr_cells);
 
 int
 prom_n_size_cells(struct device_node* np)
@@ -1276,6 +1277,7 @@ prom_n_size_cells(struct device_node* np)
        /* No #size-cells property for the root node, default to 1 */
        return 1;
 }
+EXPORT_SYMBOL_GPL(prom_n_size_cells);
 
 /**
  * Work out the sense (active-low level / active-high edge)
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
deleted file mode 100644 (file)
index 79e7ed2..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- *     Real Time Clock interface for PPC64.
- *
- *     Based on rtc.c by Paul Gortmaker
- *
- *     This driver allows use of the real time clock
- *     from user space. It exports the /dev/rtc
- *     interface supporting various ioctl() and also the
- *     /proc/driver/rtc pseudo-file for status information.
- *
- *     Interface does not support RTC interrupts nor an alarm.
- *
- *     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.
- *
- *      1.0    Mike Corrigan:    IBM iSeries rtc support
- *      1.1    Dave Engebretsen: IBM pSeries rtc support
- */
-
-#define RTC_VERSION            "1.1"
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/mc146818rtc.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/bcd.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/time.h>
-#include <asm/rtas.h>
-
-#include <asm/machdep.h>
-
-/*
- *     We sponge a minor off of the misc major. No need slurping
- *     up another valuable major dev number for this. If you add
- *     an ioctl, make sure you don't conflict with SPARC's RTC
- *     ioctls.
- */
-
-static ssize_t rtc_read(struct file *file, char __user *buf,
-                       size_t count, loff_t *ppos);
-
-static int rtc_ioctl(struct inode *inode, struct file *file,
-                    unsigned int cmd, unsigned long arg);
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-
-/*
- *     If this driver ever becomes modularised, it will be really nice
- *     to make the epoch retain its value across module reload...
- */
-
-static unsigned long epoch = 1900;     /* year corresponding to 0x00   */
-
-static const unsigned char days_in_mo[] = 
-{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/*
- *     Now all the various file operations that we export.
- */
-
-static ssize_t rtc_read(struct file *file, char __user *buf,
-                       size_t count, loff_t *ppos)
-{
-       return -EIO;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg)
-{
-       struct rtc_time wtime; 
-
-       switch (cmd) {
-       case RTC_RD_TIME:       /* Read the time/date from RTC  */
-       {
-               memset(&wtime, 0, sizeof(struct rtc_time));
-               ppc_md.get_rtc_time(&wtime);
-               break;
-       }
-       case RTC_SET_TIME:      /* Set the RTC */
-       {
-               struct rtc_time rtc_tm;
-               unsigned char mon, day, hrs, min, sec, leap_yr;
-               unsigned int yrs;
-
-               if (!capable(CAP_SYS_TIME))
-                       return -EACCES;
-
-               if (copy_from_user(&rtc_tm, (struct rtc_time __user *)arg,
-                                  sizeof(struct rtc_time)))
-                       return -EFAULT;
-
-               yrs = rtc_tm.tm_year;
-               mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
-               day = rtc_tm.tm_mday;
-               hrs = rtc_tm.tm_hour;
-               min = rtc_tm.tm_min;
-               sec = rtc_tm.tm_sec;
-
-               if (yrs < 70)
-                       return -EINVAL;
-
-               leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
-               if ((mon > 12) || (day == 0))
-                       return -EINVAL;
-
-               if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-                       return -EINVAL;
-                       
-               if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-                       return -EINVAL;
-
-               if ( yrs > 169 )
-                       return -EINVAL;
-
-               ppc_md.set_rtc_time(&rtc_tm);
-               
-               return 0;
-       }
-       case RTC_EPOCH_READ:    /* Read the epoch.      */
-       {
-               return put_user (epoch, (unsigned long __user *)arg);
-       }
-       case RTC_EPOCH_SET:     /* Set the epoch.       */
-       {
-               /* 
-                * There were no RTC clocks before 1900.
-                */
-               if (arg < 1900)
-                       return -EINVAL;
-
-               if (!capable(CAP_SYS_TIME))
-                       return -EACCES;
-
-               epoch = arg;
-               return 0;
-       }
-       default:
-               return -EINVAL;
-       }
-       return copy_to_user((void __user *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-       nonseekable_open(inode, file);
-       return 0;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-/*
- *     The various file operations we support.
- */
-static struct file_operations rtc_fops = {
-       .owner =        THIS_MODULE,
-       .llseek =       no_llseek,
-       .read =         rtc_read,
-       .ioctl =        rtc_ioctl,
-       .open =         rtc_open,
-       .release =      rtc_release,
-};
-
-static struct miscdevice rtc_dev = {
-       .minor =        RTC_MINOR,
-       .name =         "rtc",
-       .fops =         &rtc_fops
-};
-
-static int __init rtc_init(void)
-{
-       int retval;
-
-       retval = misc_register(&rtc_dev);
-       if(retval < 0)
-               return retval;
-
-#ifdef CONFIG_PROC_FS
-       if (create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)
-                       == NULL) {
-               misc_deregister(&rtc_dev);
-               return -ENOMEM;
-       }
-#endif
-
-       printk(KERN_INFO "i/pSeries Real Time Clock Driver v" RTC_VERSION "\n");
-
-       return 0;
-}
-
-static void __exit rtc_exit (void)
-{
-       remove_proc_entry ("driver/rtc", NULL);
-       misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_init);
-module_exit(rtc_exit);
-
-/*
- *     Info exported via "/proc/driver/rtc".
- */
-
-static int rtc_proc_output (char *buf)
-{
-       
-       char *p;
-       struct rtc_time tm;
-       
-       p = buf;
-
-       ppc_md.get_rtc_time(&tm);
-
-       /*
-        * There is no way to tell if the luser has the RTC set for local
-        * time or for Universal Standard Time (GMT). Probably local though.
-        */
-       p += sprintf(p,
-                    "rtc_time\t: %02d:%02d:%02d\n"
-                    "rtc_date\t: %04d-%02d-%02d\n"
-                    "rtc_epoch\t: %04lu\n",
-                    tm.tm_hour, tm.tm_min, tm.tm_sec,
-                    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-
-       p += sprintf(p,
-                    "DST_enable\t: no\n"
-                    "BCD\t\t: yes\n"
-                    "24hr\t\t: yes\n" );
-
-       return  p - buf;
-}
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
-{
-        int len = rtc_proc_output (page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-#ifdef CONFIG_PPC_RTAS
-#define MAX_RTC_WAIT 5000      /* 5 sec */
-#define RTAS_CLOCK_BUSY (-2)
-unsigned long rtas_get_boot_time(void)
-{
-       int ret[8];
-       int error, wait_time;
-       unsigned long max_wait_tb;
-
-       max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-       do {
-               error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-                       wait_time = rtas_extended_busy_delay_time(error);
-                       /* This is boot time so we spin. */
-                       udelay(wait_time*1000);
-                       error = RTAS_CLOCK_BUSY;
-               }
-       } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-       if (error != 0 && printk_ratelimit()) {
-               printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-                       error);
-               return 0;
-       }
-
-       return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
-}
-
-/* NOTE: get_rtc_time will get an error if executed in interrupt context
- * and if a delay is needed to read the clock.  In this case we just
- * silently return without updating rtc_tm.
- */
-void rtas_get_rtc_time(struct rtc_time *rtc_tm)
-{
-        int ret[8];
-       int error, wait_time;
-       unsigned long max_wait_tb;
-
-       max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-       do {
-               error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-                       if (in_interrupt() && printk_ratelimit()) {
-                               printk(KERN_WARNING "error: reading clock would delay interrupt\n");
-                               return; /* delay not allowed */
-                       }
-                       wait_time = rtas_extended_busy_delay_time(error);
-                       msleep_interruptible(wait_time);
-                       error = RTAS_CLOCK_BUSY;
-               }
-       } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-        if (error != 0 && printk_ratelimit()) {
-                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-                      error);
-               return;
-        }
-
-       rtc_tm->tm_sec = ret[5];
-       rtc_tm->tm_min = ret[4];
-       rtc_tm->tm_hour = ret[3];
-       rtc_tm->tm_mday = ret[2];
-       rtc_tm->tm_mon = ret[1] - 1;
-       rtc_tm->tm_year = ret[0] - 1900;
-}
-
-int rtas_set_rtc_time(struct rtc_time *tm)
-{
-       int error, wait_time;
-       unsigned long max_wait_tb;
-
-       max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-       do {
-               error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
-                                 tm->tm_year + 1900, tm->tm_mon + 1, 
-                                 tm->tm_mday, tm->tm_hour, tm->tm_min, 
-                                 tm->tm_sec, 0);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-                       if (in_interrupt())
-                               return 1;       /* probably decrementer */
-                       wait_time = rtas_extended_busy_delay_time(error);
-                       msleep_interruptible(wait_time);
-                       error = RTAS_CLOCK_BUSY;
-               }
-       } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-        if (error != 0 && printk_ratelimit())
-                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
-                      error); 
-
-        return 0;
-}
-#endif
index 2e64e8c3e8e54c1aafbe66e34d3d64cf0f96f895..cb3cf0f228221154a2dd5e658b8550733a966866 100644 (file)
@@ -37,17 +37,43 @@ int __atomic_add_return(int i, atomic_t *v)
        spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
        return ret;
 }
+EXPORT_SYMBOL(__atomic_add_return);
 
-void atomic_set(atomic_t *v, int i)
+int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
+       int ret;
        unsigned long flags;
+
        spin_lock_irqsave(ATOMIC_HASH(v), flags);
+       ret = v->counter;
+       if (likely(ret == old))
+               v->counter = new;
 
-       v->counter = i;
+       spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+       return ret;
+}
+
+int atomic_add_unless(atomic_t *v, int a, int u)
+{
+       int ret;
+       unsigned long flags;
 
+       spin_lock_irqsave(ATOMIC_HASH(v), flags);
+       ret = v->counter;
+       if (ret != u)
+               v->counter += a;
        spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+       return ret != u;
 }
 
-EXPORT_SYMBOL(__atomic_add_return);
-EXPORT_SYMBOL(atomic_set);
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+/* Atomic operations are already serializing */
+void atomic_set(atomic_t *v, int i)
+{
+       unsigned long flags;
 
+       spin_lock_irqsave(ATOMIC_HASH(v), flags);
+       v->counter = i;
+       spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+}
+EXPORT_SYMBOL(atomic_set);
index 94b05e8c906c78ca4701ccb766573f01b2798c75..2e168d16547f93234602de95762346a727b730d8 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/smp_lock.h>
+#include <linux/string.h>
 #include <linux/bitops.h>
 
 #include <asm/bitext.h>
index 3b5f47c469073df1ca4b0bac35bc06dff2aaaeaf..563301fe5df8bbfb4bfd5680e5489d23b91e0ba4 100644 (file)
@@ -7,7 +7,6 @@ config UML
        bool
        default y
 
-# XXX: does UM have a mmu/swap?
 config MMU
        bool
        default y
@@ -36,12 +35,6 @@ config IRQ_RELEASE_METHOD
        bool
        default y
 
-menu "Host processor type and features"
-
-source "arch/i386/Kconfig.cpu"
-
-endmenu
-
 menu "UML-specific options"
 
 config MODE_TT
@@ -209,7 +202,8 @@ config MAGIC_SYSRQ
 config SMP
        bool "Symmetric multi-processing support (EXPERIMENTAL)"
        default n
-       depends on (MODE_TT && EXPERIMENTAL && !SMP_BROKEN) || (BROKEN && SMP_BROKEN)
+       #SMP_BROKEN is for x86_64.
+       depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
        help
        This option enables UML SMP support.
        It is NOT related to having a real SMP box. Not directly, at least.
index 5d92cacd56c6a71cddf0c88026d7788fedbd3e39..c71b39a677aa49b41bab93ffaf7374800948abb0 100644 (file)
@@ -1,3 +1,9 @@
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
 config UML_X86
        bool
        default y
@@ -42,7 +48,3 @@ config ARCH_HAS_SC_SIGNALS
 config ARCH_REUSE_HOST_VSYSCALL_AREA
        bool
        default y
-
-config X86_CMPXCHG
-       bool
-       default y
index 1f7dcb064aee65602eac0d5fbb18cc77aad6754e..7a0e04e34bf96f2cb4a89a6be34cfbe8f1e6cf90 100644 (file)
@@ -35,4 +35,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
 
 CFLAGS += $(cflags-y)
 USER_CFLAGS += $(cflags-y)
-
index 16e7dc89f61d78e2508b71a3c6cb2bb046c09785..5b58fad45290fc8ad26c50034979224389e16cda 100644 (file)
@@ -89,8 +89,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
        return(-EIO);
 }
 
-static int not_configged_console_write(int fd, const char *buf, int len,
-                                      void *data)
+static int not_configged_console_write(int fd, const char *buf, int len)
 {
        my_puts("Using a channel type which is configured out of "
               "UML\n");
@@ -299,7 +298,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
                chan = list_entry(ele, struct chan, list);
                if(!chan->output || (chan->ops->console_write == NULL))
                        continue;
-               n = chan->ops->console_write(chan->fd, buf, len, chan->data);
+               n = chan->ops->console_write(chan->fd, buf, len);
                if(chan->primary) ret = n;
        }
        return(ret);
index 1c55d580248993c9ef1dd7249ccf8bb8e548c745..5d50d4a44abf4879220e045b9eaecf0d48d8f9d7 100644 (file)
@@ -20,7 +20,7 @@
 #include "choose-mode.h"
 #include "mode.h"
 
-int generic_console_write(int fd, const char *buf, int n, void *unused)
+int generic_console_write(int fd, const char *buf, int n)
 {
        struct termios save, new;
        int err;
index c1b03f7c1daa962195a6e8ee26d09580abfab615..1bb085b2824d19e25e88ce4e931bcfba25f07a76 100644 (file)
@@ -98,7 +98,7 @@ static int connect_to_switch(struct daemon_data *pri)
                printk("daemon_open : control setup request failed, err = %d\n",
                       -n);
                err = -ENOTCONN;
-               goto out;               
+               goto out_free;
        }
 
        n = os_read_file(pri->control, sun, sizeof(*sun));
@@ -106,12 +106,14 @@ static int connect_to_switch(struct daemon_data *pri)
                printk("daemon_open : read of data socket failed, err = %d\n",
                       -n);
                err = -ENOTCONN;
-               goto out_close;         
+               goto out_free;
        }
 
        pri->data_addr = sun;
        return(fd);
 
+ out_free:
+       kfree(sun);
  out_close:
        os_close_file(fd);
  out:
index f0b888f66e0561ad3f73af964428f0d42c96e674..3296e86a03a5cd3a197007c1593e127fee3c1d7c 100644 (file)
@@ -76,13 +76,6 @@ static void fd_close(int fd, void *d)
        }
 }
 
-static int fd_console_write(int fd, const char *buf, int n, void *d)
-{
-       struct fd_chan *data = d;
-
-       return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops fd_ops = {
        .type           = "fd",
        .init           = fd_init,
@@ -90,7 +83,7 @@ struct chan_ops fd_ops = {
        .close          = fd_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = fd_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = generic_free,
        .winch          = 1,
index 5db136e2651cc20a7883ad6ce3048423bbfaa8dd..afe85bfa66e0872eabc55cd1e0b25dace52900bc 100644 (file)
@@ -54,7 +54,7 @@ static int mcast_open(void *data)
        struct mcast_data *pri = data;
        struct sockaddr_in *sin = pri->mcast_addr;
        struct ip_mreq mreq;
-       int fd, yes = 1, err = 0;
+       int fd, yes = 1, err = -EINVAL;
 
 
        if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
@@ -63,40 +63,40 @@ static int mcast_open(void *data)
        fd = socket(AF_INET, SOCK_DGRAM, 0);
 
        if (fd < 0){
+               err = -errno;
                printk("mcast_open : data socket failed, errno = %d\n", 
                       errno);
-               err = -errno;
                goto out;
        }
 
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
+               err = -errno;
                printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
                        errno);
-               err = -errno;
                goto out_close;
        }
 
        /* set ttl according to config */
        if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
                       sizeof(pri->ttl)) < 0) {
+               err = -errno;
                printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
                        errno);
-               err = -errno;
                goto out_close;
        }
 
        /* set LOOP, so data does get fed back to local sockets */
        if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
+               err = -errno;
                printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
                        errno);
-               err = -errno;
                goto out_close;
        }
 
        /* bind socket to mcast address */
        if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
-               printk("mcast_open : data bind failed, errno = %d\n", errno);
                err = -errno;
+               printk("mcast_open : data bind failed, errno = %d\n", errno);
                goto out_close;
        }               
        
@@ -105,22 +105,22 @@ static int mcast_open(void *data)
        mreq.imr_interface.s_addr = 0;
        if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
                       &mreq, sizeof(mreq)) < 0) {
+               err = -errno;
                printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
                        errno);
                printk("There appears not to be a multicast-capable network "
                       "interface on the host.\n");
                printk("eth0 should be configured in order to use the "
                       "multicast transport.\n");
-               err = -errno;
-                goto out_close;
+               goto out_close;
        }
 
        return fd;
 
  out_close:
-        os_close_file(fd);
+       os_close_file(fd);
  out:
-        return err;
+       return err;
 }
 
 static void mcast_close(int fd, void *data)
index ed4a1a6c5d83fa03fb515f69a2fc30340f596301..c43e8bb3250264940af52ea528fe6a378fe41f67 100644 (file)
@@ -100,13 +100,6 @@ static void port_close(int fd, void *d)
        os_close_file(fd);
 }
 
-static int port_console_write(int fd, const char *buf, int n, void *d)
-{
-       struct port_chan *data = d;
-
-       return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops port_ops = {
        .type           = "port",
        .init           = port_init,
@@ -114,7 +107,7 @@ struct chan_ops port_ops = {
        .close          = port_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = port_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = port_free,
        .winch          = 1,
index 0306a1b215b7d8016f04bd3eca2dba996ee53dfa..1c555c38de4d0184adb129755058b71a1449553f 100644 (file)
@@ -118,13 +118,6 @@ static int pty_open(int input, int output, int primary, void *d,
        return(fd);
 }
 
-static int pty_console_write(int fd, const char *buf, int n, void *d)
-{
-       struct pty_chan *data = d;
-
-       return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops pty_ops = {
        .type           = "pty",
        .init           = pty_chan_init,
@@ -132,7 +125,7 @@ struct chan_ops pty_ops = {
        .close          = generic_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = pty_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = generic_free,
        .winch          = 0,
@@ -145,7 +138,7 @@ struct chan_ops pts_ops = {
        .close          = generic_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = pty_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = generic_free,
        .winch          = 0,
index 6fbb670ee2741a73d30dfa9eb20e1cad2d78f00a..94c9265a4f2ca54e034f4f79c11bf48ee061bdf2 100644 (file)
@@ -60,13 +60,6 @@ static int tty_open(int input, int output, int primary, void *d,
        return(fd);
 }
 
-static int tty_console_write(int fd, const char *buf, int n, void *d)
-{
-       struct tty_chan *data = d;
-
-       return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops tty_ops = {
        .type           = "tty",
        .init           = tty_chan_init,
@@ -74,7 +67,7 @@ struct chan_ops tty_ops = {
        .close          = generic_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = tty_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = generic_free,
        .winch          = 0,
index b530f1a6540d506a556e38c90dc3afec63f2f7f6..aaa63666104333f487d01521bb6792250cb40a14 100644 (file)
@@ -194,13 +194,6 @@ static void xterm_free(void *d)
        free(d);
 }
 
-static int xterm_console_write(int fd, const char *buf, int n, void *d)
-{
-       struct xterm_chan *data = d;
-
-       return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops xterm_ops = {
        .type           = "xterm",
        .init           = xterm_init,
@@ -208,7 +201,7 @@ struct chan_ops xterm_ops = {
        .close          = xterm_close,
        .read           = generic_read,
        .write          = generic_write,
-       .console_write  = xterm_console_write,
+       .console_write  = generic_console_write,
        .window_size    = generic_window_size,
        .free           = xterm_free,
        .winch          = 1,
index f77d9aa4c164f103995dd83cd0407a226d31a7cd..659bb3cac32f51f3e7f8017bd137270e068cabf6 100644 (file)
@@ -25,7 +25,7 @@ struct chan_ops {
        void (*close)(int, void *);
        int (*read)(int, char *, void *);
        int (*write)(int, const char *, int, void *);
-       int (*console_write)(int, const char *, int, void *);
+       int (*console_write)(int, const char *, int);
        int (*window_size)(int, void *, unsigned short *, unsigned short *);
        void (*free)(void *);
        int winch;
@@ -37,7 +37,7 @@ extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
 extern void generic_close(int fd, void *unused);
 extern int generic_read(int fd, char *c_out, void *unused);
 extern int generic_write(int fd, const char *buf, int n, void *unused);
-extern int generic_console_write(int fd, const char *buf, int n, void *state);
+extern int generic_console_write(int fd, const char *buf, int n);
 extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
                               unsigned short *cols_out);
 extern void generic_free(void *data);
index 84c0868cd5613610c4f874aa280283d2d5f0a35b..f8760a3f43b0f0f6e0402f21089d87e56ba62c29 100644 (file)
 #include "uaccess-skas.h"
 #endif
 
+#define __under_task_size(addr, size) \
+       (((unsigned long) (addr) < TASK_SIZE) && \
+         (((unsigned long) (addr) + (size)) < TASK_SIZE))
+
+#define __access_ok_vsyscall(type, addr, size) \
+        ((type == VERIFY_READ) && \
+         ((unsigned long) (addr) >= FIXADDR_USER_START) && \
+         ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
+         ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
+
+#define __addr_range_nowrap(addr, size) \
+       ((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
+
 #define access_ok(type, addr, size) \
-       CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
+       (__addr_range_nowrap(addr, size) && \
+        (__under_task_size(addr, size) || \
+         __access_ok_vsyscall(type, addr, size) || \
+         segment_eq(get_fs(), KERNEL_DS) || \
+         CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
 
 static inline int copy_from_user(void *to, const void __user *from, int n)
 {
index 7da0c2def0ef1c6ca8c2034619ad3ba2777a1b55..f611f83ad4ff815397f1746a10ba2e5656c3d9bc 100644 (file)
@@ -9,14 +9,8 @@
 #include "asm/errno.h"
 #include "asm/fixmap.h"
 
-#define access_ok_skas(type, addr, size) \
-       ((segment_eq(get_fs(), KERNEL_DS)) || \
-        (((unsigned long) (addr) < TASK_SIZE) && \
-         ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
-        ((type == VERIFY_READ ) && \
-         ((unsigned long) (addr) >= FIXADDR_USER_START) && \
-         ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
-         ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
+/* No SKAS-specific checking. */
+#define access_ok_skas(type, addr, size) 0
 
 extern int copy_from_user_skas(void *to, const void __user *from, int n);
 extern int copy_to_user_skas(void __user *to, const void *from, int n);
index 75195281081e10252e840ea2bf533e3cd193a27d..a5a47528dec7a68cbab0c9e290461a66eea6af2c 100644 (file)
@@ -143,7 +143,7 @@ int copy_from_user_skas(void *to, const void __user *from, int n)
                return(0);
        }
 
-       return(access_ok_skas(VERIFY_READ, from, n) ?
+       return(access_ok(VERIFY_READ, from, n) ?
               buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
               n);
 }
@@ -164,7 +164,7 @@ int copy_to_user_skas(void __user *to, const void *from, int n)
                return(0);
        }
 
-       return(access_ok_skas(VERIFY_WRITE, to, n) ?
+       return(access_ok(VERIFY_WRITE, to, n) ?
               buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
               n);
 }
@@ -193,7 +193,7 @@ int strncpy_from_user_skas(char *dst, const char __user *src, int count)
                return(strnlen(dst, count));
        }
 
-       if(!access_ok_skas(VERIFY_READ, src, 1))
+       if(!access_ok(VERIFY_READ, src, 1))
                return(-EFAULT);
 
        n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
@@ -221,7 +221,7 @@ int clear_user_skas(void __user *mem, int len)
                return(0);
        }
 
-       return(access_ok_skas(VERIFY_WRITE, mem, len) ?
+       return(access_ok(VERIFY_WRITE, mem, len) ?
               buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
 }
 
index 95c8f8733bafb516e67d044d6d78a87779a46c98..0d4c10a736077702556fea90e281b82b109ada06 100644 (file)
@@ -95,7 +95,16 @@ survive:
                pte = pte_offset_kernel(pmd, address);
        } while(!pte_present(*pte));
        err = 0;
+       /* The below warning was added in place of
+        *      pte_mkyoung(); if (is_write) pte_mkdirty();
+        * If it's triggered, we'd see normally a hang here (a clean pte is
+        * marked read-only to emulate the dirty bit).
+        * However, the generic code can mark a PTE writable but clean on a
+        * concurrent read fault, triggering this harmlessly. So comment it out.
+        */
+#if 0
        WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
+#endif
        flush_tlb_page(vma, address);
 out:
        up_read(&mm->mmap_sem);
index dc2ebfa8c54fb621c6d790659417f4f68c010d26..b9bfe9c481c4eadd31601623bbe2e9de89dec1ea 100644 (file)
 extern unsigned long end_vm;
 extern unsigned long uml_physmem;
 
-#define under_task_size(addr, size) \
-       (((unsigned long) (addr) < TASK_SIZE) && \
-         (((unsigned long) (addr) + (size)) < TASK_SIZE))
-
 #define is_stack(addr, size) \
        (((unsigned long) (addr) < STACK_TOP) && \
         ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
         (((unsigned long) (addr) + (size)) <= STACK_TOP))
 
 #define access_ok_tt(type, addr, size) \
-       ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
-         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
-          (under_task_size(addr, size) || is_stack(addr, size))))
+       (is_stack(addr, size))
 
 extern unsigned long get_fault_addr(void);
 
index a72aa632972f4ebc72c66ac09593600f7caefd33..1cb60726567ed43da205922b9b004fcd42be8a7b 100644 (file)
@@ -8,7 +8,7 @@
 
 int copy_from_user_tt(void *to, const void __user *from, int n)
 {
-       if(!access_ok_tt(VERIFY_READ, from, n))
+       if(!access_ok(VERIFY_READ, from, n))
                return(n);
 
        return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
@@ -17,7 +17,7 @@ int copy_from_user_tt(void *to, const void __user *from, int n)
 
 int copy_to_user_tt(void __user *to, const void *from, int n)
 {
-       if(!access_ok_tt(VERIFY_WRITE, to, n))
+       if(!access_ok(VERIFY_WRITE, to, n))
                return(n);
 
        return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
@@ -28,7 +28,7 @@ int strncpy_from_user_tt(char *dst, const char __user *src, int count)
 {
        int n;
 
-       if(!access_ok_tt(VERIFY_READ, src, 1))
+       if(!access_ok(VERIFY_READ, src, 1))
                return(-EFAULT);
 
        n = __do_strncpy_from_user(dst, src, count,
@@ -47,7 +47,7 @@ int __clear_user_tt(void __user *mem, int len)
 
 int clear_user_tt(void __user *mem, int len)
 {
-       if(!access_ok_tt(VERIFY_WRITE, mem, len))
+       if(!access_ok(VERIFY_WRITE, mem, len))
                return(len);
 
        return(__do_clear_user(mem, len, &current->thread.fault_addr,
index c6c9791d77c18aa2ed7025f7b9c7a0b07e18f132..a9368d4c4aba1ceba5df433b9fdfb90713f1f543 100644 (file)
@@ -515,7 +515,7 @@ void i8254_timer_resume(void)
 }
 
 static struct sysdev_class timer_sysclass = {
-       set_kset_name("timer"),
+       set_kset_name("timer_pit"),
        .resume         = timer_resume,
 };
 
index 6a4da417c16b1f996435fd49b8418302ad430406..606f8733a776cf4ab3473db6a8288431f7d9bc84 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_X86
@@ -754,7 +755,7 @@ static int __init acpi_init(void)
        result = acpi_bus_init();
 
        if (!result) {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
                if (!PM_IS_ACTIVE())
                        pm_active = 1;
                else {
index 98f6c02d6790a9d78220ccffa33b616cae91a30d..59dacb6552c0c5b5088c65377f607310d43ee0c8 100644 (file)
@@ -526,18 +526,23 @@ request_firmware_work_func(void *arg)
 {
        struct firmware_work *fw_work = arg;
        const struct firmware *fw;
+       int ret;
        if (!arg) {
                WARN_ON(1);
                return 0;
        }
        daemonize("%s/%s", "firmware", fw_work->name);
-       _request_firmware(&fw, fw_work->name, fw_work->device,
+       ret = _request_firmware(&fw, fw_work->name, fw_work->device,
                fw_work->hotplug);
-       fw_work->cont(fw, fw_work->context);
-       release_firmware(fw);
+       if (ret < 0)
+               fw_work->cont(NULL, fw_work->context);
+       else {
+               fw_work->cont(fw, fw_work->context);
+               release_firmware(fw);
+       }
        module_put(fw_work->module);
        kfree(fw_work);
-       return 0;
+       return ret;
 }
 
 /**
@@ -586,6 +591,8 @@ request_firmware_nowait(
 
        if (ret < 0) {
                fw_work->cont(NULL, fw_work->context);
+               module_put(fw_work->module);
+               kfree(fw_work);
                return ret;
        }
        return 0;
index 59e5982a5db35bb0b2c18a2ebe6ca7870bd71b67..c0233efabebae2216eabeabda378bba0aafce661 100644 (file)
@@ -1188,7 +1188,7 @@ static void pkt_count_states(struct pktcdvd_device *pd, int *states)
        struct packet_data *pkt;
        int i;
 
-       for (i = 0; i <= PACKET_NUM_STATES; i++)
+       for (i = 0; i < PACKET_NUM_STATES; i++)
                states[i] = 0;
 
        spin_lock(&pd->cdrw.active_list_lock);
index fdf4370db994ca6f17be96070a0b2153a087764a..970f70d498f4c814e1cf3362e33d7e23ac53c299 100644 (file)
@@ -735,7 +735,7 @@ config SGI_IP27_RTC
 
 config GEN_RTC
        tristate "Generic /dev/rtc emulation"
-       depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 && !SPARC64
+       depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64
        ---help---
          If you say Y here and create a character special file /dev/rtc with
          major number 10 and minor number 135 using mknod ("man mknod"), you
index c8255312b8c1f3728fb608928ebf554913cff4d2..50947e38501a1903bf98b6376f4f3efc05ba2895 100644 (file)
@@ -557,6 +557,10 @@ static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
                .device_id      = PCI_DEVICE_ID_APPLE_U3H_AGP,
                .chipset_name   = "U3H",
        },
+       {
+               .device_id      = PCI_DEVICE_ID_APPLE_IPID2_AGP,
+               .chipset_name   = "UniNorth/Intrepid2",
+       },
 };
 
 static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
index d22bfdc13563f722ab869043127fcf8778fcdeab..27c1179ee52749a7062c597e71f506321eeb7287 100644 (file)
@@ -18,5 +18,29 @@ config SYNCLINK_CS
          The module will be called synclinkmp.  If you want to do that, say M
          here.
 
+config CARDMAN_4000
+       tristate "Omnikey Cardman 4000 support"
+       depends on PCMCIA
+       help
+         Enable support for the Omnikey Cardman 4000 PCMCIA Smartcard
+         reader.
+
+         This kernel driver requires additional userspace support, either
+         by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/),
+         or via the cm4000 backend of OpenCT (http://www.opensc.com/).
+
+config CARDMAN_4040
+       tristate "Omnikey CardMan 4040 support"
+       depends on PCMCIA
+       help
+         Enable support for the Omnikey CardMan 4040 PCMCIA Smartcard
+         reader.
+
+         This card is basically a USB CCID device connected to a FIFO
+         in I/O space.  To use the kernel driver, you will need either the
+         PC/SC ifdhandler provided from the Omnikey homepage
+         (http://www.omnikey.com/), or a current development version of OpenCT
+         (http://www.opensc.org/).
+
 endmenu
 
index 1fcd4c591958043cbb653efd4f35bfb8dd45ebcc..0aae20985d5732059700e7fb50dec7d6573682a2 100644 (file)
@@ -5,3 +5,5 @@
 #
 
 obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o
+obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o
+obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
new file mode 100644 (file)
index 0000000..ef011ef
--- /dev/null
@@ -0,0 +1,2078 @@
+ /*
+  * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000"
+  *
+  * cm4000_cs.c support.linux@omnikey.com
+  *
+  * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files
+  * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files
+  * Thu Nov 14 16:34:11 GMT 2002 mh   - added PPS functionality
+  * Tue Nov 19 16:36:27 GMT 2002 mh   - added SUSPEND/RESUME functionailty
+  * Wed Jul 28 12:55:01 CEST 2004 mh  - kernel 2.6 adjustments
+  *
+  * current version: 2.4.0gm4
+  *
+  * (C) 2000,2001,2002,2003,2004 Omnikey AG
+  *
+  * (C) 2005 Harald Welte <laforge@gnumonks.org>
+  *    - Adhere to Kernel CodingStyle
+  *    - Port to 2.6.13 "new" style PCMCIA
+  *    - Check for copy_{from,to}_user return values
+  *    - Use nonseekable_open()
+  *
+  * All rights reserved. Licensed under dual BSD/GPL license.
+  */
+
+/* #define PCMCIA_DEBUG 6 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+#include <linux/cm4000_cs.h>
+
+/* #define ATR_CSUM */
+
+#ifdef PCMCIA_DEBUG
+#define reader_to_dev(x)       (&handle_to_dev(x->link.handle))
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0600);
+#define DEBUGP(n, rdr, x, args...) do {                                \
+       if (pc_debug >= (n))                                            \
+               dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x,     \
+                          __FUNCTION__ , ## args);                     \
+       } while (0)
+#else
+#define DEBUGP(n, rdr, x, args...)
+#endif
+static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
+
+#define        T_1SEC          (HZ)
+#define        T_10MSEC        msecs_to_jiffies(10)
+#define        T_20MSEC        msecs_to_jiffies(20)
+#define        T_40MSEC        msecs_to_jiffies(40)
+#define        T_50MSEC        msecs_to_jiffies(50)
+#define        T_100MSEC       msecs_to_jiffies(100)
+#define        T_500MSEC       msecs_to_jiffies(500)
+
+static void cm4000_detach(dev_link_t *link);
+static void cm4000_release(dev_link_t *link);
+
+static int major;              /* major number we get from the kernel */
+
+/* note: the first state has to have number 0 always */
+
+#define        M_FETCH_ATR     0
+#define        M_TIMEOUT_WAIT  1
+#define        M_READ_ATR_LEN  2
+#define        M_READ_ATR      3
+#define        M_ATR_PRESENT   4
+#define        M_BAD_CARD      5
+#define M_CARDOFF      6
+
+#define        LOCK_IO                 0
+#define        LOCK_MONITOR            1
+
+#define IS_AUTOPPS_ACT          6
+#define        IS_PROCBYTE_PRESENT      7
+#define        IS_INVREV                8
+#define IS_ANY_T0               9
+#define        IS_ANY_T1               10
+#define        IS_ATR_PRESENT          11
+#define        IS_ATR_VALID            12
+#define        IS_CMM_ABSENT           13
+#define        IS_BAD_LENGTH           14
+#define        IS_BAD_CSUM             15
+#define        IS_BAD_CARD             16
+
+#define REG_FLAGS0(x)          (x + 0)
+#define REG_FLAGS1(x)          (x + 1)
+#define REG_NUM_BYTES(x)       (x + 2)
+#define REG_BUF_ADDR(x)                (x + 3)
+#define REG_BUF_DATA(x)                (x + 4)
+#define REG_NUM_SEND(x)                (x + 5)
+#define REG_BAUDRATE(x)                (x + 6)
+#define REG_STOPBITS(x)                (x + 7)
+
+struct cm4000_dev {
+       dev_link_t link;                /* pcmcia link */
+       dev_node_t node;                /* OS node (major,minor) */
+
+       unsigned char atr[MAX_ATR];
+       unsigned char rbuf[512];
+       unsigned char sbuf[512];
+
+       wait_queue_head_t devq;         /* when removing cardman must not be
+                                          zeroed! */
+
+       wait_queue_head_t ioq;          /* if IO is locked, wait on this Q */
+       wait_queue_head_t atrq;         /* wait for ATR valid */
+       wait_queue_head_t readq;        /* used by write to wake blk.read */
+
+       /* warning: do not move this fields.
+        * initialising to zero depends on it - see ZERO_DEV below.  */
+       unsigned char atr_csum;
+       unsigned char atr_len_retry;
+       unsigned short atr_len;
+       unsigned short rlen;    /* bytes avail. after write */
+       unsigned short rpos;    /* latest read pos. write zeroes */
+       unsigned char procbyte; /* T=0 procedure byte */
+       unsigned char mstate;   /* state of card monitor */
+       unsigned char cwarn;    /* slow down warning */
+       unsigned char flags0;   /* cardman IO-flags 0 */
+       unsigned char flags1;   /* cardman IO-flags 1 */
+       unsigned int mdelay;    /* variable monitor speeds, in jiffies */
+
+       unsigned int baudv;     /* baud value for speed */
+       unsigned char ta1;
+       unsigned char proto;    /* T=0, T=1, ... */
+       unsigned long flags;    /* lock+flags (MONITOR,IO,ATR) * for concurrent
+                                  access */
+
+       unsigned char pts[4];
+
+       struct timer_list timer;        /* used to keep monitor running */
+       int monitor_running;
+};
+
+#define        ZERO_DEV(dev)                                           \
+       memset(&dev->atr_csum,0,                                \
+               sizeof(struct cm4000_dev) -                     \
+               /*link*/ sizeof(dev_link_t) -                   \
+               /*node*/ sizeof(dev_node_t) -                   \
+               /*atr*/ MAX_ATR*sizeof(char) -                  \
+               /*rbuf*/ 512*sizeof(char) -                     \
+               /*sbuf*/ 512*sizeof(char) -                     \
+               /*queue*/ 4*sizeof(wait_queue_head_t))
+
+static dev_info_t dev_info = MODULE_NAME;
+static dev_link_t *dev_table[CM4000_MAX_DEV];
+
+/* This table doesn't use spaces after the comma between fields and thus
+ * violates CodingStyle.  However, I don't really think wrapping it around will
+ * make it any clearer to read -HW */
+static unsigned char fi_di_table[10][14] = {
+/*FI     00   01   02   03   04   05   06   07   08   09   10   11   12   13 */
+/*DI */
+/* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11},
+/* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11},
+/* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3},
+/* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4},
+/* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5},
+/* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6},
+/* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8},
+/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
+};
+
+#ifndef PCMCIA_DEBUG
+#define        xoutb   outb
+#define        xinb    inb
+#else
+static inline void xoutb(unsigned char val, unsigned short port)
+{
+       if (pc_debug >= 7)
+               printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+       outb(val, port);
+}
+static inline unsigned char xinb(unsigned short port)
+{
+       unsigned char val;
+
+       val = inb(port);
+       if (pc_debug >= 7)
+               printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+
+       return val;
+}
+#endif
+
+#define        b_0000  15
+#define        b_0001  14
+#define        b_0010  13
+#define        b_0011  12
+#define        b_0100  11
+#define        b_0101  10
+#define        b_0110  9
+#define        b_0111  8
+#define        b_1000  7
+#define        b_1001  6
+#define        b_1010  5
+#define        b_1011  4
+#define        b_1100  3
+#define        b_1101  2
+#define        b_1110  1
+#define        b_1111  0
+
+static unsigned char irtab[16] = {
+       b_0000, b_1000, b_0100, b_1100,
+       b_0010, b_1010, b_0110, b_1110,
+       b_0001, b_1001, b_0101, b_1101,
+       b_0011, b_1011, b_0111, b_1111
+};
+
+static void str_invert_revert(unsigned char *b, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4];
+}
+
+static unsigned char invert_revert(unsigned char ch)
+{
+       return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4];
+}
+
+#define        ATRLENCK(dev,pos) \
+       if (pos>=dev->atr_len || pos>=MAX_ATR) \
+               goto return_0;
+
+static unsigned int calc_baudv(unsigned char fidi)
+{
+       unsigned int wcrcf, wbrcf, fi_rfu, di_rfu;
+
+       fi_rfu = 372;
+       di_rfu = 1;
+
+       /* FI */
+       switch ((fidi >> 4) & 0x0F) {
+       case 0x00:
+               wcrcf = 372;
+               break;
+       case 0x01:
+               wcrcf = 372;
+               break;
+       case 0x02:
+               wcrcf = 558;
+               break;
+       case 0x03:
+               wcrcf = 744;
+               break;
+       case 0x04:
+               wcrcf = 1116;
+               break;
+       case 0x05:
+               wcrcf = 1488;
+               break;
+       case 0x06:
+               wcrcf = 1860;
+               break;
+       case 0x07:
+               wcrcf = fi_rfu;
+               break;
+       case 0x08:
+               wcrcf = fi_rfu;
+               break;
+       case 0x09:
+               wcrcf = 512;
+               break;
+       case 0x0A:
+               wcrcf = 768;
+               break;
+       case 0x0B:
+               wcrcf = 1024;
+               break;
+       case 0x0C:
+               wcrcf = 1536;
+               break;
+       case 0x0D:
+               wcrcf = 2048;
+               break;
+       default:
+               wcrcf = fi_rfu;
+               break;
+       }
+
+       /* DI */
+       switch (fidi & 0x0F) {
+       case 0x00:
+               wbrcf = di_rfu;
+               break;
+       case 0x01:
+               wbrcf = 1;
+               break;
+       case 0x02:
+               wbrcf = 2;
+               break;
+       case 0x03:
+               wbrcf = 4;
+               break;
+       case 0x04:
+               wbrcf = 8;
+               break;
+       case 0x05:
+               wbrcf = 16;
+               break;
+       case 0x06:
+               wbrcf = 32;
+               break;
+       case 0x07:
+               wbrcf = di_rfu;
+               break;
+       case 0x08:
+               wbrcf = 12;
+               break;
+       case 0x09:
+               wbrcf = 20;
+               break;
+       default:
+               wbrcf = di_rfu;
+               break;
+       }
+
+       return (wcrcf / wbrcf);
+}
+
+static unsigned short io_read_num_rec_bytes(ioaddr_t iobase, unsigned short *s)
+{
+       unsigned short tmp;
+
+       tmp = *s = 0;
+       do {
+               *s = tmp;
+               tmp = inb(REG_NUM_BYTES(iobase)) |
+                               (inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0);
+       } while (tmp != *s);
+
+       return *s;
+}
+
+static int parse_atr(struct cm4000_dev *dev)
+{
+       unsigned char any_t1, any_t0;
+       unsigned char ch, ifno;
+       int ix, done;
+
+       DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len);
+
+       if (dev->atr_len < 3) {
+               DEBUGP(5, dev, "parse_atr: atr_len < 3\n");
+               return 0;
+       }
+
+       if (dev->atr[0] == 0x3f)
+               set_bit(IS_INVREV, &dev->flags);
+       else
+               clear_bit(IS_INVREV, &dev->flags);
+       ix = 1;
+       ifno = 1;
+       ch = dev->atr[1];
+       dev->proto = 0;         /* XXX PROTO */
+       any_t1 = any_t0 = done = 0;
+       dev->ta1 = 0x11;        /* defaults to 9600 baud */
+       do {
+               if (ifno == 1 && (ch & 0x10)) {
+                       /* read first interface byte and TA1 is present */
+                       dev->ta1 = dev->atr[2];
+                       DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1);
+                       ifno++;
+               } else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */
+                       dev->ta1 = 0x11;
+                       ifno++;
+               }
+
+               DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0);
+               ix += ((ch & 0x10) >> 4)        /* no of int.face chars */
+                   +((ch & 0x20) >> 5)
+                   + ((ch & 0x40) >> 6)
+                   + ((ch & 0x80) >> 7);
+               /* ATRLENCK(dev,ix); */
+               if (ch & 0x80) {        /* TDi */
+                       ch = dev->atr[ix];
+                       if ((ch & 0x0f)) {
+                               any_t1 = 1;
+                               DEBUGP(5, dev, "card is capable of T=1\n");
+                       } else {
+                               any_t0 = 1;
+                               DEBUGP(5, dev, "card is capable of T=0\n");
+                       }
+               } else
+                       done = 1;
+       } while (!done);
+
+       DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n",
+             ix, dev->atr[1] & 15, any_t1);
+       if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) {
+               DEBUGP(5, dev, "length error\n");
+               return 0;
+       }
+       if (any_t0)
+               set_bit(IS_ANY_T0, &dev->flags);
+
+       if (any_t1) {           /* compute csum */
+               dev->atr_csum = 0;
+#ifdef ATR_CSUM
+               for (i = 1; i < dev->atr_len; i++)
+                       dev->atr_csum ^= dev->atr[i];
+               if (dev->atr_csum) {
+                       set_bit(IS_BAD_CSUM, &dev->flags);
+                       DEBUGP(5, dev, "bad checksum\n");
+                       goto return_0;
+               }
+#endif
+               if (any_t0 == 0)
+                       dev->proto = 1; /* XXX PROTO */
+               set_bit(IS_ANY_T1, &dev->flags);
+       }
+
+       return 1;
+}
+
+struct card_fixup {
+       char atr[12];
+       u_int8_t atr_len;
+       u_int8_t stopbits;
+};
+
+static struct card_fixup card_fixups[] = {
+       {       /* ACOS */
+               .atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 },
+               .atr_len = 7,
+               .stopbits = 0x03,
+       },
+       {       /* Motorola */
+               .atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07,
+                       0x41, 0x81, 0x81 },
+               .atr_len = 11,
+               .stopbits = 0x04,
+       },
+};
+
+static void set_cardparameter(struct cm4000_dev *dev)
+{
+       int i;
+       ioaddr_t iobase = dev->link.io.BasePort1;
+       u_int8_t stopbits = 0x02; /* ISO default */
+
+       DEBUGP(3, dev, "-> set_cardparameter\n");
+
+       dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8);
+       xoutb(dev->flags1, REG_FLAGS1(iobase));
+       DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1);
+
+       /* set baudrate */
+       xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase));
+
+       DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv,
+             ((dev->baudv - 1) & 0xFF));
+
+       /* set stopbits */
+       for (i = 0; i < ARRAY_SIZE(card_fixups); i++) {
+               if (!memcmp(dev->atr, card_fixups[i].atr,
+                           card_fixups[i].atr_len))
+                       stopbits = card_fixups[i].stopbits;
+       }
+       xoutb(stopbits, REG_STOPBITS(iobase));
+
+       DEBUGP(3, dev, "<- set_cardparameter\n");
+}
+
+static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
+{
+
+       unsigned long tmp, i;
+       unsigned short num_bytes_read;
+       unsigned char pts_reply[4];
+       ssize_t rc;
+       ioaddr_t iobase = dev->link.io.BasePort1;
+
+       rc = 0;
+
+       DEBUGP(3, dev, "-> set_protocol\n");
+       DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, "
+                "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, "
+                "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol,
+                (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2,
+                ptsreq->pts3);
+
+       /* Fill PTS structure */
+       dev->pts[0] = 0xff;
+       dev->pts[1] = 0x00;
+       tmp = ptsreq->protocol;
+       while ((tmp = (tmp >> 1)) > 0)
+               dev->pts[1]++;
+       dev->proto = dev->pts[1];       /* Set new protocol */
+       dev->pts[1] = (0x01 << 4) | (dev->pts[1]);
+
+       /* Correct Fi/Di according to CM4000 Fi/Di table */
+       DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1);
+       /* set Fi/Di according to ATR TA(1) */
+       dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F];
+
+       /* Calculate PCK character */
+       dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2];
+
+       DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n",
+              dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]);
+
+       /* check card convention */
+       if (test_bit(IS_INVREV, &dev->flags))
+               str_invert_revert(dev->pts, 4);
+
+       /* reset SM */
+       xoutb(0x80, REG_FLAGS0(iobase));
+
+       /* Enable access to the message buffer */
+       DEBUGP(5, dev, "Enable access to the messages buffer\n");
+       dev->flags1 = 0x20      /* T_Active */
+           | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */
+           | ((dev->baudv >> 8) & 0x01);       /* MSB-baud */
+       xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+       DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n",
+              dev->flags1);
+
+       /* write challenge to the buffer */
+       DEBUGP(5, dev, "Write challenge to buffer: ");
+       for (i = 0; i < 4; i++) {
+               xoutb(i, REG_BUF_ADDR(iobase));
+               xoutb(dev->pts[i], REG_BUF_DATA(iobase));       /* buf data */
+#ifdef PCMCIA_DEBUG
+               if (pc_debug >= 5)
+                       printk("0x%.2x ", dev->pts[i]);
+       }
+       if (pc_debug >= 5)
+               printk("\n");
+#else
+       }
+#endif
+
+       /* set number of bytes to write */
+       DEBUGP(5, dev, "Set number of bytes to write\n");
+       xoutb(0x04, REG_NUM_SEND(iobase));
+
+       /* Trigger CARDMAN CONTROLLER */
+       xoutb(0x50, REG_FLAGS0(iobase));
+
+       /* Monitor progress */
+       /* wait for xmit done */
+       DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n");
+
+       for (i = 0; i < 100; i++) {
+               if (inb(REG_FLAGS0(iobase)) & 0x08) {
+                       DEBUGP(5, dev, "NumRecBytes is valid\n");
+                       break;
+               }
+               mdelay(10);
+       }
+       if (i == 100) {
+               DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting "
+                      "valid\n");
+               rc = -EIO;
+               goto exit_setprotocol;
+       }
+
+       DEBUGP(5, dev, "Reading NumRecBytes\n");
+       for (i = 0; i < 100; i++) {
+               io_read_num_rec_bytes(iobase, &num_bytes_read);
+               if (num_bytes_read >= 4) {
+                       DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
+                       break;
+               }
+               mdelay(10);
+       }
+
+       /* check whether it is a short PTS reply? */
+       if (num_bytes_read == 3)
+               i = 0;
+
+       if (i == 100) {
+               DEBUGP(5, dev, "Timeout reading num_bytes_read\n");
+               rc = -EIO;
+               goto exit_setprotocol;
+       }
+
+       DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n");
+       xoutb(0x80, REG_FLAGS0(iobase));
+
+       /* Read PPS reply */
+       DEBUGP(5, dev, "Read PPS reply\n");
+       for (i = 0; i < num_bytes_read; i++) {
+               xoutb(i, REG_BUF_ADDR(iobase));
+               pts_reply[i] = inb(REG_BUF_DATA(iobase));
+       }
+
+#ifdef PCMCIA_DEBUG
+       DEBUGP(2, dev, "PTSreply: ");
+       for (i = 0; i < num_bytes_read; i++) {
+               if (pc_debug >= 5)
+                       printk("0x%.2x ", pts_reply[i]);
+       }
+       printk("\n");
+#endif /* PCMCIA_DEBUG */
+
+       DEBUGP(5, dev, "Clear Tactive in Flags1\n");
+       xoutb(0x20, REG_FLAGS1(iobase));
+
+       /* Compare ptsreq and ptsreply */
+       if ((dev->pts[0] == pts_reply[0]) &&
+           (dev->pts[1] == pts_reply[1]) &&
+           (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) {
+               /* setcardparameter according to PPS */
+               dev->baudv = calc_baudv(dev->pts[2]);
+               set_cardparameter(dev);
+       } else if ((dev->pts[0] == pts_reply[0]) &&
+                  ((dev->pts[1] & 0xef) == pts_reply[1]) &&
+                  ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) {
+               /* short PTS reply, set card parameter to default values */
+               dev->baudv = calc_baudv(0x11);
+               set_cardparameter(dev);
+       } else
+               rc = -EIO;
+
+exit_setprotocol:
+       DEBUGP(3, dev, "<- set_protocol\n");
+       return rc;
+}
+
+static int io_detect_cm4000(ioaddr_t iobase, struct cm4000_dev *dev)
+{
+
+       /* note: statemachine is assumed to be reset */
+       if (inb(REG_FLAGS0(iobase)) & 8) {
+               clear_bit(IS_ATR_VALID, &dev->flags);
+               set_bit(IS_CMM_ABSENT, &dev->flags);
+               return 0;       /* detect CMM = 1 -> failure */
+       }
+       /* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */
+       xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase));
+       if ((inb(REG_FLAGS0(iobase)) & 8) == 0) {
+               clear_bit(IS_ATR_VALID, &dev->flags);
+               set_bit(IS_CMM_ABSENT, &dev->flags);
+               return 0;       /* detect CMM=0 -> failure */
+       }
+       /* clear detectCMM again by restoring original flags1 */
+       xoutb(dev->flags1, REG_FLAGS1(iobase));
+       return 1;
+}
+
+static void terminate_monitor(struct cm4000_dev *dev)
+{
+
+       /* tell the monitor to stop and wait until
+        * it terminates.
+        */
+       DEBUGP(3, dev, "-> terminate_monitor\n");
+       wait_event_interruptible(dev->devq,
+                                test_and_set_bit(LOCK_MONITOR,
+                                                 (void *)&dev->flags));
+
+       /* now, LOCK_MONITOR has been set.
+        * allow a last cycle in the monitor.
+        * the monitor will indicate that it has
+        * finished by clearing this bit.
+        */
+       DEBUGP(5, dev, "Now allow last cycle of monitor!\n");
+       while (test_bit(LOCK_MONITOR, (void *)&dev->flags))
+               msleep(25);
+
+       DEBUGP(5, dev, "Delete timer\n");
+       del_timer_sync(&dev->timer);
+#ifdef PCMCIA_DEBUG
+       dev->monitor_running = 0;
+#endif
+
+       DEBUGP(3, dev, "<- terminate_monitor\n");
+}
+
+/*
+ * monitor the card every 50msec. as a side-effect, retrieve the
+ * atr once a card is inserted. another side-effect of retrieving the
+ * atr is that the card will be powered on, so there is no need to
+ * power on the card explictely from the application: the driver
+ * is already doing that for you.
+ */
+
+static void monitor_card(unsigned long p)
+{
+       struct cm4000_dev *dev = (struct cm4000_dev *) p;
+       ioaddr_t iobase = dev->link.io.BasePort1;
+       unsigned short s;
+       struct ptsreq ptsreq;
+       int i, atrc;
+
+       DEBUGP(7, dev, "->  monitor_card\n");
+
+       /* if someone has set the lock for us: we're done! */
+       if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) {
+               DEBUGP(4, dev, "About to stop monitor\n");
+               /* no */
+               dev->rlen =
+                   dev->rpos =
+                   dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+               dev->mstate = M_FETCH_ATR;
+               clear_bit(LOCK_MONITOR, &dev->flags);
+               /* close et al. are sleeping on devq, so wake it */
+               wake_up_interruptible(&dev->devq);
+               DEBUGP(2, dev, "<- monitor_card (we are done now)\n");
+               return;
+       }
+
+       /* try to lock io: if it is already locked, just add another timer */
+       if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) {
+               DEBUGP(4, dev, "Couldn't get IO lock\n");
+               goto return_with_timer;
+       }
+
+       /* is a card/a reader inserted at all ? */
+       dev->flags0 = xinb(REG_FLAGS0(iobase));
+       DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0);
+       DEBUGP(7, dev, "smartcard present: %s\n",
+              dev->flags0 & 1 ? "yes" : "no");
+       DEBUGP(7, dev, "cardman present: %s\n",
+              dev->flags0 == 0xff ? "no" : "yes");
+
+       if ((dev->flags0 & 1) == 0      /* no smartcard inserted */
+           || dev->flags0 == 0xff) {   /* no cardman inserted */
+               /* no */
+               dev->rlen =
+                   dev->rpos =
+                   dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+               dev->mstate = M_FETCH_ATR;
+
+               dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */
+
+               if (dev->flags0 == 0xff) {
+                       DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n");
+                       set_bit(IS_CMM_ABSENT, &dev->flags);
+               } else if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
+                       DEBUGP(4, dev, "clear IS_CMM_ABSENT bit "
+                              "(card is removed)\n");
+                       clear_bit(IS_CMM_ABSENT, &dev->flags);
+               }
+
+               goto release_io;
+       } else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) {
+               /* cardman and card present but cardman was absent before
+                * (after suspend with inserted card) */
+               DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n");
+               clear_bit(IS_CMM_ABSENT, &dev->flags);
+       }
+
+       if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+               DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n");
+               goto release_io;
+       }
+
+       switch (dev->mstate) {
+               unsigned char flags0;
+       case M_CARDOFF:
+               DEBUGP(4, dev, "M_CARDOFF\n");
+               flags0 = inb(REG_FLAGS0(iobase));
+               if (flags0 & 0x02) {
+                       /* wait until Flags0 indicate power is off */
+                       dev->mdelay = T_10MSEC;
+               } else {
+                       /* Flags0 indicate power off and no card inserted now;
+                        * Reset CARDMAN CONTROLLER */
+                       xoutb(0x80, REG_FLAGS0(iobase));
+
+                       /* prepare for fetching ATR again: after card off ATR
+                        * is read again automatically */
+                       dev->rlen =
+                           dev->rpos =
+                           dev->atr_csum =
+                           dev->atr_len_retry = dev->cwarn = 0;
+                       dev->mstate = M_FETCH_ATR;
+
+                       /* minimal gap between CARDOFF and read ATR is 50msec */
+                       dev->mdelay = T_50MSEC;
+               }
+               break;
+       case M_FETCH_ATR:
+               DEBUGP(4, dev, "M_FETCH_ATR\n");
+               xoutb(0x80, REG_FLAGS0(iobase));
+               DEBUGP(4, dev, "Reset BAUDV to 9600\n");
+               dev->baudv = 0x173;     /* 9600 */
+               xoutb(0x02, REG_STOPBITS(iobase));      /* stopbits=2 */
+               xoutb(0x73, REG_BAUDRATE(iobase));      /* baud value */
+               xoutb(0x21, REG_FLAGS1(iobase));        /* T_Active=1, baud
+                                                          value */
+               /* warm start vs. power on: */
+               xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase));
+               dev->mdelay = T_40MSEC;
+               dev->mstate = M_TIMEOUT_WAIT;
+               break;
+       case M_TIMEOUT_WAIT:
+               DEBUGP(4, dev, "M_TIMEOUT_WAIT\n");
+               /* numRecBytes */
+               io_read_num_rec_bytes(iobase, &dev->atr_len);
+               dev->mdelay = T_10MSEC;
+               dev->mstate = M_READ_ATR_LEN;
+               break;
+       case M_READ_ATR_LEN:
+               DEBUGP(4, dev, "M_READ_ATR_LEN\n");
+               /* infinite loop possible, since there is no timeout */
+
+#define        MAX_ATR_LEN_RETRY       100
+
+               if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) {
+                       if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) {                                        /* + XX msec */
+                               dev->mdelay = T_10MSEC;
+                               dev->mstate = M_READ_ATR;
+                       }
+               } else {
+                       dev->atr_len = s;
+                       dev->atr_len_retry = 0; /* set new timeout */
+               }
+
+               DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len);
+               break;
+       case M_READ_ATR:
+               DEBUGP(4, dev, "M_READ_ATR\n");
+               xoutb(0x80, REG_FLAGS0(iobase));        /* reset SM */
+               for (i = 0; i < dev->atr_len; i++) {
+                       xoutb(i, REG_BUF_ADDR(iobase));
+                       dev->atr[i] = inb(REG_BUF_DATA(iobase));
+               }
+               /* Deactivate T_Active flags */
+               DEBUGP(4, dev, "Deactivate T_Active flags\n");
+               dev->flags1 = 0x01;
+               xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+               /* atr is present (which doesnt mean it's valid) */
+               set_bit(IS_ATR_PRESENT, &dev->flags);
+               if (dev->atr[0] == 0x03)
+                       str_invert_revert(dev->atr, dev->atr_len);
+               atrc = parse_atr(dev);
+               if (atrc == 0) {        /* atr invalid */
+                       dev->mdelay = 0;
+                       dev->mstate = M_BAD_CARD;
+               } else {
+                       dev->mdelay = T_50MSEC;
+                       dev->mstate = M_ATR_PRESENT;
+                       set_bit(IS_ATR_VALID, &dev->flags);
+               }
+
+               if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+                       DEBUGP(4, dev, "monitor_card: ATR valid\n");
+                       /* if ta1 == 0x11, no PPS necessary (default values) */
+                       /* do not do PPS with multi protocol cards */
+                       if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) &&
+                           (dev->ta1 != 0x11) &&
+                           !(test_bit(IS_ANY_T0, &dev->flags) &&
+                           test_bit(IS_ANY_T1, &dev->flags))) {
+                               DEBUGP(4, dev, "Perform AUTOPPS\n");
+                               set_bit(IS_AUTOPPS_ACT, &dev->flags);
+                               ptsreq.protocol = ptsreq.protocol =
+                                   (0x01 << dev->proto);
+                               ptsreq.flags = 0x01;
+                               ptsreq.pts1 = 0x00;
+                               ptsreq.pts2 = 0x00;
+                               ptsreq.pts3 = 0x00;
+                               if (set_protocol(dev, &ptsreq) == 0) {
+                                       DEBUGP(4, dev, "AUTOPPS ret SUCC\n");
+                                       clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+                                       wake_up_interruptible(&dev->atrq);
+                               } else {
+                                       DEBUGP(4, dev, "AUTOPPS failed: "
+                                              "repower using defaults\n");
+                                       /* prepare for repowering  */
+                                       clear_bit(IS_ATR_PRESENT, &dev->flags);
+                                       clear_bit(IS_ATR_VALID, &dev->flags);
+                                       dev->rlen =
+                                           dev->rpos =
+                                           dev->atr_csum =
+                                           dev->atr_len_retry = dev->cwarn = 0;
+                                       dev->mstate = M_FETCH_ATR;
+
+                                       dev->mdelay = T_50MSEC;
+                               }
+                       } else {
+                               /* for cards which use slightly different
+                                * params (extra guard time) */
+                               set_cardparameter(dev);
+                               if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1)
+                                       DEBUGP(4, dev, "AUTOPPS already active "
+                                              "2nd try:use default values\n");
+                               if (dev->ta1 == 0x11)
+                                       DEBUGP(4, dev, "No AUTOPPS necessary "
+                                              "TA(1)==0x11\n");
+                               if (test_bit(IS_ANY_T0, &dev->flags)
+                                   && test_bit(IS_ANY_T1, &dev->flags))
+                                       DEBUGP(4, dev, "Do NOT perform AUTOPPS "
+                                              "with multiprotocol cards\n");
+                               clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+                               wake_up_interruptible(&dev->atrq);
+                       }
+               } else {
+                       DEBUGP(4, dev, "ATR invalid\n");
+                       wake_up_interruptible(&dev->atrq);
+               }
+               break;
+       case M_BAD_CARD:
+               DEBUGP(4, dev, "M_BAD_CARD\n");
+               /* slow down warning, but prompt immediately after insertion */
+               if (dev->cwarn == 0 || dev->cwarn == 10) {
+                       set_bit(IS_BAD_CARD, &dev->flags);
+                       printk(KERN_WARNING MODULE_NAME ": device %s: ",
+                              dev->node.dev_name);
+                       if (test_bit(IS_BAD_CSUM, &dev->flags)) {
+                               DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
+                                      "be zero) failed\n", dev->atr_csum);
+                       }
+#ifdef PCMCIA_DEBUG
+                       else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
+                               DEBUGP(4, dev, "ATR length error\n");
+                       } else {
+                               DEBUGP(4, dev, "card damaged or wrong way "
+                                       "inserted\n");
+                       }
+#endif
+                       dev->cwarn = 0;
+                       wake_up_interruptible(&dev->atrq);      /* wake open */
+               }
+               dev->cwarn++;
+               dev->mdelay = T_100MSEC;
+               dev->mstate = M_FETCH_ATR;
+               break;
+       default:
+               DEBUGP(7, dev, "Unknown action\n");
+               break;          /* nothing */
+       }
+
+release_io:
+       DEBUGP(7, dev, "release_io\n");
+       clear_bit(LOCK_IO, &dev->flags);
+       wake_up_interruptible(&dev->ioq);       /* whoever needs IO */
+
+return_with_timer:
+       DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
+       dev->timer.expires = jiffies + dev->mdelay;
+       add_timer(&dev->timer);
+       clear_bit(LOCK_MONITOR, &dev->flags);
+}
+
+/* Interface to userland (file_operations) */
+
+static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
+                       loff_t *ppos)
+{
+       struct cm4000_dev *dev = filp->private_data;
+       ioaddr_t iobase = dev->link.io.BasePort1;
+       ssize_t rc;
+       int i, j, k;
+
+       DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid);
+
+       if (count == 0)         /* according to manpage */
+               return 0;
+
+       if ((dev->link.state & DEV_PRESENT) == 0 ||     /* socket removed */
+           test_bit(IS_CMM_ABSENT, &dev->flags))
+               return -ENODEV;
+
+       if (test_bit(IS_BAD_CSUM, &dev->flags))
+               return -EIO;
+
+       /* also see the note about this in cmm_write */
+       if (wait_event_interruptible
+           (dev->atrq,
+            ((filp->f_flags & O_NONBLOCK)
+             || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
+               if (filp->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+               return -ERESTARTSYS;
+       }
+
+       if (test_bit(IS_ATR_VALID, &dev->flags) == 0)
+               return -EIO;
+
+       /* this one implements blocking IO */
+       if (wait_event_interruptible
+           (dev->readq,
+            ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) {
+               if (filp->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+               return -ERESTARTSYS;
+       }
+
+       /* lock io */
+       if (wait_event_interruptible
+           (dev->ioq,
+            ((filp->f_flags & O_NONBLOCK)
+             || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
+               if (filp->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+               return -ERESTARTSYS;
+       }
+
+       rc = 0;
+       dev->flags0 = inb(REG_FLAGS0(iobase));
+       if ((dev->flags0 & 1) == 0      /* no smartcard inserted */
+           || dev->flags0 == 0xff) {   /* no cardman inserted */
+               clear_bit(IS_ATR_VALID, &dev->flags);
+               if (dev->flags0 & 1) {
+                       set_bit(IS_CMM_ABSENT, &dev->flags);
+                       rc = -ENODEV;
+               }
+               rc = -EIO;
+               goto release_io;
+       }
+
+       DEBUGP(4, dev, "begin read answer\n");
+       j = min(count, (size_t)(dev->rlen - dev->rpos));
+       k = dev->rpos;
+       if (k + j > 255)
+               j = 256 - k;
+       DEBUGP(4, dev, "read1 j=%d\n", j);
+       for (i = 0; i < j; i++) {
+               xoutb(k++, REG_BUF_ADDR(iobase));
+               dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+       }
+       j = min(count, (size_t)(dev->rlen - dev->rpos));
+       if (k + j > 255) {
+               DEBUGP(4, dev, "read2 j=%d\n", j);
+               dev->flags1 |= 0x10;    /* MSB buf addr set */
+               xoutb(dev->flags1, REG_FLAGS1(iobase));
+               for (; i < j; i++) {
+                       xoutb(k++, REG_BUF_ADDR(iobase));
+                       dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+               }
+       }
+
+       if (dev->proto == 0 && count > dev->rlen - dev->rpos) {
+               DEBUGP(4, dev, "T=0 and count > buffer\n");
+               dev->rbuf[i] = dev->rbuf[i - 1];
+               dev->rbuf[i - 1] = dev->procbyte;
+               j++;
+       }
+       count = j;
+
+       dev->rpos = dev->rlen + 1;
+
+       /* Clear T1Active */
+       DEBUGP(4, dev, "Clear T1Active\n");
+       dev->flags1 &= 0xdf;
+       xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+       xoutb(0, REG_FLAGS1(iobase));   /* clear detectCMM */
+       /* last check before exit */
+       if (!io_detect_cm4000(iobase, dev))
+               count = -ENODEV;
+
+       if (test_bit(IS_INVREV, &dev->flags) && count > 0)
+               str_invert_revert(dev->rbuf, count);
+
+       if (copy_to_user(buf, dev->rbuf, count))
+               return -EFAULT;
+
+release_io:
+       clear_bit(LOCK_IO, &dev->flags);
+       wake_up_interruptible(&dev->ioq);
+
+       DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n",
+              (rc < 0 ? rc : count));
+       return rc < 0 ? rc : count;
+}
+
+static ssize_t cmm_write(struct file *filp, const char __user *buf,
+                        size_t count, loff_t *ppos)
+{
+       struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
+       ioaddr_t iobase = dev->link.io.BasePort1;
+       unsigned short s;
+       unsigned char tmp;
+       unsigned char infolen;
+       unsigned char s